Theseus 模组文档
API 参考 / spi 包:游戏模式、谱面扩展与内容

ChartExtensionParser


谱面扩展段解析器。谱面 JSON 的 extensions 对象中,每个 key 对应一个已注册解析器;模组在 onPreInit 用 ctx.registries().chartExtensions().register(key, parser) 注册,注册键的 namespace:path 就是 extensions 里的 key(如 mymod:effects),因此本接口不自带 key()。宿主在谱面加载时按 key 分发,未注册或 key 格式非法的段直接忽略(第三方谱面可携带任意扩展段,不视为错误)。相关类型:ChartParseContext、ChartRuntimeContext。

方法速览

方法用途
parse(JsonObject, ChartParseContext)解析该扩展段并返回结果对象
apply(Object, ChartRuntimeContext)解析结果已自动入库后调用,用于注入运行时状态/触发效果

parse(JsonObject extensionData, ChartParseContext ctx)

签名:

java
Object parse(JsonObject extensionData, ChartParseContext ctx);

行为:extensionData 是该 key 对应的 JSON 对象;若该段不是 JSON 对象(数组、标量、null),宿主传入一个空 JsonObject。返回值可以是任意对象(也可以为 null),宿主随后会以该段 key 写入运行时上下文并调用 apply。解析失败(抛异常)时宿主捕获并跳过该段,限频告警(5 秒),不影响谱面主流程与其他扩展段。

示例:

java
@Override
public Object parse(JsonObject extensionData, ChartParseContext ctx) {
    MyEffects fx = new MyEffects();
    if (extensionData.has("bloom")) {
        fx.bloom = extensionData.get("bloom").getAsFloat();
    }
    fx.lanes = ctx.totalLanes();
    return fx;
}

apply(Object parsed, ChartRuntimeContext ctx)

签名:

java
default void apply(Object parsed, ChartRuntimeContext ctx);

行为:在 parse 返回后立即调用,parsed 是同一个返回对象。宿主已先把该对象以扩展段 key 写入运行时上下文,因此通常无需再 put(需要额外键名时才写)。游玩上下文加载时,可经 ctx.extraContent() 取得 ExtraContentApi 并立即触发演出原语;非游玩上下文(列表扫描、编辑器)该值为 null,必须判空。宿主在运行时重建(扩展数据为空时的重放)会再次走 parse → apply,实现应保持幂等。异常同样被捕获并跳过该段。

示例:

java
@Override
public void apply(Object parsed, ChartRuntimeContext ctx) {
    ExtraContentApi api = ctx.extraContent();   // 非游玩上下文为 null
    if (api != null) {
        api.setLaneAlpha(0, 0.3f);
    }
}

完整签名

java
public interface ChartExtensionParser {

    Object parse(JsonObject extensionData, ChartParseContext ctx);

    default void apply(Object parsed, ChartRuntimeContext ctx);
}

线程:源码未声明额外线程约束;宿主在谱面加载(游玩场景 loading 阶段)的 GL 主线程同步调用 parse 与 apply。

生命周期阶段:运行期谱面加载时由宿主按 key 分发调用;运行时重建时可能再次调用。

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