F8-05 — game-mode chrome cleanup + inspector compact rows #66

Merged
developer merged 4 commits from feature/issue-48-game-chrome-and-inspector-compact-rows into development 2026-05-27 14:59:22 +00:00
3 changed files with 60 additions and 34 deletions
Showing only changes of commit aee5f39a7e - Show all commits
+26 -19
View File
@@ -1,9 +1,10 @@
# Cargo routes UX # Cargo routes UX
This document covers the cargo-route surface: the four-slot This document covers the cargo-route surface: the inspector
inspector subsection, the map-driven destination pick, and the subsection (a single-row dropdown + contextual actions after
optimistic overlay that keeps the inspector and the map in lock-step F8-05), the map-driven destination pick, and the optimistic
with the local order draft. The engine semantics are quoted from overlay that keeps the inspector and the map in lock-step with
the local order draft. The engine semantics are quoted from
[`game/rules.txt`](../../game/rules.txt) section "Грузовые маршруты" [`game/rules.txt`](../../game/rules.txt) section "Грузовые маршруты"
(lines 808843); this file is the source of truth for how the UI (lines 808843); this file is the source of truth for how the UI
surfaces those rules. surfaces those rules.
@@ -25,29 +26,35 @@ than `40 × driveTech` world units along the torus-shortest path
destination becomes unreachable at the next turn is auto-removed destination becomes unreachable at the next turn is auto-removed
(`RemoveUnreachableRoutes`). (`RemoveUnreachableRoutes`).
## Four-slot inspector subsection ## Single-row inspector subsection
The cargo-routes subsection renders below the production controls The cargo-routes subsection renders below the production controls
on every owned planet inspector. Slots appear in on every owned planet inspector. F8-05 collapsed the previous
`CARGO_LOAD_TYPE_VALUES` order (COL, CAP, MAT, EMP) so visual order four-slot grid into a single `<select>` that lists the load-types
matches the engine's load priority — players who scan top-down see in `CARGO_LOAD_TYPE_VALUES` order (COL, CAP, MAT, EMP) — same
the highest-priority cargo first. order as the engine's load priority — preceded by a placeholder
option that absorbs the old "cargo routes" section title. Nothing
else is rendered until the player picks a type; after a pick the
dropdown stays on the chosen type and the row reveals one of two
states:
Slot states: - **Empty** — a single `Add` button.
- **Empty** — `(no route)` text plus a single `Add` button.
- **Filled** — `→ {destination name}` plus `Edit` and `Remove`. - **Filled** — `→ {destination name}` plus `Edit` and `Remove`.
`Add` and `Edit` open a renderer-driven destination pick (see next `Add` and `Edit` open a renderer-driven destination pick (see next
section). `Remove` emits a `removeCargoRoute` command. The collapse section). `Remove` emits a `removeCargoRoute` command. The
rule on the order draft store ensures only one entry per collapse rule on the order draft store ensures only one entry per
`(source, loadType)` slot survives in the draft at any time, so a `(source, loadType)` slot survives in the draft at any time, so a
sequence of `Add → Edit → Remove` collapses to the latest verb only sequence of `Add → Edit → Remove` collapses to the latest verb
(matching the production-controls pattern). only (matching the production-controls pattern). After a
successful pick or remove the dropdown deliberately stays on the
just-acted type so the player sees the result of the gesture in
place.
Disabled state: every button is disabled when the Disabled state: the dropdown and every action button are disabled
`OrderDraftStore` or `MapPickService` context is missing (the when the `OrderDraftStore` or `MapPickService` context is missing
component is mounted outside the in-game shell, in tests, etc.). (the component is mounted outside the in-game shell, in tests,
etc.).
## Map-driven destination pick ## Map-driven destination pick
+16 -1
View File
@@ -62,7 +62,11 @@ transition. The validator (`lib/util/entity-name.ts`) is a TS port
of `pkg/util/string.go.ValidateTypeName`, exercised on every render of `pkg/util/string.go.ValidateTypeName`, exercised on every render
in the inline editor and re-run by the store on every `add`. The in the inline editor and re-run by the store on every `add`. The
submit pipeline filters the draft to `valid` entries only — any submit pipeline filters the draft to `valid` entries only — any
`invalid` row blocks the Submit button. `invalid` row blocks the Submit button. The entry point in the
inspector is the planet name itself: clicking it opens an inline
`<input>` with a single ✓ confirm icon on the right; Escape (or
leaving the inspector) cancels the edit without touching the
draft.
## Command status state machine ## Command status state machine
@@ -178,6 +182,17 @@ optimistic overlay rewrites `planet.production` using
mirrors the engine's `Cache.PlanetProductionDisplayName` so the mirrors the engine's `Cache.PlanetProductionDisplayName` so the
overlay stays byte-equal with the next server report. overlay stays byte-equal with the next server report.
The inspector surface that composes a `setProductionType`
(`lib/inspectors/planet/production.svelte`) is two dropdowns on
one row — a primary `industry / materials / research / ship`
plus a secondary one (tech / science / ship class) that appears
for the `research` and `ship` contexts — together with a green ✓
apply and yellow ✗ cancel icon. The ✓ button stays disabled
until the row selection differs from the planet's current
effective production; ✗ resets the local row state back to that
effective value without touching the draft. The Order tab is
the only place that can revoke an already-applied command.
### Collapse-by-target rule ### Collapse-by-target rule
`setProductionType` carries a collapse-by-target rule. `setProductionType` carries a collapse-by-target rule.
+18 -14
View File
@@ -74,22 +74,26 @@ which surfaces as `rejected` in the order tab.
## Production-picker integration ## Production-picker integration
The planet inspector's Research sub-row The planet inspector's production row
(`lib/inspectors/planet/production.svelte`) renders the four tech (`lib/inspectors/planet/production.svelte`) is two `<select>`s
buttons and one extra button per defined science from the player's plus a green ✓ apply / yellow ✗ cancel pair after F8-05. With
`localScience` overlay. A click on a science button dispatches the primary picker on `research`, the secondary picker lists the
four tech display strings and one extra option per defined
science from the player's `localScience` overlay. Picking a
science target and pressing ✓ dispatches
`setProductionType("SCIENCE", "<scienceName>")`, mirroring the `setProductionType("SCIENCE", "<scienceName>")`, mirroring the
wire-level `CommandPlanetProduce` shape wire-level `CommandPlanetProduce` shape
(`pkg/schema/fbs/order.fbs.CommandPlanetProduce`). (`pkg/schema/fbs/order.fbs.CommandPlanetProduce`).
The active highlight is derived from `planet.production` — the The active value of both selects is derived from
display string the engine emits in the report. A science name `planet.production` — the display string the engine emits in the
shadows the matching tech display string when they collide (a report. A science name shadows the matching tech display string
science deliberately named `Drive` wins over the Drive tech when they collide (a science deliberately named `Drive` wins over
button), because the wire string is ambiguous and the user clearly the Drive tech option), because the wire string is ambiguous and
intended the named science. This is a pragmatic accept; a the user clearly intended the named science. This is a pragmatic
structured production tag on the wire would let us disambiguate accept; a structured production tag on the wire would let us
without the shadow rule, but that is a separate backend concern. disambiguate without the shadow rule, but that is a separate
backend concern.
## Tests ## Tests
@@ -102,5 +106,5 @@ without the shadow rule, but that is a separate backend concern.
fractions, view-mode Delete dispatches `removeScience`, fractions, view-mode Delete dispatches `removeScience`,
duplicate-name guard against the overlay. duplicate-name guard against the overlay.
- `tests/e2e/sciences.spec.ts` — full Playwright walkthrough: - `tests/e2e/sciences.spec.ts` — full Playwright walkthrough:
create → list → set planet production via the Research sub-row create → list → set planet production via the research/target
→ delete. dropdown pair + ✓ apply → delete.