本教程基于 RTM 2.4.24 for Minecraft 1.12.2 编写,面向RTM追加开发新手。
| 工具 | 用途 | 获取 |
|---|---|---|
| Metasequoia 4(水杉) | 3D建模——RTM社区标准工具,原生MQO格式 | metaseq.net(免费Standard版 / 付费EX版) |
| paint.net / Photoshop | 基础贴图绘制 | paint.net,PS需订阅 |
| Substance 3D Painter(可选) | PBR贴图绘制 | Adobe官网 |
| VS Code | JSON / JS编辑 | 免费 |
| Audacity | 音效编辑,导出OGG | 免费 |
| MCTE模组 | 导出NGTO格式(方块→模型) | mcmod.cn介绍页 |
| Minecraft 1.12.2+Forge | 运行环境 | Forge 14.23.5.2860 + RTM + NGTLib |
在正式进行RTM追加的制作前,我们需要在项目文件夹下构建正确的追加包文件结构。
但值得注意的是,RTM本体只支持加载压缩包形式的追加包,不支持加载文件夹形式的追加,若想要加载文件夹形式的追加,可以安装fixRTM模组。
RTM追加包存在两种合法的文件结构,RTM模组均可正确加载。
你问我这两种有什么区别?我不到啊。
你说的对,但是水杉(Metasequoia 4)是由Tetraface开发的一款基于多边形建模技术的三维建模软件,适用于游戏开发、动画制作后面忘了
水杉(Metasequoia 4)是RTM社区的常见建模工具。且RTM本体对水杉原生模型格式的支持性最好,所以建议新手使用水杉进行追加包模型的建模。
而且模型的质量往往直接决定了RTM追加包的精细程度,所以建模是RTM追加制作至关重要的一环
但是你也得注意优化,否则你做出来的包会非常之卡。
但RTM支持的模型格式不止水杉的原生模型格式一种,以下是RTM支持的模型类型:
| 格式 | 扩展名 | 说明 |
|---|---|---|
| MQO | .mqo | Metasequoia原生格式,RTM最常用 |
| MQOZ | .mqoz | MQO的压缩版本,本质是GZip压缩的.mqo,减小文件体积 |
| OBJ | .obj | Wavefront OBJ通用格式,可从Blender等导出 |
| NGTO | .ngto | NGT自定义格式——用MCTE模组将Minecraft方块结构导出为模型。详见MCTE介绍 |
了解了这些,你就可以开始建模了。
不过这里不教建模,你可以观看b站up@Huli-awsl的视频
除此之外,在进行RTM追加包的模型制作时,有些事情需要你注意:
| 概念 | 数值 |
|---|---|
| 1 米 (游戏中) | = 100 水杉单位 |
| X 轴 | 左右(正=右),车门沿X轴滑动 |
| Y 轴 | 上下(正=上) |
| Z 轴 | 前后(正=前/列车运行方向) |
一个RTM列车通常由两个独立的.mqo文件组成:
var车体和转向架的相对位置通过JSON中bogiePos指定。

水杉保存即为.mqo格式。如使用.mqoz(压缩MQO),可在水杉中另存为对应格式。.obj格式可从Blender等建模软件导出。所有模型放入assets/minecraft/models/。
贴图制作有两个层级:基础贴图适用于所有开发者,PBR贴图是高阶选项。建议新手从基础贴图开始。
用水杉的UV编辑器展开UV → 导出UV布局图 → 在GIMP/Photoshop中绘制贴图 → 保存为PNG。
| 属性 | 要求 |
|---|---|
| 格式 | PNG(支持Alpha透明通道) |
| 分辨率 | 1*1到4096*4096范围内均可 |
不过这里也不教画贴图,你可以观看b站up@Huli-awsl的视频
PBR贴图是基于物理的渲染(Physically Based Rendering)技术中使用的一种贴图类型,旨在更真实地模拟光与物体表面的相互作用。
在我的世界中,你可以通过使用PBR贴图以及支持PBR贴图的光影来制造一些十分真实的效果。

RTM兼容基于labPBR标准的PBR材质,而labPBR标准对于每个材质都有三种贴图,分别为基础色贴图,反射贴图(后缀_s)和法线贴图(后缀_n)。建议使用Substance 3D Painter绘制并创建特定的导出模板来导出PBR贴图。这个导出模板遵循固定的通道布局:
| 文件名 | 通道布局 |
|---|---|
| $textureSet.png | R=BaseColor.R G=BaseColor.G B=BaseColor.B A=Opacity |
| $textureSet_s.png | R=Glossiness(粗糙度反转) G=F0(金属反射率) B=空 A=空 |
| $textureSet_n.png | RGB=Normal OpenGL(OpenGL标准法线) A=空 |

由于原生的Minecraft没有SSAO,在使用Substance 3D painter绘制贴图时,开发者习惯将AO贴图直接以正片叠底(Multiply)方式直接叠加到基础色贴图上,以提升贴图的质感。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它用人类可读的文本存储数据对象。你可以把它理解成一张「物品配置表」——每个 .json 文件记录了 RTM 中一个物品(列车、轨道、信号机等)的所有属性:它叫什么名字、用哪个模型、贴什么图、有什么功能。
当 RTM 模组启动 Minecraft 时,它会在 mods/ 目录下寻找所有追加包文件夹,然后扫描每个追加包中的子目录,读取里面的每个 .json 文件。一个 .json 文件 = 一个物品。如果 JSON 文件命名或格式不对,RTM 就会跳过它,物品就不会出现在游戏中。
下面是 RTM 支持的所有物品类型,每种类型都有固定的文件前缀和存放目录。RTM 模组启动时会扫描这些目录,根据文件名前缀判断物品类型。例如所有以 ModelTrain_ 开头的 .json 文件都会被当作列车处理。
| 前缀 | 类型 | 目录 |
|---|---|---|
| ModelTrain_ | 列车 | mods/RTM/train/ |
| ModelRail_ | 轨道 | mods/RTM/rail/ |
| ModelConnector_ | 接触网设施 | mods/RTM/stuff/ |
| ModelMachine_ | 机器设备 | mods/RTM/machine/ |
| ModelWire_ | 线缆 | mods/RTM/wire/ |
| ModelSignal_ | 信号机 | mods/RTM/signal/ |
| ModelContainer_ | 货柜/集装箱 | mods/RTM/container/ |
| ModelFirearm_ | 武器(火炮等) | mods/RTM/firearm/ |
| ModelVehicle_ | 载具(坦克/汽车) | mods/RTM/vehicle/ |
| ModelMechanism_ | 机械传动部件 | mods/RTM/mechanism/ |
| ModelNPC_ | NPC | mods/RTM/npc/ |
| ModelOrnament_ | 装饰物 | mods/RTM/ornament/ |
列车是 RTM 追加包中最常见也最复杂的类型。它的 .json 文件定义了列车的外观模型(MQO 格式)、贴图材质(PNG 格式)、物理参数(编组间距、速度、座位等)和交互功能(车门、灯光、报站)。下面从最简版本开始,一步一步教你构建完整的列车 JSON。每一步只加几个新键,逐步累积。
做追加包就像搭积木——先搭个能跑的骨架,再往上添门窗、座位、报站。别想一口吃成胖子。
第 1 步——基础创建。你需要创建一个.json文件,名称为:ModelTrain_列车名.json,然后使用记事本或vscode打开这个.json文件,在这个文件中填入以下内容
这些内容包含了RTM列车追加包最基础的信息:列车名,列车类型和列车在游戏内显示的标签名,其中列车名只能使用ASCII字符。
第 2 步——加上转向架和车体模型。在trainModel2和bogieModel2两键下的modelFile键后填入车体/转向架的模型名称,textures键后的数组中以["材质名","材质对应贴图在assets/minecraft目录下的相对路径","材质渲染选项"]的形式将对应模型的所有材质填入:
Light——启用光照。此选项需配合对应的xxx_light0,xxx_light1,xxx_light2发光贴图使用,当填入此选项时,若在游戏中放下该列车并在RTM控制GUI开启前灯/后灯/前后灯时,RTM会自动将对应的xxx_light0,xxx_light1,xxx_light2发光贴图作为一层不受环境光亮度影响的发光贴图层覆盖到列车的模型上。AlphaBlend——启用 Alpha 透明度混合。用于玻璃窗户、半透明隔板等需要透出后方景物的材质。必须配合带 Alpha 通道的 PNG 贴图使用。""(空字符串)——默认行为,不启用任何特殊处理。"Light,AlphaBlend" 会同时启用光照和半透明。到了这步,你的追加就可以正常进入游戏了。
不过这些内容只是最基础的,RTM还提供了许多键供开发者使用:
车门。车门是 RTM 列车最重要的交互功能。door_right 定义右侧门,door_left 定义左侧门。transform 参数控制滑动动画:
座位和车内灯。seatPos 定义了玩家可以坐下的位置,其值的子数组的第四项控制座椅类型(0=南、1=西、2=北、3=东):
但值得注意的是,seatPos所传入的坐标并不是以m为单位的,而是以1/16m为单位。且其所传入的坐标只能是整数。如果觉得这样太麻烦且精度欠佳,可以使用seatPosF,其结构与seatPos一致。
方向幕和报站音效。rollsignTexture 是方向幕的贴图,rollsignNames 是可选路线名称列表,sound_Announcement 把每条报站名称关联到音效 ID:
当然,RTM 的大多数 JSON 键都可选,所以有些你用不到的功能直接不写就行了,缺的键 RTM 会用默认行为处理。下面是这些键的完整参考。
| 键 | 必需 | 类型 | 说明 |
|---|---|---|---|
| trainName | 是 | String | 列车在游戏内显示的任意名称,无字符限制 |
| trainModel2 | 是 | Object | 车体模型对象,包含 modelFile(MQO/MQOZ/OBJ/NGTO 文件路径)、textures(材质映射数组)和可选的 rendererPath(JS 渲染脚本路径) |
| trainType | 否 | String | 列车动力类型枚举:EC=电力动车/电力机车、DC=内燃动车/内燃机车、CC=货车、N/A=无动力(纯客车/货车靠牵引)、TC=测试专用(部分版本)、TEST/Test=开发调试用测试列车。不写默认为 EC |
| bogieModel2 | 否 | Object | 转向架模型对象,结构同 trainModel2(modelFile + textures + rendererPath)。不设置此键则列车无转向架 |
| bogieModel3 | 否 | Object | 用于设置两组不同的转向架。结构同 bogieModel2 |
| bogiePos | 否 | Float[][] | 转向架在车体坐标系下的安装位置 [[x,y,z],[x,y,z]],单位米。x=左右偏移、y=高度、z=前后距离车体中心。前后各一个,通常 z 值互为相反数 |
| buttonTexture | 否 | String | 列车在选车界面的按钮贴图目录 |
| playerPos | 否 | Float[][] | 玩家右键上车后的站立位置 [[x,y,z],[x,y,z]]。分别对应两个转向架 |
| trainDistance | 否 | Float | 列车的半长,单位m |
| isSingleTrain | 否 | Boolean | 是否为独立的车辆 |
| doCulling | 否 | Boolean | 是否启用单面渲染,默认true |
| smoothing | 否 | Boolean | 是否启用平滑着色。默认true |
| tags | 否 | String | RTM物品的显示标签 |
| accuracy | 否 | String | 碰撞检测精度枚举:LOW=低精度、MEDIUM=中等精度、HIGH=高精度 |
| color | 否 | Int[3] | 列车默认车体颜色 [R, G, B],三个整数分别对应红绿蓝通道,取值范围各为 0-255。设置了此键后,玩家可通过列车 GUI 的颜色选择器调整 |
| customButtons | 否 | String[] | 自定义 GUI 按钮的文本标签列表,每项对应一个按钮,在列车 GUI 中显示额外的功能入口。与 customButtonTips 数组一一对应,一般搭配js实现功能 |
| customButtonTips | 否 | String[] | customButtons 数组中每个按钮对应的鼠标悬停提示文本列表,长度必须与 customButtons 一致 |
| collisionParts | 否 | String[] | 参与物理碰撞检测的模型部件名(MQO 中的对象名)列表。适用于自定义碰撞体积的车型 |
| headLights | 否 | Float[][] | 列车头灯(前照灯)的发光点位置列表 [[x,y,z],...],单位m。每个位置对应一个独立的点光源,列车的行驶方向为 Z 正方向 |
| tailLights | 否 | Float[][] | 列车尾灯(红色标志灯)的发光点位置列表 [[x,y,z],...],单位m。格式与 headLights 相同,通常位于列车后端两侧 |
| fragmentShaderPath | 否 | String | 片段着色器 GLSL 脚本路径,用于自定义每个像素的渲染颜色(shader-test 系列列车使用)。文件路径相对于 assets/minecraft/ |
| interiorLights | 否 | Object[] | 车厢内部照明的光源位置列表 [{'pos':[x,y,z]},...],每个元素包含一个 pos 键。 |
| jointDelay | 否 | Float | 铰接列车的关节延迟时间,单位是游戏刻(ticks,20 ticks = 1 秒)。数值越大后一节车厢对前一节的跟随响应越滞后。 |
| maxSpeed | 否 | Float | 列车在五个挡位上的最高速度,单位为m/tick |
| muteJointSound | 否 | Boolean | 是否关闭撞轨音效 |
| offset | 否 | Float[3] | 模型整体在轨道上的位置微调偏移量 [x,y,z],单位m。用于调整模型在铁轨上的视觉位置。正值在 x 方向向右移、y 方向向上移、z 方向向前移 |
| pantoPos | 否 | Float[][] | 受电弓位置 [[x,y,z],...],单位m。每个位置对应一个受电弓滑板与接触网的接触点。列车运行时 RTM 根据这些位置使得受电弓高度与接触网匹配(需结合js实现该功能) |
| rolling | 否 | Object | 侧滚(左右摇摆)行为配置的父级对象,包含三个子系数键。此对象存在时列车过弯和轨道不平时车身会产生左右摇摆效果。注意 rolling 本身不是数值,其子键 rollSpeedCoefficient、rollVariationCoefficient 和 rollWidthCoefficient 才是实际控制参数。 |
| rollSpeedCoefficient | 否 | Float | 侧滚速度系数,控制列车过弯时的倾斜响应速度。数值越大倾斜反应越快。取值范围约为 0 到 0.25 |
| rollVariationCoefficient | 否 | Float | 侧滚变化系数,控制列车因轨道不平顺引起摇晃的随机变化程度。数值越大过弯时倾斜幅度的不规律变化越明显。取值范围约为 0.51 到 0.7 |
| rollWidthCoefficient | 否 | Float | 侧滚宽度系数,控制列车过弯时车身倾斜的幅度(左右摆动的最大角度)。数值越大倾斜幅度越大。取值范围约为 0.5 到 1.25 |
| scale | 否 | Float | 模型的整体缩放倍率。1.0 = 原始大小不变。注意缩放同时也会影响碰撞箱大小和物理行为 |
| seatPos | 否 | Int[][] | 乘客座位位置列表 [[x,y,z,type],...]。注意其坐标并不是以m为单位的,而是以1/16m为单位。且其所传入的坐标只能是整数、type=座椅类型(0=南、1=西、2=北、3=东) |
| seatPosF | 否 | Float[][] | seatPos的浮点数版本 |
| serverScriptPath | 否 | String | 服务端专用的 JavaScript 脚本路径,用于实现需要服务器权威验证的自定义逻辑。文件路径相对于 assets/minecraft/ |
| smoke | 否 | Float[][] | (DC 内燃类型使用)烟雾粒子的发射位置列表 [[x,y,z],...],单位m。每个位置是一个排烟口。set [](空数组)可关闭默认烟雾 |
| soundScriptPath | 否 | String | 运行时动态音效的 JS 脚本路径,用于实现 VVVF 变频牵引声、空气压缩机声等复杂的随速变化音效。文件路径相对于 assets/minecraft/ |
| sound_DoorOpen | 否 | String | 车门打开时播放的音效 ID。格式为 'sounds_XXX:xxx'(追加包内,sounds_XXX为assets目录下你存放声音文件的目录名)或'rtm:xxx'(RTM 本体) |
| sound_DoorClose | 否 | String | 车门关闭时播放的音效 ID,格式同 sound_DoorOpen |
| sound_Acceleration | 否 | String | 列车牵引加速时播放的音效 ID,例如 VVVF 牵引逆变器升频声 |
| sound_Deceleration | 否 | String | 列车减速/电气制动时播放的音效 ID,例如 VVVF 回馈制动降频声 |
| sound_Stop | 否 | String | 列车完全停稳时播放的音效 ID,例如气动制动缓解声 |
| sound_BrakeRelease | 否 | String | 制动缓解(松刹车)时的音效 ID,例如排风声 |
| sound_BrakeRelease2 | 否 | String | 第二段制动缓解音效 ID,用于分段缓解声效果——先松一部分再全松 |
| sound_Horn | 否 | String | 鸣笛音效 ID。 |
| sound_Announcement | 否 | String[][] | 报站广播列表,格式为 [['显示名称','音效ID'],...]。玩家在列车 GUI 中看到显示名称,点击后播放对应的音效 |
| sound_D_S | 否 | String | 行驶中的特殊音效 ID,例如磁轨制动声、齿轮箱啮合声等附加行驶音效 |
| sound_S_A | 否 | String | 启动加速辅助音效 ID(Station Acceleration),用于播放列车起步时的辅助提示音 |
| rollsignTexture | 否 | String | 方向幕(列车前/侧/尾部的路线显示屏)的贴图 PNG 路径,贴图中按 UV 坐标排列了各路线名称的图案 |
| rollsignNames | 否 | String[] | 方向幕上的可选路线/目的地名称列表 ['None','站A','站B',...]。名称顺序决定了按方向幕切换按钮时循环的路线顺序 |
| rollsigns | 否 | Object[] | 方向幕显示位置的定义数组。每项包含:uv[4](贴图 UV 坐标 [uMin,uMax,vMin,vMax],范围 0.0-1.0)、pos[4][3](四角顶点三维坐标)、doAnimation(是否逐行滚动切换)、disableLighting(是否忽略环境光照始终全亮) |
| wheelRotationSpeed | 否 | Float | 车轮自转速度的倍率系数。取值范围为 0.016 到 0.8。 |
| vertexShaderPath | 否 | String | 顶点着色器 GLSL 脚本路径,用于自定义模型每个顶点的位置变换(shader-test 系列列车使用)。文件路径相对于 assets/minecraft/ |
| accelerateion | 否 | Float | 加速度值。注意 JSON 配置键的拼写为 accelerateion(NGT的拼写错误),单位为m/tick² |
| type | 否 | String | 列车子类型标识字符串(部分测试/特殊列车使用)。取值如内部测试标识等,非必需键。注意此 type 是列车 JSON 顶层的键,与 Machine/Machine 中的 type 无关 |
| 键 | 必需 | 类型 | 说明 |
|---|---|---|---|
| accuracy | 否 | String(LOW/MEDIUM/HIGH) | 碰撞检测精度,可选 LOW(低精度/高性能)、MEDIUM(中等)、HIGH(高精度/低性能),轨道一般设为 LOW |
| allowCrossing | 否 | Boolean | 是否允许行人(NPC/玩家)横穿这条轨道,true=允许横穿,false=禁止横穿 |
| ballastWidth | 否 | Int | 道砟的宽度,用于无模型轨道的道砟渲染 |
| blockMetadata | 否 | String | 道砟方块的元数据值,对于有不同变体的方块用于指定具体子类型 |
| blockName | 否 | String | 道砟方块的 Minecraft 注册 ID,如 gravel(砂砾)、stone(石头)或 air(无道砟) |
| buttonTexture | 否 | String(path) | 创造模式物品栏中显示的图标 PNG 路径 |
| defaultBallast | 否 | Object | 默认道砟设置数组,每个元素包含 blockName(方块 ID,如 gravel)、blockMetadata(方块元数据)、height(道砟高度,单位米) |
| height | 否 | Float/Float[] | 道砟层的高度,单位是米。0.0625 对应 Minecraft 的 1/16 格 |
| model | 否 | Object | 模型定义对象,包含 modelFile(MQO/MQOZ/OBJ 模型路径)、textures(材质映射数组)和可选的 rendererPath(渲染脚本路径) |
| polygonType | 否 | String | 轨道的多边形渲染类型,控制轨道截面形状 |
| railModel | 否 | Object | 轨条的独立模型路径,与主模型分开的单独轨条模型(部分轨道类型使用) |
| railName | 否 | String | 轨道在游戏内显示的名称,建议包含轨距信息(如 1435mm_PC 表示标准轨混凝土轨枕) |
| railTexture | 否 | String(path) | 轨条的独立贴图路径,与 railModel 配对使用 |
| rendererPath | 否 | String(path) | 自定义渲染 JS 脚本路径,用于实现道岔切换动画等效果 |
| tags | 否 | String | 创造模式物品栏中的分类标签,相同 tag 的物品归为一组 |
| 键 | 必需 | 类型 | 说明 |
|---|---|---|---|
| accuracy | 否 | String(LOW/MEDIUM/HIGH) | 碰撞检测精度,LOW/MEDIUM/HIGH |
| buttonTexture | 否 | String(path) | 创造模式物品栏图标路径 |
| connectorType | 否 | String | 连接器类型:Relay=中继连接器(两端均可接线)、RelaySN=侧式中继、Input=输入端(接受信号/能量输入)、Output=输出端(发送信号/能量)、NoModel=无形连接点(无模型仅用于接线) |
| doCulling | 否 | Boolean | 是否启用背面剔除优化,墙上的连接器建议设为 true,独立支柱建议 false |
| model | 否 | Object | 模型定义对象,含 modelFile、textures 和可选的 rendererPath |
| name | 否 | String | 物品在游戏内显示的名称 |
| smoothing | 否 | Boolean | 是否启用模型平滑着色,true=平滑过渡法线,false=保留面片棱角 |
| tags | 否 | String | 物品栏分类标签 |
| textures | 否 | String(path) | 材质映射数组 [[材质名, 贴图路径, 渲染选项],...],材质名必须与 MQO 模型中的材质名称完全一致 |
| useCustomColor | 否 | Boolean | 是否允许玩家在游戏中自定义物品的颜色 |
| wirePos | 否 | Float/Float[] | 线缆接入点的三维坐标 [x,y,z],相对于物品的本地坐标系,决定了线缆从哪个位置引出 |
| 键 | 必需 | 类型 | 说明 |
|---|---|---|---|
| accuracy | 否 | String(LOW/MEDIUM/HIGH) | 碰撞精度 LOW/MEDIUM/HIGH |
| brightness | 否 | Float/Float[] | 机器的自发光亮度值,范围 0.0-1.0,用于显示器屏幕、灯具等发光设备 |
| buttonTexture | 否 | String(path) | 物品栏图标路径 |
| defaultData | 否 | Object | 默认可编程数据数组,每个元素包含 key(数据键名)、type(数据类型)和 value(默认值) |
| defaultValues | 否 | Object | 默认值配置数组,每个元素除了 key/type/value 外,还可包含 minmax(取值范围 [最小,最大])、suggestions(建议值列表)和 pattern(格式模式) |
| doCulling | 否 | Boolean | 背面剔除 |
| followRailAngle | 否 | Boolean | 是否自动跟随轨道方向旋转朝向,true=机器角度随轨道方向调整(用于 ATC 装置、止冲挡等安装在轨道上的设备) |
| key | 否 | String | defaultData/defaultValues 中的数据键名标识符 |
| machineType | 否 | String | 机器功能类型标识:Antenna_Send=信号发送天线、Turnstile=闸机、Gate=屏蔽门、TicketVendor=自动售票机、Noticer=列车接近报警器、Point=转辙机、CrossingGate=道口栏木机、TrainDetector=列车检测器、SoundSignal=音响信号机、Speaker=扬声器/喇叭、Vendor=自动贩卖机、Windmill=风车、BeamGenerator=光束发生器、LighthouseLamp=灯塔灯、RevolvingLight=旋转警示灯、SearchLight=探照灯、CameraMonitor/PictureMonitor/ThinMonitor/ThinEBB/TweetMonitor=各类显示器/信息屏、MirrorBall=镜球灯、Torii=鸟居、TrainWasher=洗车机、BumpingPost=止冲挡、ATC=列车自动控制装置 |
| minmax | 否 | Float[] | 数值型数据的取值范围 [最小值, 最大值] |
| model | 否 | Object | 模型定义对象,含 modelFile、textures 和可选的 rendererPath |
| name | 否 | String | 机器在游戏内显示的名称 |
| pattern | 否 | String | 文本型数据的输入格式验证模式 |
| renderAABB | 否 | String | 自定义渲染包围盒 [minX, minY, minZ, maxX, maxY, maxZ],超出此范围的模型部分会被裁剪掉,用于优化大型设备的渲染性能 |
| rendererPath | 否 | String(path) | 自定义渲染 JS 脚本路径,用于实现闸机开合、屏蔽门滑动等动画效果 |
| rotateByMetadata | 否 | Boolean | 是否根据放置时的方块元数据(metadata)自动旋转朝向,true=右键放置时自动面向玩家 |
| serverScriptPath | 否 | String(path) | 服务端脚本路径,用于实现需要服务器端处理的逻辑 |
| smoothing | 否 | Boolean | 模型平滑着色 |
| sound_OnActivate | 否 | String | 机器被触发/激活时播放的音效 ID,例如 'minecraft:random.door_open' |
| sound_Running | 否 | String | 机器持续运行时的音效 ID,适用于道口栏木机等有持续动作的设备 |
| suggestions | 否 | String | 输入时显示的建议值列表 |
| tags | 否 | String | 分类标签 |
| textures | 否 | String(path) | 材质映射 [[材质名,路径,选项],...] |
| type | 否 | String | 数据类型标识,用于 defaultData/defaultValues 中定义值的类型(如 string/int/float) |
| useCustomColor | 否 | Boolean | 允许玩家自定义颜色 |
| value | 否 | String | 默认值或当前值 |
| 键 | 必需 | 类型 | 说明 |
|---|---|---|---|
| buttonTexture | 否 | String(path) | 物品栏图标路径 |
| deflectionCoefficient | 否 | Float/Float[] | 线缆的下垂系数,0.0 表示完全绷直(接触网承力索),正值越大下垂幅度越大(如馈线、链条) |
| doCulling | 否 | Boolean | 线缆建议设为 false(双面渲染),否则从某些角度看线缆会消失 |
| lengthCoefficient | 否 | Float/Float[] | 线缆的长度倍率,用于调整线缆在两端 Connector 之间的分段密度,数值越小分段越密 |
| model | 否 | Object | 模型定义对象,含 modelFile、textures 和可选的 rendererPath |
| name | 否 | String | 线缆在游戏内显示的名称 |
| rendererPath | 否 | String(path) | 线缆渲染脚本路径,用于实现接触网的动态视觉效果 |
| sectionLength | 否 | Float/Float[] | 每小段线缆的长度(单位:米),默认 1.0,影响线缆的平滑程度 |
| smoothing | 否 | Boolean | 平滑着色 |
| textures | 否 | String(path) | 材质映射 [[材质名,路径,选项],...] |
| useCustomColor | 否 | Boolean | 允许玩家自定义线缆颜色 |
| yOffset | 否 | Float/Float[] | 线缆的 Y 轴位置偏移量,用于微调线缆在高度方向上的位置 |
| 键 | 必需 | 类型 | 说明 |
|---|---|---|---|
| buttonTexture | 否 | String(path) | 物品栏图标路径 |
| doCulling | 否 | Boolean | 背面剔除 |
| lights | 否 | String[] | 灯位定义字符串数组,每条格式为 S(信号态编号) I(初始显示态) P(对应部件名),例如 'S(1) I(0) P(light1)' 表示信号态 1 时点亮 light1 部件 |
| lightTexture | 否 | String(path) | 灯光贴图路径,这张贴图的不同区域对应不同的灯位,通过 UV 坐标控制各灯位的显示图案 |
| modelPartsBody | 否 | String | 信号机的可旋转灯体部件定义对象,结构与 modelPartsFixture 相同。灯体会跟随 rotateBody 设置旋转 |
| modelPartsFixture | 否 | String | 信号机的固定部件定义对象,包含 objects(固定部件的 MQO 对象名列表)和 pos(位置偏移 [x,y,z]) |
| objects | 否 | String[] | 模型部件名列表 |
| pos | 否 | Float/Float[] | 位置偏移 [x,y,z] |
| rendererPath | 否 | String(path) | 渲染脚本路径(部分复杂信号机使用) |
| rotateBody | 否 | String | 灯体是否跟随朝向旋转,true=灯体(含 lights 灯位)始终面向轨道方向 |
| signalModel | 否 | Object | 信号机模型的 MQO 路径 |
| signalName | 否 | String | 信号机在游戏内的名称标识 |
| signalTexture | 否 | String(path) | 信号机主体贴图路径 |
| smoothing | 否 | Boolean | 平滑着色 |
| tags | 否 | String | 分类标签 |
货柜是可以放在平板货车上运输的集装箱。它使用独立的模型/贴图字段(containerModel/containerTexture)而非通用的 model 对象。
| 键 | 必需 | 类型 | 说明 |
|---|---|---|---|
| buttonTexture | 否 | String(path) | 物品栏图标路径 |
| containerHeight | 否 | Float/Float[] | 货柜的高度(单位:米),标准 20 英尺货柜一般为 2.5 米 |
| containerLength | 否 | String | 货柜的长度(单位:米),20 英尺标准货柜约为 6.058 米 |
| containerModel | 否 | Object | 货柜专用的 MQO/OBJ 模型路径,注意它不使用通用 model 对象,而是用这个独立字段单独指定 |
| containerName | 否 | String | 货柜在游戏内显示的名称 |
| containerTexture | 否 | String(path) | 货柜专用的贴图路径,与 containerModel 配对使用 |
| containerWidth | 否 | String | 货柜的宽度(单位:米),标准货柜宽度为 2.438 米(8 英尺) |
| doCulling | 否 | Boolean | 背面剔除,设为 false 时货柜内部可见 |
| model | 否 | Object | 通用模型定义对象(部分货柜使用,含 modelFile、textures、rendererPath) |
| rendererPath | 否 | String(path) | 渲染脚本路径(使用通用 model 时) |
| tags | 否 | String | 分类标签 |
| textures | 否 | String(path) | 材质映射(使用通用 model 时) |
武器是可旋转可射击的防御装置,包括舰炮、近防炮和多管火箭等。武器通过四层级部件模型(N→Y→X→Barrel)实现多轴旋转控制。
| 键 | 必需 | 类型 | 说明 |
|---|---|---|---|
| ammoType | 否 | String | 弹药类型编号,不同的整数代表不同的弹种(1=小型弹、2=中型弹等),影响伤害和弹道 |
| buttonTexture | 否 | String(path) | 物品栏图标路径 |
| doCulling | 否 | Boolean | 背面剔除 |
| firearmModel | 否 | Object | 武器专用的 MQO 模型路径,与通用的 model 对象二者选一 |
| firearmName | 否 | String | 武器在游戏内的显示名称 |
| firearmTexture | 否 | String(path) | 武器专用的贴图路径 |
| fpvMode | 否 | Boolean | 是否支持第一人称瞄准视角,true=玩家按 Shift 可切换到瞄准镜视角 |
| magazineSize | 否 | Float/Float[] | 弹匣或弹鼓的弹药容量,打空后需要时间装填,期间无法射击 |
| model | 否 | Object | 通用模型定义对象(含 modelFile、textures、rendererPath),与 firearmModel/firearmTexture 二选一 |
| modelPartsBarrel | 否 | String | 炮管部件对象,可以独立于俯仰面做更精细的角度调整,结构与 modelPartsN 相同 |
| modelPartsN | 否 | String | 底座部件对象,包含 objects(部件名列表)和 pos(位置偏移 [x,y,z]),底座不参与旋转 |
| modelPartsX | 否 | String | 俯仰旋转层部件对象,绕 X 轴(水平轴)做俯仰旋转,结构与 modelPartsN 相同 |
| modelPartsY | 否 | String | 水平旋转层部件对象,绕 Y 轴(竖直轴)做水平旋转,结构与 modelPartsN 相同 |
| muzzlePos | 否 | Float/Float[] | 炮口位置的三维坐标 [x,y,z],弹道粒子和发射效果从这个位置生成 |
| objects | 否 | String[] | 模型部件名列表 |
| pitch | 否 | Float/Float[] | 俯仰角限制范围 [最小值, 最大值],正值为向上仰、负值为向下俯,例如 [80, -20] 表示可上仰 80 度、下俯 20 度 |
| playerPos | 否 | Float/Float[] | 玩家操作武器时的站立位置 [x,y,z] |
| pos | 否 | Float/Float[] | 位置偏移 [x,y,z] |
| rateOfFire | 否 | Int | 每分钟的射速,数值越大射击间隔越短,连续射击会产生热量积累 |
| recoil | 否 | Float/Float[] | 后坐力系数,影响连续射击时炮口的抬升幅度和散布增大 |
| rendererPath | 否 | String(path) | 渲染脚本路径(武器旋转动画等) |
| rotationSpeedX | 否 | String | 俯仰旋转速度系数 |
| rotationSpeedY | 否 | String | 水平旋转速度系数,数值越大瞄准时转动越灵敏 |
| smoothing | 否 | Boolean | 模型平滑着色 |
| tags | 否 | String | 分类标签 |
| textures | 否 | String(path) | 材质映射 |
| yaw | 否 | Float/Float[] | 水平旋转角度限制范围 [最小值, 最大值],例如 [-180, 180] 表示全向旋转,限制过大会影响瞄准范围 |
载具指非铁路类的可驾驶车辆——坦克、汽车、船只、矿车、盾构机等。
| 键 | 必需 | 类型 | 说明 |
|---|---|---|---|
| acceleration | 否 | Float/Float[] | 加速度系数,影响载具从静止到最高速度的快慢 |
| accuracy | 否 | String(LOW/MEDIUM/HIGH) | 碰撞精度 LOW/MEDIUM/HIGH |
| buttonTexture | 否 | String(path) | 物品栏图标路径 |
| changeYawOnStopping | 否 | Boolean | 设为 true 时载具停止后保持当前朝向不回正,false=停下来后自动回正方向 |
| collisionParts | 否 | String[] | 参与物理碰撞的模型部件名列表,例如 ['-all'] 表示所有部件参与碰撞,也可以指定具体部件名精确定义碰撞范围 |
| color | 否 | String | 默认载具颜色 [R,G,B] (0-255) |
| connectionDistance | 否 | Float/Float[] | 多节载具连接间距(米) |
| customButtons | 否 | String[] | 自定义 GUI 按钮文本列表 |
| customButtonTips | 否 | String | 自定义按钮的提示文本 |
| doCulling | 否 | Boolean | 背面剔除 |
| friction | 否 | String | 地面摩擦力系数,影响载具的制动距离和转向抓地力 |
| gripPos | 否 | Float/Float[] | 抓地力检测点位置,决定载具与地面的接触判定点 |
| guiScriptPath | 否 | String(path) | 自定义 GUI 脚本路径 |
| guiTexture | 否 | String(path) | 自定义 GUI 背景贴图路径 |
| headLights | 否 | String[] | 头灯位置 |
| hoveringSpeed | 否 | String | 悬浮/飞行载具的悬停速度 |
| maxSpeed | 否 | Float/Float[] | 最高速度限制 |
| maxYaw | 否 | Float/Float[] | 最大转向角度限制 |
| model | 否 | Object | 模型定义对象,含 modelFile 和 textures |
| name | 否 | String | 载具在游戏内显示的名称 |
| offset | 否 | Float/Float[] | 模型整体位置偏移 [x,y,z] |
| pitchCoefficient | 否 | Float/Float[] | 俯仰系数,影响载具上下坡时的车身姿态 |
| playerPos | 否 | Float/Float[] | 玩家驾驶/乘坐时的位置坐标 [[x,y,z],...],多个值时玩家随机分配到其中一个 |
| pos | 否 | Float/Float[] | 位置偏移 [x,y,z] |
| r | 否 | String | 旋转角度 [俯仰, 偏航, 横滚] |
| rendererPath | 否 | String(path) | 自定义渲染 JS 脚本路径,用于实现特殊动画效果 |
| rollCoefficient | 否 | String | 侧倾系数,影响载具转弯时的车身倾斜程度 |
| scale | 否 | Float/Float[] | 模型缩放倍率 |
| serverScriptPath | 否 | String(path) | 服务端脚本路径 |
| size | 否 | Float/Float[] | 载具的碰撞盒尺寸 [宽度, 高度],单位是米,决定载具能否通过狭窄通道或低矮隧道 |
| slotPos | 否 | Float/Float[] | 载具内部物品槽位位置,用于存储系统 |
| smoothing | 否 | Boolean | 平滑着色 |
| soundScriptPath | 否 | String(path) | 运行时音效脚本路径 |
| tags | 否 | String | 分类标签 |
| tailLights | 否 | String[] | 车尾灯位置 [[x,y,z],...] |
| textures | 否 | String(path) | 材质映射 |
| type | 否 | String | 类型标识(部分载具使用) |
| useCustomColor | 否 | Boolean | 允许玩家自定义载具的颜色 |
| vehicleType | 否 | String | 载具的分类标识字符串,不同的类型决定不同的驾驶方式和物理行为(如 Car、Trolley、Tank、Ship 等) |
| vibration | 否 | Float/Float[] | 行驶时的震动参数 [振幅, 频率],振幅控制颠簸幅度,频率控制抖动的快慢(高频低幅=路面细碎震动,低频高幅=越野摇晃) |
| yawCoefficient | 否 | Float/Float[] | 转向灵敏度系数,数值越小转向越迟钝(适合重型车辆),数值越大转向越灵敏(适合轻型车辆) |
机械部件用于 RTM 的动力传输系统,包括齿轮、离合器、减速器、电机、滑轮、传动轴和换向器。
| 键 | 必需 | 类型 | 说明 |
|---|---|---|---|
| acceleration | 否 | Float/Float[] | 加速能力系数,数值越大部件从静止到最高转速的响应速度越快 |
| accuracy | 否 | String(LOW/MEDIUM/HIGH) | 碰撞精度 LOW/MEDIUM/HIGH |
| buttonTexture | 否 | String(path) | 物品栏图标路径 |
| doCulling | 否 | Boolean | 背面剔除 |
| maxSpeed | 否 | Float/Float[] | 部件的最高转速限制,单位 RPM(转每分钟),超过此转速可能导致机械损坏 |
| model | 否 | Object | 模型定义对象,含 modelFile、textures 和 rendererPath |
| name | 否 | String | 机械部件在游戏内显示的名称 |
| radius | 否 | Float/Float[] | 部件的物理半径,用于碰撞检测和齿轮啮合时的视觉对齐 |
| rendererPath | 否 | String(path) | 渲染脚本路径,用于实现齿轮旋转动画等 |
| smoothing | 否 | Boolean | 平滑着色 |
| tags | 否 | String | 分类标签 |
| teethCount | 否 | Int | 齿数(仅用于齿轮和滑轮),两个啮合齿轮的 teethCount 比值决定实际传动比 |
| textures | 否 | String(path) | 材质映射 |
| transmissionRatioOFF | 否 | Float[] | 未激活状态(离合器分离)时的传动比五元数组,结构与 transmissionRatioON 相同,用于空转/分离状态 |
| transmissionRatioON | 否 | Float[] | 激活状态下的传动比五元数组 [档1, 档2, 档3, 档4, 档5],五个元素对应五个不同的传动档位,数值越大该档位的输出扭矩越高 |
| type | 否 | String | 部件的机械类型标识,TRANSMISSION=传动组件,不同的类型影响 RTM 引擎对部件的物理计算方式 |
RTM 内置了 NPC 系统——乘务员、守卫、乘客、售货员、猫女仆等。NPC 有两种制作方式:使用 texture 单贴图的简易平面 NPC,或使用 model 对象的完整 3D 模型 NPC。
| 键 | 必需 | 类型 | 说明 |
|---|---|---|---|
| buttonTexture | 否 | String(path) | 创造模式物品栏图标路径 |
| damage | 否 | String | NPC 每次攻击造成的伤害值,仅对攻击型 NPC(guard 守卫)有效 |
| doCulling | 否 | Boolean | 背面剔除 |
| health | 否 | String | NPC 的生命值,受到攻击后减少,归零时 NPC 死亡并从世界中消失 |
| lightTexture | 否 | String(path) | 发光层贴图路径,在 NPC 身上叠加一层不受光照影响的半透明发光层,用于角色眼睛、名牌等特殊效果 |
| model | 否 | Object | 3D 模型 NPC 的模型定义对象,含 modelFile、textures 和 rendererPath。使用 model 的 NPC 需要完整的 3D 模型和骨骼动画脚本 |
| name | 否 | String | NPC 在游戏内显示的名称 |
| rendererPath | 否 | String(path) | NPC 动画脚本路径,用于实现行走、呼吸、交互等动画效果 |
| role | 否 | String | 行为角色标识字符串,不同的值决定不同的 AI 行为:attendant=乘务员(跟随玩家交互)、buyer=买家(收购物品)、guard=守卫(巡逻攻击)、passenger=乘客(随机走动)、salesperson=售货员(固定交易)、mannequin=假人(站立不动) |
| smoothing | 否 | Boolean | 平滑着色 |
| speed | 否 | String | NPC 的移动速度倍率,1.0 为默认速度,小于 1.0 走得慢,大于 1.0 走得快 |
| texture | 否 | String(path) | 简易 NPC 使用的平面贴图路径,使用此字段时 NPC 不需要 3D 模型,只用一张带透明通道的 PNG 贴图显示 |
| textures | 否 | String(path) | 材质映射 |
| useCustomColor | 否 | Boolean | 允许玩家自定义 NPC 的贴图颜色 |
装饰物是纯视觉效果物品,用于场景美化——树木、荧光灯、铁架、电线杆、管道、脚手架、自动扶梯等。
| 键 | 必需 | 类型 | 说明 |
|---|---|---|---|
| buttonTexture | 否 | String(path) | 物品栏图标路径 |
| conveyorSpeed | 否 | Float/Float[] | 自动扶梯类装饰物的传送带移动速度,扶梯台阶表面根据此值驱动运动 |
| doCulling | 否 | Boolean | 背面剔除 |
| minRandomScale | 否 | Float/Float[] | 放置时的最小随机缩放倍率。系统在每个放置位置从 minRandomScale 到 1.0 之间随机取值,对模型进行缩放,实现同一棵植物有高矮大小的自然差异 |
| model | 否 | Object | 模型定义对象,含 modelFile 和 textures |
| name | 否 | String | 装饰物在游戏内显示的名称 |
| offset | 否 | Float/Float[] | 放置时的位置偏移量 [x,y,z],用于微调装饰物相对于方块中心的位置,植物类通常向下偏移使底部对齐地面 |
| ornamentType | 否 | String | 装饰物的分类标识字符串,影响 RTM 对它的渲染和放置方式。Plant=植物类(支持随机缩放),LinePole=线杆类(可悬挂线缆) |
| renderAABB | 否 | String | 手动指定的渲染包围盒 [minX, minY, minZ, maxX, maxY, maxZ],超出该范围的模型部分会被裁剪掉。合理设置可以大幅减少不必要的渲染计算 |
| rendererPath | 否 | String(path) | 自定义渲染脚本路径,用于实现装饰物的动态效果(如风车旋转、荧光灯闪烁) |
| smoothing | 否 | Boolean | 平滑着色 |
| textures | 否 | String(path) | 材质映射 [[材质名,路径,选项],...] |
| useCustomColor | 否 | Boolean | 允许玩家自定义装饰物的颜色 |
RTM 支持两种音效方式:sounds.json 注册的静态音效(报站、开关门声、运行声)和 JS 脚本控制的运行时音效(牵引/制动变频声)。
RTM 追加包的音效系统是一个三步流程:准备音频文件 → 放入正确目录 → 在 sounds.json 中注册。下面从零演示完整流程。
第一步——在 assets 下创建音效目录结构。在追加包的 assets/sounds/ 下新建一个子目录用于存放音效文件。建议按类别分子目录:
第二步——放入音频文件。将处理好的所有 .ogg 文件按类别放入 sounds/ 的对应子目录中。文件路径中的目录名必须全部小写且不含空格。
第三步——在 sounds.json 中注册。创建 assets/sounds/sounds.json,为每个音频文件定义一个唯一的音效 ID(建议采"类别.名称"格式),并指定其相对于 sounds/ 子目录的路径(不带 .ogg 扩展名)。详细格式见 6.2 节。
引用规则:在 JSON 和 JS 脚本中引用音效时,使用格式 命名空间:音效ID,例如 "sounds:train.NJ01H" 或 "rtm:train.door"。其中 sounds: 代表 assets/sounds/ 目录(即存放音效文件的目录),这是追加包内音效的标准命名空间;rtm: 代表 RTM 模组自带的音效;minecraft: 代表原版 Minecraft 音效。
音频必须使用 OGG Vorbis 格式(.ogg),采样率 44100Hz,单声道或立体声均可。推荐使用 Adobe Audition 进行音频处理和导出——在 Audition 中完成剪辑后,通过 File → Export → Multitrack Mixdown → Entire Session,格式选择 FLAC/Ogg Vorbis (.ogg),质量设为 0.5 即可在音质和文件大小之间取得平衡。导出后的 .ogg 文件放入 assets/sounds/sounds/ 目录。
位置:assets/sounds/sounds.json。每行定义一个音效 ID:
在 JSON 中引用时使用 sounds:音效ID(追加包内音效)、rtm:音效ID(RTM 本体音效)或 minecraft:音效ID(原版音效)。注意 sounds.json 中的路径不要带 .ogg 扩展名。
在列车 JSON 中通过 "soundScriptPath": "scripts/sound_NJ01A.js" 指定。核心函数为每帧调用的 onUpdate(su),其中 su 是 SoundUpdater 对象,提供以下 API:
| API | 说明 |
|---|---|
| su.getSpeed() | 列车当前速度,单位是 m/s(米每秒) |
| su.getNotch() | 手柄级位:正值为牵引级位,负值为制动级位,0 为惰行 |
| su.isComplessorActive() | 空压机是否工作中,返回布尔值(true/false) |
| su.complessorCount() | 空压机启动后的运行计数值 |
| su.playSound('sounds', 'train.NJ01A', vol, pitch) | 播放音效。参数:命名空间、音效 ID、音量(0.0-1.0)、音高(倍率) |
| su.stopSound('sounds', 'train.NJ01A') | 停止播放指定的音效 |
渲染JS可以为追加包添加一些天马行空的功能,包括但不限于可动驾驶台、自定义电显、ATP系统......但这些功能的实现往往伴随着复杂的语法,所以我们建议具备一定编程基础的人来学习本章节。
新建 .js 文件,将 .js 文件放在 assets/minecraft 下的 scripts文件夹,并在 .json 中用 trainModel2下的rendererPath 指定。
| 关键代码 | 解释 |
|---|---|
| var renderClass = "..." | 宣告脚本用于哪种物品——必须是 11.0 节中列出的 10 个全限定类名之一 |
| importPackage(...) | 导入扩展库:org.lwjgl.opengl=3D数学运算,jp.ngt.rtm.render=RTM API |
| renderer.registerParts | 把 MQO 对象名注册为 Parts 组。后续用 .render(renderer) 渲染 |
| render(entity,pass,par3) | 每帧调用。entity=物品实例,pass=渲染通道(0/1/2),par3=补间参数 |
| GL11.glPushMatrix() | 保存当前 3D 变换状态 |
| GL11.glPopMatrix() | 恢复保存的状态 |
RTM 的 JS 引擎是 Java 的 Nashorn(JDK 8 内置的 JavaScript 引擎),这意味着 JS 脚本可以直接调用任何 Java 类。使用 importPackage() 或 importClass() 导入后,即可在脚本中使用该 Java 包中的所有类和方法。以下为 RTM 内置 78 个脚本中实际使用的 20 个包:
| 导入语句 | 使用次数 | 用途 |
|---|---|---|
| Packages.org.lwjgl.opengl | 62 | OpenGL 3D 图形库——所有 glTranslatef/glRotatef/glPushMatrix 等 3D 变换函数。渲染 JS 必须导入 |
| Packages.jp.ngt.rtm.render | 63 | RTM 渲染器核心包——包含 Parts, renderer.* 等所有渲染 API。渲染 JS 必须导入 |
| Packages.jp.ngt.ngtlib.renderer | 28 | NGTLib 渲染工具——NGTRenderHelper, NGTTessellator(曲面细分)等高阶图形工具 |
| Packages.jp.ngt.ngtlib.math | 21 | 数学运算库——NGTMath 的 getSin/getCos/toDegrees 等角度与三角函数 |
| Packages.jp.ngt.rtm.block | 8 | RTM 方块 API——装饰物/管道类脚本用于访问方块状态,如 entity.getAttachedSide() |
| Packages.jp.ngt.rtm.entity.train.util | 6 | 列车实体工具——TrainState(列车状态枚举)、Formation(编组)等 |
| Packages.jp.ngt.rtm.rail.util | 5 | 轨道工具——RailDir(道岔方向枚举)、RailPosition(轨位)等 |
| Packages.jp.ngt.ngtlib.math.NGTMath | 5 | NGTMath 类的所有静态方法——与 importPackage 版本相同但更精确 |
| Packages.jp.ngt.rtm.render.Parts | 4 | Parts 类独立导入——可以直接 new Parts(...) 而不需要包名前缀 |
| Packages.jp.ngt.ngtlib.util | 5 | NGTLib 工具集——MCWrapper(Minecraft 包装器,访问世界/实体/粒子等) |
| Packages.org.lwjgl.input | 3 | LWJGL 输入库——Keyboard.isKeyDown() 检测键盘按键 |
| Packages.jp.ngt.ngtlib.io | 2 | NGTLib 输入输出——NGTLog(调试日志)等 |
| Packages.jp.ngt.ngtlib.renderer.NGTRenderer | 5 | NGTRenderer 类独立导入——renderWebCamera/renderMap 等显示器功能 |
| Packages.jp.ngt.ngtlib.renderer.GLHelper | 1 | GLHelper 类独立导入——disableLighting/enableLighting 等光照控制 |
| Packages.jp.ngt.rtm | 1 | RTM 根包——访问 RTM 核心类的顶级接口 |
| Packages.jp.ngt.rtm.sound | 1 | RTM 音效 API——音效播放相关的底层接口 |
| Packages.net.minecraft.tileentity | 1 | Minecraft 方块实体——TileEntity(方块实体基类),用于访问方块的 NBT 数据 |
| Packages.net.minecraft.util | 1 | Minecraft 工具库——ChatAllowedCharacters 等游戏内工具类 |
| Packages.org.lwjgl.util.vector | 1 | LWJGL 向量数学——Vector2f/Vector3f 等三维向量运算 |
importPackage("Packages.org.lwjgl.opengl") 导入整个包(所有类都可用),而 importClass("Packages.org.lwjgl.opengl.GL11") 只导入 GL11 这一个类。使用 importClass 可以避免类名冲突,但需要为每个用到的类单独导入。| # | renderClass | 适用物品 | 脚本数 |
|---|---|---|---|
| 1 | MachinePartsRenderer | 闸机、屏蔽门、旋转灯、显示器等 | 18 |
| 2 | VehiclePartsRenderer | 列车和载具:车门、车轮、履带、受电弓 | 16 |
| 3 | RailPartsRenderer | 轨道:道岔切换和轨道变形 | 7 |
| 4 | OrnamentPartsRenderer | 装饰物:荧光灯、管道、脚手架、扶梯 | 10 |
| 5 | NPCPartsRenderer | NPC:二足角色、人形生物 | 3 |
| 6 | FirearmPartsRenderer | 武器:近防炮、舰炮、多管火箭 | 3 |
| 7 | MechanismPartsRenderer | 机械传动:齿轮、离合器、电机 | 5 |
| 8 | WirePartsRenderer | 线缆:接触网电线、馈线、链条 | 3 |
| 9 | SignalPartsRenderer | 信号机:色灯信号机、时钟 | 1 |
| 10 | PartsRenderer | 上述9种基类——通用API均可用 | — |
RenderPass 定义了渲染通道,来源: jp.ngt.rtm.render.RenderPass 枚举类。在 JS 中可通过 RenderPass.名称.id 获取数值:
| 名 | id | 渲染内容 |
|---|---|---|
| NORMAL | 0 | 不透明物体——车身、门、座位。最常用 |
| TRANSPARENT | 1 | 半透明物体——玻璃窗户,需 AlphaBlend |
| LIGHT | 2 | 发光物体——头灯、信号灯,不受时间天气影响 |
| LIGHT_BACK | 3 | 发光物体背面——前灯亮时同时渲染尾灯,来源: Render223.js 等列车脚本 |
| OUTLINE | 4 | 轮廓线——选中有碰撞体积的物品时显示线框,来源: Render223.js |
| PICK | 5 | 拾取判定——用于方块高亮和右键交互,来源: Render223.js |
pass == 0 也可以用 pass == RenderPass.NORMAL.id。复杂列车动画通常同时覆盖 4-6 个 pass 值。| 方法 | 作用 |
|---|---|
| GL11.glPushMatrix() | 保存状态(所有脚本使用) |
| GL11.glPopMatrix() | 恢复状态 |
| GL11.glTranslatef(x,y,z) | 平移(米) |
| GL11.glRotatef(a,x,y,z) | 绕(x,y,z)轴旋转a度 |
| GL11.glScalef(x,y,z) | 缩放(1.0=原大) |
| GL11.glEnable/glDisable | 启用/禁用 GL_TEXTURE_2D 等 |
| GL11.glColor4f(r,g,b,a) | 颜色RGBA(0-1) |
| GL11.glBlendFunc(a,b) | 透明混合 GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA |
| GL11.glDepthMask(f) | 深度写入开关 |
| GL11.glShadeModel(m) | 着色模式 GL_SMOOTH/GL_FLAT |
| API | 说明 | 来源 |
|---|---|---|
| renderer.registerParts(new Parts(...)) | 注册部件组 | 所有脚本 |
| renderer.bindTexture(Material) | 绑定材质/贴图 | LibRenderRail.js |
| renderer.renderLightEffect(pass) | 渲染发光效果 | RenderLighthouseLamp.js |
| renderer.renderLightSurface(pass) | 渲染发光面 | RenderLighthouseLamp.js |
| renderer.setBrightness(int) | 设置亮度 | LibRenderRail.js |
| renderer.setLightmapMaxBrightness() | 最大光照(pass=2用) | RenderTorii.js |
| renderer.getWorld(entity) | 获取Minecraft世界对象 | LibRenderRail.js |
| renderer.getMinecraft() | 获取客户端实例 | EntityPartsRenderer |
| renderer.getConfig() | 获取物品配置对象 | RenderBevelGear.js |
| renderer.getModelName() | 获取模型名 | RenderClock.js |
| renderer.getModelObject() | 获取模型对象(含纹理信息) | LibRenderRail.js |
| renderer.getColor(tileEntity) | 自定义颜色值 | RenderBasicWire.js |
| renderer.getMetadata() | 方块metadata(0-15) | RenderBeamGenerator.js |
| renderer.currentMatId | 当前材质ID | render_crh2c_test.js |
| renderer.isPowered() | 红石信号激活? | RenderClutch.js |
| renderer.isRidden(entity) | 玩家正乘坐? | RenderNGT-18.js |
| renderer.getX/Y/Z(entity) | 世界坐标 | RenderMonorail.js |
| renderer.getSystemTime() | 系统时间(毫秒) | PartsRenderer |
| renderer.getSystemHour/Minute/Second | 系统时/分/秒 | RenderClock.js |
| renderer.getSystemMillisecond | 系统毫秒值 | RenderShieldMachine.js |
| renderer.getSystemTimeMillis() | 毫秒时间戳 | RenderBeamGenerator.js |
| renderer.getMCHour/Minute | 游戏内时间 | RenderClock.js |
| renderer.getViewerVec() | 玩家视线方向 | PartsRenderer |
| renderer.setData(entity,key,val) | 保存持久化数据 | PartsRenderer |
| renderer.getData(entity,key) | 读取持久化数据 | PartsRenderer |
| renderer.renderItem(item, pass) | 渲染物品栏物品 | RenderC20FT_NC.js |
| renderer.sigmoid(x) | 平滑插值函数(S型曲线) | Render223.js |
| renderer.renderWireDeflection(tileEntity,connection,vec,par8) | 渲染线缆下垂(仅Wire类) | RenderIllumination.js |
| renderClass | 专用 API 及说明 (来源) |
|---|---|
| Machine | getMovingCount(entity): 开合0.0-1.0(RenderTurnstile01.js)。getLightState(entity): 灯0/1(RenderBeamGenerator.js)。getTick(entity): tick累计20tick=1秒。getYaw/Pitch(entity): 偏航/俯仰角。getNormal(entity): 法线方向(RenderLighthouseLamp.js)。getLightPos(): 灯位坐标。getRotation(entity,Axis): 指定轴旋转(RenderWindmill.js)。rotate(degs,axis,x,y,z): 绕轴旋转(RenderTurnstile01.js) |
| Vehicle | getWheelRotationR/L(entity): 左右轮角度(RenderTest4.js)。getDoorMovementL/R(entity): 门滑动0-1(RenderOhmi220.js)。getPantographMovementFront/Back(entity): 受电弓升降(Render223.js)。getBogieId(entity): 转向架ID。getPlayerYaw(entity): 乘客视角(RenderTank.js)。getTrain(entity): 编组对象(Render223.js)。getWheelRotationR 也可以在 entity 上直接获取(entity.wheelRotationR, RenderMechaCentipede.js) |
| Rail | isSwitchRail(tileEntity): 是否道岔(LibRenderRail.js)。renderStaticParts(tileEntity,x,y,z): 固定部分渲染。renderRailMapStatic(...): 轨道段渲染。shouldRenderObject(...): 可选渲染判断。getModelObject(): 模型对象。getRailPositions/Pitch/Rotation/Height/Brightness: 轨道属性 |
| Ornament | getDir(entity): 朝向0-7对应8方向(RenderFluorescent.js)。isOpaqueCube(entity): 不透明方块?(RenderClock.js) |
| NPC | setRotationAngles(entity,tick): 设置身体旋转。rotateAndRender(parts,x,y,z,ax,ay,az): 旋转+渲染部位。18角度属性: headAngleX/Y/Z, bodyAngleX/Y/Z, rightArmAngleX/Y/Z, leftArmAngleX/Y/Z, rightLegAngleX/Y/Z, leftLegAngleX/Y/Z(RenderBiped.js) |
| Firearm | entity.getBarrelYaw(): 炮管水平角。entity.getBarrelPitch(): 俯仰角。entity.getRecoil(): 后坐力(RenderPhalanx.js) |
| Mechanism | getRotation(entity,Axis): 指定轴旋转。Axis: POSITIVE_X/NEGATIVE_X/POSITIVE_Y/NEGATIVE_Y/POSITIVE_Z/NEGATIVE_Z(RenderBevelGear.js) |
| Wire | getColor(tileEntity): 颜色值(RenderBasicWire.js)。NGTTessellator.instance: 曲面细分。renderWireStatic/Dynamic 特有函数签名 |
| Signal | isOpaqueCube(entity): 不透明方块?。getMCMinute/MCHour: 游戏时间用于时钟(RenderClock.js) |
| API | 说明 | 来源脚本 |
|---|---|---|
| GLHelper.disableLighting() | 禁用光照(用于pass=2发光渲染) | RenderMechaCentipede.js |
| GLHelper.enableLighting() | 启用光照 | RenderMechaCentipede.js |
| GLHelper.preMoveTexUV(cfg,id) | 纹理UV预移动 | Render223.js |
| GLHelper.postMoveTexUV(cfg,id) | 纹理UV后移动 | Render223.js |
| GLHelper.setColor(i,r,g,b) | 设置渲染颜色 | RenderIllumination.js |
| NGTMath.getSin/Cos(deg) | 正弦/余弦(度输入) | RenderMechaCentipede.js |
| NGTMath.getSinD/CosD(deg) | 正弦/余弦(度输入,D版本) | LibBeamEffect.js |
| NGTMath.sin/cos(rad) | 正弦/余弦(弧度输入) | RenderNGT-18.js |
| NGTMath.toDegrees(rad) | 弧度转度 | RenderHumanoid.js |
| NGTMath.toRadians(deg) | 度转弧度 | RenderHumanoid.js |
| NGTMath.getAtan2D(y,x) | 反正切(度输出) | RenderTank.js |
| NGTMath.normalizeAngle(a) | 角度归一化到0-360 | RenderMechaCentipede.js |
| NGTMath.RANDOM | 随机数生成器 | RenderRailStandardGrass.js |
| NGTRenderer.renderDesktop(w,h) | 渲染桌面画面到方块 | RenderCameraMonitor.js |
| NGTRenderer.renderEBB(w,h) | 渲染电子公告板 | RenderThinEBB.js |
| NGTRenderer.renderFire() | 渲染火焰效果 | RenderNGT-18.js |
| NGTRenderer.renderMap() | 渲染地图 | RenderMapMonitor.js |
| NGTRenderer.renderPicture(w,h) | 渲染图片 | RenderPictureMonitor.js |
| NGTRenderer.renderTweet() | 渲染Twitter推文 | RenderTweetMonitor.js |
| NGTRenderer.renderWebCamera(w,h) | 渲染网络摄像头 | RenderCameraMonitor.js |
| MCWrapper.getWorld(entity) | 通过entity获取世界 | RenderNGT-18.js |
| MCWrapper.getPosX/Y/Z(entity) | 通过entity获取坐标 | sound_crusader.js |
| MCWrapper.getPitch/Yaw(entity) | 通过entity获取角度 | sound_crusader.js |
| MCWrapper.getDistanceSq(e1,e2) | 两实体距离平方 | RenderTorii.js |
| MCWrapper.getRandom(world) | 获取随机生成器 | RenderNGT-18.js |
| MCWrapperClient.playSound(...) | 客户端播放音效 | RenderNGT-18.js |
| MCWrapperClient.spawnParticle(...) | 生成粒子效果 | RenderTank.js |
| MCWrapperClient.execCommand(cmd) | 执行Minecraft命令 | RenderTorii.js |
| MCWrapperClient.getPlayer(world) | 获取当前玩家 | RenderTorii.js |
| Keyboard.isKeyDown(key) | 键盘按键是否按下 | RenderNGT-18.js |
| Keyboard.KEY_F / KEY_* | 键盘按键常量 | RenderTank.js |
| NGTLog.debug(msg) | 输出调试日志 | RenderTank.js |
| NGTLog.sendChatMessageToAll(m) | 发送聊天消息 | render_crh2c_test.js |
| PooledVec3.create(x,y,z) | 创建可复用三维向量 | RenderHumanoid.js |
| NGTTessellator.instance | 曲面细分器实例 | RenderBasicWire.js |
| tessellator.startDrawing(mode) | 开始绘制(GL_TRIANGLE_STRIP等) | LibBeamEffect.js |
| tessellator.startDrawingQuads() | 开始四边形绘制 | RenderSimpleCatenary.js |
| tessellator.addVertex(x,y,z) | 添加顶点 | LibBeamEffect.js |
| tessellator.addVertexWithUV(x,y,z,u,v) | 添加带UV的顶点 | RenderSimpleCatenary.js |
| tessellator.setColorOpaque_I(i) | 设置不透明颜色(int) | RenderBasicWire.js |
| tessellator.setColorRGBA_I(i,a) | 设置颜色+透明度 | LibBeamEffect.js |
| tessellator.draw() | 提交绘制 | RenderBasicWire.js |
VehiclePartsRenderer 是最复杂也最常用的渲染器——RTM 内置 16 个脚本使用它渲染 223 系、ohmi 系、kiha 系、N700 系等列车以及坦克、台车等载具。重要:许多列车动画通过 entity.* 直接调用而非 renderer.*。以下是列车渲染的核心模式:
来源: Render223.js(RenderOhmi220.js(RenderN2100.js 等 16 个列车脚本。这些方法直接从 entity 读取列车实时状态:
| entity 方法/属性 | 说明 |
|---|---|
| entity.getResourceState() | 获取资源状态对象——从中可以读/写跨帧持久化数据(61+脚本使用,最常用) |
| entity.getNotch() | 牵引/制动级位。正值=牵引(1-5级)、负值=制动、0=惰行。用于播放对应加速/减速声 |
| entity.getSpeed() | 当前速度(m/s)。配合 getNotch 实现VVVF变频声 |
| entity.getTrainDirection() | 列车运行方向。0=正向、1=反向。用于判断前后端 |
| entity.getConnectedTrain(dir) | 获取指定方向的邻接车厢。null=该方向无连接。用于判断车头/车尾 |
| entity.getVehicleState(TrainStateType) | 获取车辆状态。TrainStateType 包含: State_TrainDir(方向)/State_Notch(级位)/State_Speed(速度)/State_Door(门状态)/Destination(目的地)等 |
| entity.getSignal()/getSignal2() | 获取列车信号状态。在 pass=PICK 中用于判断列车外部高亮 |
| entity.getFormation() | 获取编组数据——编组中每节车厢的类型和顺序。用于编写连挂识别逻辑 |
| entity.getRollsignAnimation() | 方向幕滚动动画值。返回浮点型进度用于UV滚动 |
| entity.getSeatRotation() | 座位旋转角度。用于翻转座椅朝向 |
| entity.getCouplerYaw() | 车钩偏航角。前后车厢连接处的转角。用于绘制连接处管道/篷布 |
| entity.train | 列车编组对象(属性)。可从中获取编组中任一节车厢 |
| entity.wheelRotationR | 车轮旋转角度(属性)。等效 renderer.getWheelRotationR(entity) |
| entity.getDir() | 朝向(0-7对应8方向)。Ornament/装饰物类中广泛使用 |
| entity.getMoveDir() | 移动方向(±1)。-1=后退,+1=前进。用于坦克履带方向 |
| entity.isControlCar() | 是否为控制车(带驾驶室)。非控制车不显示方向幕 |
| entity.isConnected(side) | 指定侧是否已连接。用于管道/连接件的自动延展 |
| entity.syncNotch() | 同步手柄级位到客户端。防止多人游戏时不同步 |
| entity.setVehicleState(type) | 设置车辆状态。用于自定义列车行为 |
| entity.getResourceState().getDataMap() | 获取跨帧数据映射——可在其中读写自定义键值对实现复杂状态机(如坦克炮塔角度、射击冷却) |
| entity.getX/Y/Z() | 列车当前坐标(动态位置) |
entity.getConnectedTrain(dir) == null 来判断是否为编组端点。前车为空=自己是车头(显示车头模型+车头灯),后车为空=自己是车尾(显示尾灯)。在 JS 脚本中,每一次 render() 调用都是一个独立的帧,帧与帧之间不共享变量。如果脚本需要在多帧之间记住某个状态(比如炮塔的当前角度、射击的冷却计时器、门的开关进度),就必须使用 dataMap。
dataMap 可以理解为「脚本的记事本」——每一帧你都可以往上面写东西,下一帧再翻出来读。RTM 会帮你保管这份数据,即使 Minecraft 重载资源包也不会丢失。
这行代码必须放在 render() 函数内部调用——因为 entity 参数在 init() 中不存在。
| 方法 | 说明 | 来源脚本 |
|---|---|---|
| dm.getDouble(key) | 读取浮点数值。返回 double 类型,默认值 0.0 | RenderTank.js(4个不同key使用) |
| dm.getInt(key) | 读取整数值。返回 int 类型,默认值 0 | render_crh2c_test.js(最常见,60+处调用) |
| dm.getBoolean(key) | 读取布尔值。返回 true/false,默认值 false | RenderTank.js, RenderNGT-18.js |
| dm.getString(key) | 读取字符串值。默认值空字符串 "" | RenderTweetMonitor.js, RenderPictureMonitor.js |
| dm.getHex(key) | 读取十六进制颜色值(如 0xFF00AA)。返回 int,默认 0xFFFFFF(白) | RenderBeamGenerator.js(4个颜色key) |
| dm.setDouble(key, value, syncFlag) | 写入浮点数值。syncFlag 0=本地/1=同步到服务端/3=广播所有玩家 | RenderTank.js, render_crh2c_test.js |
| dm.setInt(key, value, syncFlag) | 写入整数值。syncFlag 同上,也可传 Boolean(true=同步) | render_crh2c_test.js, RenderTorii.js |
| dm.setBoolean(key, value, syncFlag) | 写入布尔值。同上 | RenderTank.js, RenderNGT-18.js |
| syncFlag | 含义 | 使用场景 |
|---|---|---|
| 0 | 仅写入本地,不通知服务端。最快 | 视觉动画数据(炮塔旋转、履带进度) |
| 1 | 同步到服务端,服务端再分发给其他玩家 | 炮口火焰标记(其他玩家需要看到开火)、启动方向 |
| 3 | 不经过缓冲区,立即广播所有玩家。最慢 | 缩放比例(RenderPalm.js)、门锁密码(RenderTorii.js) |
| true | 等效于 1,布尔参数便捷写法 | render_crh2c_test.js(5处使用) |
这个模式展示了如何通过 entity.getFormation() 遍历编组中的所有车厢,并将同一个值写入每一节车厢的 dataMap。用于实现编组内状态同步——例如所有车厢的方向幕显示相同的路线、所有车厢的灯光状态一致。
dataMap 的 key 是完全自定义的字符串,RTM 不限制内容。以下是 78 个脚本中常见的命名模式:
| key 示例 | 存储内容 | 数据类型 |
|---|---|---|
| "turret_yaw" | 炮塔/武器水平角度 | Double |
| "fire_count" / "fired" | 射击冷却/扳机状态 | Int / Boolean |
| "prev_time" / "recentTick" | 上一帧时间戳(帧差计算用) | Int |
| "mov_amount" | 履带累积位移 | Double |
| "start_notch" / "start_time" | 启动时的级位/时间(音效脚本用) | Int |
| "input_num" / "password" | 用户输入数字/密码 | Int |
| "signal" / "preSignal" | 信号状态/前一帧信号 | Int |
| "scale" / "sizeX" / "sizeY" | 缩放/尺寸(显示器脚本用) | Double |
| "url" / "keyword" / "type" | URL/关键词/类型(显示器脚本用) | String |
| "insideColor" / "outsideAlpha" | 内外颜色/透明度(光束效果用) | Hex |
除了渲染视觉效果之外,RTM 的 JS 脚本也能响应玩家的交互操作——右键点击部件、拖拽操纵杆、打开 GUI 等。这些交互通过以下几套机制实现。
普通的 Parts 只能被渲染,不能响应点击或拖拽。要让某个部件变成可交互的,必须使用 ActionParts 类。来源: render_crh2c_test.js(全功能测试列车):
| ActionType | 含义 | 使用场景 |
|---|---|---|
| DRAG_X | 沿 X 轴拖拽 | 列车操纵杆(前后推拉)、制动阀 |
| DRAG_Y | 沿 Y 轴拖拽 | 升降式操纵杆、油门杆 |
| DRAG_Z | 沿 Z 轴拖拽 | 侧推杆 |
| CLICK | 单击 | 按钮、开关(用普通 Parts 即可) |
RTM 提供了几个特定名称的函数,只要在脚本中定义了这些函数,RTM 就会在对应事件发生时自动调用。来源: render_crh2c_test.js, RenderTorii.js:
| 回调函数 | 触发时机 | 参数说明 |
|---|---|---|
| onRightClick(entity, parts) | 玩家右键点击某个部件时 | entity=被点击的物品实例, parts=被点击的 ActionParts 对象 |
| onRightDrag(entity, parts, move) | 玩家右键拖拽某个部件时 | move=拖拽位移量(float),正负表示方向 |
| onRightClick(entity) | 玩家右键点击物品本体(非特定部件)时 | entity=被点击的物品实例 |
以下示例来自 render_crh2c_test.js,展示了如何用 ActionParts + onRightDrag 实现列车的牵引手柄(mascon)和制动阀(brake)的拖拽操作:
move 值的解读:move 是本次拖拽的累积位移量(float),不是拖拽的方向。如果 move > 0 表示正方向拖拽,move < 0 表示反方向拖拽。通常配合阈值判断(如 Math.abs(move) > 0.05)来防止微小的鼠标移动触发操作。
车门滑动 (来源: Render223.js)
车轮旋转 (来源: RenderTest4.js)
switch-case 根据模型名切换 (来源: Renderdoor.js)
VVVF 变频声 (来源: sound_223.js)
使用 dataMap 持久化数据 (来源: RenderTank.js)
来源: RenderC20FT_NC.js。货柜/集装箱内部可以放置物品,JS 脚本通过 renderer.renderItem() 将其中一个物品渲染出来:
鸟居(Torii)方块通过 dataMap 实现了一个四位密码输入系统。右键点击时累计输入数字,达到 4 位后与预设密码比对:
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 物品不显示 / 无名称 | JSON 文件名不符合前缀规范 | 确认文件名以 ModelTrain_ 或 ModelRail_ 等正确前缀开头 |
| 模型显示为紫黑方块 | MQO 文件路径错误或文件不存在 | 检查 modelFile 路径与实际文件位置是否一致,注意大小写 |
| 贴图全白 | 贴图路径错误或 MQO 材质名与 JSON 不匹配 | 确认 textures 数组中的材质名与 MQO 模型中的材质名完全一致 |
| 车门不滑动 | 未绑定 JS 渲染器,或 Parts 注册的对象名不匹配 | 确认 rendererPath 正确指定;Parts('door') 中的名字与 MQO 对象名一致 |
| 音效不播放 | 未在 sounds.json 注册或文件格式不对 | 确认 OGG 格式正确,sounds.json 路径不包含 .ogg 扩展名 |
| JS 报错 | 语法错误或 renderClass 不正确 | 查看 .minecraft/logs/latest.log 中的 JavaScript 错误栈 |
| 列车无法编组 | isSingleTrain 设为 true | 将 isSingleTrain 改为 false 允许挂多节 |
将整个追加包文件夹打包为 .zip 或 .jar 文件发布。用户下载后将文件放入 mods 文件夹即可使用。注意压缩包内不要嵌套多余的目录层——解压后应直接看到 assets/、mods/ 和 ReadMe.txt。