跳到主要内容

Song 歌曲格式

本文档详细介绍 RhythMC 歌曲的完整格式,基于实际反序列化器实现。

如果你是想手动添加解锁规则,而不是只看字段定义,请直接看 docs/unlock-method-guide.md

目录结构

song_folder/
├── manifest.yml # 歌曲信息 (YAML)
├── world.rmcc # 主世界谱面 (JSON)
├── nether.rmcc # 下界谱面 (JSON)
├── end.rmcc # 末地谱面 (JSON)
└── void.rmcc # 虚空谱面 (JSON)

manifest.yml

格式:YAML

name: 歌曲名称
composer: 作曲家
icon: STONE
alias: 别名
length: 180000
respack_sha1: "0000000000000000000000000000000000000000"
description: "描述"
song_id: 1
version: "1.0"
comments:
- 评论1
- 评论2
player-alias:
- 玩家别名
tags:
- rhythmc:series.maimai
- rhythmc:story.chapter1
unlockSong:
- type: regular
unlockWorld:
- type: permission
value: rhythmc:chart.world
unlockNether:
- type: money
value: 500
unlockVoid:
- type: songacc
song: thisDef
value: 98
字段类型默认值说明
nameStringUnknown Title歌曲名称
composerStringUnknown Composer作曲家
iconMaterialNOTE_BLOCK物品图标
aliasString""别名
lengthint0歌曲时长(毫秒)
respack_sha1String (hex)""资源包SHA1
descriptionString""描述
song_idint0歌曲ID
versionString"1.0"版本
commentsList[]谱师评论
player-aliasList[]玩家别名
tagsList<Key>[]精选集/分类标签键,建议直接填写 namespace:path 形式的收藏品 Key,例如版本、种类、剧情线等
unlockSongList[]整首歌解锁条件,作用于 RawSong
unlockWorldList[]world.rmcc 难度解锁条件
unlockNetherList[]nether.rmcc 难度解锁条件
unlockVoidList[]void.rmcc 难度解锁条件

tags 约定

  • tags 会在反序列化时解析为 Key 列表,而不是普通字符串。
  • 推荐直接复用服务端 collections 里的 tag 定义,这样同一个 Key 可以同时承担歌曲精选集分类、显示文案和解锁逻辑条件。
  • 典型写法:
tags:
- rhythmc:version.maimai_dx
- rhythmc:category.story
- rhythmc:type.original

Level 谱面 (world.rmcc / nether.rmcc / end.rmcc / void.rmcc)

格式:JSON

每个世界结构相同:

{
"meta": { ... },
"tracks": [ ... ],
"effects": [ ... ]
}

旧版解锁字段

  • Song/Chart 仍以 SongManifest 内的旧字段为准:unlockSongunlockWorldunlockNetherunlockVoid
  • 客户端会在反序列化时把这些旧配置转换成统一的 CommonUnlockMethod,但 chart 文件本身不再作为解锁配置入口。
  • 当前内置兼容类型:
    • regular: 直接解锁
    • permission: 要求玩家拥有指定权限,字段通常写在 value
    • money: 要求 player.wattHour >= value
    • songacc: 要求 player.songRecords.<levelId>.acc >= value * 10000
  • songacc.song 支持数字 levelId,或 thisDef 表示当前难度自身。

Meta

{
"uid": 1,
"initialArena": "arenaName",
"offset": 0,
"level": 12.5,
"charters": ["谱师名"],
"comments": ["注释"],
"bpms": [
{ "beat": 0, "bpm": 120 }
]
}
字段类型说明
uidint难度ID (对应 Java 字段 levelId)
initialArenaString初始地图名称 (对应 Java 字段 Arena 对象)
offsetlong时间偏移(毫秒)
leveldouble难度等级
chartersList谱师列表
commentsList注释
bpmsListBPM事件列表

BPM

{ "beat": 0, "bpm": 120 }
字段类型说明
beatdouble起始拍数
bpmdoubleBPM值

Track

{
"id": 0,
"speedEvents": [],
"xTransformEvents": [],
"yTransformEvents": [],
"zTransformEvents": [],
"xRotateEvents": [],
"yRotateEvents": [],
"zRotateEvents": [],
"xScaleEvents": [],
"yScaleEvents": [],
"zScaleEvents": [],
"notes": []
}

Note

重要:位置、缩放、旋转均为数组格式:

{
"noteType": 0,
"beat": 4.0,
"pos": [0, 0, 0],
"scale": [1, 1, 1],
"rotation": [0, 0, 0],
"holdGroup": -1
}
字段类型说明
noteTypeint音符类型 (0=TAP, 1=LOOK, 2=HOLD, 3=DODGE)
beatdouble拍数位置
posdouble[3][X, Y, Z] 坐标 (数组格式)
scalefloat[3][X, Y, Z] 缩放 (数组格式)
rotationfloat[3][X, Y, Z] 旋转角度 (数组格式)
holdGroupint长押组ID (-1表示非长押)

NumEvent

{
"startBeat": 0,
"endBeat": 4,
"startValue": 1,
"endValue": 2,
"easingType": 0
}
字段类型说明
startBeatdouble起始拍数
endBeatdouble结束拍数
startValuedouble起始值
endValuedouble结束值
easingTypeint缓动函数ID

缓动函数 ID 对照表

ID名称说明
0LINEAR线性变化
1IN_SINE正弦加速进入
2OUT_SINE正弦减速离开
3IN_OUT_SINE正弦加速进入、减速离开
4IN_QUAD二次加速进入
5OUT_QUAD二次减速离开
6IN_OUT_QUAD二次加速进入、减速离开
7IN_CUBIC三次加速进入
8OUT_CUBIC三次减速离开
9IN_OUT_CUBIC三次加速进入、减速离开
10IN_QUART四次加速进入
11OUT_QUART四次减速离开
12IN_OUT_QUART四次加速进入、减速离开
13IN_QUINT五次加速进入
14OUT_QUINT五次减速离开
15IN_OUT_QUINT五次加速进入、减速离开
16IN_EXPO指数加速进入
17OUT_EXPO指数减速离开
18IN_OUT_EXPO指数加速进入、减速离开
19IN_CIRC圆形加速进入
20OUT_CIRC圆形减速离开
21IN_OUT_CIRC圆形加速进入、减速离开
22IN_BACK回退加速进入
23OUT_BACK回退加速离开
24IN_OUT_BACK回退加速进入、离开
25IN_ELASTIC弹性加速进入
26OUT_ELASTIC弹性减速离开
27IN_OUT_ELASTIC弹性加速进入、减速离开
28IN_BOUNCE弹跳进入
29OUT_BOUNCE弹跳离开
30IN_OUT_BOUNCE弹跳进入、离开
31IN_SQUARE平方加速进入
32OUT_SQUARE平方减速离开
33IN_OUT_SQUARE平方加速进入、减速离开

Effect

{
"effectType": "HOLOGRAM",
"beat": 4.0,
"properties": { ... }
}
字段类型说明
effectTypeString效果类型名称
beatdouble触发拍数
propertiesJSONObject效果参数

效果类型 (String)

类型说明
HOLOGRAM全息图
REMOVE_HOLOGRAM移除全息图
TITLE标题显示
FIREWORK烟花
TIME时间控制
EFFECT药水效果
CLEAR_EFFECT清除药水效果
WEATHER天气
ARENA切换地图
TEXT_DISPLAY文本显示
TEXT_DISPLAY_EFFECT文本显示效果
TEXT_DISPLAY_SYNC_TRACK文本跟随轨道
TEXT_DISPLAY_DESYNC_TRACK文本分离轨道
HIDE_NOTES隐藏音符
GLOW_COLOR发光颜色
MESSAGE消息
TEXT_DISPLAY_REMOVE移除文本显示

完整示例

manifest.yml

name: Example Song
composer: Example Artist
icon: MUSIC_DISC
alias: example
length: 120000
description: "An example song"
song_id: 1
version: "1.0"
comments: []
player-alias: []
tags:
- demo
unlockSong: []
unlockWorld: []
unlockNether: []
unlockVoid: []

world.rmcc

{
"meta": {
"uid": 1,
"initialArena": "arena1",
"offset": 0,
"level": 10.0,
"charters": ["Charter"],
"comments": [],
"bpms": [
{ "beat": 0, "bpm": 120 }
]
},
"tracks": [
{
"id": 0,
"speedEvents": [],
"xTransformEvents": [],
"yTransformEvents": [],
"zTransformEvents": [],
"xRotateEvents": [],
"yRotateEvents": [],
"zRotateEvents": [],
"xScaleEvents": [],
"yScaleEvents": [],
"zScaleEvents": [],
"notes": [
{
"noteType": 0,
"beat": 4.0,
"pos": [0, 0, 0],
"scale": [1, 1, 1],
"rotation": [0, 0, 0],
"holdGroup": -1
}
]
}
],
"effects": []
}