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;
}