Spaces:
Paused
Paused
Commit History
-
Boot the game in a real browser in CI β the one thing 2502 tests cannot seeβ
Claude +1: Claude Opus 4.8Unverified signatureThere is no build step, so the files in the repo are the files the browser loads. The suite is headless and dependency-free, which is the point of it, and it means nothing in it can catch a page that parses, imports cleanly, and then throws on load. static-integrity.test.js catches STATIC breakage β a syntax error, an import pointing at a moved file, a getElementById for an id that does not exist β and stops exactly there. The failure it cannot reach is a blank white screen, and the way that has been found here before is a human clicking. Measured rather than asserted. Adding a bad draw call to renderUnits.js β one line, valid syntax, imports fine β leaves all 2502 tests passing and takes the game down on its first frame. tools/smoke.js catches it and exits 1 with the stack. A second mutation (a runtime throw in boot.js) is caught by BOTH this and the existing "imports cleanly under Node" guard, which is why the render one is the honest demonstration of what is new here. tools/smoke.β¦778e159 -
Document the main-branch gate, and fix the docs my own changes falsifiedβ
Claude +1: Claude Opus 4.8Unverified signatureThe three items left open after the review merge. BRANCH PROTECTION. I cannot set it: there is no MCP tool for the branch protection API and a direct call returns 403, so this is a repository setting only a human with admin can apply. What I can do is remove the guesswork, so CONTRIBUTING.md now carries the exact steps β target `main`, require status checks, and the two check names verbatim (`tests (node 20)` and `tests (node 22)`, both, because the matrix produces one per Node version and requiring only one lets a version-specific regression through), plus require-up-to-date and block-force-pushes. It also notes the coupling nobody would otherwise notice: those names come from the workflow's job `name:` line, so editing that silently unhooks the gate. DOCS THAT CONTRADICT THE CODE. Fixed the ones this branch's own work falsified, rather than pruning anyone's design work: - README's module map predated inputCommands.js and described input.js as one thing. It also called tools/ "a β¦2b4cf02
-
Tier 1, step 5: close the coverage gaps and the doc drift (C6-C16, E1, E2)β
Claude +1: Claude Opus 5Unverified signatureThe mutation-proven gaps first. Each of these was verified by re-introducing the exact defect and confirming the new test goes red. C8 β drawBuildingBars and drawBuildGhost were covered only by assert.doesNotThrow, so replacing either body with `return;` survived the full suite: every health bar, build-progress bar, output gauge and paused/stalled badge in the game could vanish with CI green on both Node versions. The recording ctx this file already had is now used to assert real output, that a damaged building gets a bar, and that a paused producer is drawn differently from a running one. (Not "draws more" β a running-but-throttled factory draws the busier badge of the two.) C9 β dropping aiColonyTarget, aiLastThreatAt, or the entire playerAi block from persist.js also survived. Re-checked by mutation: both single-field drops now fail. The failure mode is "the AI behaves differently after reload", the hardest class of bug to report. C14 β commit ac44339's ore-surplus army-cap featuβ¦cce54f5
-
Vary neighbour worlds' AI difficulty and personality across the galaxyβ
Claude +1: Claude Sonnet 5Unverified signatureToday the player's single splash-screen Difficulty + AI Strategy pick applies to every world in the galaxy uniformly β once you pick Hard, every world you ever visit plays Hard, with no variety to discover. neighbourAiProfile(seed, planetId) (engine/galaxy.js) resolves an independent, deterministic difficulty (with matching aiApm/aiMicro, never a mismatched pair) and AI Strategy for a world, derived from the galaxy seed + planet id the same way per-world map generation already is β no new randomness source, fully replay-safe. addPlanet now uses the player's actual settings only for the start seat (planetId === galaxy.activeId); every other world resolves its own profile instead. Nothing new is needed for "the player must discover it by playing" β galaxyStatus already hides everything about a world until galaxy.discovered has it. Written test-driven, per the new process (see CONTRIBUTING.md): the tests in test/livingGalaxy.test.js were written first, against neighbourAiProfile before β¦9f4b083
-
Persistence: fix docs contradicting the code, document a hazard, add dialog a11yβ
Claude +1: Claude Sonnet 5Unverified signature- CONTRIBUTING.md told contributors to make the loader tolerant of older saves; README.md had two passages that disagreed with each other, one correctly saying an incompatible save is rejected, the other claiming loaders stay "backward-tolerant." The actual code (deserializeGame/deserializeGalaxy) does an exact version-match throw, no migration, no tolerance at all. Rewrote all three passages to describe what the code actually does, and to explain when a version bump is (and isn't) needed. - peekEntityId/restoreEntityId touch a module-global counter in engine/state.js from four call sites in persist.js, with no comment in persist.js itself flagging the shared-mutable-state hazard - the only place this was documented was a test comment elsewhere. Added a clear comment at the import site. - saveload.js's goHome() hand-built confirmation modal (gates real data loss) had no role="dialog", no aria-modal, and no focus management. Added both, plus focus-into-dialog-oβ¦b6109dc
-
Add JSDoc typedefs + // @ts-check for the core sim shapes (no build step)β
Claude +1: Claude Opus 4.8Unverified signatureAddress the top architectural-review finding β an untyped mutable `state` bag threaded through ~360 functions, where a mistyped or renamed field reads undefined silently and the same-seed determinism test can't see it. Now that class of bug is a check-time error. Zero runtime cost and no build step: the shipped code stays plain ES modules. - engine/types.js: JSDoc @typedefs for the core shapes (State, Unit, Building, Player, AiState, Resources, Cargo, Order, ResourceNode, GameMap, Fog, Market, Diplomacy, Galaxy, β¦). No runtime code, never imported β global typedefs the checker and any editor's TS language service resolve project-wide. - jsconfig.json + `npm run typecheck` (tsc, noEmit): checking is OPT-IN per file via a `// @ts-check` pragma, so coverage grows file-by-file. Editors check the annotated files live with no install; the script needs a tsc available. - Enabled + annotated on the core data + hot path: state.js (the factories bind the types to the real objects), β¦e3658fa -
Tier 5: release hygiene β docs, license, dev server, npm startβ
Claude +1: Claude Opus 4.8Unverified signatureTurn the repo into something a stranger can clone, run, and contribute to. - README: rewritten to lead with how to run it (npm start), fix the stale "no tech tree" claim (there's a Refinery doctrine system, a Foundry gate and Datacenter research), and document the whole Odyssey open-world layer, the two save channels, and the versioning scheme β none of which were mentioned. - tools/serve.js + `npm start`: a zero-dependency static server so the ES-module game runs with nothing but Node (no npx, no Python), serving .js as application/javascript (or the modules won't load) with a path-traversal guard. - LICENSE: MIT. - CONTRIBUTING.md: the load-bearing invariants (engine purity, determinism, no build step, versioned saves) with the guarding test for each, plus a release checklist. - CHANGELOG.md: the 1.0.0 entry. Full suite green (560 tests). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AEQUVetLk31Jj7niDQAsXLd0e9298