diff --git a/CLAUDE.md b/CLAUDE.md index d5439c7..c5889c1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -25,6 +25,14 @@ The codebase is organized by layer (see architecture doc). Current phase state lives in memory (`memory/project_*.md`), plans in `docs/plans/`, research in `docs/research/`. +**UI strategy:** three-layer split — swappable backend (Hexa.NET.ImGui for +Phase D.2a short-term, custom retail-look toolkit for D.2b later) / +stable `AcDream.UI.Abstractions` layer (ViewModels + Commands + `IPanel` +/ `IPanelRenderer`) / unchanged game state. **All plugin-facing UI +targets `AcDream.UI.Abstractions` — never import a backend namespace +from a panel.** Full design: `docs/plans/2026-04-24-ui-framework.md`. +Memory crib: `memory/project_ui_architecture.md`. + ## How to operate **You are the lead engineer AND architect on this project at all times.** diff --git a/docs/architecture/acdream-architecture.md b/docs/architecture/acdream-architecture.md index 3fb1e96..e5f7f85 100644 --- a/docs/architecture/acdream-architecture.md +++ b/docs/architecture/acdream-architecture.md @@ -66,6 +66,32 @@ game state through well-defined interfaces that the retail client never had. └──────────────────────────────────────────────────────────────┘ ``` +### UI Architecture (companion stack, spans Layers 1 & 5) + +The UI is split into its own three-layer stack with a swappable backend, +designed 2026-04-24. Full design: `docs/plans/2026-04-24-ui-framework.md`. + +``` +┌─────────────────────────────────────────────────────────────┐ +│ UI BACKEND (swappable) │ +│ Hexa.NET.ImGui (Phase D.2a, short-term) │ +│ or custom retail-look toolkit (Phase D.2b, later) │ +├─────────────────────────────────────────────────────────────┤ +│ AcDream.UI.Abstractions (stable contract) │ +│ ViewModels, Commands, IPanel, IPanelHost, IPanelRenderer │ +│ ► plugin-facing UI API lives HERE, not in the backend │ +├─────────────────────────────────────────────────────────────┤ +│ Game state + events (unchanged) │ +│ IGameState / IEvents / WorldSession — UI only reads │ +└─────────────────────────────────────────────────────────────┘ +``` + +The backend is pluggable; ViewModels / Commands / `IPanelRenderer` are +stable across the swap. ImGui persists forever as the +`ACDREAM_DEVTOOLS=1` devtools overlay regardless of which backend owns +the game UI. See `memory/project_ui_architecture.md` for the session +crib-sheet version. + --- ## Project Structure (target) @@ -206,6 +232,12 @@ exposes them as `WorldEntitySnapshot`. GameWindow becomes thin. 6. Plugin tick └── Fire IEvents, drain IActions queue + +6a. UI tick + IPanelHost.Draw → iterate registered IPanel instances, build + ViewModels from IGameState, dispatch user Commands via ICommandBus. + Backend-agnostic — ImGui or custom retail-look draws here depending + on which is compiled in. See docs/plans/2026-04-24-ui-framework.md. ``` --- diff --git a/docs/plans/2026-04-11-roadmap.md b/docs/plans/2026-04-11-roadmap.md index ddbced3..1559590 100644 --- a/docs/plans/2026-04-11-roadmap.md +++ b/docs/plans/2026-04-11-roadmap.md @@ -142,17 +142,14 @@ Plus polish that doesn't get its own phase number: **Sub-pieces:** - **D.1 — 2D ortho overlay + font rendering.** ✅ SHIPPED 2026-04-17 as the dev-facing debug overlay (StbTrueTypeSharp system-font atlas + `TextRenderer` + `DebugOverlay`). -- **D.2 — Retail UI framework + first panels.** Research + scaffold landed 2026-04-17 (see `docs/research/retail-ui/`). Ships: - - `UiRoot` + `UiElement` + `UiPanel` + `UiHost` with retail-faithful event codes (`0x01` click, `0x15` drag-begin, `0x3E` drop, `0x201` WM_LBUTTONDOWN, tooltip delay ~1000ms, etc.) - - Focus / modal / capture / drag-drop / hover state machine - - `WorldMouseFallThrough` / `WorldKeyFallThrough` preserves existing camera+player controls - - First concrete panel (chat window) uses wire messages Phase 4.7 already parses -- **D.3 — AcFont from portal.dat.** Replace stb_truetype system font with retail `Font` DBObjs (`0x40000000..0x40000FFF`) baked from `RenderSurface` source sheets — see research slice 03 §4. Preserves retail visual identity. -- **D.4 — Dat sprites + 9-slice panel backgrounds.** Load `RenderSurface` (`0x06xxxxxx`) as GL textures; add `DrawSprite` to `UiRenderContext`. Enables retail panel art. -- **D.5 — Core panels.** Attributes (`chunk_00470000.c:FUN_0047ba70`), Skills (same), Paperdoll (`chunk_004A0000.c:FUN_004A5200`), Inventory, Spellbook (`chunk_004C0000.c`), Fellowship, Allegiance. Each uses the port sketches in slice 05. -- **D.6 — HUD.** Vital orbs (scissor-rect partial fill, dat sprites `0x060013B2`), radar (`0x06001388` / `0x06004CC1`, 1.18× range factor), compass strip (scrolling U), target name plate, damage floaters, selection indicator. See slice 06. -- **D.7 — Cursor manager.** OS + dat-sourced custom cursors (`FUN_0043c1c0` GDI HCURSOR builder pattern from slice 03). -- **D.8 — Sound.** `SoundTable` parser, `Sound` dat decode, audio engine (OpenAL via Silk.NET.OpenAL), per-entity 3D positional audio, optional music. +- **D.2a — Hexa.NET.ImGui scaffold + `AcDream.UI.Abstractions` layer.** NEW pre-piece introduced 2026-04-24. Wires Hexa.NET.ImGui as the short-term backend behind `ACDREAM_DEVTOOLS=1`. Defines `IPanel` / `IPanelHost` / `IPanelRenderer` / `ICommandBus` + the first ViewModels (`VitalsVM` etc.) in the new `AcDream.UI.Abstractions` project. First real panel: `VitalsPanel` reading HP/stam/mana from `IGameState`. This is what gets game-logic iteration moving; looks like a debugger, acceptable. +- **D.2b — Custom retail-look backend.** Implements the same `IPanel` / `IPanelRenderer` contracts using a custom retained-mode toolkit sourced from retail dat assets. Requires D.2a shipped. Panels get reskinned one at a time; ImGui stays as the `ACDREAM_DEVTOOLS=1` overlay forever. The original 2026-04-17 scaffold research (`UiRoot` / `UiElement` / `UiPanel` / `UiHost` + retail event codes + focus / drag-drop state machine + `WorldMouseFallThrough`) is the implementation foundation here — see `docs/research/retail-ui/`. +- **D.3 — AcFont from portal.dat.** Replace stb_truetype system font with retail `Font` DBObjs (`0x40000000..0x40000FFF`) baked from `RenderSurface` source sheets — see research slice 03 §4. Preserves retail visual identity. **(D.2b dependency — needs the custom renderer.)** +- **D.4 — Dat sprites + 9-slice panel backgrounds.** Load `RenderSurface` (`0x06xxxxxx`) as GL textures; add `DrawSprite` to `UiRenderContext`. Enables retail panel art. **(D.2b dependency.)** +- **D.5 — Core panels.** Attributes (`chunk_00470000.c:FUN_0047ba70`), Skills (same), Paperdoll (`chunk_004A0000.c:FUN_004A5200`), Inventory, Spellbook (`chunk_004C0000.c`), Fellowship, Allegiance. Each uses the port sketches in slice 05. **(Targets `AcDream.UI.Abstractions` — ships with D.2a using ImGui-rendered widgets; reskinned by D.2b.)** +- **D.6 — HUD.** Vital orbs (scissor-rect partial fill, dat sprites `0x060013B2`), radar (`0x06001388` / `0x06004CC1`, 1.18× range factor), compass strip (scrolling U), target name plate, damage floaters, selection indicator. See slice 06. **(Targets `AcDream.UI.Abstractions` — ships with D.2a; reskinned by D.2b.)** +- **D.7 — Cursor manager.** OS + dat-sourced custom cursors (`FUN_0043c1c0` GDI HCURSOR builder pattern from slice 03). **(D.2b dependency.)** +- ~~**D.8 — Sound.**~~ **Superseded — shipped as Phase E.2** (`SoundTable`/`Sound` dat decode, OpenAL 16-voice engine, per-entity 3D positional audio via `AudioHookSink`). Entry kept here for history; see the shipped table. **Reference docs:** `docs/research/retail-ui/00-master-synthesis.md` + slices 01-06. Every AC-specific behavior has a decompiled FUN_ / DAT_ citation. @@ -184,7 +181,7 @@ Research: R1 + R2 + R6 + R8 + UI slices 04/05. - **F.2 — Item + inventory model.** `ItemInstance` / `Container` / `PropertyBundle`. Appraise round-trip (`0x00C8` → `0x00C9`). Burden math. See `r06-items-inventory.md` + `src/AcDream.Core/Items/`. - **F.3 — Combat math + damage flow.** Damage formula, per-body-part AL, crit, hit-chance sigmoid. Server broadcasts damage events; client displays + HP bar. See `r02-combat-system.md` + `src/AcDream.Core/Combat/`. - **F.4 — Spell cast state machine.** `SpellCastStateMachine` + active buff tracking. Buffs + recalls first, projectile spells later. Fizzle sigmoid + mana conversion. See `r01-spell-system.md` + `src/AcDream.Core/Spells/`. -- **F.5 — Core panels.** Attributes / Skills / Paperdoll / Inventory / Spellbook — using the retail-ui framework from Phase D.2. See `05-panels.md` under retail-ui. +- **F.5 — Core panels.** Attributes / Skills / Paperdoll / Inventory / Spellbook — using the retail-ui framework from Phase D.2. See `05-panels.md` under retail-ui. **(Targets `AcDream.UI.Abstractions`; unblocked by D.2a — ships with ImGui widgets — and reskinned when D.2b lands.)** **Acceptance:** equip a weapon, swing at a monster, see damage numbers, buff yourself, recall to the lifestone. @@ -202,7 +199,7 @@ Research: R9 + R12 + R13. Research: R7 + R10 + R11 + UI slice 05. -- **H.1 — Chat window.** UI panel + all 6 wire opcodes (Channel, Tell, System, HearSpeech, HearRangedSpeech, TurbineChat). +- **H.1 — Chat window.** UI panel + all 6 wire opcodes (Channel, Tell, System, HearSpeech, HearRangedSpeech, TurbineChat). *(Wire layer already shipped per the shipped table; remaining work is the panel, which targets `AcDream.UI.Abstractions` — unblocked by D.2a, reskinned when D.2b lands.)* - **H.2 — Allegiance.** Tree model + XP pass-up math + 5 allegiance chat channels + MOTD. See `r11-allegiance.md`. - **H.3 — Emote scripts + quests + dialogs.** 122 EmoteType × 39 Trigger mini-VM. Contract tracker UI. NPC dialog rendered via chat with `` markup. See `r10-quest-dialogs.md`. - **H.4 — Character creation.** `0xE000002 CharGen` dat + 13 heritages + templates + appearance picker + preview renderer. See `r07-character-creation.md`. diff --git a/docs/research/retail-ui/00-master-synthesis.md b/docs/research/retail-ui/00-master-synthesis.md index 7c9975b..7882a9c 100644 --- a/docs/research/retail-ui/00-master-synthesis.md +++ b/docs/research/retail-ui/00-master-synthesis.md @@ -1,5 +1,16 @@ # Retail AC Client GUI — Master Synthesis +> **Scope note (2026-04-24):** This document describes retail's Keystone +> UI toolkit — it is the research foundation for **Phase D.2b (custom +> retail-look backend)**, not **Phase D.2a (Hexa.NET.ImGui scaffold)**. +> When reading this for implementation guidance, assume D.2a has shipped +> a working `AcDream.UI.Abstractions` layer (`IPanel`, `IPanelRenderer`, +> ViewModels, Commands) and you are building the custom retained-mode +> toolkit that implements the same contracts using dat-sourced fonts / +> sprites / cursors. See `docs/plans/2026-04-24-ui-framework.md` for the +> staged UI strategy and `memory/project_ui_architecture.md` for the +> one-page crib-sheet. + **Date:** 2026-04-17 **Sources:** 6 parallel Opus research passes over the decompiled `acclient.exe` (22,225 functions / 688K lines). Individual deep dives: diff --git a/memory/project_ui_architecture.md b/memory/project_ui_architecture.md new file mode 100644 index 0000000..2d6240d --- /dev/null +++ b/memory/project_ui_architecture.md @@ -0,0 +1,74 @@ +# Project: UI architecture — three-layer stable pattern + +**Agreed 2026-04-24.** Read once per session. Full design: +[`docs/plans/2026-04-24-ui-framework.md`](../docs/plans/2026-04-24-ui-framework.md). + +## The separation + +``` +┌─────────────────────────────────────────┐ +│ UI backend (ImGui today / custom later)│ ← swappable +├─────────────────────────────────────────┤ +│ ViewModels + Commands (per-panel) │ ← stable contracts +├─────────────────────────────────────────┤ +│ Game state + events + net (unchanged) │ ← game logic +└─────────────────────────────────────────┘ +``` + +- **UI backend** (bottom swap axis): `Hexa.NET.ImGui` for Phase D.2a + (short-term, debugger-look, validates game logic fast). Custom + retail-look toolkit for Phase D.2b (long-term, uses dat assets). + ImGui stays **forever** as the `ACDREAM_DEVTOOLS=1` overlay. +- **ViewModels + Commands** (the stable contract): per-panel data + records (`VitalsVM`, `InventoryVM`, `ChatVM`, …) and action records + (`UseItemCmd`, `SendChatCmd`, `CastSpellCmd`, …). Lives in + `AcDream.UI.Abstractions`. **Does not change across the backend swap.** +- **Game state + events + net**: existing `IGameState`, `IEvents`, + `WorldSession`, etc. Unchanged. UI only reads/subscribes; never + touches these. + +## Module layout (future) + +- `src/AcDream.UI.Abstractions/` — `IPanel`, `IPanelHost`, + `IPanelRenderer`, `ICommandBus`, all ViewModels + Commands. Backend- + agnostic. +- `src/AcDream.UI.ImGui/` — Hexa.NET.ImGui-based implementation of + `IPanelRenderer` + ImGui bootstrap. Phase D.2a. +- `src/AcDream.UI.Retail/` (later) — custom retained-mode toolkit using + dat assets, same `IPanelRenderer` contract. Phase D.2b. + +## Hard rules + +1. **No panel references a backend namespace.** If a panel imports + `Hexa.NET.ImGui` or a custom-toolkit widget class directly, it's a + bug. +2. **Plugin API targets the abstraction layer only.** Plugins define + `IPanel` instances; they never see which backend draws them. +3. **Features that only ImGui can express → not in `IPanelRenderer`.** + If a feature can't be expressed by a future retained-mode toolkit + with dat-sourced sprites/fonts, don't expose it in the abstraction. +4. **D.3 AcFont / D.4 dat sprites / D.7 cursor manager are D.2b + dependencies** — they plug into the custom backend only. +5. **D.5 core panels / D.6 HUD ship against the abstraction**, not + against a specific backend. They render via ImGui first, reskin + under custom later. + +## Why staged (not pure custom from day one) + +- Gets the whole game-logic loop validated in weeks: chat-send, + inventory-click, vitals-bar-read-from-real-state. Requires zero + widget art. +- Forces the abstraction design to pass a real backend test before we + commit to the custom toolkit. If `IPanelRenderer` is wrong, we + discover it during Phase D.2a, not after Phase D.2b lands with a + dozen broken panels. +- Custom retail-look toolkit then delivers the aesthetic layer without + the plugin API or game logic needing to change. + +## Links + +- Full design: `docs/plans/2026-04-24-ui-framework.md` +- Roadmap entry: `docs/plans/2026-04-11-roadmap.md` Phase D (see the + 2026-04-24 callout block). +- Custom-backend research (applies to D.2b, NOT D.2a): + `docs/research/retail-ui/00-master-synthesis.md` + slices 01-06.