跳转至

Openttd-Cluster

暂无简介,欢迎浏览仓库了解更多。

项目信息
仓库 https://github.com/Maicarons/Openttd-Cluster
主要语言 Rust
Stars 0
类型 原创项目
许可证 —
最近更新 2026-08-12

📦 该仓库已归档(Archived),内容仅供查阅。


otc — a JGRPP fork with a Rust server runtime

otc is a fork of JGRPP (OpenTTD/JGRPP multiplayer patchpack). Like JGRPP, it ships as a single binary that is both the client (GUI) and the dedicated server (-D). On top of the game, a Rust server runtime (otc-engine, compiled to a staticlib) is FFI-linked into the same binary and provides the advanced server-side features this project exists for:

  • Admin (Admin v3 / RCON) and Metrics (Prometheus)
  • Cluster (multi-node world directory, scheduling, failover)
  • Web control panel (runtime UI on the configured web port)
  • Snapshot bridge and command bus into the C++ simulation

The game simulation itself stays in C++ (OpenTTD's deterministic lockstep). The Rust side drives networking, admin, metrics, cluster control, and the web UI, and talks to the simulation through the snapshot/command bridges. This is exactly the "one program" end state described in plan.md.

There is no separate Rust server process. The server is the fork binary. A pure-Rust otc-standalone server used to exist for protocol testing, but it spoke a private OTC dialect that stock JGRPP clients cannot join, so it has been removed. Use otc-link-smoke for end-to-end protocol self-tests instead.

Fork model

The fork's source of truth is two parts:

Path Role
refs/jgrpp/ Pristine upstream JGRPP v0.73.0 (reference, git-ignored)
patches/jgrpp-0.73.0/ The 6 OTC patches that turn JGRPP into otc (revision handshake, snapshot bridge, raw command bridge, FFI host integration, version metadata, vanilla native server compat)

scripts/prepare_otc_fork.ps1 applies the patches onto a copy of refs/jgrpp to produce the build source; scripts/build_native_otc.bat compiles it (MSVC) with OTC_SERVER=ON, linking otc-engine into openttd.exe.

Build

## 1) prepare patched fork source from refs/jgrpp + patches/
powershell -File scripts/prepare_otc_fork.ps1
## 2) compile (MSVC x64, links Rust runtime)
scripts\build_native_otc.bat

Output: target\jgrpp-otc-build\openttd.exe — the single client+server binary.

Run

## dedicated server (starts both native :3979 and OTC :3989 game listeners)
target\jgrpp-otc-build\openttd.exe -D -c openttd.cfg
## GUI client — connect to native JGRPP port (stock-compatible)
target\jgrpp-otc-build\openttd.exe -n localhost:3979
## GUI client — connect to OTC protocol port
target\jgrpp-otc-build\openttd.exe -n localhost:3989

See client/README.md for the packaged client launcher.

Runtime configuration (OTC server features)

The fork binary starts the Rust server runtime on OnStartGame and drives it every frame. The advanced features are toggled with environment variables read at server start:

Variable Default Effect
OTC_GAME_PORT 3989 OTC game protocol port (OTC-protocol clients connect here)
OTC_ADMIN_PORT 3977 Admin v3 / RCON port
OTC_METRICS_PORT 9100 Prometheus metrics HTTP (/metrics, /json, /health). Set to 0 to disable
OTC_CLUSTER 0 (off) Set 1 to enable the multi-node cluster fabric
OTC_CLUSTER_PORT 7900 Cluster gossip/bind port (used when OTC_CLUSTER=1)
OTC_CLUSTER_SEED (unset) Seed node address (host:port) to join on startup (e.g. 127.0.0.1:7900)
OTC_SNAPSHOT_DIR (unset) Enable the snapshot store by pointing at a writable directory

Dual-stack ports: The fork binary listens on two game ports simultaneously: - 3979 — native JGRPP server (accepts stock JGRPP 0.73.0 clients via the vanilla protocol) - 3989 — Rust OTC game server (accepts OTC-protocol clients; controlled by OTC_GAME_PORT)

This means stock JGRPP clients connect to :3979 as usual, while OTC-aware clients connect to :3989. Both share the same game simulation running in the single binary.

Example — dedicated server with metrics + cluster + snapshot store:

set OTC_METRICS_PORT=9100
set OTC_CLUSTER=1
set OTC_CLUSTER_PORT=7900
set OTC_SNAPSHOT_DIR=%CD%\snapshots
target\jgrpp-otc-build\openttd.exe -D -c openttd.cfg

Multi-node — second node joining the first:

:: Node 2: different ports + seed pointing to node 1's cluster port
set OTC_GAME_PORT=3980
set OTC_ADMIN_PORT=3978
set OTC_METRICS_PORT=9101
set OTC_CLUSTER=1
set OTC_CLUSTER_PORT=7901
set OTC_CLUSTER_SEED=127.0.0.1:7900
target\jgrpp-otc-build\openttd.exe -D -c openttd2.cfg

The web control panel (runtime UI) listens on its default port (9180) regardless of the variables above. cargo run -p otc-link-smoke -- --protocol exercises the same Rust runtime in-process for self-tests without a C++ build.

Dev / self-test

## link check: otc-ffi C ABI links & runs (no C++ toolchain)
cargo run -p otc-link-smoke
## protocol self-test: in-process OtcEngine (auth -> map -> frame + admin/metrics/web)
cargo run -p otc-link-smoke -- --protocol
cargo run -p otc-link-smoke -- --protocol --strict   # encrypted-auth path
cargo test --workspace

Repository layout

  • crates/ — Rust runtime: protocol, admin, crypto, metrics, storage, cluster, FFI, and the otc-engine staticlib entry point.
  • cpp-bridge/ — C++ host bridge (otc_bridge.cpp / otc_ffi.h) + CMake FFI glue.
  • patches/jgrpp-0.73.0/ — the OTC fork patches applied to JGRPP.
  • refs/jgrpp/ — upstream JGRPP reference source.
  • scripts/ — fork-source prep + MSVC build.
  • web/ — runtime web control panel assets.
  • docs/ — architecture, protocol, and usage reference.

See plan.md for the full architecture, phased roadmap, and the definition of done.