chore(build): replace Makefile with Justfile Switch the build tooling from make to just. - Remove Makefile. - Add Justfile with run, build, build-wasm, serve, and play-web recipes.
feat(crew): restrict movement to room cell slots Add per-room cell slots and limit crew movement to unoccupied cells. - Add Cells field to Room and populate two slots per player room. - Shift enemy-ship cells by the same x-offset as rooms. - Build a cellSet lookup and gate moves on it, skipping occupied cells. - Add cellOccupied check so two crew cannot share a slot. - Render dim cell markers in render.go. - Cover cellSet and occupancy with tests; tighten hit-flash test timing.
docs(combat): record review conclusion
docs(combat): record verify summary
docs(combat): record approved plan and execute deviation
combat: thread ship through shield/evasion readouts drawShieldsIndicator and drawEvasionReadout took no Ship and were calling NewPlayerShip() per frame to locate the Shields/Engines room. That allocates a 5-room slice each draw call and hides the coupling. Pass g.ship through instead — explicit interface (GPC1), zero alloc, and the renderer follows whatever layout main.go owns.
combat: render, input, restart - drawShip gains hitFlashT param; red flash overlay on hit - drawEnemyShip: full roleColor rooms, same flash rule - drawHullBars, drawWeaponCharge, drawShieldsIndicator, drawEvasionReadout, drawResultOverlay - Game gains combat/enemy/rng; updateCombat wired in Update - HUD clicks no-op after result; R key restarts when fight is decided
combat: NewEnemyShip layout PH2 of combat task: enemy ship layout. - ship.go: NewEnemyShip() returns same 5 rooms as NewPlayerShip with each GridX shifted +24 tiles. Pure data; no Ebitengine (IV1). - ship_test.go: 2 tests covering room count and per-room shift (GridX +24, all other fields preserved). Refs: docs/tasks/combat.md PH2
combat: Combat data + updateCombat with tests PH1 of combat task: pure tick logic. - combat.go: GameResult/CombatSide/Combat types, NewCombat, playerShieldMax, resolveIncoming, updateCombat. Constants WeaponChargeMax/ShieldRegen/EnemyFireInterval/HitFlashDuration/ PlayerHullMax/EnemyHullMax. Imports math/rand only (IV1). - combat_test.go: 17 tests covering initial state, shield max, shield absorb / hull damage / hull clamp / evasion miss-and-hit in resolveIncoming, post-result no-op, hit-flash tick, shield regen and clamp-on-power-drop, weapon fires / no-charge-when-zero, enemy fires on timer, victory and defeat transitions, determinism. Tests cannot execute in this Claude Code session (Ebitengine GLFW init requires a display); compile + vet are clean. Refs: docs/tasks/combat.md PH1
docs(combat): record approved design combat
docs(systems-power): record review conclusion systems-power
systems-power: hoist HUD cellBottom out of inner loop Reviewer flagged the per-iteration recomputation of cellBottom inside drawHud's column/cell loops; the value was loop-invariant. Hoist to a file-scope const and simplify the algebra. systems-power
docs(systems-power): record verify summary systems-power
systems-power: drawHud, room dimming, right-click input systems-power
systems-power: HUD geometry + hudHitTest with tests systems-power
systems-power: System data + addPower/removePower with tests systems-power
docs(systems-power): record approved plan systems-power
docs(systems-power): record approved design systems-power
docs(crew-movement): record review conclusion
docs(crew-movement): record verify summary