221 lines
12 KiB
Markdown
221 lines
12 KiB
Markdown
# Settings track handoff — retail Options panel campaign (fresh session)
|
|
|
|
Written 2026-08-10 at the close of Campaign CH (chat parity, CLOSED
|
|
USER-ACCEPTED the same day). The user pivoted the alpha program's settings
|
|
track: the target is **retail's four-tab Options panel**, not merely a
|
|
status-bar button over the existing F11 panel. The user supplied four
|
|
retail screenshots (transcribed below — the fresh session cannot see
|
|
them). Deep research REQUIRED before implementation, campaign-style.
|
|
|
|
## What the user showed (retail screenshots, transcribed)
|
|
|
|
The options button opens a tall panel with four tabs:
|
|
**Gameplay Options | Character | Chat | Config**, with Apply / Reset /
|
|
Defaults buttons at the bottom of (at least) the Character tab. Options
|
|
render as LED-style dots (lit green = on) beside labels, grouped under
|
|
gold section headers, with a scrollbar.
|
|
|
|
### Tab 1 — "Gameplay Options" (button list, no LEDs)
|
|
- Exit to Character Selection
|
|
- Exit Game
|
|
- Configure Keyboard
|
|
- Use Mouse Turning Settings
|
|
- In-Game Help Files
|
|
- Urgent Assistance
|
|
- Report Abuse
|
|
|
|
### Tab 2 — "Character" (scrolling LED option list; three screenshots)
|
|
**User Interface Behavior:** Keep Combat Targets in View · Salvage
|
|
Multiple Materials at Once · Use Main Pack as Default for Picking Up
|
|
Items.
|
|
**User Interface Display:** Vivid Targeting Indicator · Display 3D
|
|
Tooltips · Show Coordinates By the Radar · Side By Side Vitals · Display
|
|
Spell Durations · Disable Most Weather Effects · Disable Distance Fog ·
|
|
Always Daylight Outdoors · Disable House Restriction Effects · Use
|
|
Crafting Chance of Success Dialog · Confirm Use of Rare Gems · Display
|
|
Timestamps · Filter Language · Show Your Helm or Head Gear · Show Your
|
|
Cloak.
|
|
**Grouping:** Ignore Allegiance Requests · Ignore Fellowship Requests ·
|
|
Show Allegiance Logons · Share Fellowship Experience and Luminance ·
|
|
Share Fellowship Loot · Automatically Accept Fellowship Requests.
|
|
**Other Players:** Accept Corpse Looting Permissions · Attempt to
|
|
Deceive Other Players · Let Other Players Give You Items · Ignore All
|
|
Trade Requests · Drag Item to Player Opens Trade · Allow Others to See
|
|
Your Date of Birth · ...Your Age · ...Your Chess Rank · ...Your Fishing
|
|
Skill · ...Your Number of Deaths · ...Your Number of Titles.
|
|
**Character Behavior:** Run as Default Movement · Advanced Combat
|
|
Interface · Auto Target · Automatically Repeat Attacks · Use Charge
|
|
Attack · Lead Missile Targets · Use Fast Missiles.
|
|
**Chat:** Stay in Chat Mode After Sending a Message · Listen to
|
|
Allegiance Chat · Listen to General Chat · Listen to Trade Chat · Listen
|
|
to LFG Chat · Listen to Roleplay Chat · Listen to Society Chat · Listen
|
|
to PK death messages.
|
|
|
|
### Tabs 3+4 — "Chat" and "Config"
|
|
Not screenshotted. Research must derive their contents (Chat tab is
|
|
plausibly the per-window text-type filter blocks + opacity the CH
|
|
research already located in `gmChatOptionsUI`; Config is unknown —
|
|
plausibly video/audio/mouse).
|
|
|
|
## What already exists (do NOT re-derive)
|
|
|
|
- **The chat digest** (`claude-memory/project_chat_digest.md`) — START
|
|
THERE. Campaign CH built most of the plumbing this campaign needs.
|
|
- **Wire, already working:** `SetSingleCharacterOption (0x0005)` codec +
|
|
the six Hear-chat toggles (CH3); `RuntimeCharacterOptionsState`
|
|
(Options1/Options2 words, `SetOptionBit`, seeded from every
|
|
PlayerDescription); the membership-gate consumption of those bits.
|
|
ACE's `CharacterOption.cs` maps option id → bit; `CharacterOptions1.Default
|
|
= 0x50C4A54A` (verified; the register once carried a phantom mismatch —
|
|
see `docs/research/2026-08-09-chat-side-channels-vs-ace.md` corrections).
|
|
- **Wire, known-missing:** the full-blob `SetCharacterOptions (0x01A1)`
|
|
builder was DELETED at CH3 (the old one was malformed:
|
|
`CharacterOptionDataFlag.CharacterOptions2 = 0x40` collides with
|
|
`CharacterOptions1.AllowGive`; ACE's real layout is in
|
|
`GameActionSetCharacterOptions.cs`). Retail's Apply button presumably
|
|
sends the blob — the REAL builder must be ported. The per-window
|
|
GameplayOptions blob (`0x1000008C`, elements `0x1000008B`) is stored by
|
|
ACE as an opaque byte[] it never parses — acdream owns that format
|
|
(research: `2026-08-09-chat-retail-window-shell.md` §4).
|
|
- **Decomp beachheads:** `gmChatOptionsUI::InitOptions @0x0049FC60` (the
|
|
five per-window filter blocks, SetUserData ids 8/2/3/4/5, defaults);
|
|
opacity options `0x10000080/0x10000081` (`ChatInterface::SetOpacity
|
|
@0x004F3120` family — implemented in CH6c); `PlayerModule` option
|
|
accessors (`InqChatWindowOption 0x1000007F`, `SetHearGeneralChat
|
|
@0x005D35C0` writes options2 locally THEN notifies — the local-write
|
|
pattern CH3/CH4 ported). The options panel class family
|
|
(gmOptionsUI? gmGameplayOptionsUI? the tab host) is UNEXPLORED.
|
|
- **UI machinery, fully proven by CH6:** LayoutDesc import (incl.
|
|
Resizebar grips, buttons, scrollbars, outline properties 0x21/0x22),
|
|
`RetailWindowManager`/`UiRoot`, fixture generation
|
|
(`RetailLayoutFixtureGenerator` — add layouts, commit fixtures, pin
|
|
conformance), the retained-controller pattern
|
|
(`ChatWindowController`/`FloatingChatWindowController` are the
|
|
templates), the settings persistence seams
|
|
(`RuntimeSettingsController`/`RuntimeSettingsTargets`, J4.4
|
|
generation-gated command path).
|
|
- **The F11 panel** (`SettingsPanel`, UI.Abstractions) — the NON-retail
|
|
developer/client surface: audio sliders, quality presets, keybind
|
|
rebinding (modal capture), chat opacity sliders (CH6c), Hear-chat
|
|
toggles (CH3). The user's original ask ("client settings, different
|
|
from retail") coexists with the retail panel — how they split (retail
|
|
panel = retail options; Config tab or F11 = acdream client settings?)
|
|
is a DESIGN DECISION for the plan, made by Claude, reactable at the
|
|
gate.
|
|
- **Keybinds:** `KeyBindings.RetailDefaults()` (the ONLY production
|
|
table — `AcdreamCurrentDefaults()` is dead; #358's lesson),
|
|
`InputDispatcher` modal capture, the F11 rebind UX. Retail's
|
|
"Configure Keyboard" screen is unexplored decomp territory.
|
|
- **Status bar:** the retail toolbar exists (`RetailUiRuntime` mounts
|
|
it); the options BUTTON on it (which authored element, what it opens)
|
|
is unexplored.
|
|
|
|
## Research questions for the campaign's Opus lanes
|
|
|
|
1. **Panel structure:** which LayoutDesc(s) author the Options panel
|
|
(tab host + four tab pages)? The class family in the decomp
|
|
(grep gmOptionsUI / gmGameplayOptionsUI / gmCharacterOptionsUI /
|
|
gmConfigOptionsUI / the tab control); how Apply/Reset/Defaults work
|
|
(what each sends/restores, per tab or global); how the panel opens
|
|
(the status-bar button element + any keybind).
|
|
2. **The Character tab's complete option map:** every row transcribed
|
|
above → its storage (CharacterOptions1 bit / CharacterOptions2 bit /
|
|
PlayerModule property id) → its wire (0x0005 single vs 0x01A1 blob) →
|
|
ACE's handling (which bits ACE honors server-side vs stores-only) →
|
|
acdream's current state (exists/ignored/missing). acclient.h +
|
|
`PlayerModule`/`CharacterOptionsMapper` decomp + ACE enums.
|
|
3. **The Chat tab and Config tab contents** (no screenshots): derive
|
|
from the decomp/LayoutDescs what retail shows there.
|
|
4. **The real 0x01A1 blob:** exact layout from ACE's reader + retail's
|
|
builder; when retail sends blob vs single-option.
|
|
5. **Configure Keyboard:** retail's keymap UI + storage (the keymap
|
|
file/wire?) — and the design call on reusing acdream's existing
|
|
rebind UX vs porting retail's screen.
|
|
6. **Gameplay Options tab actions:** Exit to Character Selection (ties
|
|
into the FUTURE pre-world flow — probably lands as Exit Game
|
|
initially with a register row), Urgent Assistance / Report Abuse
|
|
(server messages?), In-Game Help Files, Use Mouse Turning Settings.
|
|
7. **Which options have live acdream consumers today** (timestamps →
|
|
chat; hear-chat → CH3 gate; run-as-default → movement; weather/fog/
|
|
daylight → sky pipeline; helm/cloak → appearance) vs options whose
|
|
subsystems don't exist yet (chess rank...) — the implement-vs-store
|
|
split per row.
|
|
|
|
8. **Headless bot settings (user-directed 2026-08-10):** character
|
|
options must be settable by bots too. DESIGN CONSTRAINT for the plan:
|
|
the option map (option -> CharacterOptions1/2 bit or PlayerModule
|
|
property -> wire) is RUNTIME-owned, exposed as a typed set-option
|
|
command on the shared IGameRuntimeCommands surface; the graphical
|
|
Options panel and the headless host are BOTH consumers of that one
|
|
seam (CH3's hear-chat toggles are the proven precedent). The headless
|
|
session config (K1 strict versioned JSON) gains an optional
|
|
`characterOptions` block of declared desired values; at login, after
|
|
the PlayerDescription seeds actual state, the host DIFFS declared vs
|
|
actual and sends only changes through the shared command path
|
|
(0x0005 per change or one 0x01A1 blob) — idempotent on reconnect.
|
|
Presentation-only settings (opacity/audio/quality) stay graphical-only;
|
|
the strict schema keeps them out of bot config by construction.
|
|
Research: verify which options a bot can meaningfully hold and whether
|
|
ACE rejects any option change from a logged-in session.
|
|
|
|
## Process (binding, from Campaign CH's five gate rounds)
|
|
|
|
- Model split: Opus research lanes → Fable (main loop) plans →
|
|
Sonnet implements → dual-lens Opus review per slice, fixes applied;
|
|
REJECT verdicts get focused re-reviews.
|
|
- Max 3-4 agents in parallel INCLUDING children; every agent prompt
|
|
carries an explicit no-subagent clause; ONE implementer at a time on
|
|
shared files; agents never launch the graphical client; the user runs
|
|
connected gates.
|
|
- Ledger discipline: never blanket-replace "(this commit)" placeholders
|
|
(anchor every replacement); post-amend SHAs recorded by the
|
|
coordinator, not chased in the same commit.
|
|
- User gates are AXIOMS; screenshots must be transcribed into docs
|
|
immediately (they don't survive sessions); honesty markers NEVER
|
|
appear in user-visible text; decomp claims byte-verified (BN pooled
|
|
strings, `sbb` idioms, and ~33-char previews are known artifact
|
|
classes — sweep push-imm32 literals from the PDB-paired binary at
|
|
`C:\Users\erikn\Downloads\acclient.exe`, `check_exe_pdb.py` MATCH
|
|
first).
|
|
- SERIAL TREE OWNERSHIP: only ONE agent that builds/tests may run at a
|
|
time (all agents share the one worktree; concurrent dotnet build/test
|
|
collide on bin locks). Read-only research/review agents may overlap a
|
|
builder EXCEPT at their end-of-run targeted test step — in practice,
|
|
run reviews and implementers serially; overlap only pure-read research.
|
|
- ESCALATION ON REPEATED REVIEW FAILURE (user-directed 2026-08-10): if a
|
|
slice fails review TWICE (two REJECT rounds, or a rework that fails its
|
|
re-review), the main loop (Fable) takes over and fixes it directly —
|
|
no third Sonnet dispatch. Two failures mean the contract or the
|
|
mechanism is being misunderstood at the implementer tier; the fix needs
|
|
the coordinator'''s full context.
|
|
- STALLED/YIELDED AGENTS: a watchdog-killed or early-yielding agent is
|
|
resumed with SendMessage to its id — the transcript survives and it
|
|
continues where it stopped (used twice in Campaign CH). Never redo its
|
|
work from scratch before trying a resume.
|
|
- PERSIST WHAT TWO CONSUMERS NEED: review findings that feed both a fixer
|
|
AND a re-reviewer go into a docs/research findings doc (committed)
|
|
before dispatching either — notification text does not survive session
|
|
restarts or compaction. Same for any diagnosis a later agent works from.
|
|
- VERIFY AGENT CLAIMS AT THE SEAMS: spot-check each agent'''s load-bearing
|
|
claims against source before building on them (git log for SHAs, the
|
|
cited file:line for mechanisms) — reported SHAs are stale-by-one after
|
|
amends, and two review rounds this campaign found implementer summaries
|
|
that overclaimed what shipped.
|
|
- `dotnet build` + FULL Release suite green per commit (baseline at
|
|
handoff: 12,610/4/0 at `bcc34ee3`; plus the in-flight polish commit
|
|
below). Register rows same-commit. CLAUDE.md campaign paragraph
|
|
updated at close (see `feedback_claude_md_staleness`).
|
|
|
|
## In-flight at handoff
|
|
|
|
A post-gate polish agent (round-5 review S1-S3: per-block outline pass,
|
|
non-UiText outline plumbing, citation fix) was running when this handoff
|
|
was written — check `git log` for `fix(ui): round-5 review polish` and
|
|
collect/verify its landing first if absent.
|
|
|
|
## Carried tail (do not lose)
|
|
|
|
#360/#361 (command families), #366 (unseen-text indicator), #368
|
|
(headless thread affinity — separate session exists), #369 (floaty send
|
|
channel), AP-177 (SpewBox line lifetime), AP-190 (opacity ease),
|
|
AP-191 (transcript tag colors).
|