-
Notifications
You must be signed in to change notification settings - Fork 54
此页用于记录Majdata Play部分实现细节
Majdata Play每帧会对处于活动状态的Note进行判定,判定区间为闭区间
请注意,Majdata Play内所有判定区间上界与下界单位都是ms,特殊情况会额外进行说明
PlayerLoop流程简化图如下:
---------------
| PreUpdate |
---------------
|
MajTimeline.PreUpdate
|
InputManager.PreUpdate
|
INoteTimeProvider.PreUpdate
|
NoteManager.PreUpdate
|
NoteDrop.PreUpdate
|
------------
| Update |
------------
|
NoteDrop.Update
|
----------------
| LateUpdate |
----------------
|
NoteAudioManager.LateUpdate
|
NoteDrop.LateUpdate (if exists)
|
EachLineDrop.LateUpdate
Source: NoteDrop.cs#L165
总区间: [-150,150]
详情:
为方便查看,表格内使用帧数表示区间上界与下界
1f表示60帧下的1帧间隔,换算成ms为1f * 16.6666
| 等级 | 范围 | 累计 |
|---|---|---|
| TooFast | (-inf, -9f) |
None |
| FastGood | [-9f, -6f) |
3f |
| FastGreat 3rd | [-6f, -5f) |
1f |
| FastGreat 2nd | [-5f, -4f) |
1f |
| FastGteat 1st | [-4f, -3f) |
1f |
| FastPerfect 3nd | [-3f, -2f) |
1f |
| FastPerfect 2nd | [-2f, -1f) |
1f |
| Perfect | [-1f, 1f] |
2f |
| LatePerfect 2nd | (1f, 2f] |
1f |
| LatePerfect 3nd | (2f, 3f] |
1f |
| LateGteat 1st | (3f, 4f] |
1f |
| LateGreat 2nd | (4f, 5f] |
1f |
| LateGreat 3rd | (5f, 6f] |
1f |
| LateGood | (6f, 9f] |
3f |
| Miss | (9f, inf) |
None |
参见 Tap
Source: HoldDrop.cs#L449
Majdata Play会忽略Hold的开头6f与结尾12f,并且会根据头部判定对Hold时值进行修正,详情参见Hold 尾判判定
当累计释放时长大于2f,也就是33.3333ms时,才会认为Hold被释放,并累计释放时长
Source
- Deluxe: NoteLongDrop.cs#L30
- FiNALE: NoteLongDrop.cs#L221
对于Deluxe:
当判定误差(_judgeDiff)为Fast(_judgeDiff < 0) 时,不对Hold时值进行修正
当判定误差为Late时,会从Length减去_judgeDiff再进行尾判
如果Hold修正后的时值小于等于0.3s,不会进行尾判,最终判定等级为头部判定等级
以下是尾判修正的详细说明:
Tip: 为方便表述,下面将使用p表示“Hold完成比例”
- 如果 p >= 1
- 如果头判为
Great 2nd/3rd,向上修正为Great - 如果头判为
Good,向上修正为Great - 如果头判为
Miss,向上修正为Good - 其他等级不进行任何修正
- 如果头判为
- 如果 p >= 0.67
- 如果头判为
Critical Perfect, 向下修正为Perfect 2nd - 如果头判为
Great 2nd/3rd,向上修正为Great - 如果头判为
Good,向上修正为Great - 如果头判为
Miss,向上修正为Good
- 如果头判为
- 如果 p >= 0.33
- 如果头判等级比
Great高,向下修正为Great - 如果头判为
Great 2nd/3rd,向上修正为Great - 如果头判为
Good,向上修正为Great - 如果头判为
Miss,向上修正为Good
- 如果头判等级比
- 如果 p >= 0.05
- 如果头判等级比
Good高,向下修正为Good - 如果头判为
Miss,向上修正为Good
- 如果头判等级比
- 如果 p >= 0
- 如果头判等级比
Good高,向下修正为Good
- 如果头判等级比
- Deluxe: SlideBase.cs#L182
- FiNALE: SlideBase.cs#L224
注意
Slide常数由内录/判定区图片叠加分析得出,数值可能不准确
Slide Deluxe判定实现参考自: maimai判定详解 - Moying
感谢软壳与热心mai友提供Great子区间
总区间: (-inf,600]
_lastWaitTime为Slide在最后一个判定区的停留时间
_table.Const/wifiConst为Slide在最后一个判定区滞留时间与Slide时值的比例
Perfect区间不是静态的,此区间会根据_lastWaitTime动态扩展,由基础区间+扩展区间组成
基础区间: [-14f, 14f]
扩展区间: ext = _lastWaitTime / 4,最大为22f
扩展时,Perfect会挤占Great区间,详情见图:
扩展前:
| <- Fast Great(15f) ->| <- Perfect(28f) -> | <- Late Great(15f) -> |
扩展后:
| <- Fast Great(10f) ->| <- Perfect(28 + 10f) -> | <- Late Great(10f) -> |
对比:
| <- Fast Great(15f) ->| <- Perfect(28f) -> | <- Late Great(15f) -> |
| <- Perfect(28 + 10f) -> |
为实现旧框体的严判,Majdata Play自行实现了Perfect子区间:
Perfect: (基础区间+扩展区间) * 0.3333
Perfect 2nd: (基础区间+扩展区间) * 0.6666
Perfect 3rd: 基础区间+扩展区间
当严判被关闭时,Slide会自动将Perfect 2nd和Perfect 3rd修正为Perfect
详情:
| 等级 | 范围 | 累计 |
|---|---|---|
| FastGood | (-inf, -29f) |
None |
| FastGreat 3rd | [-29f, -25f) |
4f |
| FastGreat 2nd | [-25f, -21f) |
4f |
| FastGteat 1st | [-21f, -14f) |
7f |
| Perfect | [-14f, 14f] |
28f |
| LateGteat 1st | (14f, 21f] |
7f |
| LateGreat 2nd | (21f, 25f] |
4f |
| LateGreat 3rd | (25f, 29f] |
4f |
| LateGood | (36f, 29f] |
7f |
| Miss | (36f, inf) |
None |
Waning
FiNALE Slide判定由手元、谱面确认、软壳经验分析而得,数据可能不准确
欢迎在issue提出任何提案
Finale的Perfect区间是静态的,不会根据Slide在最后一个判定区停留时长动态扩展
为兼容Deluxe的Break Slide,Majdata Play自行实现了FiNALE的Great子区间:
| 等级 | 范围 | 累计 |
|---|---|---|
| FastGood | (-inf, -27f) |
None |
| FastGreat 3rd | [-27f, -21f) |
6f |
| FastGreat 2nd | [-21f, -15f) |
6f |
| FastGteat 1st | [-15f, -9f) |
6f |
| FastPerfect 3nd | [-9f, -6f) |
3f |
| FastPerfect 2nd | [-6f, -3f) |
3f |
| Perfect | [-3f, 3f] |
6f |
| LatePerfect 2nd | (3f, 6f] |
3f |
| LatePerfect 3nd | (6f, 9f] |
3f |
| LateGteat 1st | (9f, 15f] |
6f |
| LateGreat 2nd | (15f, 21f] |
6f |
| LateGreat 3rd | (21f, 27f] |
6f |
| LateGood | (36f, 21f] |
15f |
| Miss | (36f, inf) |
None |
. -‐. : . : . : . : . :. : . : .
/: . : . : . : . : . : . : . : . : . : \....
/: . : . : . : . : . : . : . : . : . : . : . \ ::.;
/}レ': : . : . : . : . : . : . : . : . : .\: . ヽ: . : . :.ヽ
/: :/: . : . : . : . :l: :八: . : . : : \: : : :+———+ : '.:.:l:
/: :/: . : . :+———+: . :/l: :|\\: :\: : : \::.: | X.|::.:l:.::...:|:
/: ://: : . : .| X.|: / .j: :| | \\: ヽ\:ヽ\: :..+———+:.:|::|::|: .
//://|: : :l: :+———+. i斗'^ ,ィf弌ぅ 、 |:.:.l::|::|:.:|\| __ __ ______ __ ______ __ ______ __ __
//:ノ /|: :/}: : : |: l ,ィf゚う ト::)゚ィリ ヽ |:.:|:/:::|:.:| /\ "-./ \ /\ __ \ /\ \ /\ == \ /\ \ /\ __ \ /\ \_\ \
}: : /|:|:/: |: :∧:i /ん:::ハ 弋c少' |:.:|:.::.|:.:| \ \ \-./\ \ \ \ __ \ _\_\ \ \ \ _-/ \ \ \____ \ \ __ \ \ \____ \
|: / .|:|': : |: :/: :i 弋cソ 、、、、、. |:.:八:.:八:.| \ \_\ \ \_\ \ \_\ \_\ /\_____\ \ \_\ \ \_____\ \ \_\ \_\ \/\_____\
|/ l: : : :|V: : ハ 、、、、 ′ l:∧: ./ ヽ \/_/ \/_/ \/_/\/_/ \/_____/ \/_/ \/_____/ \/_/\/_/ \/_____/
八: :.∧: |: :人 r 、_ 、 ィノ:/:/\:./
∨ V}: : |: /i>}/ ,へ、 イj:V/:/ V
八: :|/ __ ! / ハ _ 斗‐{
∧! _| ' /´ 》────────--、
_/ |:::_} .|ー─--< |
/___ i }∧ ノ::::::::::::/ / |
V / }. イ l\::::::::::/ / :|
rヘ xヘ ∨ | |:| \/_/ 人
/_/ '、 _ヽ | |:| ./ - ─ - 〉
/ ヽ /// j/ 〈 / -‐ /