Repository navigation
Timer wheel
How the timer wheel works as built, and why: the millisecond timers each owner keeps on its own thread, fired in order without allocating. The rules are on Timer wheel rules; the maps are its first users (Owners map), and what's still to build is on Timer wheel design.
Every rule is in milliseconds, never in ticks. An owner schedules a timer for a time on its clock, and each tick advances its wheel to now, firing whatever came due in order. The tick rate only sets how finely those times land.
A timer carries a value, never a reference. Its payload is a small struct handed to the owner when it fires, so a steady schedule-and-fire cycle allocates nothing. A map's save timer names the character by id, and the map looks the character up again when it fires.
One owner, one wheel, one thread. Only the owner that holds the wheel touches it, inside its own tick, so it needs no locks.
A long gap costs nothing when there's nothing to fire. An empty wheel jumps straight to now, and a map advances its empty wheel to just before now on each tick, so a map that opens long after the server started schedules its first timer from the present.
A rule counted in ticks changes whenever the tick rate does, and the tick can differ between maps. In milliseconds, a timer means the same thing on every map, and changing a map's tick is a quantization knob, nothing more.
| Idea | What killed it |
|---|---|
| Rules counted in ticks | Changing the tick rate would change every rule. In milliseconds, the rate is only a quantization knob |
None. The slot count is fixed in code; the owner gives the wheel its start time and its first capacity.
| Piece | Path |
|---|---|
| The wheel, its handles and its handler | Source/NexusTomorrow.Maps/Timing/ |
| Tests | Tests/NexusTomorrow.Maps.Tests/Timing/ |
Start here
How the server works
The protocol
Working on it