Theseus 模组文档
API 参考 / judge 包:判定管线

JudgmentPolicy


想先跑起来?

这一页是签名与行为参考。五个毫秒窗口,多份策略合并取最宽松。直接做一遍:教程 · 添加判定等级。

判定策略:定义 PERFECT / GREAT / MISS / 长音符结尾 / 迟到截断五个时间窗口(毫秒)。在 onPreInit 内经 ctx.registries().judgmentPolicies() 注册,宿主在每局装配时合并所有策略的窗口。

合并规则是「逐字段取最大」:宿主先排除内置默认策略 seecmd:default(70/150/150/150/50),只对模组注册的策略取最大;一个模组都没注册时才回退到内置默认。因此单个模组的注册值直接生效(可以比默认更宽,也可以更窄),多个模组同时注册时较窄的一侧会被更宽者覆盖。要无条件收紧判定结果,请用 JudgmentAdjuster 改写结果,而不是依赖窗口竞争。

方法速览

方法用途
perfectWindowMs()PERFECT 判定窗口(毫秒)
greatWindowMs()GREAT 判定窗口(毫秒)
missWindowMs()MISS 判定窗口(毫秒)
holdEndWindowMs()长音符结尾判定窗口(毫秒)
lateCutoffMs()越过判定线后仍可补判的时长(毫秒)

完整签名

java
public interface JudgmentPolicy {

    long perfectWindowMs();

    long greatWindowMs();

    long missWindowMs();

    long holdEndWindowMs();

    long lateCutoffMs();
}

perfectWindowMs()

签名:

java
long perfectWindowMs();

行为:PERFECT 的最大时间偏差(毫秒)。值越大越宽松。宿主合并时与其它模组策略同字段取最大值;读取过程中抛异常的策略会被跳过并限频告警,已读出的字段保留在合并结果中。接口不校验范围,负值或 0 会让该档判定不可用,策略作者应保证非负。

示例:

java
long perfect = policy.perfectWindowMs();

greatWindowMs()

签名:

java
long greatWindowMs();

行为:GREAT 的最大时间偏差(毫秒),语义与 perfectWindowMs() 相同;通常应不小于 PERFECT 窗口。

示例:

java
long great = policy.greatWindowMs();

missWindowMs()

签名:

java
long missWindowMs();

行为:MISS 的超时兜底窗口(毫秒)。普通音符超过 time + missWindowMs 仍未判定时由宿主兜底判 MISS(长音符走 holdEndWindowMs() 与结尾时间)。值越大,留给玩家的补救时间越长。

示例:

java
long miss = policy.missWindowMs();

holdEndWindowMs()

签名:

java
long holdEndWindowMs();

行为:长音符结尾判定的时间窗口(毫秒),只作用于 HOLD 的终点判定;长音符起点仍使用 PERFECT / GREAT / MISS 窗口。

示例:

java
long holdEnd = policy.holdEndWindowMs();

lateCutoffMs()

签名:

java
long lateCutoffMs();

行为:越过判定线之后仍可补判的时长(毫秒)。与其它四个字段同向:值越大越宽松。超过该时长仍未处理的音符进入 MISS 流程。

示例:

java
long late = policy.lateCutoffMs();

完整注册示例:

java
@Override
public void onPreInit(ModContext ctx) {
    ctx.registries().judgmentPolicies().register(
            RegistryKey.of("my_mod", "wide", JudgmentPolicy.class),
            new JudgmentPolicy() {
                @Override public long perfectWindowMs() { return 105L; }
                @Override public long greatWindowMs() { return 225L; }
                @Override public long missWindowMs() { return 225L; }
                @Override public long holdEndWindowMs() { return 225L; }
                @Override public long lateCutoffMs() { return 75L; }
            });
}

线程:源码未声明额外线程约束。宿主在每局装配时一次性读取全部策略,合并结果整局不变;注册表冻结后只读。

生命周期阶段:onPreInit 注册;运行期可经 GameplayContext#judgmentWindowMs() 读取当前生效窗口,经 defaultJudgmentWindowMs() 读取内置默认值(70/150/150/150/50)。

稳定性:2.0 起冻结:2.x 内只增不破(禁止删签名/改签名/改语义)。