When coding unit tests, you expect for behavior to be performed as fast as possibe, often much faster than production. With Minecraft development this is different; For actual ingame unit testing server software will cap you at 20Ticks per second(TPS) A scenario that waits 200 ticks waits 10 real seconds. Our reference workload — walk 200 blocks, mine a log in survival, verify the block is air, wait 200 ticks — took 68 seconds of wall time at stock speed, most of it just standing around while the clock ticked. Multiply that by every test run and real time becomes the product's biggest cost.
In this blog post, I will outline how we made those instances run at up to ~3,000 ticks per second: reverse engineering the engine's timer in the BDS binary, and hooking it with a native shim.
Everything about this project is pinned to exactly this build — BDS 1.26.52.3, SHA-256 0a490c711d4a2ce075debcd979e8862b7eaba008373f9970f0edbb67f98f9207, GNU build ID c0ff36e2eacfc191f01e189237df71f139b5d04a.
Timer::advanceTime starts at RVA 0xb4cef50. This is the function that decides how much game time passes in one engine update.
Only two call sites own gameplay: the ones returning to 0x9e929e6 and 0x9e929f5. Everything else that touches a timer is not the simulation. At those call sites, ServerInstance sits in rbx, its simulation and update timers live at +0xb0 and +0xb8, and each timer carries a float scale at +0xc — how much game time one real moment is worth.
The constructor at 0x9e51c50 initializes a field at ServerInstance+0x210 to 5,000 microseconds. The main loop at 0x9e92835 multiplies it by 1,000 to get nanoseconds. That is the engine's wake interval: how often the loop wakes up to advance the timers.
At 0xb4cf10f, one update is capped at ten ticks, no matter how much time the timer says has passed.