Commit Graph

6 Commits

Author SHA1 Message Date
Ilia Denisov eb5018342e feat(ui): F8-12 — owner feedback round 2 (#55)
Tests · UI / test (push) Has been cancelled
Tests · UI / test (pull_request) Successful in 3m18s
* Bug fix: theme flip no longer leaves planets oversized. The
  camera-preserving remount now calls a new
  `RendererHandle.refreshCameraDerivedDraws` explicitly after the
  manual moveCenter/setZoom pair so the post-mount geometry tracks
  `viewport.scaled` even if pixi-viewport's `'zoomed'` listener
  races the next Ticker tick.
* Doc #3: clicks on a planet label route through the same hit-test
  path as a click on the disc. The label `Container` now has a
  pointer hit area sized to the text + frame padding; pointertap
  simulates a click at the planet centre, so selection and
  pick-mode resolution behave identically.
* Doc #4: battle X-crosses + cargo arrowhead wings grow
  sub-linearly with zoom (PLANET_SIZE_ZOOM_ALPHA). New
  `Style.softLengthAnchor` ('center' / 'start') makes the renderer
  treat the recorded endpoints as the geometry "at the reference
  scale" and rescale around the midpoint (X-cross) or the start
  endpoint (arrow wings). Arrowhead base length is halved from 6
  to 3 world units to match the owner's "in half" request.
* Doc #5: picker overlay loses the anchor ring at the source, the
  cursor line drops to a cargo-route-thin 0.6 px stroke, and the
  hover ring around the destination is replaced by a planet-style
  outline (visible disc + 1 px padding) in the `pickHighlight`
  accent — so candidate destinations read like selection in warm
  yellow.
* Doc #6: regression test pins the in-disc hit zone.
* Perf #1: camera-driven redraws are throttled onto the next
  Ticker tick. A rapid wheel / pinch burst now coalesces into at
  most one `clear() + redraw` pass per painted frame, which keeps
  the 500-planet map responsive on zoom and toggle flips.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 09:40:20 +02:00
Ilia Denisov 6996a79286 perf(ui): F8-12 — pixel-space planet sizing + single-copy label/outline layers (#55)
Tests · UI / test (push) Has been cancelled
Tests · UI / test (pull_request) Successful in 3m20s
* Planet size formula moves to pixel-space:
  `pointRadiusBasePx = 2 + 2 * cbrt(size / SIZE_NORMALIZER)`. The
  on-screen disc now reads ~4-7 px at the reference zoom regardless
  of how large the world rectangle is — the previous `world-units`
  formulation blew up on small maps and made Source-class planets
  swallow their neighbours.
* Labels + outlines live in the origin copy only. The 9× replication
  across torus copies was the dominant cost on a 100+ planet map
  (Pixi.Text creation + Graphics rebuilds on every zoom step); the
  origin-copy layout is what the camera-wrap listener guarantees
  the user actually sees.
* `setPlanetLabels` and `setPlanetOutlines` skip Pixi-object
  rebuilds when the input fingerprint is unchanged — toggle flips
  and selection changes now keep the existing Text / Graphics
  instances alive and only repaint the affected pieces.
* `renderer.md` updated to the new contract.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 00:39:19 +02:00
Ilia Denisov 680ebac919 feat(ui): F8-12 — map polish (zoom invariance, labels, selection, soft radius) (#55)
Tests · UI / test (push) Waiting to run
Tests · UI / test (pull_request) Failing after 5m16s
* Honest pixel-space sizing for `pointRadiusPx` / `strokeWidthPx`: the
  renderer divides by the current camera scale on every
  `viewport.zoomed` so thin lines / small markers stay the same on-screen
  size at any zoom.
* Known-size planets switch to `pointRadiusWorld`, softened against the
  reference scale by `PLANET_SIZE_ZOOM_ALPHA = 0.33`; unidentified
  planets pin to a 3-px disc.
* New planet label layer renders a two-line `name / #N` legend under
  each planet (`#N` only for unidentified or when the new `planetNames`
  toggle is off). Selection now paints an inverse-fill frame around the
  selected planet's label plus an outline on the disc; the old
  selection-ring primitive is retired.
* Bombing markers swap the separate CirclePrim for a planet-outline
  overlay (damaged / wiped colour); the report deep-link moves to a
  "view bombing report" link in the planet inspector.
* Docs + tests follow: `renderer.md` reflects the new sizing contract +
  label / outline layers, vitest covers the sizing math, label
  formatting, and the new toggle, and the map-toggles e2e adds a
  persistence case for `planetNames`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 23:51:16 +02:00
Ilia Denisov 2bd1b54936 feat(ui): Phase 29 map visibility toggles
Tests · Go / test (push) Successful in 2m31s
Tests · UI / test (push) Failing after 8m7s
Adds the gear-icon popover on the map view with per-game persistence
of every category toggle plus the wrap-mode radio. Hide-by-id and
visibility-fog facilities land on the renderer so every flip applies
within one frame without a Pixi remount; the wrap-mode toggle keeps
its existing remount + camera-preserve path. A new server-side turn
force-resets every flag to defaults so a hidden category never makes
the player miss the next turn's news.

Also fixes the FligthDistance → FlightDistance typo in pkg/calc/race.go
(plus the single Go caller); the TS side keeps duplicating the formula
until a race-level WASM bridge lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 21:33:53 +02:00
Ilia Denisov 7c8b5aeb23 ui/phase-16: cargo routes inspector + map pick foundation
Add per-planet cargo routes (COL/CAP/MAT/EMP) to the inspector with
a renderer-driven destination picker (faded out-of-reach planets,
cursor-line anchor, hover-highlight) and per-route arrows on the
map. The pick-mode primitives are exposed via `MapPickService` so
ship-group dispatch in Phase 19/20 can reuse the same surface.

Pass A — generic map foundation:
- hit-test now sizes the click zone to `pointRadiusPx + slopPx` so
  the visible disc is always part of the target.
- `RendererHandle` gains `onPointerMove`, `onHoverChange`,
  `setPickMode`, `getPickState`, `getPrimitiveAlpha`,
  `setExtraPrimitives`, `getPrimitives`. The click dispatcher is
  centralised: pick-mode swallows clicks atomically so the standard
  selection consumers do not race against teardown.
- `MapPickService` (`lib/map-pick.svelte.ts`) wraps the renderer
  contract in a promise-shaped `pick(...)`. The in-game shell
  layout owns the service so sidebar and bottom-sheet inspectors
  see the same instance.
- Debug-surface registry exposes `getMapPrimitives`,
  `getMapPickState`, `getMapCamera` to e2e specs without spawning a
  separate debug page after navigation.

Pass B — cargo-route feature:
- `CargoLoadType`, `setCargoRoute`, `removeCargoRoute` typed
  variants with `(source, loadType)` collapse rule on the order
  draft; round-trip through the FBS encoder/decoder.
- `GameReport` decodes `routes` and the local player's drive tech
  for the inline reach formula (40 × drive). `applyOrderOverlay`
  upserts/drops route entries for valid/submitting/applied
  commands.
- `lib/inspectors/planet/cargo-routes.svelte` renders the
  four-slot section. `Add` / `Edit` call `MapPickService.pick`,
  `Remove` emits `removeCargoRoute`.
- `map/cargo-routes.ts` builds shaft + arrowhead primitives per
  cargo type; the map view pushes them through
  `setExtraPrimitives` so the renderer never re-inits Pixi on
  route mutations (Pixi 8 doesn't support that on a reused
  canvas).

Docs:
- `docs/cargo-routes-ux.md` covers engine semantics + UI map.
- `docs/renderer.md` documents pick mode and the debug surface.
- `docs/calc-bridge.md` records the Phase 16 reach waiver.
- `PLAN.md` rewrites Phase 16 to reflect the foundation + feature
  split and the decisions baked in (map-driven picker, inline
  reach, optimistic overlay via `setExtraPrimitives`).

Tests:
- `tests/map-pick-mode.test.ts` — pure overlay-spec helper.
- `tests/map-cargo-routes.test.ts` — `buildCargoRouteLines`.
- `tests/inspector-planet-cargo-routes.test.ts` — slot rendering,
  picker invocation, collapse, cancel, remove.
- Extensions to `order-draft`, `submit`, `order-load`,
  `order-overlay`, `state-binding`, `inspector-planet`,
  `inspector-overlay`, `game-shell-sidebar`, `game-shell-header`.
- `tests/e2e/cargo-routes.spec.ts` — Playwright happy path: add
  COL, add CAP, remove COL, asserting both the inspector and the
  arrow count via `__galaxyDebug.getMapPrimitives()`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 20:01:34 +02:00
Ilia Denisov db415f8aa4 ui/phase-9: PixiJS map renderer with torus and no-wrap modes
Stand up the vector map renderer in ui/frontend/src/map/ on top of
PixiJS v8 + pixi-viewport@^6. Torus mode renders nine container
copies for seamless wrap; no-wrap mode pins the camera at world
bounds and centres on an axis when the viewport exceeds the world
along that axis. Hit-test is a brute-force pass with deterministic
[-priority, distSq, kindOrder, id] ordering and torus-shortest
distance, validated by hand-built unit cases.

The development playground at /__debug/map exposes a window
debug surface for the Playwright spec, which forces WebGPU on
chromium-desktop, WebGL on webkit-desktop, and accepts the
auto-picked backend on mobile projects.

Algorithm spec lives in ui/docs/renderer.md, which also pins the
new deprecation status of galaxy/client (the entire Fyne client
module, including client/world). client/world/README.md and the
Phase 9 stub in ui/PLAN.md gain matching deprecation banners.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 14:06:23 +02:00