User:UnknownFeathers


 * 警告，这里只是谱面格式的介绍帖，自制谱一切后果自负！


 * 由于lowiro明确讲过禁止传播官方以外的版本，所以本页面将保持孤立状态，严禁链入/引用!

总论
谱面的后缀名为aff，所有在安装包中的官方谱面（即Arcaea曲包中的曲目的PST/PRS/FTR难度和愚人节版本中的愚人节谱面）没有加密，可以直接阅读

谱面所在位置为(Android apk)/assets/songs/<曲目id> 或 (iOS ipa)/Payload/Arc-mobile.app/songs/<曲目id>里，其中0，1，2，3分别对应PST，PRS，FTR，BYD. 其他的是什么东西自己打开便知道了

理论上更改aff文件以及对应音源后重新正确封包即可游玩

在该文件里并没有曲名、难度等级、谱师之类的歌曲信息，请移步歌曲信息(songlist)格式

关于解歌条件的部分，请移步解锁条件(unlocks)格式

关于曲包相关内容，请移步曲包信息(packlist)格式

文件头
所有谱面文件开始部分都一定包含以下两行： AudioOffset:x - 第一行代码表示谱面整体向前(-)/向后(+)移动x毫秒

一般情况下x=0，这样物件对应的毫秒数即为歌曲播放进度的毫秒数

但是如果x≠0，物件在音乐中实际对应的毫秒数=物件时间+x

鉴于有些音源以开头为基准的第一个采音不在整拍上，所以可能有时候的确需要x≠0

有些谱面会在AudioOffset行下方加入一行TimingPointDensityFactor： AudioOffset:x TimingPointDensityFactor:y - 这行代码表示音弧和长条的物量密度调整为正常值的y倍

y=1时效果与省略此行相同

如果y的值特别大的话...

注：在"-"所在的行之前，你可以参照以上两行的格式写自己的“标注”

例如“ChartVersion:2”，游戏会正常读取并记录相关数据，但是并不会有任何效果；物件的读取从"-"所在的行之后开始

Timing
Timing代码如下 timing(t,bpm,beats);
 * t(ms)：Timing起始位置，数字为整数
 * bpm(拍/分钟)：节奏速度，数字为不可省略小数点后两位的一个数
 * beats(四分音个数(拍))：表示每多少个四分音符(拍)为一小节（出现一条小节线），数字为不可省略小数点后两位的一个数，比如4.00就是4/4拍，代表四拍一小节
 * 需要注意的是每个谱面一定要有一个t=0的Timing！而且其bpm数值不可为负数！

地面Note & 地面Hold
地面Note & 地面Hold代码如下 (t,lane); hold(t1,t2,lane);
 * t(ms):地面Note所在时间，数字为整数
 * t1,t2(ms):地面Hold物件开始/结束的时间，数字为整数，t1＜t2
 * lane(0～5):物件所在轨道，一般情况下轨道的编号从左到右依次为1，2，3，4，绝大部分情况下也只需要用到1~4轨道
 * 4.0.0版本起新增“enwidenlane”的scenecontrol类型（见下文Scenecontrol），在标记为启用后，轨道由4条扩充至6条，在1轨左侧新增0轨，在4轨右侧新增5轨；在不在谱面文件内标记开启“enwidenlane”的情况下，游戏依然会正常摆放相应物件 （但是你打不到）

Arc & 天空Note（Arctap）
Arc & 天空Note（Arctap）代码如下 arc(t1,t2,x1,x2,easing,y1,y2,color,hitsound,skylineBoolean); arc(t1,t2,x1,x2,easing,y1,y2,color,hitsound,true)[arctap(tn1),arctap(tn2),……,arctap(tnm)];
 * t1,t2(ms)：Arc物件开始/结束的时间，数字为整数，t1可以等于t2，当t1=t2时，Arc与判定线平行，物量为0，且此种类型的Arc可以起到连接Arc组的作用（即宏观上算作不分立的Arc，不能换手）
 * 只有skylineBoolean=true时t1可以大于t2
 * x1,x2：代表Arc物件开始/结束时的横坐标，数字为不可省略小数点后两位的一个数
 * easing(b,s,si,so)：Arc滑动方式. b=Both=Sine in & out，s=straight，si=Sine in，so=Sine out. 当t1=t2时该参数无意义（都是直的）
 * si与so可以两个在一起自由组合(如siso,sisi等)，siso代表x方向上滑动方式为si、y方向上滑动方式为so
 * y1,y2：代表Arc物件开始/结束时的纵坐标，数字为不可省略小数点后两位的一个数
 * color：Arc颜色，0蓝，1红，2绿，在skylineBoolean=true时该参数无意义，且能被游戏正常读取 （很多官方谱面中出现color=3的黑线推测是为方便谱师写黑线时做标记用）
 * 只有愚人节版本（v2.0.2、v2.6.1、v3.5.3、v3.12.6）可以正常读取绿Arc，其他版本不能正常读取绿Arc
 * hitsound：v4.0.0实装，给予Arctap特殊打击音效，对整条黑线上所有的Arctap生效，将它们替换为特殊样式，并应用特殊打击音效. 举例：填写glass_wav时，将把/(songid)/glass.wav作为打击音效，填写“none”代表不应用特殊音效，无arctap或skylineBoolean=false时，该参数无意义（但是不能乱填，起码不能让游戏崩溃），等价于填写“none”
 * skylineBoolean(false,true)：判定这一段Arc是不是天空Note的判定线（黑线）. false为普通Arc，true为天空Note的判定线，但是只要有Arctap本参数就无意义（会将此Arc的类型强制转换为天空Note的判定线）
 * 当skylineBoolean=true，并且该Arc上有天空Note（Arctap）时，代码如下
 * tn1,tn2,……,tnm(ms)：m个天空物件在这条判定线上的时间点，数字为整数，且不能超出t1和t2的区间

Camera
camera(t,transverse,bottomzoom,linezoom,steadyangle,topzoom,angle,easing,lastingtime); 本功能在v1.7.0在代码中被标记关闭，v1.8.0中相关代码被彻底删除，但在之后的愚人节版本（v2.0.2、v2.6.1、v3.5.3、v3.12.6）中被恢复
 * 于v1.6.1实装，代码如下：
 * t(ms)：camera开始时间
 * transverse：轨道底部左右横向移动，正←负→.
 * bottomzoom：轨道底部上下移动，正↓负↑
 * linezoom：判定线前后移动，正远离负靠近
 * steadyangle(°)：原地的摄像头视角转向，正逆时针负顺时针
 * topzoom：轨道顶部的上下移动，正↓负↑
 * angle(°)：底盘依照屏幕中心旋转，正逆时针负顺时针
 * easing(qi,qo,l,reset,s)：camera移动方式，qi=Cubic in，qo=Cubic out，l=Linear，s=Sine in&out
 * lastingtime(ms)：本语句持续时间

Scenecontrol
于v2.6.1实装，代码如下： scenecontrol(t,type,*param1(float),*param2(int)); 目前已知可填写的type及其参数情况如下：
 * t(ms)：开始时间
 * type：要执行的场景控制类型
 * param：参数，“*”代表可选，但是两个参数同时出现/不出现
 * trackhide：隐藏轨道
 * trackshow：显示轨道
 * 不填参数
 * 使用例：scenecontrol(10240,trackhide);
 * trackdisplay：轨道透明度控制
 * （注意：此type并未在任何官方谱面中使用过，但是包含此type的sc语句可以正常被Arcaea本体读取并正确执行，请谨慎使用 （ 高效率程序员看不惯单单是轨道显示/隐藏就写了两个type，于是造了个轮子（结果惨遭忽视）） ）
 * param1：轨道从当前alpha变换到目标alpha(param2)所要花费的时间，数字为不可省略小数点后两位的一个数，单位为秒，填0.00等价于填1.00
 * param2：轨道需要变换到的目标alpha值，可以填非负整数；<255时有黑色背景特效，否则没有；=0为轨道完全透明，=255为轨道不透明，>=256时透明度对256取余数计算.
 * 使用例：scenecontrol(20480,trackdisplay,6.00,0);
 * redline（v3.0.0新增）：Arcahv解锁演出时的背景红线效果
 * param1：红线存在的时间，数字为不可省略小数点后两位的一个数，单位为秒
 * param2：未知参数
 * 使用例：scenecontrol(40960,redline,1.88,0);


 * arcahvdistort（v3.0.0新增）：Arcahv解锁演出时的背景变形效果
 * arcahvdebris（v3.0.0新增）：Arcahv解锁演出时的背景碎片效果
 * param1：从当前alpha变换为指定alpha的持续时间，数字为不可省略小数点后两位的一个数，单位为秒
 * param2：目标alpha值
 * 使用例：scenecontrol(1000,arcahvderis,1.00,128);
 * hidegroup（v3.5.3新增）：是否隐藏该时间组(timinggroup)内的note(由param2决定)
 * param1：未知参数
 * param2：隐藏或显示该时间组的note（1/0）
 * 使用例：scenecontrol(81920,hidegroup,0.00,1);
 * 需要放在时间组(timinggroup)中使用


 * enwidencamera（v4.0.0新增）：使Camera按一定比例远离轨道，同时skyinput也会变高
 * enwidenlanes（v4.0.0新增）：使轨道两侧的ExtraLane展示
 * 两种enwiden类型的scenecontrol的param用法如下:
 * param1：持续时长（ms）
 * param2：淡入或淡出该事件展示的效果（1/0）
 * 使用例：scenecontrol(1000,enwidencamera,1000.00,1);
 * enwidencamera的相机移动效果实际相当于camera(t,0,450,450,0,0,0,s,duration);语句，但enwidencamera会同时将Sky Input线移动至y=1.61处.

Timinggroup
于v3.0.0实装，代码如下： timinggroup{ //正常aff语句 }; 可以通过在括号内添加标识来达到特殊效果，不填则不使用任何特殊效果. 不同特殊效果之间可以叠加，用下划线隔开即可，如timinggroup(noinput_anglex200).
 * 每一个timinggroup语句块中的语句（物件）使用其内部单独的timing语句（并且至少包含一个timing语句），因此可以实现同时刻不同note流速
 * timinggroup语句块中的timing语句不会产生小节线，小节线是由所有timinggroup语句块外面的timing语句决定的
 * 一张谱面理论可以存在无限多个timinggroup语句块，也可以仅由t=0的timing和无数timinggroup组成

目前已有特殊效果标识有：
 * noinput（v3.5.3新增）：
 * 此时本timinggroup内的物件只有显示效果，没有打击效果和物量，不会判定为击中
 * noinput中的实体Arc和hold在经过判定线后依然会消失而不会直接穿过（v3.12.6起）
 * noinput中的实体Arc保留了部分判定，因此依然可以实现一些正常的判定特性，如当异色Arc相交时，可以用任意一只手去接/换手
 * v3.12.6的愚人节曲目 Mistempered Malignance 中的同色Arc段便是利用这个特性实现的，原理是在其中一条同色Arc上放了一条完全重叠的异色noinput隐藏Arc
 * fadingholds（v3.12.2新增）：
 * 此时在未击中Hold时，Hold会进行alpha渐变效果，直到变成未击中时的alpha
 * 此效果仅对timinggroup中的Hold生效，其他物件不受影响
 * 与noinput叠加时会正常触发fadingholds效果（但是你仍然无法击中hold）
 * anglex/angley（v3.12.6新增）：
 * 分别表示对timinggroup内的天键的轨迹进行旋转，旋转轴为经过天键在判定平面落点的平行于x/y轴的直线，其后需要接一个非负整数参数，表示旋转角（单位：度）的10倍
 * 实际落点和判定位置不受影响
 * 此特殊效果仅影响天键，不影响地面tap/实体Arc/黑线
 * x轴旋转时正方向为上转，y轴旋转时正方向为向左转
 * 两者可以叠加，叠加时先绕x轴平行线转再绕y轴平行线转，不受参数顺序影响
 * 例：timinggroup(angley3400_anglex200)则会将所有天键的轨迹绕其对应的x轴平行线向上旋转20°然后绕其对应的y轴平行线向右旋转20°

Flick
代码如下： flick(t,x,y,vx,vy);
 * t(ms):Flick所在时间
 * x,y:Flick初始位置的横、纵坐标，数字为不可省略小数点后两位的一个数
 * vx,vy:Flick滑动方向向量的横向、纵向值，数字为不可省略小数点后两位的一个数，实际滑动方位角为正右方基础上逆时针arctan(vy/vx)
 * 官方谱面目前还没有实装过Flick，请谨慎使用Flick
 * v3.5.3开始的版本删除了部分Flick代码，因此这些版本不能正常读取flick

综合

 * 代码排列顺序除了第一个t=0的Timing外不受限制.
 * 通常（无Camera）情况下，实体Arc的起始点和结束点、Arctap的坐标不应超出(-0.50,0.00)，(1.50,0.00)，(0.00,1.00)，(1.00,1.00)四个点组成的梯形（Beyond难度中后两个点改为(-0.25,1.00)，(1.25,1.00))
 * 存在enwidencamera的情况下，实体Arc的起始点和结束点、Arctap的坐标不应超出(-1.00,0.00)，(2.00,0.00)，(-0.25,1.61)，(1.25,1.61)四个点组成的梯形（Beyond难度中后两个点改为(-0.63,1.61)，(1.63,1.61))
 * 超出Beyond难度梯形范围可能会导致部分Arc或Arctap位于屏幕外
 * 当Arc类型为黑线时，其没有坐标界限（如 Dreamin' Attraction!! FTR的长方形隧道、Fracture Ray FTR的开头倒数），但一般来说为了美观都会将其放置在上述的梯形区间内
 * 但其搭载的Arctap仍需位于坐标界限内
 * Tempestissimo 的BYD谱面中间的四押的部分Arc的y坐标达到了1.01，以此达成了整条音弧在上下剧烈颤动以及高架桥的视觉效果

物量计算
有的时候我们并不能玩到自制谱面，这个时候我们可以通过以下方式计算本谱物量： 需要指出，Hold和Arc可能会出现误差，原因在于末尾处可能刚好超过计数点零点几毫秒，不过即使如此正常情况下误差总计也不会太大
 * 统计所有地面note和arctap数量，每统计一个+1
 * Hold物件逐个计算，每个hold被起始位置所在BPM的1/2拍（即8分音符，或(30000/BPM)毫秒）分成一个一个判定块，每个判定块开始处物量+1，每个Hold最后一个判定块不加物量
 * BPM＞=255时，判定块间隔变为所在BPM的1拍（即4分音符，或(60000/BPM)毫秒）
 * BPM=0时，本物件不存在，更无从谈及物量
 * BPM＜0时，按BPM的绝对值进行计算
 * 当Hold长度短于本来的判定块长度时，整个物件对半分为两个判定块，最后一个判定块同样不计入物量
 * 当Hold跨越timing时，按Hold起始点的BPM进行计算
 * 当存在TimingPointDensityFactor时，每个判定块的时间需要除以TimingPointDensityFactor的值
 * Arc物件基本与Hold相同，注意每个arc语句单算
 * 持续时长为0的arc物量为0
 * skylineBoolean为true时物量为0
 * Arc可以连接形成Arc组，此时头Arc按照Hold方式计算，其它Arc物量+1（存疑）
 * 连接条件：与Arc颜色无关，要求前一个Arc结尾和后一个Arc开头x坐标差小于0.1，y坐标相等，时间差小于10
 * 即使不在同一timinggroup内也可以连成Arc组（具有noinput参数也可以）

还是一句老话，编完请你自己high，不要大规模传播!!

---


 * 本页保持孤立!

总论
本文件是关于更改歌曲信息的.

关于谱面本身的格式，请移步谱面格式

关于解歌条件的部分，请移步解锁条件(unlocks)格式

关于曲包相关内容，请移步曲包信息(packlist)格式

阅读总论
本文件名为songlist，包含了除教程及愚人节外的全部歌曲相关信息.

本文件在安卓apk安装包里的位置为 /assets/songs/songlist，在苹果ipa安装包内位置为 /Payload/Arc-mobile.app/songs/songlist

本文件为json文档，有大量花括号与中括号，格式要求较为严格，最后一个字段后不能出现多余的逗号. 本文件用两空格缩进整理版面.

'''任何对本文件的修改都会导致游戏程序崩溃，这是因为程序中对本文件有哈希校验. '''

''事实上，可通过修改特定的函数，使程序在哈希校验失败时不调用结束进程的函数，从而达到修改songlist等文件的目的. ''

从这里开始就会涉及到危险操作了,请为自己的行为负责!

框架
本文件总体框架如下. 每一首歌曲的信息互不干扰. {  "songs": [ {      // song 1 },    {       // song 2 } ...  ] }

细节解析

 * 数据格式：
 * string -- 字符串 例："brandnewworld"
 * int -- 整数 例：54401
 * boolean -- 布朗值 例：true（是）, false（否）

以下为歌曲信息最完整的格式. （歌曲信息中每一项的填写可以乱序，没有顺序要求） {  "idx": int, "id": string (ASCII), "title_localized": { "en": string ... },  "artist": string, "artist_localized": { "en": string ... },  "bpm": string, "bpm_base": float, "set": string, "purchase": string, "audioPreview": int, "audioPreviewEnd": int, "side": int (0, 1), "bg": string (ASCII), "bg_inverse": string (ASCII) "bg_daynight": { "day": string (ASCII), "night": string (ASCII) },  "date": int (timestamp), "version": string, "world_unlock": boolean, "remote_dl": boolean, "byd_local_unlock": boolean, "songlist_hidden": boolean, "no_pp": boolean, "source_localized": { "en": string ... },  "source_copyright": string, "no_stream": boolean, "jacket_localized": { "ja": boolean ... },  "difficulties": [ {      "ratingClass": int (0, 1, 2, 3), "chartDesigner": string, "jacketDesigner": string, "rating": int, "ratingPlus": boolean, "plusFingers": boolean, "jacket_night": string (ASCII), "jacketOverride": boolean, "audioOverride": boolean, "hidden_until_unlocked": boolean, "bg": string (ASCII), "world_unlock": boolean } ...  ] }
 * localized字段可选属性：
 * "en" -- 英文 如果其他语言的字段不存在，默认使用此字段
 * "ja" -- 日文
 * "ko" -- 韩文
 * "zh-Hans" -- 简体中文
 * "zh-Hant" -- 繁体中文

歌曲信息
注：以下必需字段指官方songlist文件中每首歌都有的字段，删除后是否会导致游戏崩溃并未经测试. {  "idx": int, // 游戏内"Link Play"功能用来判断各玩家歌曲解锁情况时用的唯一标识符 必需字段 "id": string (ASCII), // 游戏程序识别歌曲的唯一ID 只能使用ASCII字符 必需字段 "title_localized": { "en": string, "ja": string ... },// 游戏内显示的曲名，可分语言设定 必需字段 "artist": string, "artist_localized": { "en": string ...  },// 游戏内显示的作曲者，可分语言设定. 可只填artist，默认为英语 必需字段 "bpm": string, // 游戏内显示的BPM 必需字段 "bpm_base": float, // 基准BPM，实际游玩速度为设置的音符流速除以"bpm_base"再乘以谱面Timing bpm 必需字段 "set": string, // 本曲所属曲包id，参考曲包信息(packlist)格式 必需字段 "purchase": string, // 本曲购买方式，曲包曲填所属曲包名，单曲填本曲"id"，无需购买则留空 必需字段 "audioPreview": int, "audioPreviewEnd": int, // 本曲预览的开始与结束时间，单位为毫秒 必需字段 "side": int (0, 1, 2), // 本曲属性，0为光芒侧，1为纷争侧，2为消色之侧 必需字段 "bg": string (ASCII), // 本曲背景文件名，背景jpg储存在/assets/img/bg目录中，留空即为默认背景（base_light(光芒侧)或base_conflict(纷争侧)） 只能使用ASCII字符 必需字段 "bg_inverse": string (ASCII), // 本曲反转背景文件名，性质同bg，是使用光 & 对立（Reunion）时更换的背景. 可不填（将无法触发技能）. 只能使用ASCII字符 "bg_daynight": { "day": string (ASCII), "night": string (ASCII) },// 自定义白天及夜晚显示的不同背景，参考 群愿 的技能 只能使用ASCII字符 "date": int (timestamp), // 本曲加入时刻的10位时间戳 必需字段 "version": string, // 本曲加入时的游戏版本，用于歌曲分类 必需字段 "world_unlock": boolean, // 本曲是否需要世界模式解锁，不填默认为false "remote_dl": boolean, // 本曲是否需要从服务器下载，不填默认为false "byd_local_unlock": boolean, // 本曲Beyond难度是否在本地解锁. 应与"world_unlock"相反 "songlist_hidden": boolean, // 本曲解锁前是否在歌曲界面中隐藏，不填默认为false "no_pp": boolean, // 标记lowiro是否拥有本曲的版权. 本字段对游戏没有影响 "source_localized": { "en": string ...  },// 本曲出处，可分语言设定. 歌曲界面中选择歌曲后，歌曲下方会显示 from 「"source_localized"」（其他语言）/来自 《》（中文） "source_copyright": string, // 本曲版权方，仅当"source_localized"不为空时显示在 from 「」之后（以©「"source_copyright"」显示） "no_stream": boolean, // 本曲是否能够在直播模式中游玩（目前出现此标识的值均为true） "jacket_localized": { "ja": boolean ...  },// 自定义本曲封面，可分语言设定. 封面文件名为base_ja.jpg，base_ja_256.jpg（即在base后加“_语言代码”） }

难度信息
难度谱面信息框架如下： "difficulties": [ {      // difficulty PST } ...  ] 各难度代码结构如下： {      "ratingClass": int (0, 1, 2, 3), // 本段代码所定义难度. 0 -- PST, 1 -- PRS, 2 -- FTR, 3 -- BYD 必需字段 "chartDesigner": string, // 本难度谱师名 必需字段 "jacketDesigner": string, // 本难度封面绘师 必需字段 "rating": int, // 本难度等级. 3.0更新前1-9对应本身，10对应9+，11对应10；3.0更新后均对应本身. 0均对应“?” 必需字段 "ratingPlus": boolean, // 本难度等级是否有“+”，不填默认为false 3.0新增 "plusFingers": boolean, // 本难度是否有多指操作，实际并无作用 "jacket_night": string (ASCII), // 本难度夜晚时显示的封面文件名 只能使用ASCII字符 "jacketOverride": boolean, // 本难度是否有根据难度替换的封面. 封面文件名为0.jpg，0_256.jpg（即为"ratingClass"），不填默认为false "audioOverride": boolean, // 本难度是否有根据难度替换的音频文件. 音频文件名为3.ogg（即为"ratingClass"），不填默认为false "hidden_until_unlocked": boolean, // 本难度解锁前是否歌曲界面中隐藏，不填默认为false "bg": string (ASCII), // 自定义本难度背景名，对于安卓apk，背景jpg储存在/assets/img/bg目录中；对于苹果ipa，背景jpg储存在/Payload/Arc-mobile.app/img/bg中 只能使用ASCII字符 "world_unlock": boolean // 本难度是否需要世界模式解锁，不填默认为false }

---


 * 本页面内容保持孤立！


 * 本页面内容已涉及到lowiro根本利益，在阅读本页面前，请你面对本页面郑重发誓：你对你自己的行为负全责！


 * (反正我支持正版，丢完信息就去氪金)

总论
文件在/assets/songs下 {"packs": [{曲包信息1},{曲包信息2},……,{曲包信息n}]} 有点熟悉不是吗

细节解析
例子 {     "id": "vs", "plus_character": -1, "name_localized": { "en": "Black Fate" },     "description_localized": { "en": "A storm fast approaches.\nReconciliation may not be possible.\nIs this the only destiny afforded them?\nWhat truth will they find at the end of their paths?\n\nA continuation of the main story of Arcaea.\nIt's suggested to play other main story packs first.", "ja": "嵐は来る――すぐに近くまで. \n和解はきっと、できないかもしれない. \nこれが唯一、許される運命なのだろうか. \n選んだ道の先、二人が見出す真実とは――. \n\nArcaeaメインストーリーの続編です. \nここまでの物語をクリアの後、購入を推奨します. ", "ko": "빠르게 다가오는 폭풍.\n아마도 불가능해 보이는 화해.\n이것이 그들에게 주어진 유일한 운명인가?\n그 여정의 끝자락에서 발견하게 될 진리는 무엇인가?\n\n이어지는 아르케아의 메인 스토리.\n다른 메인 스토리 팩을 먼저 플레이 해보시길 추천드립니다.", "zh-Hant": "一場暴風雨正呼嘯而來. \n妥協的可能性，或許並不存在. \n一切，真的只是命中註定嗎？\n在終點站等待著少女們的，究竟是怎樣的真理？\n\n韻律源點主線故事的下一篇章. \n在此之前，強烈建議先遊玩過去的故事包. ", "zh-Hans": "一场暴风雨正呼啸而来. \n妥协的可能性，或许并不存在. \n一切，真的只是命中注定吗？\n在终点站等待着少女们的，究竟是怎样的真理？\n\n韵律源点主线故事的下一篇章. \n在此之前，强烈建议先游玩过去的故事包. " }   } 归纳 {     "id": "ID", "custom_banner": bannerBoolean, "plus_character": characterID, "pack_parent": parentID "name_localized": { "en": "name", "ja": "名称" },     "description_localized": { "en": "Description", "ja": "説明", "ko": "설명", "zh-Hant": "説明", "zh-Hans": "说明" } }
 * ID(ansistring):曲包ID，引用的基础，不能出现非ASCII字符
 * 顺便说一下单曲曲包的ID为"single"，不在这个文件内.
 * bannerBoolean(true,false):本曲包在曲包界面显示时是否显示其本来定义的名称(即name)，true为不显示，false为显示. 可删除. 
 * characterID(-1～40,integer):该曲包下方显示附带的搭档，-1为不加，数字对应搭档见下


 * 曲包的图片默认名为"select_ .png",存放于/assets/songs/pack下
 * parentID(ansistring):该曲包为pack append时的所属曲包ID. 如果该曲包不是pack append，那么整个字段都不存在. 
 * name(ansistring):曲包在游戏内显示的名称.
 * Description(ansistring):购买曲包时显示的介绍文字. 可删除
 * 对应语言其实填什么都是无所谓的

---


 * 本页面内容保持孤立！

总论
文件在\assets\songs下

打开文件大概是这样的画风： { "unlocks": [ {     "songId": …, "ratingClass": …, "conditions": [ …       ],        …    },    …  ] } 整个文件以一个大括号和一个”unlocks”字符串开头，大体结构如下 { "unlocks":[ //all contents… ] }

细节解析
例子 {     "songId": "chronostasis", "ratingClass": 1, "conditions": [ {         "type": 1, "song_id": "infinityheaven", "song_difficulty": 1, "grade": 0 },       {          "type": 0, "credit": 80 }     ] } 归纳 {  "songId": this.songname, "ratingClass": classNum, "conditions": [ {     //condition 1 },    {      //condition 2 } ]  //end of condition(s) } 从上到下依次解析如下： 每一个语句组中一定有一个type语句，根据type的取值不同，其中会有不同的呈现.
 * songId (String）：双引号包含的字符串，代表了欲限定条件的歌曲名称. 至关重要，所引用歌曲对应谱面文件夹也必须是id名，不能出现非ASCII字符
 * ratingClass (int)：代表了欲限定条件的歌曲难度，取值只能为0，1，2，3. 0为PST难度，1为PRS难度，2为FTR难度，3为BYD难度.
 * conditions：unlocks文件中的核心，以一对英文方括号包裹，每一个condition语句组以一对大括号包含. 一个歌曲的一个难度可以有很多个condition语句组，它们之间以英文逗号分开.

type 0：残片型解锁
{   "type": 0, "credit": frag_needed_to_unlock } 当type取0时，为残片型解锁. 玩家需要花费残片来开启当前歌曲的游玩权限. credit的取值是一个整数，代表了解锁当前难度歌曲需要花费的残片数量.

在该解锁条件情况下，花费残片后可以永久解锁对应谱面，意味着解锁后其他条件不满足时对应谱面不会锁回去.

type 1：先行通过歌曲型解锁
{    "type":1, "song_id": songname, "song_difficulty": difficulty, "grade": gradeNum } type取1时，为先行通过歌曲型解锁，玩家需要在其前置歌曲中达到相应要求.
 * song_id (String)：指在游玩本难度的歌曲时，需要先行通过的歌曲名称，引用要求与songId相同.
 * song_difficulty (int)：取值为0，1，2，与ratingClass含义相同.
 * grade (int)：限定先行通过的歌曲需要达到的评级，0为不限定，1为达到C，2为达到B，3为达到A，4为达到AA，5为达到EX，6为达到EX+.

type 2：先行游玩歌曲型解锁
{    "type":2, "song_id": songname, "song_difficulty": difficulty } type取2时，为先行游玩歌曲型解锁，与先行通过歌曲型解锁类似，不过对应结果为游玩相应曲目即可. 变量不再赘述.

type 3：多次通过歌曲型解锁
{    "type":3, "song_id": songname, "song_difficulty": difficulty, "grade": gradeNum, "times": timesNum } type取3时，为多次通过歌曲型解锁，与先行通过歌曲型解锁类似，不过需要多次通过相应曲目并达到给定评级. 其他变量不再赘述.
 * times (int)：指先行通过的歌曲需要达到限定评级的次数.

type 4：选择任务型解锁
{    "type":4, "conditions": [ {     //condition 1 },    {      //condition 2 } ]  //end of condition(s) } type取4时，为选择任务型解锁. 其中conditions类似最外侧的conditions，可填入不同的condition语句组. 玩家只需挑选其中任意一个任务完成即可解锁. 套娃警告

type 5：个人游玩潜力值型解锁
{    "type":5, "rating": potentialNum } type取5时，为个人游玩潜力值型解锁，玩家需要取得或超过限定的潜力值即可解锁.
 * rating (int)：指限定的个人游玩潜力值乘以100后的整数. 可以随便填，负数都行，但即使填负数在未登录状态下本条件仍然算未达成

type 101：特殊解锁类型
{   "type": 101, "min": minNum, "max": maxNum } type取101时，为特殊解锁类型，通常用于解锁异象曲/终末曲.
 * min (int)：解锁异象曲或终末曲失败时获得的最小进度数.
 * max (int)：解锁异象曲或终末曲失败时获得的最大进度数.

type 103：搭档解锁类型
{   "type": 103, "id": int } type取103时，为搭档解锁类型. 目前仅有Aegleseeker出现此种解锁方式.

除演出曲目Aegleseeker外，在普通曲目上使用该解锁类型会导致使用对应搭档游玩结束并返回到选曲界面后切换为其他搭档后对应曲目不显示曲绘和曲目信息(但可正常选择该曲目进入游戏).
 * id (int): 该曲解锁时所需的搭档(此处值不可为-1)，数字对应搭档见下

type 104：剧情解锁类型
{   "type": 104, } type取104时，通常不会有其他语句一起存在，但type104出现且仅出现于Final Verdict及其附加内容Silent Answer的所有曲目中（开门曲Defection除外）

type 105：搭档技能解锁类型
{   "type": 105, "char_id": int, "awakened": boolean, "inverted": boolean } type取105时，为搭档剧情解锁类型（存疑），目前仅有Last｜Eternity的byd难度存在该解锁条件.
 * char_id (int): 和type103的id作用相同，此处不再赘述.
 * awakened (boolean)、inverted (boolean): 当搭档技能为觉醒技能/未觉醒技能时是否显示该难度，true为显示，false为不显示.

type 106：绑定谱面解锁类型
{   "type": 106, "song_id": string, "song_difficulty": int, "inverted": boolean } type取106时，为绑定谱面解锁类型（存疑），目前仅有Last的byd难度（即Last｜Moment）存在该解锁条件.
 * song_id (string): 曲目的songid.
 * song_difficulty (int): 捆绑曲目的难度.
 * inverted (boolean): 当搭档技能为未觉醒技能时是否显示该难度，true为显示，false为不显示.