03 GUIDE · PORTING
Move a game
onto the kernel.
Five games have moved onto Fizlet's kernel so far. A port keeps gameplay: same numbers, same controls, and the page comes back byte for byte. What changes is underneath. This guide is the order that worked, smallest change first, each step tested before the next.
The order
Measure first
Bundle the game as it ships today, minified and gzipped, and write the number down. Every port so far got bigger in bytes; you want to know by how much, and what each byte bought.
Hand the loop to the kernel
Replace the game's own
requestAnimationFramewith one engine. Its update becomesstep(fixeddt), its drawingrender, and every layout read moves toread.Write through the ledger
Every style, class, attribute, text node or element the game puts on the page goes through
engine.ledger. Thendestroy()gives the page back, and a browser test can compare the DOM with a snapshot.Seed it
Swap
Math.randomin the step forengine.random. Now a run replays from its seed, and a replay test can pin the gameplay before you touch the rules.State into typed arrays
Move positions, health and timers into typed arrays made once. An allocation test (young-generation GCs over many busy steps) tells you when the step stops allocating.
Swap in bricks
Only where one does the same job:
@fzlt/core/collidefor a spatial hash,@fzlt/core/steerfor movers,@fzlt/core/rulesfor waves, drops and score,@fzlt/core/board-pagefor the page as terrain,@fzlt/core/arcadefor the whole shell of a page arcade game.Measure again
Bundle and gzip the port. Say the delta, and say what it bought.
// Before: game.loop() called requestAnimationFrame, Math.random and el.style itself.
const e = createEngine({ root: host, seed });
e.add({
read: () => game.measure(), // layout reads move here
step: (e, dt) => game.update(dt, e.random), // fixed dt, the seeded random
render: (e) => game.draw((el, prop, v) => e.ledger.style(el, prop, v)), // writes through the ledger
});
e.start(); // one shared rAF; e.destroy() gives the page backWhat the ports cost
Every game got bigger in gzip bytes. Most of the growth is the shared Board UI kit the arcade games now bake in; the rest buys steps that never allocate, runs that replay from a seed and one shell for three games. Moving the games onto a 4 KB kernel has every number.
Questions
Do I have to port everything at once?
No. Each step above ships on its own and keeps the game playable. The kernel runs fine with one system that calls the old update and draw.
Will the port change how the game plays?
It shouldn't. Write a replay test from a seed before you start (inputs in, final state out) and keep it green through every step.