ui/phase-18: ship-class calc bridge with live designer preview
Wires pkg/calc/ship.go into the WASM Core boundary as seven thin
wrappers (DriveEffective, EmptyMass, WeaponsBlockMass, FullMass,
Speed, CargoCapacity, CarryingMass). The ship-class designer reads
Core through a new CORE_CONTEXT_KEY populated by the in-game layout
and renders a five-row preview pane (mass, full-load mass, max
speed, range at full load, cargo capacity) that updates reactively
on every form edit and on the player's localPlayer{Drive,Weapons,
Shields,Cargo} tech levels — three of which are now decoded from
the report's Player block alongside the existing localPlayerDrive.
CarryingMass is the seventh wrapper added to the original six-function
list so that "full-load mass" composes through pkg/calc/ functions
without putting math in TypeScript.
This commit is contained in:
+42
-21
@@ -2012,28 +2012,44 @@ Targeted tests:
|
||||
class, list it, delete it; rejected-submit kept; field-validation
|
||||
kept (Save disabled with localised tooltip).
|
||||
|
||||
## Phase 18. Ship Classes — Calc Bridge
|
||||
## ~~Phase 18. Ship Classes — Calc Bridge~~
|
||||
|
||||
Status: pending.
|
||||
Status: done.
|
||||
|
||||
Goal: wire `pkg/calc/` ship math into the designer for live mass,
|
||||
speed, range, and cargo capacity previews.
|
||||
|
||||
Artifacts:
|
||||
|
||||
- `ui/core/calc/ship.go` thin Go bridge wrapping `pkg/calc/.FullMass`,
|
||||
`EmptyMass`, `Speed`, `CargoCapacity`, `WeaponsBlockMass`,
|
||||
`DriveEffective` in JSON-marshallable signatures, exported through
|
||||
the `Core` API
|
||||
- `ui/frontend/src/platform/core/index.ts` extends `Core` interface
|
||||
with the new calc methods
|
||||
- live-updating preview pane in the ship-class designer showing mass,
|
||||
full-load mass, max speed, range, and cargo capacity at the player's
|
||||
current tech levels
|
||||
- audit step recorded in `ui/docs/calc-bridge.md`: every wired
|
||||
function listed against its `pkg/calc/` source
|
||||
- if any required `pkg/calc/` function is missing, this phase raises a
|
||||
blocker and the function is added to `pkg/calc/` first (owner-led)
|
||||
- `ui/core/calc/ship.go` thin Go bridge wrapping seven functions
|
||||
from `pkg/calc/ship.go` — `DriveEffective`, `EmptyMass`,
|
||||
`WeaponsBlockMass`, `FullMass`, `Speed`, `CargoCapacity`,
|
||||
`CarryingMass` — each as a one-line passthrough; the seventh
|
||||
function (`CarryingMass`) was added during stage implementation
|
||||
to let the preview compose `full-load mass` from `CargoCapacity`
|
||||
without injecting math into TS;
|
||||
- `ui/wasm/main.go` registers the seven wrappers under
|
||||
`globalThis.galaxyCore`; `ui/frontend/src/platform/core/index.ts`
|
||||
extends `Core` with the matching typed methods (`emptyMass` and
|
||||
`weaponsBlockMass` return `number | null`, mirroring the Go
|
||||
`(_, false)` validator path);
|
||||
- `ui/frontend/src/api/game-state.ts` extends `GameReport` with
|
||||
`localPlayerWeapons`, `localPlayerShields`, `localPlayerCargo`
|
||||
alongside the existing `localPlayerDrive`. The decoder reads
|
||||
all four from the `Player` row in the report's player block.
|
||||
Phases 19-21 reuse these fields without re-extending the report;
|
||||
- `ui/frontend/src/lib/core-context.svelte.ts` exposes a
|
||||
`CoreHolder` through `CORE_CONTEXT_KEY`. The in-game layout
|
||||
(`routes/games/[id]/+layout.svelte`) populates the holder after
|
||||
`loadCore()` resolves, so the designer reads `Core` from context
|
||||
without re-booting WASM;
|
||||
- live-updating preview pane in the ship-class designer showing
|
||||
empty mass, full-load mass, max speed (at empty), range at full
|
||||
load, and cargo capacity per ship at the player's current tech
|
||||
levels; the pane only renders when the form passes validation
|
||||
*and* `Core` is ready;
|
||||
- audit step recorded in `ui/docs/calc-bridge.md`: live surface
|
||||
table lists every wired function against its `pkg/calc/` source.
|
||||
|
||||
Dependencies: Phases 5 (Core skeleton), 17.
|
||||
|
||||
@@ -2047,11 +2063,14 @@ Acceptance criteria:
|
||||
|
||||
Targeted tests:
|
||||
|
||||
- Go parity tests in `ui/core/calc/` against `pkg/calc/` outputs on
|
||||
shared fixtures;
|
||||
- Vitest snapshot tests for the preview pane on canonical inputs;
|
||||
- Playwright e2e: edit a ship class, observe preview updates and
|
||||
submit, confirm server-side mass matches.
|
||||
- Go parity tests in `ui/core/calc/ship_test.go` against `pkg/calc/`
|
||||
outputs on shared fixtures, plus a composition test that exercises
|
||||
the exact preview pipeline (empty → cargo capacity → carrying mass
|
||||
→ full-load mass → speed at empty + at full);
|
||||
- Vitest coverage in `ui/frontend/tests/designer-ship-class.test.ts`
|
||||
asserts preview hidden until validation passes, hidden when no
|
||||
`Core` is available, renders five rows with computed values once
|
||||
the form is valid, and reactively refreshes on subsequent edits.
|
||||
|
||||
## Phase 19. Inspector — Ship Group (Read-Only)
|
||||
|
||||
@@ -2112,7 +2131,9 @@ Artifacts:
|
||||
`SendGroup`, `LoadCargo`, `UnloadCargo`, `Modernize`, `Dismantle`,
|
||||
`TransferToRace`, `AssignToFleet` command variants
|
||||
- `Send` action picks destination through a planet picker filtered by
|
||||
the group's reach (uses `pkg/calc/` reach function via Core)
|
||||
the group's reach (uses `pkg/calc/` reach function via Core; the
|
||||
player's tech levels are already on `GameReport.localPlayer*` from
|
||||
Phase 18, no extra plumbing needed)
|
||||
- `Modernize` cost preview using `pkg/calc/` formula via Core
|
||||
- confirmation dialog for `Dismantle` over a foreign planet with
|
||||
colonists onboard (special-case from [`rules.txt`](../game/rules.txt): colonists die)
|
||||
|
||||
Reference in New Issue
Block a user