C++ native scripting
Gives resource pack authors for Minecraft Transit Railway 4 the ability to write all five script kinds โ vehicle, PIDS, lift, eyecandy, and platform screen doors โ in C++, with the same lifecycle and the same API surface as JavaScript scripts, and zero JVM crossings on the hot path. The full documentation of JavaScript scripting (the upstream JCM scripting system) is in the JavaScript Scripting section below.
What this is
Vanilla Joban Client Mod (JCM) lets resource packs write dynamic display scripts in JavaScript. The Yanyang fork adds C++ native scripting on top: scripts are compiled into native shared libraries (.dll / .so / .dylib) that the mod loads in game and drives frame by frame.
C++ and JS scripts can be mixed within the same declaration entry and rendered side by side. The mod detects the language automatically from file characteristics โ .js is JavaScript; anything else is parsed as a C++ module. Each side captures its own draw commands and replays them independently, without interfering with the other.
Same script model
The create / render / dispose lifecycle and per-instance persistent state are exactly the same as JS; snapshot wrappers line up with the JS Wrappers field by field.
Zero-JNI transport
Java โ C++ communicates over a shared-memory polling plane (any JDK โฅ 16) or Panama FFM (JDK 22+), never through JNI; just one host crossing per frame per instance.
Native bridges for 8 platforms
windows-x64 / windows-arm64 / linux-x64 / linux-arm64 / android-arm64 / macos-x64 / macos-arm64 / ios-arm64 are all bundled in the jar and matched automatically by system architecture.
Crash isolation
A script crash disables only the faulty module and leaves a single log line; the game process is unaffected. C++ exceptions thrown inside the module are intercepted by the same crash guard.
The journey of a frame
natives/<platform>/ library files
Serializes compact snapshots every frame
Reads snapshots ยท writes draw records
The same render path as JS scripts
A PIDS script in fifteen lines
#include <mtr/script.hpp>
struct ArrivalState {};
struct ArrivalDisplay : mtr::PidsScript<ArrivalState> {
static constexpr auto ID = "example:arrivals";
void render(mtr::PidsContext& ctx, ArrivalState&, const mtr::Pids& pids) override {
for (int row = 0; row < pids.rows(); row++) {
if (pids.is_row_hidden(row)) continue;
std::string text = pids.get_custom_message(row).str();
if (text.empty() && row < pids.arrivals().size())
text = pids.arrivals().at(row).destination().str();
if (!text.empty())
mtr::Text::create().text(text.c_str())
.pos(2, row * 10.0 + 2).size(pids.width() - 4, 9).draw(ctx);
}
}
};
MTR_REGISTER_PIDS_SCRIPT(ArrivalDisplay)
No JNI, no reflection, no per-call boxing โ pids.rows() and arrivals().at(i).destination() are plain memory reads over a compact snapshot.
When to choose C++
| Scenario | Recommendation |
|---|---|
| High-resolution LCDs / dot-matrix screens repainting large numbers of pixels every frame | C++ Gfx2D software rasterizer + dirty-rectangle uploads; pixels never cross the JVM |
| Heavy string processing / per-frame sorting / math | C++ Native computation, zero allocations |
| Needs to call lots of Java APIs (networking, files, sound managers) | Either Both sides reach the same set of public objects through Api |
| Simple one-off display logic | JS No toolchain needed; faster iteration |
Compatibility
| Item | Requirement |
|---|---|
| Minecraft | 1.17.1 โ 1.20.4 (Fabric / Forge) |
| Prerequisites | Minecraft Transit Railway 4.0.5+ (required); the Fabric build also needs Fabric API |
| Java | 16 or newer; 22+ automatically enables the end-to-end zero-JNI FFM plane |
| ABI | The host accepts ABI 6โ13 modules; the current SDK builds ABI 13 |
| Toolchain | C++17; MSVC / GCC / Clang; CMake โฅ 3.16 (recommended) |