Skip to content

Make Game-Mode lever hints locate, inspect, and simulate on click - #199

Merged
marota merged 2 commits into
ainetus:mainfrom
marota:claude/co-study4grid-click-behavior-ipux85
Jul 23, 2026
Merged

Make Game-Mode lever hints locate, inspect, and simulate on click#199
marota merged 2 commits into
ainetus:mainfrom
marota:claude/co-study4grid-click-behavior-ipux85

Conversation

@marota

@marota marota commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

In Game Mode, the beginner-assistance "most-used levers" panel previously only pre-filled the Inspect field when a lever was clicked — it did not center on the asset, did not open the substation SLD, and offered no way to act on a lever. This makes each lever fully actionable:

  • Single-click → locate & inspect: fills the Inspect field, centers the NAD on the element (resolving an injection or coupling switch to its home voltage level), and opens that substation's SLD so the beginner can inspect it.
  • Double-click → simulate: runs the mapped action directly — a catalogue branch disco/reco or a coupling maneuver at the resolved VL — producing a card in the feed.
  • Magnitude-free injection / PST levers carry no self-contained action (the amount differs per retained solution), so a double-click degrades to inspect with a hint to set the amount in the SLD.

The single-click action is deferred (250 ms) so a double-click pre-empts it, mirroring the existing VL-disk interaction convention.

Changes

Backend

  • NetworkService.get_element_voltage_levels now also resolves generators, loads, and switches to their home voltage level (single-VL equipment). This is what lets an injection or coupling lever be located and its SLD opened. Existing branch/VL resolution keeps precedence; the switch probe is defensive (tolerates a missing column, a blank/non-string VL, or a backend that raises).

Frontend

  • game/solutionLog.ts: buildLeverInteraction maps a lever signature to a workspace-agnostic LeverInteraction (inspect target + category + optional simulate spec).
  • game/gameBridge.ts: replaces the inspect-only hook with a registerLeverHandler / requestLeverInteraction pair.
  • game/GameHintsPanel.tsx: single-click (deferred) / double-click wiring on each lever.
  • hooks/useLeverInteraction.ts (new): the App-side handler (VL resolution + centering + SLD open + simulate dispatch), kept out of App.tsx to stay under the hub size ceiling.
  • hooks/useManualSimulation.ts: adds handleSimulateLever for coupling maneuvers, sharing a new streamSimulateToCard helper with the existing overview-pin flow.
  • api.ts / types.ts: getElementVoltageLevels method + LeverCategory / LeverInteraction types.

App.tsx still never imports game internals beyond the bridge / solutionLog helpers.

Tests

  • Backend (test_network_service.py, +10): generator / load / switch resolution, plus switch-probe robustness (blank / non-string VL, get_switches raising, missing column) and branch precedence.
  • Frontend (+20): gameBridge.test.ts (new — the lever handler pair), buildLeverInteraction signature mapping, GameHintsPanel single/double-click, useLeverInteraction (all inspect/simulate branches, VL-resolution fallback, overflow-tab remap), and useManualSimulation.handleSimulateLever (stream + error paths).

Full suite green: frontend 1893 passed / 3 skipped, backend test_network_service.py 41 passed, code-quality gate OK, ESLint + ruff clean.

Docs

Updated frontend/CLAUDE.md and docs/features/game-mode-codabench.md to describe the new single-click / double-click behavior and the useLeverInteraction hook.

🤖 Generated with Claude Code

marota and others added 2 commits July 23, 2026 14:40
The beginner-assistance "most-used levers" panel previously only
pre-filled the Inspect field on click — it did not center on the asset,
did not open the substation SLD, and offered no way to act on a lever.

Single-click now locates & inspects a lever: it fills the Inspect field,
centers the NAD on the element (resolving an injection or coupling switch
to its home voltage level), and opens that substation's SLD. Double-click
simulates the mapped action directly — a catalogue branch disco/reco or a
coupling maneuver at the resolved VL — producing a card in the feed.
Magnitude-free injection / PST levers carry no self-contained action, so a
double-click degrades to inspect with a hint to set the amount in the SLD.

- backend: extend NetworkService.get_element_voltage_levels to resolve
  generators, loads and switches to their home VL (single-VL equipment),
  so an injection or coupling lever can be located and its SLD opened.
- frontend: buildLeverInteraction maps a lever signature to a workspace-
  agnostic LeverInteraction; gameBridge exposes registerLeverHandler /
  requestLeverInteraction; the App handler lives in the new
  useLeverInteraction hook (single-click deferred so a double-click
  pre-empts it); useManualSimulation gains handleSimulateLever for coupling
  maneuvers over a shared streamSimulateToCard helper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FicdMGrZQD5mZ5YFUvoFvM
Signed-off-by: marota <amarot91@gmail.com>
Broaden coverage of the lever-hint interaction feature:

- gameBridge.test.ts (new): the registerLeverHandler / requestLeverInteraction
  pair — no-op before registration, routing of interaction + mode, and handler
  replacement.
- solutionLog buildLeverInteraction: non-branch catalogue action id passthrough,
  PST / injection levers carry no simulate spec, and a switch lever with no
  explicit target-state defaults to open.
- GameHintsPanel: single-click on a magnitude-free injection lever emits a
  simulate-less inspect; double-click on a catalogue branch lever simulates by
  action id.
- useManualSimulation.handleSimulateLever: a stream error surfaces via setError
  and registers no card.
- network_service.get_element_voltage_levels: switch resolution robustness —
  blank / non-string VL, get_switches raising, missing voltage_level_id column,
  and branch precedence over the new injection/switch probes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FicdMGrZQD5mZ5YFUvoFvM
Signed-off-by: marota <amarot91@gmail.com>
@marota
marota merged commit 35daa6c into ainetus:main Jul 23, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant