Theseus 模组文档
API 参考 / 事件系统

GameplayTickEvent


游玩逐帧事件,每个游玩帧投递两次:Pre 在游玩逻辑更新之前,Post 在其之后。暂停恢复的倒带重演窗口内也照常投递。

方法速览

方法用途
musicTimeMs()当前音乐时间(毫秒,可为负)
rewinding()是否处于倒带重演窗口
deltaSeconds()本帧真实帧间隔(秒,非负)
stepIndex()游玩场景内 tick 步号

musicTimeMs()

java
public long musicTimeMs();

行为:返回当前音乐时间 τ(毫秒,可为负,例如 count-in 阶段)。窗口内 τ 会先倒退再正向重演,不保证单调。

rewinding()

java
public boolean rewinding();

行为:true 表示本帧处于暂停恢复的倒带重演窗口(含倒带倒流段与紧随其后的正向重演段),窗口外为 false。这是「这段时间不可信」的单一信号:窗口内宿主时间在回退、其余系统未按常规整帧更新,监听器应据此跳过或重建自身累积状态。

deltaSeconds()

java
public double deltaSeconds();

行为:本帧真实帧间隔(秒,恒非负,负值在构造时被钳为 0)。可用于帧率无关积分;倒带窗口内的 tick 同样携带真实帧间隔,需与 rewinding() 配合使用。经旧构造器构造的事件返回 0.0。

stepIndex()

java
public long stepIndex();

行为:游玩场景内从 0 开始递增的 tick 步号(每帧 +1,同帧 Pre / Post 同值;倒带窗口内照常递增)。可作为与帧率无关的稳定排序键。经旧构造器构造的事件返回 -1。

示例

java
ctx.eventBus().subscribe(GameplayTickEvent.Pre.class, EventPriority.LOW, event -> {
    if (event.rewinding()) {
        // 窗口内时间不可信:改为按 τ 求值,而不是继续累加
        progress = evaluateAt(event.musicTimeMs());
        return;
    }
    progress += event.deltaSeconds() * ratePerSecond;
});

完整签名

java
public abstract class GameplayTickEvent extends Event {
    protected GameplayTickEvent(long musicTimeMs);
    protected GameplayTickEvent(long musicTimeMs, boolean rewinding);
    protected GameplayTickEvent(long musicTimeMs, boolean rewinding, double deltaSeconds, long stepIndex);
    public long musicTimeMs();
    public boolean rewinding();
    public double deltaSeconds();
    public long stepIndex();

    public static final class Pre extends GameplayTickEvent {
        public Pre(long musicTimeMs);
        public Pre(long musicTimeMs, boolean rewinding);
        public Pre(long musicTimeMs, boolean rewinding, double deltaSeconds, long stepIndex);
    }

    public static final class Post extends GameplayTickEvent {
        public Post(long musicTimeMs);
        public Post(long musicTimeMs, boolean rewinding);
        public Post(long musicTimeMs, boolean rewinding, double deltaSeconds, long stepIndex);
    }
}

行为核验:宿主逐帧构造新实例(不是复用同一对象),但仍不得缓存事件对象。宿主当前所有 tick 投递点都使用全参构造,因此实际收到的事件 deltaSeconds() 非负、stepIndex() 非负;0.0 / -1 只出现在模组自行用旧构造器创建事件时。窗口内的 tick 不等于「其它系统已按常规更新完毕」——应据 rewinding() 跳过或重建累计状态。

性能:每帧投递,监听器必须极轻。

稳定性:2.0 起冻结;deltaSeconds() / stepIndex() 为 阶段 2 纯增,旧构造器分别返回 0.0 / -1。