RankHub
各游戏

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

MuseDash

Muse Dash 官方没有 rating 系统:本页说明社区 RL 口径、Best 30 桶规则,以及 profile / score 的统一字段与原生字段(native)。

Muse Dash 游戏内没有 rating 系统。 只有单局评级(金S / 银S / S / A / B / C / D,按准确率分档) 与单局分数(0~1,000,000 量级),没有跨曲汇总的「rating」。

本页的 rating / RL(Rating Level)全部是社区口径,不是官方数据,请勿对外表述为「官方 rating」。

机器可读版本

本页字段表与服务端 GET /v1/games/musedash/format 一一对应(profile.identityFields / profile.fields / profile.nativeFields、score.keyFields / score.compareField / score.ratingField / score.fields / score.nativeFields / score.buckets)。文档可能滞后,以端点返回为准。

Profile 格式

一张 Muse Dash 档案 = 一个 RankHub 用户在 Muse Dash 上的一张卡。对外主键是 profileId(uuid)。

身份字段(建档用)

字段类型必填说明示例
musedashUidstring是存档信封里的玩家匿名 id。校验是 [0-9A-Za-z_-]、长度 1~32;真实存档值是 32 位十六进制"0a1b2c3d4e5f60718293a4b5c6d7e8f9"
  • 缺失/形状不合法 ⇒ 400(文案见写入格式 §4);建档只落库。

统一字段(player)

字段类型说明
namestring | null玩家名(原生 player_name),建档必填(可来自原生 Account.PlayerName)
ratingnumber | null总评 RL(社区口径),取档案汇总里服务端算好的值,四舍五入到 3 位小数
  • rating 只是排序键:建档时传的 rating 只是提示,返回的以服务端按成绩重算的值为准(没有成绩就是 0);
  • name 也可以由原生 Account.PlayerName 提供(见原生数据(native))。

这个 rating 不是官方值

player.rating 是服务端按本平台口径重算的 Best 30 平均(见下文), 与社区查分站的 RL 也不是同一套汇总规则。把它当「本平台的排序键」用,不要当官方评分引用。

原生字段(player.native)

字段类型说明
uidstring | null32 位十六进制的玩家匿名 id(与身份字段同源)
levelnumber | null等级。按 1 + floor(Exp / 100) 推导,官方公式未公开
bestCountnumber | nullBest 30 里实际有几条
fullComboCountnumber | nullFC 谱面数

没透出的原生字段:exp、language(在存档 Account 里,落库但不在 wire 上)。

Score 格式

成绩键与比较值

项值
成绩键 keyFieldsscoreId(wire 顶层没有能重建存储键的字段,见下)
存储键(原生)uid,形如 "{songUid}_{difficulty}"(如 0-28_3),落在 score.native.uid
比较字段 compareFieldscore(原始单局得分)
单曲评分字段 ratingFieldrating(原生列 performance,社区单曲 RL)
tie-break无(单个比较值)
  • 存储键是 uid,不是 songId:一条 uid 已经包含曲目与难度(如 0-28_3), wire 顶层没有它(只在 score.native.uid),所以端点 keyFields 只能退到 scoreId;
  • songUid 自身含连字符(如 43-53),拆键时不能简单 split('_');
  • wire 上 songId 是 songUid(不含难度后缀),同曲不同难度是不同成绩,可同时进桶。

统一字段

字段类型说明
scoreIdstring成绩行 id
songIdstring曲目 uid(原生 song_uid,如 0-28)
songNamenull恒 null:原生存档不带曲名
difficultystring | null难度号字符串:"1" ~ "5"
levelIndexnumber | null难度号数字:1 ~ 5
levelstring | null曲库给的显示等级,是字符串,可能是 "?" / "¿" / "a2" 这类占位符
achievementsnumber | null准确率,量纲 0~1
scorenumber | null单局得分(0 ~ 1,000,000 量级)
ratingnumber | null单曲 performance(社区 RL)
fcstring | null全连时为 "fc",否则 null
nativeobject | null原生字段,见下表

恒为 null(原生没有或无映射):type、rank、dxScore、dxStar、fs、playTime。

难度号与难度名:1 萌新 / 2 高手 / 3 大触 / 4 隐藏 / 5 弹幕。 注意社区曲库里 difficulty 是 0-indexed(0~4),服务端归一入曲库时已经 +1,两者不要混用。

原生字段(score.native)

字段类型说明
uidstring成绩行 id:{songUid}_{difficulty}(成绩键)
evaluatenumber | null结算评级枚举。本服务注释到 0=D 1=C 2=B 3=A 4=S 5=银S;社区口径共 7 档(还缺「金S」)
combonumber | null本次最大连击
clearnumber | null通关标记(缺省 1);原生语义未公开
chartRlnumber | null曲库给的相对难度 relative(diffdiff,不是官方定数);实测 1.03 ~ 12.5
failCountnumber | null该谱面的失败次数(缺省 0)

评分语义与量纲

单曲 performance(社区口径):

performance(acc, relative) =
  1                                , acc = 100
  (f − f² + f⁴) × relative         , 其它,f = acc / 100
符号含义量纲
acc单局准确率社区口径 0~100;本服务用 0~1(等价,f = acc/100)
relative谱面「相对难度」(diffdiff)小数,实测 1.03 ~ 12.5;不是官方定数
结果单曲 RL无量纲小数,随 relative 浮动

acc = 100 时 performance 恒为 1(与 relative 无关):performance 上限并不高, 单曲 RL 主要由玩家准确率决定,relative 只做难度缩放。

relative 是从排行榜数据反推的「等效等级」:按玩家间 accJudge 差值排难度序,再以「等级 10」为中心 按排名位置做正态插值,所以不能与游戏内显示的等级直接比较。另两条社区规则: 上线不足一周的曲子 relative 记 0(不参与 RL);使用加分角色/精灵的成绩被排除。

总评汇总 —— 两套口径,量级不同:

口径公式说明
社区RL = ( Σ vₖ × 0.8^(n−1−k) ) / 5全谱面递减加权,分母恒为 5,无 top N 截断
本平台RL = ( Σ 前 30 条 performance ) / 30Best 30 算术平均,不足 30 条也除 30

同样一批成绩两者能差一个量级:只有 1 条 performance = 12 时,本平台 12/30 = 0.4、社区 12/5 = 2.4(6 倍)。

  • 精度:两套公式都不做舍入;wire 上总评与桶合计四舍五入到 3 位小数。
  • 上界的现实差距:写入守卫的 bounds.rating 是 [0, 1000],而实测社区 RL 值域在 0 ~ 20 附近 (头部约 12.35)—— 上界宽松了 50 倍以上,不要把它当语义区间。

最佳成绩桶

GET /v1/games/musedash/profiles/{profileId}/bests 固定返回一个桶:

keylabel成员规则totalsKeys
best30Best 30按谱面去重(uid = 曲目 + 难度,同曲不同难度可同时进桶)→ 排除曲库缺失(relative 不可得)的谱面 → performance 降序取前 30rl、bestCount
  • totals.rl:总评(top30 之和 ÷ 30,四舍五入 3 位);totals.bestCount:桶里实际有几条;
  • buckets[0].total:桶内各条 rating 的和,不是总评 RL(RL 是平均)。

写入(第三方)

请求体形状、idempotencyKey、批量上限、428/403 等通用规则见写入格式; 这里只写 Muse Dash 真正特殊的部分。

两种写形状

  • RankHub 格式:直接给统一字段(songId / difficulty / score / accuracy …);
  • 游戏原生格式(native):player.native / scores[].native 里放原生形状,服务端按唯一一套换算归一, 与顶层同名字段同时出现时 native 优先;不合法 ⇒ 400 common.invalidArgument(message 指明键)。

本游戏的写入规则

  • 必给:songId + difficulty(缺失/非法直接 400)+ score + accuracy; rating 缺失不报错(服务端会用曲库 relative 现算),但曲库查不到时算成 0,所以真值请自己给。
  • accuracy 收 0~1 或 0~100:>1 会被当成百分数自动除 100,落库统一成 0~1。
  • 比较值是 score(原始得分),不是 rating;同一 uid 只有分数更高才会覆盖。
  • 谁算分:单曲 rating(performance)由调用方给(maimai / arcaea 之外的游戏都是调用方给, 只有那两者服务端算);不给时服务端按社区公式现算。总评 RL(Best 30 ÷ 30)由服务端重算, 与社区查分站的递减加权口径不同。
  • 唯一键:uid(= {songUid}_{difficulty});同曲不同难度是两条成绩,可同时进桶。
  • 可选但常用:evaluate(0=D … 5=银S,缺省 0)、combo、cleared(false 才写未通关)、 fullCombo(落 fc)、constant(曲库查不到时当 relative 参与算分)。playTime 不读取。
  • 通用上界(写入守卫开启时生效,默认 off):score / achievements 越界 400, rating / constant / accuracy 越界或 playTime 晚于现在 1 小时 422。

原生数据(native)

建档:原生对象里取身份与名字。

native 键类型换算
UserIDstring,必填musedashUid
AccountJSON 字符串或对象取其中的 PlayerName → name;取不到时回落 UserID
Achievement—忽略(成绩逐条用 scores[].native 推)

成绩:原生 highest 行是一条一条的。

native 键类型换算
uidstring,必填,形如 <songUid>_<1..5>uid + songId(songUid)+ difficulty(1~5,数字)
accuracynumber,必填,0~1accuracy(与统一字段同为 0~1 口径)
score / combo / evaluate整数 0~100000000同名统一字段
clear数字或布尔cleared(clear !== 0)
  • ❗ native.accuracy 只收 0~1:超过 1.000001 直接 400,不会帮你折算 (只有顶层 accuracy 才有 >1 ⇒ /100 的宽容);
  • 可写字段(native,除身份与唯一键外全部):profile 侧 Account.PlayerName(→ name)、level、 best_count、full_combo_count(建档或 PATCH /v1/games/musedash/profiles/{profileId} 的 native); score 侧 accuracy / score / combo / evaluate / clear。
  • 不可改:身份 musedashUid(原生 uid)—— PATCH 的 native 里给了不同的 UserID ⇒ 400,message = native.musedashUid cannot be changed (identity field);成绩唯一键 uid 顶层与 native 都给时必须一致,不一致以 native 为准(会写到另一张谱面上)。

示例(示意数据) —— 一条推成绩请求(原生格式):

curl -sS -X POST https://api.rankhub.cc/v1/games/musedash/profiles/$PROFILE_ID/scores \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "scores": [
      {
        "native": { "uid": "0-28_3", "accuracy": 0.9842, "score": 302027, "combo": 612, "evaluate": 5, "clear": 1 },
        "rating": 9.842
      }
    ]
  }'

消费者注意事项

  1. rating 是社区口径,不是官方 rating:对外表述必须写清「社区 RL」。
  2. 本平台总评与社区总评不是同一个数:本平台 Σ前30 / 30,社区递减加权 Σ(v×0.8ᵏ) / 5; 直接对比会得到「差一个量级」的结论。
  3. achievements 是 0~1;score 是单局得分(0~1,000,000 量级),两者不是一回事。
  4. difficulty 是 "1"~"5" 字符串、levelIndex 是 1~5 数字;level 是曲库显示串, 可能是 "?" / "¿" / "a2",不能当数字解析。
  5. songName 恒为 null:曲名要自己接曲库。
  6. evaluate 枚举不全:本服务只到 5 = 银S,社区口径有 7 档(缺「金S」)。
  7. 曲库缺失的谱面不进桶:relative 取不到时该条 chartRl 为 null、不参与 RL。
  8. 推成绩时 rating 优先:调用方给了就用;没给则按 performance = (acc − acc² + acc⁴) × chartRl 用曲库 relative 现算(曲库缺失则为 0)。

相关

本页内容

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