首页 / JS 脚本手册 / MTR 3.x 兼容与迁移

MTR 3.x 兼容与迁移

RTE 提供一层兼容对象,让 3.x 时代的脚本尽量原样运行。这页讲它覆盖了什么、以及必须手动改的地方。

兼容对象

MTR 4 重构了数据结构,3.x 脚本用的类大多已不存在。 RTE 在 cn.jstxjf_.rte.scripting.compat 下提供了替代实现, 它们在白名单内可直接使用。

兼容类对应 3.x 概念
StationCompat车站
RouteCompat线路
PlatformCompat站台
RoutePlatformCompat线路站台关联
DepotCompat车厂
SidingCompat车厂线
RailCompat轨道
PathDataCompat路径数据
DataCacheCompat数据缓存
ClientDataCompat客户端数据
ColorNameCompat颜色名
ScriptLongMap长整型键映射
ScriptVector向量

脚本里通过全局 MTRClientData 访问客户端数据, 它是 ClientDataCompat 的别名。要用 MTR 4 原生结构则用 MTRClientData4

必须手改的:时间基准

MTR 3.x 按 tick 或秒计算,MTR 4 内部一律用毫秒。 1 tick = 50 毫秒。速度、加速度、停站时间三处都受影响。

RTE 已经在 TrainWrapper 层面做了换算 —— speed() 返回米每刻、speedKmh() 返回 km/h,都是 3.x 脚本期望的量级。 但如果你的脚本绕过封装直接读底层对象,就得自己乘 50。

最稳妥的做法:显示速度一律用 train.speedKmh(),不要自己算。

必须手改的:贴图路径

MTR 4 判定基础贴图时要求路径严格等于 default.png, 而老包常写成 xxx/default.png。 RTE 的 legacyDefaultTextureFallback 开关把它放宽为按文件名匹配,默认开启。

引擎差异

3.x 脚本基本都是为 Rhino 写的。迁移时先用 rhino, 跑通了再考虑换 GraalJS。

差异点说明
Java 互操作两个引擎包装 Java 对象的方式不同,遍历、类型转换的写法可能要调整
语法级别Rhino 对 ES6+ 支持有限,GraalJS 支持完整。反过来,为 Rhino 写的老写法在 GraalJS 下通常仍可用
数字类型Java 的 int 与 double 在两个引擎里转成 JS number 的行为略有出入

在资源包里用 engine 字段指定,或让用户在客户端配置 scriptEngine 里选。 注意:客户端设成具体引擎时会覆盖资源包的声明。

与 JCM、方速、S1 共存

这几个附属都会改动 MTR 的同一批代码。双方都在同一处注入并取消原版时, 只有先跑的一方生效,另一方静默失效且不报错 —— 表现为「装了 A 之后 B 的功能就没了」。

RTE 检测到它们时会弹一次仲裁窗口,按领域让你指定由谁接管: 轨道角度运算、节点右键、轨道预览角度、单向箭头、网格去重、车辆脚本、眼糖脚本。 同一领域有两个以上附属在场时,还可展开「按附属分别设置」。

RTE 只能仲裁自己一侧,即主动让位,无法关闭对方的注入。 脚本域另有「自动去重」—— 逐个实例检测该车辆/眼糖是否已被 JCM 接管,是则本侧跳过。

选择存在配置项 compat 中;旧的 jcmJsChoice 会被自动读为车辆脚本域的取值。

脚本可能从别的附属加载

资源包 include 的命名空间不一定由 RTE 提供。典型例子是 mtrsteamloco:scripts/display_helper.js —— NTE 没有 4.x 版本,实际提供者是 JCM。 于是脚本文件来自 JCM,却在 RTE 的引擎里执行,两边的 API 命名必须对得上。

已知的一处差异是 ModelManager.upload(JCM)与 uploadVertArrays(RTE), 两者语义相同,RTE 现已把 upload 补为别名。 若你遇到 TypeError: Cannot find function X in object ..., 多半就是这类命名差异,请开 Issue 告知。

已知不兼容

并非所有 3.x 脚本都能原样跑。常见卡点: