acdream/docs/superpowers/plans/2026-06-18-d53a-selected-object-meter-plan.md
Erik e8562fc4e2 docs(D.5.3a): spec + plan — selected-object meter (Stream A)
Brainstormed design for the action bar's bottom strip: name + Health meter
on selection (mana deferred #140). Decisions: SelectionChanged via property
setter; send QueryHealth(0x01BF) on select. Grounded in retail
gmToolbarUI::HandleSelectionChanged (acclient_2013_pseudo_c.txt:198635) —
clear-then-populate, overlay state 0x1000000b, health gate
IsPlayer||pet||attackable. Render-bug fix is BuildMeter-only (single-image
back+fill meter; UiMeter already renders it).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 22:19:14 +02:00

2.9 KiB

D.5.3a — Selected-object meter — implementation plan

Spec: docs/superpowers/specs/2026-06-18-d53a-selected-object-meter-design.md. Pre-approved by user 2026-06-18; subagent-driven, sequential (build-safe in one worktree).

Mandatory per task: cite named-retail anchors in comments; dotnet build + the relevant dotnet test green; match surrounding code style. No commits by subagents — the lead commits the coherent set after the full build+test passes.

Task order (each builds on the accumulated working tree)

T1 — WorldSession.SendQueryHealth (+ net test) · project: AcDream.Core.Net

  • Add SendQueryHealth(uint targetGuid) mirroring SendChangeCombatMode (WorldSession.cs:1134): NextGameActionSequence()SocialActions.BuildQueryHealth(seq, guid)SendGameAction(body).
  • Test in tests/AcDream.Core.Net.Tests/: drive it through the existing send-capture seam used by the other WorldSession.Send* tests; assert captured bytes == BuildQueryHealth(seq, guid).
  • Accept: dotnet test for AcDream.Core.Net.Tests green.

T2 — DatWidgetFactory.BuildMeter single-image shape (+ test) · project: AcDream.App

  • Handle containers.Count == 1: BackLeft = info.StateMedia[""].File, FrontLeft = containers[0].StateMedia[""].File, tile/right = 0. Keep >= 2 (vitals) path unchanged. Warn only on Count == 0 / Count > 2.
  • Extend tests/AcDream.App.Tests/UI/Layout/DatWidgetFactoryTests.cs: 1-container synthetic meter asserts Back/Front populated + others 0; 2-container case asserts vitals path unchanged.
  • Accept: dotnet test for AcDream.App.Tests green.

T3 — SelectedObjectController (+ test) · project: AcDream.App

  • New src/AcDream.App/UI/Layout/SelectedObjectController.cs per spec §3 (Bind signature, bind-time setup, OnSelectionChanged clear-then-populate). Cite HandleSelectionChanged:198635.
  • New tests/AcDream.App.Tests/UI/Layout/SelectedObjectControllerTests.cs per spec §Testing item 2 (mirror ToolbarControllerTests for building a minimal ImportedLayout + recording delegates).
  • Accept: dotnet test for AcDream.App.Tests green.

T4 — GameWindow integration + register rows · project: AcDream.App (depends on T1, T3)

  • Convert _selectedGuid field → SelectedGuid property + SelectionChanged event (spec §1); replace the 3 write sites; leave read sites on the field.
  • Remove 0x100001A1 + 0x100001A2 from ToolbarController.HiddenIds (keep 0x100001A4).
  • Wire SelectedObjectController.Bind(...) after ToolbarController.Bind (spec §5).
  • Add the 2 divergence rows (spec §Divergence) to docs/architecture/retail-divergence-register.md.
  • Accept: full dotnet build + dotnet test green.

Then (lead)

  • Adversarial Opus review of the full diff vs spec + decomp.
  • Commit the coherent set to the branch; update roadmap/ISSUES if applicable; memory if a durable lesson.
  • Stop for the user's visual gate (the acceptance test for this stream).