Spaces:
Paused
Paused
Commit History
-
Tier 2a: collapse the cross-module duplicates, pin the tie-breaks
Claude +1: Claude Opus 5Unverified signatureradiusOf existed THREE times in engine/ and bomb.js's comment asserted the copies were "the same". They were not: only bomb.js's handled a building, by reading the instance radius state.js stamps at construction; movement.js and formation.js returned the magic constant 9 for any building — while movement.js is a // @ts-check'ed file whose JSDoc advertises @param {Unit|Building}. The type layer was actively telling callers a Building was supported on a path that silently under-sized it, which is the exact class of bug MAX_UNIT_RADIUS exists to prevent and which no determinism test can see, being wrong-but-stable on every seed. One shared helper now lives in colliders.js, which already reasoned about def.radius and b.radius. Consolidating it surfaced a real subtlety the plan didn't predict: keying on `kind` alone broke formation.js, whose callers are frequently unit-shaped literals carrying no `kind` field at all. The helper resolves by TYPE first, with a comment recording why. clamp a…e847942 -
Tier 1, step 2b: expand // @ts-check coverage from 10 files to 20 (D3)
Claude +1: Claude Opus 5Unverified signatureAdopted in the order docs/code-improvement-tiers.md sets out, cheapest and highest bug-class value first: supply, aiCommon, colliders, victory, production, scout, the three AI leaves (aiStrategy, aiDifficulty, aiArchetypes), and finally persist.js — the prize, because every save field is a State/Unit/Building field read by name, so annotating it makes save-shape drift a check-time error. Each file's exports are annotated with the shared typedefs, not just given the pragma: per the guard added in the previous commit, a pragma without annotations checks nothing. Doing it surfaced three more genuine drifts in engine/types.js, all found by the checker rather than by reading: - Building.rally was typed {x, y} but carries nodeId — the rally-to-resource feature, where a rally dropped on a live node makes a produced unit spawn already mining (engine/production.js). - Building.queue entries were typed {unitType, progress} but carry `alt`, which records that a job was charged the unit's…7e764b0
-
Content: terrain — rough ground, high ground, and no-build zones
Claude +1: Claude Fable 5Unverified signatureGives the map spatial identity without any pathfinding rewrite: a static per-cell terrain field (a flat Uint8Array, fog-grid idiom) drives three purely local effects. - map.js: TERRAIN table + generateTerrain (fixed fractional feature specs, mirrored for fairness, scaling self-similarly) + sampleTerrain (O(1), OPEN out of bounds). Consumes ZERO rng draws, so the node layout stays byte-identical and determinism is untouched. Terrain is static for the whole match. Per-world specs on Glacius (rough ice fields flanking a central lane — a soft choke), Forge (rough industrial sprawl), and Pyralis (a high-ground mesa); the original three worlds stay all-open. - movement.js: rough ground slows the step (never to zero — no unit can ever be trapped, so a wave can't deadlock and the resolves-to-a-winner guarantee holds). Honours an optional per-unit allTerrain flag (forward-compat). - fog.js: high ground sees farther (per-source sight scaled by terrain). - combat.js: an attacker …03f71c7
-
Tier 4 foundation: placement validation, buildable expansion CC, guaranteed ore
Claude +1: Claude Fable 5Unverified signatureAdd engine/colliders.js as the single source of truth for building placement: canPlaceBuilding rejects overlap with buildings, live resource nodes, and map bounds (units are deliberately ignored — they move, and separation already untangles them), and findPlacement does a deterministic outward ring search so the AI can slide a fouled build spot to nearby valid ground. issueBuild now validates placement before charging, so a rejected spot never leaks resources. The AI routes its barracks/refinery spots through findPlacement in the same change, so validation can't stall its build order. Make the Command Center buildable (400 ore, 30s) instead of free and instant; the starting CC is still seeded complete. Multi-CC dropoff and all-CCs victory already worked, so an expansion is a real second base with no further plumbing. generateMap guarantees a lean mirrored ore cluster near each base on any world whose deposit table yields no ore (distance-triggered, so ore-bearing maps stay byte-iden…1c88bda