RankHub
各游戏

API 目前处于 Early Preview 阶段, 可能存在诸多不完善与错误之处,欢迎加群交流反馈:加入官方交流群(1073434398)

Arcaea

arcaea 的 Profile 与 Score 格式:arcaeaId/character 身份、player/native 的 potential 统计、score.native 的判定位图字段、服务端算的单曲潜力值与 Best 50 桶。

本页是 arcaea 在 RankHub 上的字段级格式说明。arcaea 与 maimai 一样属于 服务端算分族:单曲潜力值(ptt)由服务端按 score + 曲库定数重算,不看调用方传的 rating。

机器可读版本

GET /v1/games/arcaea/format 返回与本页一致的格式数据(同一份字段表)。 文档可能滞后,以端点返回为准。

arcaea 的评分由服务端算

推成绩时 scores[].rating 对 arcaea 无效:服务端用 score(与 clearType)从曲库定数重算单曲 ptt。 另外 arcaea 的 achievements 恒为 null:它没有「达成率」这个统一字段的对应概念。

Profile 格式

身份字段(建档用)

字段类型必填说明示例
arcaeaIdnumber是Arcaea ID(9 位数字)123456789
characterstring是当前搭档 id(与曲库 characters 对照校验);空串 ⇒ 该游戏既有服务返回 400"character_1"
friendCodestring否9 位好友码(好友码导入链路的标识,也是身份列之一)"123456789"
  • character 虽然来自「玩家资料」而不是「账号标识」,但建档必须有它(既有服务校验), 所以它是身份字段而不是可选展示字段。
  • syncCapable 恒为 false。
  • name 也是建档必填项,但它是统一字段(player.name)而不是身份键,所以不在上表;10 个游戏一致。

统一字段(player)

字段类型可空单位说明
namestring可空—显示名
ratingnumber可空Potential(小数 3 位)取 potential.potential;不是桶内合计(见「最佳成绩桶」)

原生字段(player.native)

原生字段(wire 键)类型单位 / 取值语义可空
arcaeaIdnumber9 位Arcaea ID(原生 arcaea_id)可空
coursenumber整数course 值;语义未在代码/文档里定义(只做透传)可空
characterstring搭档 id当前搭档(原生是整数,wire 上是字符串)可空
friendCodestring9 位数字好友码(原生 friend_code)可空
b30AvgnumberPotential「前 30 平均值」;原生没有这个指标,是 RankHub 自己算的可空
b50AvgnumberPotential「前 50 平均值」;同样是 RankHub 自算可空
  • avatar / nameplate 是档案里的可空展示字段,不在 player.native 里。
  • potential.potential 走统一字段 player.rating;其余 potential 统计(b10_avg、 speculate_r10_avg、max_potential)只在 bests.totals 里出现,不重复进 native。

Score 格式

成绩键与比较值

项值说明
keyFieldssongId / difficulty一条成绩 = 曲目 + 难度(难度是 0~5 的数字,wire 上 difficulty 是它的字符串形式)
compareFieldscore「只升不降」按得分比较(0~10,000,000+)
ratingFieldrating单曲评分字段是统一 rating(原生字段 potential)。值由服务端算:上游自 v4.4.6 起不再返回单曲 ptt
  • difficulty 取值:0=PST、1=PRS、2=FTR、3=BYD、4=ETR、5=INS。
  • wire 上 difficulty 是数字的字符串(如 "2"),levelIndex 是同一个数字的数值形式; 要按难度过滤(?difficulty=2)时传 "2"。
  • 比 score 时不要用 achievements:arcaea 的 achievements 恒 null。

本页 keyFields / compareField / ratingField 里的名字都是 v1 wire 字段名(GameScoreDto 的顶层字段);游戏原生列名写在说明列。

统一字段

arcaea 会填的统一字段:

字段类型单位 / 量纲可空说明
scoreIdstring—否成绩行 id
songIdstring—否曲目 id(曲库 songlist 的 id)
difficultystring"0"~"5"可空难度(数字串)
levelIndexnumber0~5可空难度下标(数值形式)
scorenumber0~10,000,000+可空得分(比较值);全大 Pure 时可超过 1,000 万
ratingnumber小数,3 位可空单曲潜力值(服务端算)
rankstringEX+ / EX / AA / A / B / C / D可空评级(按 score 分档,服务端算)
playTimestring(RFC3339)—可空游玩时间(原生 Unix 秒)

恒为 null 的字段:achievements(arcaea 没有达成率概念)、songName、type、level、 fc / fs(全连语义在 native.clearType 里)、dxScore / dxStar。

原生字段(score.native)

arcaea 的 score.native 是固定的 9 个键:

原生字段(wire 键)类型单位 / 取值语义可空
scoreBelowMaxnumber整数「距理论值的差值」(原生 score_below_max);理论值 = 1,000 万 + 大 Pure 数,所以不等于 10,000,000 - score可空
clearTypenumber0~5本次通关类型:0=Track Lost、1=Normal Clear、2=Full Recall、3=Pure Memory、4=Easy Clear、5=Hard Clear。决定 +0.2 通关奖励可空
bestClearTypenumber0~5该谱面历史最高通关类型;与 clearType 混用会算错单曲 ptt可空
shinyPerfectCountnumber0~物量大 Pure(Shiny Pure)数可空
perfectCountnumber0~物量小 Pure 数可空
nearCountnumber0~物量Far 数(原生字段名用 near 而不是 far)可空
missCountnumber0~物量Lost 数可空
healthnumber0~100结算剩余回忆率(%)可空
constantnumber1.0~12.0,精度 0.1谱面定数(服务端算分用;来自曲库,不在成绩里)可空

评分语义与量纲

单曲潜力值(现行移动版口径)分三段 + 通关奖励,结果 round3(3 位小数):

base(S, C) =
    S >= 10,000,000              ->  C + 2
    9,800,000 <= S < 10,000,000  ->  C + 1 + (S - 9,800,000) / 200,000
    S < 9,800,000                ->  max(0, C + (S - 9,500,000) / 300,000)

chart_ptt = round3( base(S, C) + clear_bonus )

clear_bonus = 0.2   若 clearType 不是 0(即通关:Full Recall / Pure Memory / Normal / Easy / Hard Clear)
            = 0.0   若 clearType = 0(Track Lost)
量量纲说明
score读侧 0~10,000,000+;写侧硬上限 10,010,000每个大 Pure 额外 +1 分,所以理论上限 = 1,000 万 + 大 Pure 数
constant(谱面定数)1.0~12.0,精度 0.1来自曲库;查不到定数时回落到上游给的单曲 ptt
chart_ptt小数,3 位单曲值;通关奖励是逐次成绩绑定的,不看该谱面的历史最高通关状态
player.rating(总分)小数,3 位现行口径 (ΣB50 + ΣB10) / 60:前 50 名单曲值之和 + 前 10 名的额外一份,除以 60
  • 算分口径按移动版现行版本(Best 50 + Best 10,分母 60);历史档案无法从字段上区分旧口径(Best 30 + Recent 10)。
  • 官方从未公开 potential 公式:上表是社区口径(证据等级 community),不是官方规范。

最佳成绩桶

GET /v1/games/arcaea/profiles/{profileId}/bests 返回一个桶:

keylabel成员规则totals 键
best50Best 50全部谱面按单曲 potential 降序取前 50 条(同一谱面不重复;同曲不同难度可各占一格)potential / b30Avg / b50Avg / maxPotential
  • totals.potential = 档案的 potential(round3);不等于 buckets[0].total。
  • buckets[0].total = 桶内 50 条 rating 的和,不是 potential。
  • totals.b30Avg / b50Avg / maxPotential 都是原生没有的派生指标: b30Avg = 前 30 之和 / 30、b50Avg = 前 50 之和 / 50; maxPotential 仍按旧口径 (Σ前30 + Σ前10) / 40 计算,与 totals.potential 不同源。
  • 桶内排序:potential 降序 → score 降序 → songId 升序 → difficulty 升序。

写入(第三方)

写入只有两种形状:RankHub 格式(上文两张统一字段表里的字段)与游戏原生格式(native)。 共享字段、批量上限与失败语义见写入格式;本节只列 arcaea 真正会读的字段。

建档(POST /v1/games/arcaea/profiles)

player 用上文的身份字段(arcaeaId、character 必填,friendCode 可选)+ name,可另给 course / avatar / nameplate 与 potential(snake_case 子键,缺省按 0)。可以同时带 scores[],返回的 player.rating 已是重算后的 potential。身份重复 ⇒ 409。

推成绩(POST .../profiles/{profileId}/scores)

字段类型必给说明
songIdstring支持曲目字符串 id(如 "tiferet");难度是成绩键的另一半
difficultyinteger支持0~5(PST/PRS/FTR/BYD/ETR/INS)
scoreinteger支持0~10,010,000,整数;比较值,小数或越界 ⇒ 400
clearTypeinteger建议0~5,缺省 0 且会按 0 参与单曲 ptt 计算
bestClearTypeinteger建议0~5,必须 ≥ clearType,否则 422
scoreBelowMaxinteger可选0~11,000,000;独立字段,不与 score 做加和校验
shinyPerfectCount / perfectCount / nearCount / missCountinteger可选缺省 0(大 Pure / Pure / Far / Lost 计数)
healthinteger可选缺省 0;只做透传,不参与算分
playTimestring可选RFC3339;晚于服务端 5 分钟以上 ⇒ 422
ratingnumber不要给被忽略:单曲 ptt 由服务端用 score + 定数算(maimai / arcaea 属于这一类)
curl -sS -X POST https://api.rankhub.cc/v1/games/arcaea/profiles/$PROFILE_ID/scores \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "scores": [
      {
        "songId": "tiferet",
        "difficulty": 2,
        "score": 9968755,
        "scoreBelowMax": 31245,
        "shinyPerfectCount": 984,
        "perfectCount": 97,
        "nearCount": 3,
        "missCount": 2,
        "clearType": 3,
        "bestClearType": 3,
        "health": 100
      }
    ]
  }'

以上为示意数据:字段真实,数值虚构。

原生数据(native)

player.native / scores[].native 是游戏原生格式:与顶层同名字段同时出现时 native 优先(浅合并)。 只给 native 时,顶层的 name / arcaeaId / character 可以省略。

建档(player.native)

native 键类型必填换算
namestring(非空)支持→ name
arcaea_idinteger 1~999999999(数字串也收)支持→ arcaeaId
characterstring(非空)支持→ character
courseinteger ≥0可选→ course
friend_codestring可选→ friendCode
avatar / nameplatestring可选→ 同名字段
potential.potential / .b30_avg / .b50_avg / .b10_avg / .speculate_r10_avg / .max_potentialnumber可选→ potential.*(键名保持 snake_case;整体替换顶层 potential,缺的子键按 0)

推成绩(scores[].native)

native 键类型必填换算
song_idstring 或 number(非空)支持→ songId(统一成字符串)
difficultyinteger 0~5支持→ difficulty
scoreinteger 0~10,010,000支持→ score(比较值)
score_below_maxinteger 0~11,000,000可选→ scoreBelowMax
shiny_perfect_count / perfect_count / near_count / miss_countinteger 0~100,000可选→ 同名统一字段
clear_type / best_clear_typeinteger 0~5可选→ clearType / bestClearType
time_playedinteger(毫秒时间戳)可选→ playTime(RFC3339)
health / potential——不读:不参与换算(单曲 ptt 由服务端算)

可写字段 / 不可改

位置可写
player.native(profile)name、course、avatar、nameplate(PATCH .../profiles/{profileId} 的 native 同样生效)
scores[].native(score,除唯一键)score、score_below_max、clear_type / best_clear_type、四个判定计数、time_played
  • potential 不属于可写字段:它是服务端算分汇总,只能在建档时随 player.native 一起给。
  • 不可改:身份字段 arcaea_id / character / friend_code(与现值不同 ⇒ 400 common.invalidArgument); 成绩唯一键 song_id + difficulty(native 里必须给,换了就是另一条成绩)。

本游戏的写入规则

  • 必给:songId + difficulty + score;clearType / bestClearType 建议给(缺省 0 会参与算分)。
  • 比较值是 score:新值不更高 ⇒ 不覆盖,回 improved: false + ignored(notImproved)。
  • 谁算分:单曲 ptt 与 potential 都由服务端算(maimai / arcaea 属于这一类),scores[].rating 被忽略。
  • scoreBelowMax 独立:只校验取值域 0~11,000,000,不与 score 做加和;读侧它是「距理论值的差值」,不要反推 score。
  • 建档身份:character 缺 / 空 ⇒ 400 character is required;同一身份重复建档 ⇒ 409。

消费者注意事项

  1. achievements 恒 null:arcaea 没有达成率字段;要准度信息请读 native 的四个计数。
  2. difficulty 是数字串("2"),不是 FTR 这类标签;标签映射见本页「成绩键」段。
  3. score 可能超过 1,000 万(每个大 Pure +1 分)。任何「分数 ≤ 10,000,000」的假设都会错。
  4. 通关奖励看 clearType,不是 bestClearType:单曲 ptt 与「本次成绩」的通关状态绑定, 用历史最高通关类型会系统性偏高。
  5. totals.potential 与 buckets[].total 不是一个数:前者是按 Best 50 口径算的 potential, 后者是桶内合计(和)。maxPotential 是旧口径派生值,不要拿它跟 potential 比大小。
  6. b30Avg / b50Avg / maxPotential 原生都没有:它们是 RankHub 自算的展示字段, 跨客户端比对时不要假设其他数据源也有。
  7. native.scoreBelowMax 不是 10,000,000 - score:理论值含大 Pure 加分, 两者在满分级成绩上会不一致。
  8. syncCapable 恒 false,不是漏实现。

相关

本页内容

官方交流群二维码官方交流群问题反馈 · 版本资讯 · 成绩交流群号 1073434398