● S1B WebGPU wasm32

Flappy

One button, an endless procession of pipes, and no second chances — the same apps/flappy that builds a native binary, running here.

flappy — crcbl
Starting…
Click the canvas first. A canvas has to hold keyboard focus to receive keys, and browsers will not start audio until you have interacted with the page. Clicking away pauses the game and lets go of whatever key was held — no platform sends the release for a key that was down when focus left.
Touch reaches the engine. A contact arrives as an ordinary pointer, and the first one is also the gesture a browser waits for before it will start audio. Whether this demo can be played with one is in its controls below — not all of them can. Switching tabs pauses the game and lets go of whatever was held: no platform sends the release for an input that was down when focus left.

controls

One key or one tap, plus the three the loop keeps.

why a second game

To find out what the first one's shape left behind.

Breakout proved the engine can host a game. A single consumer cannot tell a design from an accident, though — every convenience that happens to suit a paddle and a brick grid reads as good design until something else needs the same seam. So this one is deliberately different: continuous forward motion instead of a fixed field, pipes created ahead and destroyed behind instead of a static grid, one button instead of two axes, and no lives at all.

Every place the engine resisted that is written down rather than worked around quietly — the findings are in the roadmap, next to the phase that owes the fix.

what is actually running

The native sample, with four differences the browser forces.

Start-up is polled across several frames, because requestDevice is a promise and the main thread cannot block on it. The frame loop is driven by requestAnimationFrame out here rather than by a loop inside the engine. The clock is the browser's, because wasm32-unknown-unknown has no Instant. And the best score lives in the Origin Private File System instead of ~/.config.

Everything else — the ECS, the fixed-tick server, the physics, the render graph, the spatial audio — is the same code the native build runs. The course itself is not sent anywhere: gap positions are a pure function of a seed and the pipe's index, so the client and the server agree about a thousand pipes without a byte crossing between them.

Open the console for the engine's log. The wasm module imports nothing, not even console.log, so log lines are queued inside wasm and drained by the page each frame. crcbl.audio(), crcbl.saves() and crcbl.logLevel(4) are there too.