Full House: version and change log
Back to Full HouseEvery merged change from v0.1-m1 on, newest first. Built from changelog/changes.yaml; the rules are in VERSIONING.md.
Releases
0.1.4-m1 · 3 November 2026 · pending
The public front page and the change log become indexable on www.siliconwok.com, their own address; the game, /fullhouse/play/, and all of fullhouse.siliconwok.com stay noindex. The front page takes the www site map in its header and footer.
- Before
- The front page's canonical, og:url and social image named fullhouse.siliconwok.com, which is behind a login, so a share card could not load its image; the change log carried noindex
- After
- The canonical, og:url, og:image and twitter:image name https://www.siliconwok.com/fullhouse/; the change log has no noindex and a canonical at www; the build serves /fullhouse/sitemap.xml with the two public pages. The game keeps its noindex meta tag, and the hosts' nginx keep X-Robots-Tag noindex everywhere except the two public pages on www
- Why
- Uncle James, 3 Nov 2026: make the public Full House promo indexable on www.siliconwok.com.
- Before
- On www.siliconwok.com the front page's header read Library · Heritage · Full House · Join, and its footer had two links
- After
- The www header is the site map shared with the Ghost theme and the Library's pages: The Hawker Library and Saving our Hawker Heritage with their pages in submenus (a dropdown; an accordion in a menu on small screens; Escape closes), then Full House, Downloads and Get involved. The footer has the same site map in five columns. The submenu script is inline, so the page still loads no game code
- Why
- Uncle James, 3 Nov 2026 (msgs 59269 and 59274): one navigation on every www.siliconwok.com page.
- Before
- The game had its own address, fullhouse.siliconwok.com, behind a login; the docs, the perf guide and the teaser test named it; the serving setup was recorded only on the hosts
- After
- www.siliconwok.com/fullhouse/ is the only address (the game at /fullhouse/play/ behind Access); fullhouse.siliconwok.com 301s there, path for path. The docs, the perf guide and the teaser test name www (the test had kept the old canonical). deploy/ records the nginx servers on vm101 and VM106, the deploy steps and the Access application
- Why
- Uncle James, 3 Nov 2026 (msg 59276): no subdomain-vs-path confusion anywhere; every live change captured in the repo.
- Before
- The front page's header bar was its own: system fonts, its own sizes and colours, a different menu, unlike the Ghost pages and the Library
- After
- The header bar is sw-header 1.0.0, the Ghost theme's bar as a shared kit (site/sw-header/, NAV.md), vendored byte for byte from siliconwok-theme and served as it is at /fullhouse/assets/sw-header-1.0.0/; the markup in index.html is the kit's. CI (sw-header workflow) fails if either drifts. The teaser test checks the bar and the film's poster (it still looked for the old poster image)
- Why
- Uncle James, 3 Nov 2026 (msg 59278): the header bar pixel-consistent on every www.siliconwok.com page, the Ghost header as the reference.
- Before
- The change log page (/fullhouse/changes/) had no header bar at all: the one www page without it
- After
- tools/changelog/build.mjs puts sw-header on the page (its markup, CSS, fonts and script); the sw-header check covers it in CI. The teaser test checks that the front page's bar stays at the top after scrolling 1500 px
- Why
- Uncle James, 3 Nov 2026 (msg 59280): the header sticky on every page type; the live check of every page type (siliconwok-theme scripts/check-sticky.mjs) found the change log without a bar.
0.1.3-m1 · 3 November 2026
Stall 03 (PR #9): the public front page at /fullhouse/, with a one-minute film recorded from the game, and the game at /fullhouse/play/, where every file it loads now lives, so the host can keep it behind a login. Tagged v0.1.3-m1 on 7774835.
- Before
- There was no public page: the private preview sat at the host's root
- After
- A front page at /fullhouse/, Stall 03 of Silicon Wok, in the game's own look: the pitch in Uncle James's voice, a one-minute film of the game (its renderer replaying the sim's recorded snapshots, seed 2026; app/web/teaser/, the timeline in script.mjs), three stills, the calls to action, and a header that follows the host
- Why
- Uncle James, 2 Nov 2026: Full House gets a public front page as Stall 03, with a three.js teaser instead of screenshots.
- Before
- The game at /, the log at /changes.html
- After
- Everything under /fullhouse/ (app/web/base.mjs): the game at /fullhouse/play/ (noindex, not linked), the log at /fullhouse/changes/. Vite's base, the dev server and every test and perf script follow it. The build writes app/dist/fullhouse/ and a meta-refresh at app/dist/index.html
- Why
- The address scheme Uncle James approved on 2 Nov 2026: www.siliconwok.com proxies /fullhouse/ to fullhouse.siliconwok.com, keeping the URL.
- Before
- After a jump (a seek, or a cut), a shutter set at once was not redrawn, so the hall could show shut a stall the sim had open
- After
- The world kit redraws the shutters after a jump
- Why
- The teaser's cuts are jumps, and its frames showed the fault.
- Before
- The shell always started the sim in a Web Worker, and the stage always took gestures and drew every frame
- After
- startShell takes a stand-in for the worker; createStage takes controls false and stage.setRunning(on). tools/teaser/record.mjs records the film's snapshots; npm run test:teaser plays a whole loop headless at Low; npm run stills:site makes the poster, the stills and site/og.jpg
- Why
- The film replays recorded snapshots, lets the page scroll over it, and stops drawing off-screen.
- Before
- The front page drew its film live with the game's own renderer, so it loaded the game: its code, three.js and the six world kits (79 files, 3.5 MB), from the same assets/ folder as the game
- After
- The film is a video recorded from the game (tools/teaser/video.mjs: the teaser drawn frame by frame on a virtual clock; site/video/teaser.mp4 and .webm, H.264 and VP9, 1280x720, 25 fps, silent), with a pause button, no autoplay under reduced motion, and its words listed below it. The front page and the change log load no game code. The build puts every game file (code, worker, kits, CSS) under /fullhouse/play/assets/, and the pages' own media under /fullhouse/assets/
- Why
- Uncle James, 3 Nov 2026: the front page is public on www.siliconwok.com, and the game stays behind a login. A live film needed the game's files public.
- Before
- The end-to-end run checked the fire's shutter 2.5 real seconds after the soot step. On CI it read 0.33 and 0.60, against under 0.1, and the check failed on main too
- After
- It waits for the shutter, in frame time, for up to 120 s, then checks it
- Why
- Measured on 2 throttled cores (as CI): the shutter falls 0.067 a frame (0.1 s a frame at most, 1.5 s for a full roll) at about 3 frames a second, steadily, and is down after 15 frames, 4.2 s. The game was right; the test waited by the clock on the wall.
0.1.2-m1 · 3 November 2026
M1.9, the denser hall (PR #7): James found the hall too sparse after playing the private preview on his iPhone. It now seats 17 a stall, from HC-PERIM's own mix of table shapes, packed in columns. PR #8 brings this log. Tagged on main after PR #8 merged; Stall 03 (PR #9) is 0.1.3-m1.
- Before
- 12 seats a stall: 96 in the hall and 24 on the edge, 120 in all
- After
- 17 seats a stall: 136 in the hall and 34 on the edge, 170 in all, in the same 24 × 24 m hall
- Why
- James, 2 Nov 2026: 'your table layout is too sparse'. The newest NEA centres seat about 17 to 18 a stall (MSE COS 2024, Annex H).
- Before
- Each table's kind was drawn on its own, which gave 23 to 35 tables a hall (25, 24 and 23 at seeds 2026, 7 and 11)
- After
- HC-PERIM's own table mix: 44% four-seat square, 26% six-seat rectangle (2 × 3), 12% round of six, 12% two-seat, 6% round of eight. That is 4.76 seats a table, the newest centres' figure. The hall holds 28 to 30 tables by seed, and the edge 4 or 5 benches of 6, 8 or 10
- Why
- James asked for a good mix of rectangular, round and square tables. The mix is the game's own, from the layout archetypes.
- Before
- Tables stood far apart, and James saw them all as square
- After
- Columns of tables two deep in four quarters, with stool rings 0.6 to 0.85 m apart. The main aisles keep 2.5 m. Each quarter has a single-file cut-through. Every table has an approach on a walk, and all 1,000 seeds tried fit
- Why
- James: 'the inter-table spacing is lower than you're visually representing it'. Real halls are packed.
- Before
- The kit had the square four-seat table, the two-seater, an eight-seat round marked 'later', and one edge-bench length
- After
- New TB11 six-seat rectangle and TB12 round of six; TB03 the eight-seat round moves into the slice; TB06 gains benches of 2.4 m (8 seats) and 3.0 m (10 seats). They merge into the static geometry, so world draw calls stay 31, 44 and 44 (Low, Medium, High)
- Why
- The new mix needs the shapes. Merging them keeps the draw-call budget.
- Before
- A child holding an adult's hand could step into a table from a stool's margin
- After
- The director keeps the child clear of the table
- Why
- The packed hall exposed the fault.
- Before
- At the noon peak (seeds 2026, 7, 11): seat efficiency 73.9, 73.6, 78.4%; parties sharing 74.8, 79.5, 83.9%; choped seats 2.6, 2.5, 3.1; weekday fill 12:15 to 13:15 84.5, 82.7, 89.4%; seed 2026 waited for a seat 205 times a month and went without 339 times
- After
- Seat efficiency 61.1, 59.5, 63.1%; parties sharing 72.0, 72.6, 76.9%; choped seats 3.6, 3.7, 3.8; weekday fill 71.0, 67.1, 72.8%; seed 2026 waited 4 times and went without 16 times
- Why
- More seats for the same crowd, so almost no one goes without. Demand and the score are untouched. test_m08's lunch bars hold these readings until balance pass 3.
- Before
- Golden month, seed 2026: state 4ef2eca2, text b5134145
- After
- State 0b8a52d6, text 26b171d5; the schedule hash 9636127c is unchanged
- Why
- The golden month is the regression test, and the seating changes the month.
- Before
- No §10 in docs/seating.md, no M1.9 row in PLAN §7, and PLAN §3.7 without the probe bar and the step-up rule
- After
- docs/seating.md §10 holds the evidence, sources and readings; docs/decisions.md has the calls of 2 Nov 2026; PLAN §3.7 states the probe bar and the step-up rule; PLAN §7 has the M1.9 row
- Why
- The numbers come from the record, and each is marked with its source.
- Before
- Versions were tags only, with no log
- After
- VERSIONING.md, changelog/changes.yaml, tools/changelog/build.mjs, docs/CHANGELOG.md, app/web/changes.html (built to /changes.html) and npm run check:changelog. package.json now carries the version. There is no PDF (James, 2 Nov 2026)
- Why
- James asked for a Version and Change Control Log in the format of the Hawker Library's, 2 Nov 2026.
0.1.1-m1 · 2 November 2026
Phone fixes after James's first runs of the private preview on his iPhone: the steward's cards, quality tiers that suit real phones, and crowd motion. Playwright and the end-to-end run in CI came in with it (PR #4, which the tag message does not list).
- Before
- Taps on the steward's cards were lost on iOS: the dev HUD rebuilt the cards every frame, so the button changed between touch-down and the click
- After
- Cards and events are rebuilt only when what they show changes, and each snapshot's events are read once. The event list shows the latest three, not eight, so the hall stays in view
- Why
- James found it on his iPhone on the private preview. A new test, test:tap, taps both night cards on an emulated iPhone.
- Before
- The clock stayed paused after the last card, because an answer queued for the next sim step still read open
- After
- The worker counts the answers given in this pause and posts a snapshot after each answer
- Why
- The player could not resume after answering every card.
- Before
- Options the sim refuses ('it would change nothing here', the fund, the hours) looked live
- After
- Disabled options are greyed and dashed, with the reason under the card
- Why
- The player can always see why.
- Before
- Playwright was not a dev dependency, and the end-to-end run was not in CI
- After
- playwright and @playwright/test are pinned at 1.64.1; npm run test:e2e:install installs Chromium; .github/workflows/e2e.yml runs the end-to-end test on every pull request and on main
- Why
- npm run test:e2e should work from a fresh clone. No game logic changed.
- Before
- On a slow runner a seek could send a stray resume, which closed the day card and let the clock run through 28 November; the haze test relied on game time still in flight
- After
- seek() resumes only a clock the seek held, and the first raised haze snapshot is a jump
- Why
- The end-to-end test failed on CI for these reasons. Test code only; the game is unchanged.
- Before
- The README gave the full test as 'about 20 minutes'
- After
- 'About 11 minutes on a quiet 4-core machine', with the note that its timing checks fail if the machine is busy
- Why
- PR #4 measured 1,027 passed and 0 failed in 11 min 23 s on a quiet host.
- Before
- Safari rounds frame times to 1 ms, so a phone holding 60 Hz read p95 17 to 18 ms and failed the 16.7 ms bar. James's iPhone Pro Max was given Low
- After
- High and Medium pass the probe at p95 19 ms or less (VSYNC_60_BAR_MS); a missed refresh (33 ms) still fails, so weak phones stay safe. GFX_BASE 2 makes every saved device test once more
- Why
- Quality tiers that suit real phones, from James's iPhone Pro Max runs of 2 Nov 2026 (the results are in tools/perf/device/).
- Before
- The watchdog's step-up rule could never step up at 60 Hz
- After
- Grace periods after a start (15 s), a tier change (60 s) and a new view (3 s), and a prewarm; a step down on two windows in a row over the bar; a step up when the frame's own work is under 10 ms. Every step keeps a reason, shown in the HUD, the ?perf=1 panel and the benchmark results
- Why
- A phone should be able to climb back to High once it can hold it.
- Before
- Stepping down from High left 43 MB held: an undisposed 2048² shadow map, the sign atlas at High size and a growing bone bank
- After
- Low 7.3 MB, High 52 MB, and back to Low 7.3 MB
- Why
- Memory on a phone, and a step down that really frees what High held.
- Before
- Textures made during a lunch: 84 to 128. The 238 'added' on James's Low run were 12 × 12 bone textures
- After
- 1 to 7 textures a lunch, with pooled skinned rigs and programs down to 1; a prewarm compiles and uploads at load, in the intro, before the benchmark and after each tier change
- Why
- Hitches from new programs and textures cost frames on a phone.
- Before
- People walked through each other
- After
- Shortest paths between the hall's 77 aisle nodes, computed once into a next-hop table; four aisle edges bend round the side bins. Local avoidance (avoid.mjs) on a 1 m spatial hash with a 0.3 m personal radius, keep-left lanes and single file in narrow gaps; anyone held 1.4 s passes through half-faded. Places of their own: counter pick-up, riders' wait, the wait for a seat, the tray rack and the door. The scene stays cosmetic: the sim still decides who arrives, queues, sits and leaves
- Why
- James saw people walk through each other on the private preview, 2 Nov 2026.
- Before
- Low, phone view, lunch peak, in view: 317 overlaps a minute at 1× and 1,351 at 4×; median closest pair 0.04 m; 3 to 7 figures inside furniture
- After
- 38 overlaps a minute at 1× and 219 at 4×; median closest pair 0.53 m; no figure inside furniture. Director cost 0.37 to 0.54 ms a frame, up from 0.23 to 0.31 (the budget is 1 ms); no new draw calls or textures
- Why
- Measured in PR #6. Tables now publish a footprint (plan.mjs), so a denser layout needs no routing rework.
0.1-m1 · 2 November 2026
The first tagged version. It holds the foundation (PR #1, the data and the engines) and the slice (PR #2): M0, the headless sim core, and M1 as far as M1.6c with the perf tools (M1.4). The tag message calls it 'Full House M1'. This entry is the baseline against which every later change is recorded; Part A tells how it came about.
- Before
- —
- After
- The data (250 dishes, 394 ingredients, 73 supplier types) and the engines: the news ticker (97 events), inflation, the parliament (72 measures), upgrades, the systems layer (102 cascade chains, 42 incidents, 21 crimes) and the event bus contract
- Why
- First step: the game's own repository, with every engine on one bus.
- Before
- —
- After
- The sim core runs November 2026 at Bukit Serai Food Centre headless in about 2.0 s, and prints the four weekly notes and the monthly report from copy/en. The golden month is the regression test
- Why
- M0 of the work plan: the sim before the scene.
- Before
- —
- After
- Comfort and maintenance, people and seating, the lunch fill, menus, the player's verbs, heritage and the yearly assessment, loyalty, the economy, spend and the tension triangle, each with its own test file (test_m06 to test_m12; 86, 197, 84 and 86 checks for M0.6, M0.7, M0.9 and M0.10)
- Why
- The approved order of 31 Oct 2026: the people, the money and the player go in before the scene.
- Before
- —
- After
- The life engine, the automation era and the robot stall cameo (Uncle James), the books voice, worship and help off the books, occupancy, and a famous stall in every game that is kept unless the steward plays badly
- Why
- James's calls of 1 and 2 Nov 2026, in docs/decisions.md.
- Before
- —
- After
- The balance port in tools/balance/ and two passes: the steward's scale centred at 64, so a hands-off centre reads 40.8 and good play 64.9 at NEA. Full House (71) is not yet reached at NEA
- Why
- James chose to wait for the famous stall's numbers before choosing a lever.
- Before
- —
- After
- The stage (renderer, camera rig, picking, roof fade, tiers, probe and watchdog), the world kit and figures scripted in code and exported as glTF, light, weather and FX, the figure director, the intro's six shots and tier test, and the snapshot wiring. Skinned figures are budgeted at 16, 24 and 32 at Low, Medium and High
- Why
- M1 of the work plan: the scene, on phones.
- Before
- —
- After
- A Vite page with the sim in a Web Worker, the clock (pause, 1×, 2×, 4× and 8× at night, pause at day end), the snapshot, the dev HUD and the end-to-end test (test:e2e)
- Why
- The pieces become one game page that opens with the intro as its loading screen.
- Before
- —
- After
- The Playwright lunch run with its gates, the ?perf=1 overlay and benchmark, and tools/perf/PHONES.md for James's phones
- Why
- The phones are the performance test (PLAN §7, M1).
- Before
- —
- After
- AGENTS.md and its binding rules, docs/decisions.md, the work plan in docs/slice/PLAN.md, and the readings in docs/ (comfort, people, seating, menus, heritage and others)
- Why
- The numbers come from the record, and the rules bind every agent.
Before v0.1-m1
Part A. Pre-release development history: how the repository got from its first commit (30 October 2026) to v0.1-m1, in brief. Nothing here carries a version of its own. Evidence is cited per entry. Git (commits and pull requests) is the record; dates are the author dates of the commits, in Singapore time. Where the record is silent the entry says 'not recorded'.
Foundation · 30 October 2026
The repository's first commit of substance (d7b046a): the data (250 dishes, 394 ingredients, 73 supplier types), the systems layer, the event bus contract and the docs, with AGENTS.md and CLAUDE.md. The same evening: the first design calls, crowd shares, and rent billed monthly on the 1st, one bus event per stall.
Why: The game gets its own private repository, with the Hawker Library as the source of its numbers. Every engine publishes to one bus, and no event is flavour only.
Decided by Uncle James. Evidence: commit d7b046a; commit 0ae6cac; commit 7e477a4; PR #1 (merged 2026-11-02). Sources: docs/decisions.md, 30 Oct 2026; PR #1.
The engines · 30 October 2026
The news ticker (97 seasonal and random events), inflation (four regimes fitted on Singapore's 1981 to 2025 record), the parliament (72 measures), upgrades, the weather engine, the scorecard and the letting engine. Letting's 500-seed run had all 17 calibration checks within tolerance. PR #1 reports 16 of 16 checks for events, 24 of 24 for inflation and 33 of 33 for parliament.
Why: The decisions of 30 October: inflation guided by the record, a yearly parliament, hawkers' exits and joins simulated, and then no more systems before a playable slice.
Decided by Uncle James. Evidence: commit a4eb7bb; commit 7e7ec14; commit 385c6a7; commit 028b8c8; commit 95f0bdb; PR #1. Sources: docs/decisions.md, 30 Oct 2026; PR #1.
Copy and the cultural review · 30 October 2026
Copy for the slice (1,356 strings, names, voice guide, checks). A cultural review of halal, names, forms of address, festivals, figurines and legal limits, applied to the copy as names N1 to N20 and copy rules C1 to C11.
Why: Researched recommendations stand in for human readers, so that the dignity and religion rules are checked before release.
Decided by Uncle James. Evidence: commit 5f49970; commit 373b3de; commit eebe345; commit 0104064. Sources: docs/cultural_review.md; docs/decisions.md, 30 Oct 2026.
The slice plan · 30 October 2026 to 31 October 2026
The slice's technical plan (M0 to M4) in docs/slice/PLAN.md, the 3D asset list (207 assets, 142 for the slice), the audio design (153 cues, 115 for the slice) and the balance tool's first scorecard on a 142-seed sample.
Why: After the engines, stop adding systems and build a playable slice: one centre, ten stalls, one month, the bus and the digest.
Decided by Uncle James. Evidence: commit 14b8a3b; commit 9aa6e21; commit 13ccf74; commit 5a9f45d. Sources: docs/decisions.md, 30 Oct 2026; docs/slice/PLAN.md.
M0 – the sim core, headless · 31 October 2026
M0.1 to M0.5: the clock, keyed random streams, the bus and validator, the effect store and saves that replay exactly; the adapters and the world (Bukit Serai Food Centre: ten stalls, ten hawkers, 168 seats); diners, ledger, billing and satisfaction; the systems runtime and letting; the digest and the golden month. node app/sim/cli.mjs --seed 2026 runs November 2026 in about 2.0 s. PR #2 reports checks of 95 (core), 106 (M0.2), 76 (M0.3), 69 (M0.4) and 103 (M0.5).
Why: The first step of the work plan: the sim before the scene.
Decided by Uncle James. Evidence: commit d75caff; commit 088b114; commit 4363833; commit 40c5257; commit fa2d491; PR #2 (merged 2026-11-02). Sources: docs/slice/PLAN.md §7, M0; PR #2.
M0.6 to M0.12 – the sim's layers · 31 October 2026
Comfort and maintenance (86 checks in test_m06), people and seating (197 in test_m07), the lunch fill, menus, the player's verbs (84 in test_m09), heritage and the yearly assessment (86 in test_m10), loyalty and each stall's record, the economy and Makan Voucher waves, spend by who shows up, and the tension triangle of prices, wages and costs.
Why: The approved order of 31 October 2026: the people, the money and the player go in before the scene.
Decided by Uncle James. Evidence: commit a2ad607; commit 4250191; commit 01aa9c0; commit 54e5659; commit 7105a53; commit c9573d9; merge 6b4fb8d. Sources: docs/slice/PLAN.md §7, M0.7 to M0.10.
M0.13 to M0.20 – life, automation, balance · 1 November 2026 to 2 November 2026
The life engine (households, family events, betting), the automation era and the robot stall cameo (Uncle James), the books voice, the tidy, occupancy, worship and help off the books, and two balance passes: the steward's scale centred at 64, with a hands-off centre at 40.8 and good play at 64.9 at NEA. M0.20 adds a famous stall to every game.
Why: James's calls of 31 October and 1 November: the robot stall cameo by his own request (the one exception to the invented-names rule), a score that needs active decisions, and a famous stall that survives unless the steward plays badly.
Decided by Uncle James. Evidence: merge cb0ea8e; merge aca87d2; merge ead1f01; merge a0b5b80; merge 06f7862. Sources: docs/decisions.md, 1 Nov 2026; docs/cameo.md; docs/destination.md.
M1.0 to M1.6c – the scene · 31 October 2026 to 2 November 2026
The shell and the sim in a Web Worker (M1.0), the stage with its quality tiers, probe and watchdog (M1.1), the world kit and figures scripted in code (M1.2, M1.3a), light, weather and FX (M1.3c), the figure director (M1.3b), the intro's six shots and tier test (M1.3d), the pieces as one game page (M1.5), the polish and the snapshot wiring (M1.6a to M1.6c), and the Playwright lunch run, gates and ?perf=1 overlay (M1.4).
Why: The work plan's M1: the centre, ten stalls and 60 to 80 figures playing the month from the worker, on phones.
Decided by Uncle James. Evidence: merge eae62b2; merge 6385792; merge 1251756; merge 68e3c68; merge 9d27ecf; merge 534b0a0; merge 3218770; merge abb620a. Sources: docs/slice/PLAN.md §7, M1.
Note: PR #2 is titled 'Slice M0' and its body describes M0 only. The merge also carried the M1 work above, as the git history shows.
An independent project. It is not affiliated with, endorsed by or speaking for any government agency.