A browser Breakout clone where every brick is a hex byte and clearing a row “decrypts” a line of ciphertext. Built with Zig compiled to WASM, no JS game framework, just a Canvas 2D context.
why
I wanted to learn WASM as a compile target for Zig, and I wanted to build something I’d actually play. The hex-editor framing came from spending too many hours in a hex editor during CTFs — the grid layout maps perfectly to a Breakout playfield.
architecture
The game logic is pure Zig — zero JS in the hot path. Zig exports a handful of functions that the HTML host calls:
export fn init(seed: u64) void { ... }
export fn update(dt_ms: f32) void { ... }
export fn render(canvas_ptr: [*]u8, width: u32, height: u32) void { ... }
render() writes directly into a Uint8ClampedArray that the JS host
hands to putImageData. No DOM manipulation, no requestAnimationFrame
inside Zig — the host drives the loop and Zig stays stateless.
building
zig build -Dtarget=wasm32-freestanding -Doptimize=ReleaseSmall
# → zig-out/bin/hexbreak.wasm (~28 KB)
28 KB for a playable game. I’ll take it.
controls
| key | action |
|---|---|
| ← → or A D | move paddle |
| Space | launch ball / pause |
| R | restart |