API 目前处于 Early Preview 阶段, 可能存在诸多不完善与错误之处,欢迎加群交流反馈:加入官方交流群(1073434398)
游戏数据格式总览
RankHub 的 10 个游戏共用一套 profile / score / bucket 形状:统一字段、空值语义、量纲边界,以及每个游戏的 native 字段去哪看。
本页是字段级总览:10 个游戏共用的 profile / score / bucket 形状、空值语义与量纲边界。
三层概念(各回答什么问题、为什么不能跨游戏比较)见概念;
每个游戏 native 里有什么、最佳桶怎么切,见各游戏格式页。
2. 统一 Profile 格式
一条 profile = 一个 RankHub 用户在一个游戏上的一张档案,主键是对外的 profileId(uuid),
不是游戏原生标识。
{
"profileId": "8d1f4a0e-6c2b-4a1e-9d3f-2b7c5e9a0f11",
"game": "maimai",
"player": {
"name": "Player",
"rating": 15234,
"native": { "userId": 10000001, "friendCode": "1234567890123", "courseRank": 0, "classRank": 0, "star": 12 }
},
"isPublic": true,
"origin": "app",
"createdByClientId": "cli_7Q2…",
"syncCapable": false,
"lastSyncedAt": null,
"createdAt": "2026-10-21T18:40:00Z",
"updatedAt": "2026-10-21T18:40:00Z"
}Prop
Type
身份字段不归一:每个游戏建档时填的身份字段不同(maimai 的 friendCode/userId、
arcaea 的 arcaeaId、osu 的 osuUserId…),见各游戏格式页的「身份字段」表,
或 GET /v1/games/{game}/format 的 profile.identityFields。
3. 统一 Score 格式
一条成绩 = 一张谱面 + 一次(或最佳一次)游玩结果。字段全可空是刻意的:
不同游戏只填得上其中一部分,游戏特异的部分一律留在 native。
{
"scoreId": "b1f0c2d3-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"songId": "1234",
"songName": "Example Song",
"type": "dx",
"difficulty": null,
"levelIndex": 3,
"level": "13+",
"achievements": 100.5125,
"score": null,
"rating": 320,
"rank": "sss",
"dxScore": 2500,
"dxStar": 5,
"fc": "ap",
"fs": "fs",
"playTime": "2026-10-01T12:00:00Z",
"native": { "level_index": 3, "dx_score": 2500, "…": "…" }
}Prop
Type
null 不是 0
null 的语义是「这个游戏没有这个概念」,不是 0、不是空串。
跨游戏渲染只用统一字段;游戏特异字段去读 native,不要从 native 反推统一字段。
4. 统一 Bucket(最佳成绩)格式
所有游戏的最佳成绩是一个端点、一个形状:
{
"game": "maimai",
"computedAt": "2026-10-24T02:10:00Z",
"totals": { "total": 15234, "latest": 7234, "archive": 8000 },
"buckets": [
{ "key": "latest", "label": "当期", "total": 7234, "items": [ /* 同 scores 的 items */ ] },
{ "key": "archive", "label": "往期", "total": 8000, "items": [ /* … */ ] }
]
}Prop
Type
桶的成员怎么选、数量几个,全部由服务端决定:有的按版本切(maimai)、有的按评级 (phigros 的 ϕ)、有的按状态(rizline 的 AH)、有的直接来自上游分组(chunithm/orzmic)。 具体规则见各游戏格式页的「最佳成绩桶」表。
5. 跨游戏边界与写入
跨游戏只归一形状,不归数值语义(rating 同名不同义、difficulty 取值随游戏、只能按服务端排序、
没有跨游戏总榜)—— 这四条见概念 · 跨游戏归一化的边界。
写入只有两种形状(RankHub 格式 / 游戏原生格式 native),请求体、每游戏必填项、响应与
400/422/428 语义统一见写入格式;快速选择见
怎么传数据(速查)。
6. GET /v1/games/{game}/format
新增的格式端点:返回该游戏机器可读的 profile/score 格式,用来替代"猜 native 里有什么"。
curl -sS https://api.rankhub.cc/v1/games/maimai/format \
-H "Authorization: Bearer $ACCESS_TOKEN"{
"code": "common.ok",
"message": "ok",
"data": {
"game": "maimai",
"rating": { "name": "DX Rating", "unit": "整数", "range": null, "description": "…" },
"profile": {
"identityFields": [
{ "name": "friendCode", "type": "string", "nullable": false, "required": true,
"unit": null, "range": null, "example": "123456789012345", "description": "好友码(15 位)" }
],
"fields": [
{ "name": "name", "type": "string", "nullable": true, "unit": null, "range": null, "description": "玩家显示名" },
{ "name": "rating", "type": "number", "nullable": true, "unit": "rating", "range": null, "description": "DX Rating" }
],
"nativeFields": [ { "name": "courseRank", "type": "number", "…": "…" } ]
},
"score": {
"keyFields": ["songId", "type", "levelIndex"],
"compareField": "achievements",
"ratingField": null,
"fields": [ /* 该游戏 v1 成绩会填的统一字段 */ ],
"nativeFields": [ { "name": "level_index", "type": "number", "…": "…" } ],
"buckets": [
{ "key": "latest", "label": "当期", "rule": "谱面版本 ≥ 最新版本的谱面,按单曲 rating 取前 15", "totalsKeys": ["total", "latest", "archive"] },
{ "key": "archive", "label": "往期", "rule": "…", "totalsKeys": ["total", "latest", "archive"] }
]
},
"docsSlug": "maimai",
"formatVersion": "1",
"notes": ["…"]
},
"requestId": "…"
}| 返回字段 | 说明 |
|---|---|
rating | 原生评分体系名 / 单位 / 典型区间 / 一句话口径 |
profile.identityFields | 建档身份字段(required + example) |
profile.fields | player 上的统一字段(name、rating) |
profile.nativeFields | player.native 内的字段(原名) |
score.keyFields | 成绩唯一键(统一字段名) |
score.compareField | "只升不降"比较字段 |
score.ratingField | 单曲评分字段;null = 服务端算或只在 native 里 |
score.fields | 该游戏成绩会填的统一字段 |
score.nativeFields | score.native 内的字段 |
score.buckets | 桶 key/label/成员规则/totals 键 |
formatVersion | 本格式描述的版本(不是游戏版本;破坏性变更 +1) |
notes | 消费者必须知道的坑 |
7. 10 个游戏的格式索引
| 游戏 | 原生评分体系 | 量纲 | 桶规则(现行) | 格式页 |
|---|---|---|---|---|
maimai | DX Rating | 整数(floor) | 新曲 15 + 旧曲 35(版本切桶) | maimai |
chunithm | Rating | 小数 2 位(向下截断) | BEST30 + NEW20(50 张平均) | chunithm |
arcaea | Potential(PTT) | 小数 3 位 | v7.0 起 (B50+B10)/60 | arcaea |
phigros | rks | 小数 2 位(四舍五入) | (P1+P2+P3+b27)/30 | phigros |
milthm | Reality | 小数 | 前 20 平均(分母恒 20) | milthm |
notanote | Nrk | 小数 | Best31 加权平均 | notanote |
musedash | 无官方 rating(社区 RL) | 小数 | 社区:递减加权(Σ(v×0.8ᵏ)/5) | musedash |
rizline | RKS | 小数 | (ΣAP5+ΣB35)/40(可退化为 top40) | rizline |
osu | pp | 浮点(无上限) | Σpp·0.95ⁿ(Best 100)+ bonus | osu |
orzmic | Rating | 小数 | 前 N 平均(社区口径) | orzmic |
表中"量纲/桶规则"是摘要;精确公式、边界、版本节点以各游戏格式页为准。 官方公式公开度不同(milthm/notanote/osu 有官方文档;musedash 无官方 rating;其余为社区口径), 各页会逐条标注证据等级。
8. 相关
从 LXNS(落雪咖啡屋)迁移? maimai / chunithm 两页各有一节「从 LXNS 迁移」: 认证、接口、Player/Score 字段、Best 桶与写入语义的逐项对照。