acdream/memory/project_retail_research_index.md
Erik d951304875 memory: capture full 2026-04-17 session + permanent research index
Two memory files landed:

1. Updated memory/project_session_2026_04_17.md — covers all three
   commits today:
   - ff325ab debug overlay + mouse controls
   - 7230c15 retail UI research + C# scaffold
   - 3f913f1 13-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.
2026-04-18 13:24:11 +02:00

6.6 KiB

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 First read. Has cross-references + port decisions
01 01-architecture-and-init.md Extending GameWindow's init flow or main loop
02 02-class-hierarchy.md Adding new widget types to our UI toolkit
03 03-rendering.md Building AcFont from portal.dat, dat sprites, scissor
04 04-input-events.md Adding drag-drop, tooltip, focus, modal
05 05-panels.md Porting chat, attributes, paperdoll, spellbook, inv
06 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 First read. Has the full dependency graph + phase sequence
R1 r01-spell-system.md Implementing cast flow, fizzle, mana cost, buffs, recalls
R2 r02-combat-system.md Damage formula, hit-chance, crit, body-part targeting
R3 r03-motion-animation.md Expanding MotionInterpreter, hook delivery, stance blends
R4 r04-vfx-particles.md Building the particle system, PhysicsScript dispatch
R5 r05-audio-sound.md Audio engine, SoundTable + Wave loaders, 3D falloff
R6 r06-items-inventory.md Item model, Container, Appraise, burden, stack-split
R7 r07-character-creation.md Char-creation panel, heritages, skill credits
R8 r08-network-protocol-atlas.md Anything wire-format. Complete opcode map.
R9 r09-dungeon-portal-space.md Dungeon streaming, PlayerTeleport flow, portal visibility
R10 r10-quest-dialogs.md Emote scripts, NPC dialog, quest timers, contract tracker
R11 r11-allegiance.md Allegiance tree, XP passup, allegiance chat channels
R12 r12-weather-daynight.md Sky dome, day/night, rain/snow, Portal Year clock
R13 r13-dynamic-lighting.md LightInfo dat, 8-light cap, cell ambient, blob shadow

Existing research from prior sessions (separate from these 20)


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.