Asteroids
A ship that turns, thrusts and wraps; rocks that split twice; waves that
grow — the same apps/asteroids that builds a native binary,
running here.
controls
Four keys, plus the three the loop keeps.
- Turn ← → or A D
- Thrust ↑ or W
- Fire, and start a game Space
- Restart at any time R
- Pause and resume Esc
- Fullscreen F11
- Debug overlay F3
- Debug console `
- Pause, fullscreen and the debug overlay keys — unless a control for them is listed above
- Debug console, and its on-screen keyboard the CONSOLE button, once you have touched the canvas
why a third game
To find out what happens when entities never stop dying.
Breakout spawns its world once. Flappy runs a treadmill at a couple of entities a second. This one fires a bullet every sixth of a second, turns one rock into two, and deals a whole wave at a time — so generational ids, deferred destruction and pool slot recycling all get hammered, and a leak shows up as a number that climbs. A test asserts the entity and collider accounting on every tick of an eighteen-thousand-tick soak.
It is also the first consumer of the second physics slice: thrust and damping through the force pipeline, bullets through segment CCD, and ship-versus-rock through a broadphase sphere overlap — with the screen wrap as the thing that had to decide what a teleport means to a BVH.
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. This is also the first demo where a drawn thing turns: every angle is integrated once per tick and interpolated the short way round across the frame, so the ship and the rocks are smooth at whatever rate your display happens to run.
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.