Adds the real Firebird engine to the site, and ports what applies from PGSimCity v0.39.x–v0.40.0.
The machine room
mariuz.github.io/FBSimCity/machine/
The city has always carried the same caveat: it parses no SQL and runs no Firebird code. The machine room is the other thing — Electric Firebird's WebAssembly build of the Firebird embedded engine, running in a worker on the page, with a SQL workbench and six guided sequences.
Each sequence ends in a verdict computed from what the engine actually returned, so it can report that the answer was not what was expected:
| Sequence | Asked | Settles |
|---|---|---|
| Every statement gets a transaction | CURRENT_TRANSACTION, twice |
The Transaction Hall's per-query id is behaviour, not a device |
| OIT, OAT and Next | MON$DATABASE |
The three markers over the yard are columns in a monitoring table |
| An UPDATE writes a version | MON$RECORD_STATS back-version reads and purges |
The towers grow floors because the engine really does keep the old rows |
| The catalogue is ordinary tables | RDB$RELATIONS |
Metadata is a district, not a special mechanism |
| A fetch is not a read | MON$IO_STATS |
The cache plaza is exactly this distinction |
| No write-ahead log | MON$DATABASE settings |
Page size, buffers, sweep interval, forced writes — and no log setting, because there is no log |
A strip above the workbench reads the engine's own OIT/OAT/Next after every statement you run, so you can watch next transaction climb as you work.
The page also states plainly what the runtime cannot show: one attachment means there is no second session to queue behind, so no lock wait to watch; there is no replica; gbak and nbackup are separate programs against a file that does not exist here.
A correction to v0.8.0
v0.8.0 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 cross-origin isolation, which GitHub Pages cannot grant — but a service worker can synthesise the headers for any page that ships one, including this project's own, and both projects publish to mariuz.github.io, so the engine's assets are same-origin and need no CORP header under require-corp. The old measurement was real. The iframe reported not isolated because the page doing the framing was not isolated either, which was the part not tested.
No WebAssembly is vendored here — the engine is loaded from Electric Firebird's published build — and the city itself still makes no network calls at all.
The city has already been running
Loading now warms the model for 25 model seconds before the first frame. A first-time visitor used to arrive at a database that had never run: every cache slot empty, one version per tower, markers exactly where create() left them. That is not a neutral starting state — it is one nobody will ever meet. Ported from PGSimCity v0.39.5, which shipped and fixed the same defect.
Two fingers
Camera arithmetic moved to js/camera.js so it can be tested without a canvas or a touchscreen, and then six defects came out of it — the class PGSimCity's v0.39.3 found on a real phone:
- Pinch zoomed about the canvas origin, so the city slid away from the fingers instead of staying under them.
- Two fingers could not pan — the centroid's movement was discarded entirely.
- A third finger landing, or one lifting, jumped the city, because stale positions were read as a sudden pinch. Contact counts are now compared and the gesture re-baselined.
touchcancelwas unhandled, so an OS-cancelled gesture left its positions behind and the next touch jumped.- A pinch did not cancel a camera fly-to, so the two fought each other.
- Keyboard
+/−zoomed about the origin and drifted the city, exactly as the pinch did.
The readouts are checked against the model
Twelve of the nineteen defects in PGSimCity's v0.40.0 hunt were surfaces that had drifted from the simulation behind them. The suite now walks the stats bar and compares every readout with the model, including in a pinned-OIT and a failed-replica state, and asserts the pin warning cannot appear with nothing pinning it.
Throughput gets a stricter check: completions are counted independently and the readout has to be reporting them. A gauge that wanders will happily paint a healthy city red.
Also
- The screenshot tool announced screenshots it had not taken. It never reliably waited for the browser, and on failure the previous run's image was still sitting there, so the check passed — which illustrated this release's README with a v0.6.1 city until someone looked at it. It now shoots to a temp file, waits, rejects an implausibly small image, and only then moves it into place.
- Headless Chromium will not run the engine. Measured while trying to screenshot the machine room: isolation is reached, the worker then fails. Recorded on the page.
284 assertions, all passing — and the new ones were confirmed able to fail by breaking the zoom anchoring and the warm-up and watching them go red, with two of those breakages kept as permanent meta-checks.