首页 / JS 脚本手册 / 生命周期与线程

生命周期与线程

四个入口函数、调用时机、以及一个必须知道的事实:脚本不在主线程跑。

四个入口函数

function create(ctx, state, train) { }
function render(ctx, state, train) { }
function dispose(ctx, state, train) { }
function use(ctx, state, train, event) { }
函数调用时机
create该车首次进入渲染范围时调用一次。用来初始化 state
rendercreate 成功后每帧调用。
dispose该车不再需要渲染时调用。之后若再次进入范围,会重新走 create
use玩家右键命中脚本登记的可点击区域时调用。见交互与 use 回调

带后缀的变体

列车脚本的上下文类型名是 Train,所以下面这组函数名同样会被调用

function createTrain(ctx, state, train) { }
function renderTrain(ctx, state, train) { }
function disposeTrain(ctx, state, train) { }
function useTrain(ctx, state, train, event) { }

两组都定义时两组都会执行(先无后缀、后带后缀)。 多个脚本文件里定义同名函数时,也是全部按加载顺序依次调用 —— 后者不会覆盖前者。

参数

参数说明
ctx脚本上下文。承载绘制调用缓冲区等运行时对象。
state每辆车独立的空对象,跨帧保留。放你自己的状态。
train列车包装对象,见列车 API

脚本跑在独立线程

脚本不在渲染主线程执行。 它被提交到专用线程池,与渲染并发。这带来两个后果。

后果一:不能直接碰渲染状态

要在主线程做的事,交给 MinecraftClient

MinecraftClient.execute(function() {
  // 这里在主线程
});

MinecraftClient.recordRenderCall(function() {
  // 这里在渲染阶段
});

后果二:一帧可能跳过

上一帧的脚本还没跑完时,本帧不会重复提交。所以 render 的实际调用频率 不等于帧率。不要用调用次数当计时器 —— 用 Date.now()

失败退避

脚本抛异常会被捕获并写日志。同一函数连续失败会被暂停一段时间, 避免坏脚本每帧每车抛异常拖垮整局游戏。

日志里搜 Error in RTE Resource Pack JavaScript 可看到栈。 修好后按 F7 重载即可恢复。

重载

F7 重载 RTE 客户端资源。脚本会被关闭并重新加载, 所有 state 清空,下一帧重新走 create