Two memory files landed: 1. Updated memory/project_session_2026_04_17.md — covers all three commits today: -ff325abdebug overlay + mouse controls -7230c15retail UI research + C# scaffold -3f913f113-slice deep-dive marathon + scaffolds + roadmap Includes the "what to build tomorrow" lookup table, the architectural headline findings, and session lessons (Opus-4.7 parallel swarms are worth the cost; keystone.dll landmine; GameEvent dispatcher is the biggest network gap). 2. New memory/project_retail_research_index.md — permanent index for the 20 research docs (6 UI slices + 13 subsystem slices). Quick- lookup table "use this slice when you're doing X". Also captures the critical cross-cutting findings (architecture, wire, dat ranges) and already-extracted retail-faithful formulas for instant reference. This file is the standing invariant: before writing any retail-AC- specific code, open it first to find the matching slice.
121 lines
6.6 KiB
Markdown
121 lines
6.6 KiB
Markdown
# Retail AC research index — permanent lookup table
|
|
|
|
Written 2026-04-17. Points at the 20 research documents produced in
|
|
that day's dual-swarm marathon (6 UI agents + 13 subsystem agents,
|
|
all Opus-4.7 high-effort).
|
|
|
|
**When to use:** any time you're about to write code for a retail AC
|
|
subsystem. Open the slice for that subsystem BEFORE writing the first
|
|
line — every slice has pseudocode + C# port sketch + citations.
|
|
|
|
---
|
|
|
|
## UI layer (`docs/research/retail-ui/`) — 6 slices, ~30,000 words
|
|
|
|
| ID | File | Use when… |
|
|
|----|------|-----------|
|
|
| — | [`00-master-synthesis.md`](../docs/research/retail-ui/00-master-synthesis.md) | First read. Has cross-references + port decisions |
|
|
| 01 | [`01-architecture-and-init.md`](../docs/research/retail-ui/01-architecture-and-init.md) | Extending GameWindow's init flow or main loop |
|
|
| 02 | [`02-class-hierarchy.md`](../docs/research/retail-ui/02-class-hierarchy.md) | Adding new widget types to our UI toolkit |
|
|
| 03 | [`03-rendering.md`](../docs/research/retail-ui/03-rendering.md) | Building AcFont from portal.dat, dat sprites, scissor |
|
|
| 04 | [`04-input-events.md`](../docs/research/retail-ui/04-input-events.md) | Adding drag-drop, tooltip, focus, modal |
|
|
| 05 | [`05-panels.md`](../docs/research/retail-ui/05-panels.md) | Porting chat, attributes, paperdoll, spellbook, inv |
|
|
| 06 | [`06-hud-and-assets.md`](../docs/research/retail-ui/06-hud-and-assets.md) | Vital orbs, radar, compass, any dat asset lookup |
|
|
|
|
## Subsystems (`docs/research/deepdives/`) — 13 slices, ~78,000 words
|
|
|
|
| ID | File | Use when… |
|
|
|-----|------|-----------|
|
|
| — | [`00-master-synthesis.md`](../docs/research/deepdives/00-master-synthesis.md) | First read. Has the full dependency graph + phase sequence |
|
|
| R1 | [`r01-spell-system.md`](../docs/research/deepdives/r01-spell-system.md) | Implementing cast flow, fizzle, mana cost, buffs, recalls |
|
|
| R2 | [`r02-combat-system.md`](../docs/research/deepdives/r02-combat-system.md) | Damage formula, hit-chance, crit, body-part targeting |
|
|
| R3 | [`r03-motion-animation.md`](../docs/research/deepdives/r03-motion-animation.md) | Expanding MotionInterpreter, hook delivery, stance blends |
|
|
| R4 | [`r04-vfx-particles.md`](../docs/research/deepdives/r04-vfx-particles.md) | Building the particle system, PhysicsScript dispatch |
|
|
| R5 | [`r05-audio-sound.md`](../docs/research/deepdives/r05-audio-sound.md) | Audio engine, SoundTable + Wave loaders, 3D falloff |
|
|
| R6 | [`r06-items-inventory.md`](../docs/research/deepdives/r06-items-inventory.md) | Item model, Container, Appraise, burden, stack-split |
|
|
| R7 | [`r07-character-creation.md`](../docs/research/deepdives/r07-character-creation.md) | Char-creation panel, heritages, skill credits |
|
|
| R8 | [`r08-network-protocol-atlas.md`](../docs/research/deepdives/r08-network-protocol-atlas.md) | Anything wire-format. Complete opcode map. |
|
|
| R9 | [`r09-dungeon-portal-space.md`](../docs/research/deepdives/r09-dungeon-portal-space.md) | Dungeon streaming, PlayerTeleport flow, portal visibility |
|
|
| R10 | [`r10-quest-dialogs.md`](../docs/research/deepdives/r10-quest-dialogs.md) | Emote scripts, NPC dialog, quest timers, contract tracker |
|
|
| R11 | [`r11-allegiance.md`](../docs/research/deepdives/r11-allegiance.md) | Allegiance tree, XP passup, allegiance chat channels |
|
|
| R12 | [`r12-weather-daynight.md`](../docs/research/deepdives/r12-weather-daynight.md) | Sky dome, day/night, rain/snow, Portal Year clock |
|
|
| R13 | [`r13-dynamic-lighting.md`](../docs/research/deepdives/r13-dynamic-lighting.md) | LightInfo dat, 8-light cap, cell ambient, blob shadow |
|
|
|
|
---
|
|
|
|
## Existing research from prior sessions (separate from these 20)
|
|
|
|
- [`docs/research/acclient_function_map.md`](../docs/research/acclient_function_map.md) — already-mapped FUN_ addresses (physics, motion, terrain, landblock)
|
|
- [`docs/research/2026-04-12-movement-deep-dive.md`](../docs/research/2026-04-12-movement-deep-dive.md) — cross-client movement cross-check
|
|
- [`docs/research/2026-04-13-phase-audit.md`](../docs/research/2026-04-13-phase-audit.md) — audit of decompile-verified vs guessed AC-specific code
|
|
|
|
---
|
|
|
|
## Critical cross-cutting findings (quick reference)
|
|
|
|
### Architecture facts
|
|
- **Retail UI runs in `keystone.dll`**, not `acclient.exe`. Own-toolkit
|
|
approach is the only viable path. Use retail event codes (0x01, 0x15,
|
|
0x3E, 0x201) so hand-ported panel code translates cleanly.
|
|
- **Weather is client-deterministic from Portal Year time.** No
|
|
`SetWeather` opcode exists. Same clock everywhere → same sky everywhere.
|
|
- **Lighting is D3D fixed-function, 8-light cap**, no attenuation inside
|
|
Range then hard cutoff. Terrain baked per-vertex via `AdjustPlanes`.
|
|
- **Motion hooks drive audio + VFX + combat timing.** R3 motion-hook
|
|
expansion is the blocker for R2, R4, R5 to feel retail-faithful.
|
|
|
|
### Wire protocol facts
|
|
- Of 94 GameEvents (S→C envelope `0xF7B0`), **0 are handled today**.
|
|
Biggest network gap.
|
|
- GameMessage `0xF7E0` SystemChat, `0xF7DE` TurbineChat, `0xF748`
|
|
UpdateMotion, `0xF751` PlayerTeleport, `0xF750` PlaySound, `0xF755`
|
|
PlayEffect are all unhandled.
|
|
- LoginComplete (`0x00A1`) must be re-sent after `PlayerTeleport`.
|
|
|
|
### Dat-ID ranges (de-duplicated across all 20 docs)
|
|
|
|
| Range | Type | Used by |
|
|
|---|---|---|
|
|
| `0x0A000000..0x0A00FFFF` | Wave | R5 |
|
|
| `0x20000000..0x2000FFFF` | SoundTable | R5 |
|
|
| `0x0E000002` | CharGen | R7 |
|
|
| `0x2F…` | SpellTable | R1 |
|
|
| `0x30…` | SpellComponentsTable | R1 |
|
|
| `0x40000000..0x40000FFF` | Font | UI03 |
|
|
| `0x06……` | RenderSurface | UI03, UI06, R13 shadow `0x0600102F` |
|
|
| `0x21…` | LayoutDesc | UI06 |
|
|
| `0x14…` | MasterInputMap | UI06 |
|
|
|
|
### Retail-faithful formulas already extracted
|
|
|
|
```
|
|
// Spell fizzle (R1)
|
|
chance = 1 / (1 + exp(-0.07 * (skill - difficulty))) // 0 if skill < diff-50
|
|
|
|
// Hit chance physical (R2)
|
|
chance = 1 - 1 / (1 + exp(0.03 * (attackSkill - defenseSkill)))
|
|
|
|
// Hit chance magic (R2)
|
|
chance = 1 - 1 / (1 + exp(0.07 * (attackSkill - defenseSkill)))
|
|
|
|
// Burden max (R6)
|
|
max = 150 * Strength + Strength * bonusBurden
|
|
|
|
// Audio falloff (R5)
|
|
att = (minDist^2) / (dist^2) (clamped 0..1, no doppler/cone/HRTF)
|
|
|
|
// Allegiance XP passup (R11)
|
|
direct = 50 + 22.5 * loyalty/291 * (1 + RT/730 * IG/720)
|
|
indirect = 16 + 8.0 * loyalty/291 * (1 + RT/730 * IG/720)
|
|
```
|
|
|
|
---
|
|
|
|
## Standing invariant for future sessions
|
|
|
|
**Before writing any retail-AC-specific code**, grep this index for the
|
|
subsystem and open the matching slice. The sliceds give you pseudocode +
|
|
C# port sketch + citations — you'll save hours and avoid hallucinating
|
|
constants. If the subsystem isn't in the 20 slices, add it to the
|
|
roadmap and consider dispatching an Opus-agent research pass for it
|
|
before coding.
|