The kernel — the pure decision core
@eigeninteractive/kernel is where every decision about a game is made: a pure
function from inputs to a commit plan. It touches no platform API, so it behaves
identically in every environment — which is why your hooks can be tested without
a Worker, a socket or a database anywhere in sight.
commit({ game, state, roster, intent, now, rules, staleViews }) →
CommitPlan | Rejected
intentis one ofstart(seed a new game),action(a player/bot move), orlifecycle(timeout/forfeit/autoForfeit).rulesis the game'sGameRulesunit for this game'sschemaVersion. The kernel invokes the game's hooks but owns everything around them.- A
CommitPlancarries: the nextStateRow(version, opaque state, pending set, deadline, per-player clocks), the per-seat projectedframes, theactionto log, anyoutcomes(if the game ended), thealarmtime to arm, and named effects (wakeBot,notifyTurn,notifyFinished) for the runtime to deliver post-commit. - A
Rejectedis a value, not an exception: a stablecode(illegalMove,notParticipant,board_updated, …) plus a message. The DO returns it; the Worker maps it to an HTTP status.
The kernel owns four things worth calling out:
- Timing & grace — computing the next deadline, the per-player time bank, and whether a late submission is still inside the grace window. See Timing & the deadline alarm.
- The same-view rule — whether a stale-version action is still valid. See The game lifecycle.
- Observation fan-out — calling
computeObservationonce per seat to build the frames, and enforcing that a seat's projection stays truthful about itself. - Rating math — OpenSkill posteriors, given priors and placements. (The application of ratings — reading priors, the CAS write — is in the DO/D1 layer; see Data & storage. Only the math is here.)
Version dispatch never happens inside game logic
The engine resolves the game's schemaVersion to a GameRules unit once, up
front, and every hook it calls is already the right version. A game author
never writes if (version === …). See Evolving your game.
The kernel's full API is in the @eigeninteractive/kernel reference.