Skip to content

谱面根结构

本节介绍谱面文件的根结构定义。

注意事项

本页部分兼容等级见字段描述

JSON 示例

json
{
  "Version": 0,
  "CompatLevel": 0,
  "BpmList": ...,
  "ChartInfo": ...,
  "JudgeLines": [],
  "PrprExtra": null,
  "PrprExtraFiles": null,
  "PrprUnlockVideoData": null,
  "PrprUnlockVideo": null,
  "PrprUnlockVideoPath": null
}

结构规范

唯一标识符字段名类型描述兼容等级默认值加入版本
10000Versionint谱面版本号,从 1 开始,通常无需关注011
10001CompatLevelint谱面兼容等级,详见概述001
1BpmListList<BPM>谱面 BPM 列表0-1
2ChartInfoChartInfo谱面信息0-1
3JudgeLinesList<JudgeLine>判定线列表0[]1
4PrprExtrastring?PRPR 模拟器扩展,内部存储的仅为Json,详见Phira文档4null1
5PrprExtraFilesDictionary<string, byte[]>?PRPR 模拟器扩展文件列表,string为文件名,byte[]为文件内容4null1
6PrprUnlockVideoDatabyte[]?PRPR 模拟器解锁视频数据,存储为二进制数据,详见Phira文档4null1
100PrprUnlockVideostring?PRPR 模拟器解锁视频路径,兼容用字段,不可与 PrprUnlockVideoData 同时使用4null1

行为规范

  • PrprExtra 字段用于存储 PRPR 模拟器的扩展信息,内容为 JSON 格式字符串。该字段在非 PRPR 模拟器中可以忽略。
  • BpmList 仅包含一个 BPM,Beat 转实际时间(秒)的公式为:实际时间 = Beat / BPM * 60
  • BpmList 包含多个 BPM,可参考以下示例代码进行换算:
csharp
public float BeatTimeToSecond(float beatTime, List<Bpm> bpmList, float bpmFactor)
{
    float totalTime = 0;
    float currentBeat = 0;
    for (int i = 0; i < bpmList.Count; i++)
    {
        var currentBpm = bpmList[i];
        float secPerBeat = 60f / (currentBpm.Bpm / bpmFactor);
        float endBeat = i < bpmList.Count - 1
            ? Math.Min(BeatToBeatTime(bpmList[i + 1].StartTime), beatTime)
            : beatTime;
        // 计算该 BPM 区间的拍数
        float beatInterval = endBeat - currentBeat;
        // 累加时间
        totalTime += beatInterval * secPerBeat;
        currentBeat = endBeat;
        // 达到目标拍数则结束
        if (currentBeat >= beatTime)
            break;
    }
    return totalTime;
}

proto段落

protobuf
syntax = "proto3";
package PhiCommonChart.ChartStructs;

message CommonChart {
  repeated Bpm BpmList = 1;
  Info ChartInfo = 2;
  repeated JudgeLine JudgeLines = 3;
  string PrprExtraJson = 4;
  map<string, bytes> PrprExtraFiles = 5;
  bytes PrprUnlockVideoData = 6;
  string PrprUnlockVideoPath = 100;
  int32 Version = 10000;
  int32 CompatLevel = 10001;
}