● S4 WebGPU wasm32

Viewer

Not a game — a tool. The same apps/viewer that opens a .glb from your disk, running here on the document it ships with.

viewer — 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

A mouse and four keys.

what is actually running

The native tool, with one difference that is not a porting detail.

The native viewer is pointed at a file: you give it a path, it reads the document through the asset seam, converts it, frames the camera on its bounds and draws it. Point it at something re-exported from Blender and the frame becomes the new document while you watch.

A browser tab has no path and no filesystem to resolve one against, so this build opens with a document generated in Rust and compiled into the module — and then takes whatever you drag onto the canvas. A dropped .glb or .gltf goes through a staging buffer into exactly the loader a path reaches natively, and the next frame that draws is the new document. Everything past the loading is the same code — the orbit camera, the frame-on-load, the grid scaled to the document's own size, the listing, the debug views, the exposure.

The other differences are the ones every demo here has. Start-up is polled across several frames, because requestDevice is a promise and the main thread cannot block on it — and for this sample that had to reach further than the others, because its renderer is built out of the document it is showing, so the document has to be carried through the device request rather than loaded after it.

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.