deterministic state machines pay for themselves
updated Jun 11, 2026
The riichi game engine is one GameState value and pure (state) → state functions. No mutation, no globals. It felt like over-discipline at first.
It paid off three ways. Pure functions test with no framework and no DOM, which is what a rules engine with hundreds of edge cases needs. AI turns interleave asynchronously, and without mutation a value captured earlier can’t change under you. And the one I didn’t plan for: a deterministic engine means a game saves as a tiny seed-plus-inputs tape that replays byte-for-byte. Replay, export to a standard log format, and tile-level post-game review all fell out of that, none of them designed up front.
Make the core a pure state machine and the features you haven’t thought of yet get easier.
the hub · warm terminal