Rebuilding the Minecraft Java Edition server engine in Rust — without giving up the mod ecosystem.
Minecraft 1.12.2 · Forge 14.23.5.x · Protocol 340 · Java-authoritative · Evidence-gated migration
Architecture · Status · Roadmap · Research Index · Contributing
RustCraft is a research project answering one question:
How much of Minecraft's engine can become Rust-owned while existing Forge mods — unmodified — continue to observe exactly the behavior they expect?
A naive rewrite of a Minecraft server orphans a decade of Forge mods built on Java APIs, ASM coremods, Mixins, registries, and JVM semantics. RustCraft refuses that trade. Instead, it moves engine responsibility from Java to Rust one subsystem at a time, behind proof: behavioral parity, differential testing, shadow execution, and fail-closed authority gates. Nothing is switched on because a benchmark looked good — Rust code earns ownership through recorded, reproducible evidence.
Today, RustCraft runs inside a real Forge server, captures live chunk state coherently, independently encodes it in Rust, and semantically compares the two outputs — live — on a 219-mod modpack. Java still owns every packet that reaches a client.
The numbers below are counted, machine-reconciled results from recorded campaign receipts (see status for scope and caveats).
| 903 | counted Java↔Rust live chunk comparisons in the first closure campaign — 0 semantic mismatches |
| 219 | mods in the test modpack (FTB Revelation 3.4.0) whose server the project joins and runs under |
| 157,010 | block states in the tested registry — handled without widening the snapshot format |
| 0 | Rust bytes ever selected for transmission to a client |
Read this honestly: the first closure campaign is not closed. The predefined closure criteria demand 2,000 comparisons / 300 distinct chunk incarnations / 20 reload cycles; the campaign reached 903 / 135 / 0 because the workload client was rubber-banded by the server's normal movement handling, limiting chunk diversity. Parity stayed clean; coverage came up short. Details in the 903/0 context.
- A real Forge/FML server launch — full mod lifecycle, real Phosphor mixins writing launch-scoped provenance — passes the project's V2 session-bound admission and is validated by the same qualification engine used offline (
REAL_FML_TRANSFORM_CAPTURE · PASS · OFFLINE_QUALIFIED). - A headless client joins the 219-mod server, completes the FML|HS handshake, reaches PLAY, and holds a bounded stability window — full join compatibility against the pack's real
NetworkCheckHandler. - Live chunk capture is coherent: acquire → clone → seal → release under a single-writer gate; the gate is never held while Rust computes.
- The Rust encoder's output is semantically identical to Java's authoritative packet in every counted comparison.
- Rust has no production authority.
tryEncodereturnsnull; the authority gate is fail-closed. Java is the sole producer of client-visible behavior. - Closure coverage criteria are unmet (see above).
- No whole-server performance claim is made. Component benchmarks exist (below); total-server MSPT/TPS has never been measured.
Minecraft 1.12.2/Forge is one of the largest mod ecosystems that has ever existed. Its compatibility surface is brutal: Java APIs, Forge event buses, ASM coremods, Mixins, registry substitution, classloader hierarchies, and exact JVM semantics. Any engine that breaks that surface is a toy.
So the research problem isn't "rewrite Minecraft in Rust." It is:
Migrate engine ownership to Rust under differential proof, such that the mod ecosystem cannot tell the difference.
The method — the part that makes this a systems project rather than a port:
- Shadow execution — Rust computes what Java computes, on the same inputs, at the same time. Rust's answer is recorded and compared. It never replaces Java's.
- Session-bound admission — classes injected into the live JVM carry cryptographic identity certificates bound to the specific process and transformation session. A certificate from launch A cannot authorize anything in launch B.
- Transformation-chain evidence — for every hooked class: pre-writer bytes → writer output → downstream transformers → final defined bytes, hash-linked, with an independent frame witness verifying what the loader actually defined.
- Fail-closed authority — the production authority gate has no code path to "on" without a separate, recorded authority review. Abandoned approaches (V1 retained snapshots) are fail-closed forever, not deprecated.
Every subsystem climbs the same ladder, one rung at a time, on evidence:
flowchart LR
A[Reference: Java is authoritative] --> B[Rust parity proven offline]
B --> C[Shadow execution live<br/>same inputs, compared]
C --> D[Closure campaign<br/>coverage criteria met]
D --> E[Authority review]
E --> F[Rust ownership<br/>Java becomes the shell]
style A fill:#2d333b,color:#e6edf3
style F fill:#1f6feb,color:#fff
Today, full-chunk packet encoding stands at C→D: shadow-proven live, first closure campaign run, coverage criteria not yet met.
flowchart TB
subgraph TODAY["TODAY — measured compatibility boundary"]
M1[Forge Mods .jar] --> J1[Java Minecraft / Forge server<br/>AUTHORITATIVE]
J1 --> B1[RustCraft capture + admission boundary]
B1 --> R1[Rust shadow components<br/>encode · compare · record]
R1 -.->|evidence only| E1[(receipts / journals)]
end
flowchart TB
subgraph DESTINATION["DESTINATION — Rust-owned engine"]
M2[Forge Mods / Java bytecode] --> C2[RustCraft compatibility runtime<br/>session admission · contracts]
C2 --> E2[RustCraft Engine]
E2 --> W2[World / Chunks]
E2 --> N2[Network / Packets]
E2 --> S2[Storage / NBT]
E2 --> X2[Tick / Lighting / Worldgen]
end
The boundary between the two is the point: the capture/admission machinery being built today (session contracts, coherent snapshots, differential proof) is the same machinery the destination needs for its compatibility runtime. Nothing here is a JNI helper library that gets thrown away — it is the seed of the Rust-side compatibility adapter that will validate mods, registries, and channels once at connection time, then stay out of the gameplay hot path.
The Revelation registry holds 157,010 block states, which requires 18-bit global indexing. The original snapshot transport capped at 16 bits. The blunt fix would widen every state to u32 — doubling memory and bandwidth for nothing.
RustCraft instead asked what actually travels:
flowchart TB
R[Global Forge registry<br/>157,010 states / 18 bits] --> I{actual chunk<br/>state IDs inspected}
I -->|all ≤ 65535| V2[RCSNAP02<br/>section-local u16 palette<br/>~873 B/section measured]
I -->|any ≥ 65536| X[excluded: HIGH_STATE_ID<br/>honest, counted, never truncated]
style V2 fill:#238636,color:#fff
style X fill:#6e7681,color:#fff
A chunk is admitted by its own state IDs, never by the registry's width. Measured on real captured chunks, the deterministic section-local palette averages 873 bytes/section versus 8,192 for raw u16 — and a cross-language fixture harvested from a real Revelation chunk round-trips byte-identical through the Rust encoder. The rule generalizes: global registry width is not snapshot state width. (RCSNAP02 controls · transport study)
The first full closure campaign (receipts) ran the entire pipeline under broad real workload — 3 admitted JVM sessions over a persistent pre-generated Revelation world, deterministic movement, disconnect/reconnect cycles:
| Metric | Result | Criterion |
|---|---|---|
| Counted comparisons | 903 | ≥ 2,000 |
| Semantic mismatches | 0 | 0 unexplained |
| I/O-origin comparisons | 903 (all) | ≥ 200 ✅ |
| Distinct chunk incarnations | 135 | ≥ 300 |
| Genuine reload cycles | 0 | ≥ 20 |
| Queue drops | 0 (of 256 capacity) | ≤ 10% ✅ |
| High-state exclusions | 73 (honest, counted) | ≤ 60% rate ✅ |
Every session issued its own session-bound certificates and passed real-launch admission. Parity evidence stayed perfectly clean; the shortfall was purely workload coverage — the headless client's long-distance movement is rejected by the server's normal anti-cheat (rubber-banding back to spawn), so chunk diversity stayed bounded. A stopped follow-up experiment (hop-traversal, 559 additional passes, 0 mismatches) exists but is deliberately not merged into the counted denominator.
This is what honest closure looks like: the criteria are predeclared, encoded once as numbers, pinned by boundary controls, and not met is reported as not met.
| Area | Status | What has been proven |
|---|---|---|
| Forge/FML compatibility research | ✅ Proven | 18 compatibility studies of the real 1.12.2 surfaces |
| V2 runtime qualification | ✅ Proven | Two-launch engine; static recipe vs dynamic observation; both runtimes OFFLINE_QUALIFIED |
| Real-launch session admission | ✅ Proven | Real FML JVM, fresh per-process certificates, same engine validates it |
| 219-mod client compatibility | ✅ Proven | Headless join passes all 8 checks against real NetworkCheckHandler |
| Coherent chunk capture | ✅ Proven | Single-writer gate; seal-before-release; live on both runtimes |
| RCSNAP02 logical transport | ✅ Proven | 18-bit registry decoupled; cross-language byte-identical fixture |
| Protocol-340 chunk encoder | ✅ Proven | Semantic equality, live, both runtimes |
| Clean Forge live shadow | ✅ Proven | 32/32 bounded semantic comparisons, 0 mismatch |
| Revelation live shadow | ✅ Proven | 32/32 bounded; then 903 counted campaign passes, 0 mismatch |
| Closure campaign | 🧪 Coverage open | 903/0 so far; coverage criteria unmet (see above) |
| Compression / NBT kernels | ✅ Component-proven | Historical component benchmarks — not whole-server |
| Production Rust packet authority | 🔒 Disabled | Fail-closed by design; requires authority review |
| Retained Rust chunk state | 🔒 Disabled | V1 abandoned (fail-closed forever); V2 approach planned |
| Lighting · Storage · Ticking · Worldgen | 🚧 Research | Seam studies done; migration not begun |
| Rust-hosted Java runtime | 🗺️ Vision | Long-term: mods' Java bytecode executed by a Rust-hosted runtime |
flowchart LR
P0[Phase 0<br/>Compatibility + proof infra] --> P1[Phase 1<br/>Packet / chunk boundary]
P1 --> P2[Phase 2<br/>Retained Rust ChunkState]
P2 --> P3[Phase 3<br/>Chunk I/O + packet authority]
P3 --> P4[Phase 4<br/>Storage / NBT / Anvil]
P4 --> P5[Phase 5<br/>Lighting + collision]
P5 --> P6[Phase 6<br/>World / entities / tick]
P6 --> P7[Phase 7<br/>Worldgen + scheduler]
P7 --> P8[Phase 8<br/>Forge compatibility runtime]
P8 --> P9[Phase 9<br/>Rust-hosted Java bytecode runtime]
style P0 fill:#238636,color:#fff
style P1 fill:#9e6a03,color:#fff
- Phase 0 — Compatibility & proof infrastructure — largely complete: compatibility research, canonical identity, qualification engine, session-bound admission.
- Phase 1 — Packet/chunk boundary — now: live shadow proven; closure campaign coverage in progress; next major milestone is the Rust packet authority review, then retained Rust ChunkState.
- Phases 2–9 — planned. Each phase reuses the same ladder: parity → shadow → closure → authority review → ownership. Full detail in the roadmap.
The journey is deliberate: by the time Rust owns the engine, the compatibility runtime that got it there is the product's outer shell.
RustCraft is no longer a toy FFI experiment. It has real Forge/FML server admission, 219-mod compatibility, process/session-bound transformation proof, live coherent chunk snapshots, a versioned logical transport, and real Java-vs-Rust live differential comparisons with zero observed semantic mismatches in all counted evidence.
It is also honest about what it is not: Java still owns production behavior; live closure has not met coverage criteria; retained Rust world/chunk authority is not enabled; broad engine migration is ahead. The status document is the authoritative snapshot — updated with every campaign, with receipts.
| Start here | this README |
| Understand the project | Architecture · Roadmap · Current status |
| Deep research | Research index — 82 research documents · Compatibility studies · Engineering reports |
| Rust engine | crates/ — 21 crates: native-chunk (chunk state + protocol encode), ffi (JNI boundary), compression, nbt, region-io, transport, chunk-packet, protocol, … |
| Java bridge & transformers | tools/bridge/ — writer hooks, capture gate, snapshot transport |
| Qualification machinery | tools/qualification-v2/ — the two-launch engine |
| Live shadow & campaigns | tools/live-shadow-v2/ — probes, comparator, closure evaluator |
| Machine-readable evidence | machine/ — YAML evidence manifests |
| Foundational planning docs | docs/foundation/ — the original charter, architecture notes, stage plan (historical) |
Public checkout — the Rust workspace builds and tests without any proprietary artifacts:
cargo build --locked --workspace
cargo test --locked --workspaceResearch environment — qualification, capture, and shadow-campaign work exercises real Minecraft/Forge and therefore requires externally obtained artifacts (a Java 8 toolchain, the Minecraft 1.12.2 server jar, Forge 14.23.5.2846, and the modpack jars), pinned by hash in the tooling. The repository distributes none of them; the tools refuse substitutes and check pins before use. See docs/PROJECT_STATUS.md for the pinned set and how the harness verifies it.
To build the Java bridge jar for a pinned runtime:
bash tools/live-capture/build_campaign_coremod.sh <srg-jar> <output.jar> <runtime-root>For modders — the goal is not to ask anyone to rewrite mods in Rust. Existing Java/Forge mods should keep using familiar APIs while RustCraft progressively replaces engine responsibilities underneath that compatibility surface. Today this is the architecture; universal mod compatibility is not yet claimed — it is being measured.
For Rust developers — interesting ground everywhere: high-performance serialization and palette compression, native chunk state, concurrency under a single-writer discipline, JVM interop from the native side, classfile/bytecode compatibility, a wire protocol implemented against the real thing, data-oriented engine design, storage, worldgen, and eventually SIMD. The hard constraint — behavioral indistinguishability — makes all of it harder and more interesting.
For researchers — this repo is evidence-first: canonical class identities, session-bound certificates, transformation-chain proofs, an independent frame witness, machine-readable campaign receipts, and a qualification engine that validates its own observations rather than trusting the driver. Start at the qualification model and V2 live-shadow architecture.
RustCraft's goal is architectural performance — eliminating copies, duplicate representations, GC pressure, and cross-boundary churn — verified by measurement, not benchmark theater. Historical component benchmarks (scoped, reproducible, with receipts) include:
- Native packet compression: 57.5 → 129.7 MB/s (~2.26×) component throughput on the measured corpus — explicitly not whole-server MSPT/TPS.
- Chunk-packet encode: ~1.0 µs Rust vs ~7.2 µs Java constructor on one measured shape — not like-for-like, and labeled as such.
Whole-server performance has never been measured and is not claimed. The performance claim audit tracks what evidence stands behind every number. Claims the evidence could not support were removed from this README rather than softened.
Contributions run on evidence: parity before optimization, no performance claim without a benchmark, no proprietary game artifacts in the repo. Useful entry points include protocol correctness, Forge compatibility research, Rust optimization, test fixtures, benchmarking, and documentation. See CONTRIBUTING.md.
Reporting a safety or security concern: SECURITY.md.
Licensing of project code has not yet been finalized (a deliberate open decision by the repository owner — no license file is present, and none should be inferred).
RustCraft is independent research. It is not affiliated with, endorsed by, or connected to Mojang, Microsoft, or the Forge project. Minecraft and Forge are their respective owners' works. This repository distributes no game jars, mods, or copyrighted game assets; all proprietary inputs are externally obtained and hash-pinned by the tooling.
RustCraft is testing a simple question:
how much of Minecraft Java's engine can move into Rust before the mod ecosystem notices?
Architecture · Roadmap · Status · Research · Contributing