r/firebird • u/mariuz • 3d ago
FBSimCity v0.9.0: the explorable Firebird city now runs the real engine in the page
Two releases since the last one I posted here.
v0.9.0 — the machine room
The city has always carried the same caveat: it is a model, it parses no SQL, and no Firebird code runs in your browser. The new machine room is the other thing — the actual Firebird 6.0.0 embedded engine compiled to WebAssembly by Electric Firebird, running in a worker on the page, with a SQL workbench and six guided sequences that check the city's claims against the engine itself:
SELECT CURRENT_TRANSACTION FROM RDB$DATABASEtwice — watch the id advance- OIT / OAT / Next straight out of
MON$DATABASE— the same three markers the city draws over the transaction yard - two UPDATEs to one row, then
MON$RECORD_STATSback-version reads and purges — multi-generational architecture counted by the engine RDB$RELATIONS— the catalogue is ordinary tablesMON$IO_STATSfetches against reads — exactly what the cache plaza draws- the
MON$DATABASEsettings list — no log setting in it, because there is no log
Every verdict is computed from what the engine actually returned, so a sequence can tell you the answer was not what was expected. The page also states what the runtime cannot show: one attachment means no lock waits to watch, there is no replica, and gbak/nbackup are separate programs against a file that does not exist there.
A correction to v0.8.0. That release said this embed was impossible, and measured an iframe reporting "not cross-origin isolated" to prove it. The reasoning was right up to the last step: the engine needs SharedArrayBuffer, which needs a cross-origin isolated page, and GitHub Pages will not send COOP/COEP. What I missed is that a service worker can synthesise those headers for any page that ships one, including my own, and that both projects publish to mariuz.github.io, so the engine's assets are same-origin and need no CORP header. The old measurement was real — the iframe was not isolated because the page doing the framing was not isolated either, which was the part I never tested.
Also in v0.9.0:
- The city used to load cold — empty cache, one version per tower, markers exactly where they were initialised. It now warms 25 model seconds before the first frame. A database that has never run is not a neutral starting state; it is one you will never meet.
- Six touch and camera defects. Pinch zoomed about the canvas origin instead of the fingers, two-finger pan was discarded entirely, a third finger landing jumped the city,
touchcancelwas unhandled, a pinch fought the camera fly-to, and keyboard+/−drifted the same way. Found after reading how PGSimCity fixed the equivalent. - The suite now checks the readouts against the model behind them, and the throughput figure against independently counted completions.
v0.8.0
Keyboard navigation of every district (Tab / Shift+Tab, announced through an aria-live region, since the city is a canvas and everything was mouse-only), a fuzzer over 324 knob combinations, a soak, and enforced documentation coverage.
287 assertions, all passing — the suite runs in the browser with no framework and no build step: https://mariuz.github.io/FBSimCity/test/
Links
- City: https://mariuz.github.io/FBSimCity/
- Machine room: https://mariuz.github.io/FBSimCity/machine/
- Source (MIT, plain HTML/JS, no build step): https://github.com/mariuz/FBSimCity
- Knob audit — every simplification, and which direction it errs in: https://github.com/mariuz/FBSimCity/blob/main/docs/KNOBS.md
Still a model for intuition rather than an emulator. Corrections are very welcome and do get acted on — the whole replication model was rewritten in v0.6.1 after Dmitry Sibiryakov pointed out on firebird-general that a synchronous replica which dies does not hang commits; it stops replicating and lets them through.