calcite
A server for Minecraft 26.3 that ticks regions on every core in lockstep, runs native and sandboxed plugins against one host API, and is checked against vanilla bit for bit.
- 65kLines of Calx
- 144Recorded design decisions
- 0Lines of Mojang code
Problem
Fast Minecraft servers are forks of Mojang’s code, so they inherit its single-threaded tick, and the ones that split the world across threads give results that depend on scheduling. Plugin APIs are tied to the JVM, and vanilla parity is checked by hand, if at all.
What I built
Calcite is a server written from nothing in Calx. Regions tick on every core in lockstep, so results never depend on the thread count. Plugins are native Calx at full speed or sandboxed WASM addons, built against one documented host API. Worldgen and behaviour are matched to vanilla block for block, using data read from Mojang’s official client jar at startup rather than shipped.
How
- 01
An oracle rig runs the same inputs through vanilla and through Calcite and compares the results bit for bit. Vanilla’s results are recorded once with their hashes committed, and Calcite is scored against them on every change.
- 02
Vanilla is recorded with HotSpot’s math intrinsics turned off, so Math gives StrictMath’s results, which Calx can match exactly. The intrinsic path is recorded separately to measure the gap.
- 03
Data tables are generated from the vanilla jar, and Calcite’s code generation reads them instead of hand-written registries.
- 04
Outgoing packets are encoded on codec threads and flushed once a tick. Signed chat works with chat sessions, message chains and the signature cache.
- 05
Every input to the server can be recorded and replayed with --replay, so a bug report can be a file.
- 06
Work moves in gated phases with a written decision log, so what is settled, and why, is never a matter of memory.
/// Java's `java.util.Random` generator, which vanilla's `LegacyRandomSource`
/// is: a 48-bit linear congruential generator.
const MULTIPLIER: i64 = 0x5DEECE66D
const INCREMENT: i64 = 11
const MASK: i64 = 0xFFFFFFFFFFFF
impl LegacyRandom {
fn next(mut self, bits: i32) -> i32 {
self.seed = (self.seed * MULTIPLIER + INCREMENT) & MASK
return i32.wrap(self.seed >> (48 - bits))
}
}Status
Phases 0 to 3 have passed their gates: the design, the oracle rig, the generated data tables and the Calx compiler core. Calcite’s random sources already match vanilla bit for bit on Windows and Linux. Next is the protocol, and a world a real client can join.