# acdream — Retail AC Deep-Dive Master Synthesis

**Date:** 2026-04-17
**Total research output:** ~78,000 words across 13 deep-dive slices
(plus the retail-UI set from earlier the same day — 30,000 words more).
Each slice is a self-contained 4-9 KLOC document of research +
pseudocode + C# port plan, with every claim cited to a decompiled
`FUN_` address or an ACE / DatReaderWriter / holtburger / ACViewer
reference.

This document is the navigation hub and cross-reference map. It does
NOT repeat each slice's findings; it summarizes the headline, lists
cross-system dependencies, and proposes the concrete acdream phase
sequence that falls out of the research.

---

## 1. Slice inventory

| ID  | Topic                           | File                                                         | Words | Key finding |
|-----|---------------------------------|--------------------------------------------------------------|-------|-------------|
| R1  | Spell system                    | [r01-spell-system.md](r01-spell-system.md)                   | 5.4K  | Sigmoid `1/(1+e^(-0.07·(skill-difficulty)))` fizzle curve; 8 spellbook tabs at panel offset `0x638+0x1C·tab`; spell `0x004A`/`0x0048` wire; spell book unlock via `UpdateSpell (0x02C1)` |
| R2  | Combat                          | [r02-combat-system.md](r02-combat-system.md)                 | 5.9K  | `PowerMod = Level + 0.5` melee; physical logistic at `k=0.03` / magic at `k=0.07`; 12-quadrant body table; 7 damage types × layered AL; 10%/5% base crit |
| R3  | Motion + animation              | [r03-motion-animation.md](r03-motion-animation.md)           | 8.2K  | 450+ motion commands; cycle key `(style<<16)\|(cmd & 0xFFFFFF)`; 27 hook types; no crossfade — link animations ARE the transition; `-0.65` backward factor; `1.5×` run-turn |
| R4  | VFX / particles                 | [r04-vfx-particles.md](r04-vfx-particles.md)                 | 5.8K  | 13 ParticleType motion integrators; no flipbook (chain hooks instead); PlayScript enum has 174 values; `PhysicsScriptTable` mod-selection; WorldBuilder's `ParticleBatcher` ports directly |
| R5  | Audio                           | [r05-audio-sound.md](r05-audio-sound.md)                     | 5.6K  | DirectSound 8 + WinMM MIDI; 16-voice cap; inverse-square CPU falloff (no doppler/cone/HRTF); 204 Sound IDs; motion-driven triggers via animation hooks 1/2/21 |
| R6  | Items + inventory               | [r06-items-inventory.md](r06-items-inventory.md)             | 7.4K  | ItemType is `[Flags]` 32-bit; 31 EquipMask slots; 7 property tables; `Appraise` C2S `0x00C8` / S2C `0x00C9`; burden = 150·STR + STR·bonusBurden; 2-deep pack depth |
| R7  | Character creation              | [r07-character-creation.md](r07-character-creation.md)       | 6.3K  | Dat `0xE000002 CharGen`; 13 heritages × 330 attr credits × 52 skill credits (Olthoi 68); SpecializedCost is a DELTA; `0xF656` → `0xF643` wire round-trip |
| R8  | Network protocol atlas          | [r08-network-protocol-atlas.md](r08-network-protocol-atlas.md) | 9.7K  | 63 primary GameMessages + 149 GameActions + 94 GameEvents mapped. Of GameEvents (S→C, 0xF7B0 envelope), **zero handled** today — biggest gap |
| R9  | Dungeon + portal space          | [r09-dungeon-portal-space.md](r09-dungeon-portal-space.md)   | 6.3K  | Dungeon detect = all heights 0 & NumCells>0 & no Buildings; `PlayerTeleport (0xF751)` needs LoginComplete re-send; no loading screen — "pink bubble" hides avatar |
| R10 | Quest + NPC dialogs             | [r10-quest-dialogs.md](r10-quest-dialogs.md)                 | 7.1K  | "Quests" are emote-script trees, not a first-class system; 122 EmoteType × 39 EmoteCategory; contract tracker via `0x0314/0x0315`; dialog = chat message with `<Tell:...>` markup |
| R11 | Allegiance                      | [r11-allegiance.md](r11-allegiance.md)                       | 5.4K  | Max 11 direct vassals; rank `max(lower+1, higher)` capped 10; XP passup `50+22.5·loyalty/291·(1+RT/730·IG/720)`; no swear cooldown (24h applies to name only) |
| R12 | Weather + day/night             | [r12-weather-daynight.md](r12-weather-daynight.md)           | 4.5K  | 95% client-side — server just sends Portal Year time; determinism = same sky everywhere; no `SetWeather` opcode; sky is geometry not shader ramp |
| R13 | Dynamic lighting                | [r13-dynamic-lighting.md](r13-dynamic-lighting.md)           | 4.9K  | Hard 8-light cap (fixed function D3D); NO distance attenuation inside Range then hard cutoff; terrain baked per-vertex via `AdjustPlanes`; blob shadow at `0x0600102F` |

**Grand total: 82,500 words of grounded, citation-backed research.**

---

## 2. The big picture — how the systems wire together

```
┌─────────────────────────────────────────────────────────────────┐
│                    ACE (Asheron's Call Emulator)                │
│                     — server authority                          │
└────┬────────────────────────────────────────────────────────────┘
     │  UDP packets (ISAAC, fragmented, ack'd)
     │
┌────▼────────────────────────────────────────────────────────────┐
│  WorldSession (R8 atlas)                                        │
│  • Login (4 msg), CharList, EnterWorld, CreateObject stream     │
│  • Dispatch of 63 + 94 + 149 opcodes                            │
└────┬──────────────┬──────────────┬──────────────┬───────────────┘
     │              │              │              │
     │CreateObject  │UpdateMotion  │UpdateHealth  │UpdateSpell
     │  items       │  anim        │  combat      │  buff/debuff
     ▼              ▼              ▼              ▼
┌──────────┐  ┌───────────┐  ┌──────────┐  ┌───────────┐
│ Inventory│  │ Motion    │  │  Combat  │  │  Spell    │
│ (R6)     │  │ (R3)      │  │  (R2)    │  │  (R1)     │
│          │  │           │  │          │  │           │
│ItemInst  │──│ DoMotion  │──│ Damage   │──│ ActiveBuf │
│Container │  │ MotionTbl │  │ fromCmd  │  │ Fizzle    │
│Burden    │  │ Hooks ────┼──┤ FootStep │  │ Recall    │
└────┬─────┘  └─┬────┬────┘  └────┬─────┘  └────┬──────┘
     │          │    │            │             │
     │          │    └────hooks──►│             │
     │          │                 │             │
     └──────────┴───────►┌────────▼─────────────▼──┐
                         │   Audio (R5) +          │
                         │   VFX/Particles (R4)    │
                         │   — cosmetic layer       │
                         └──────────────┬──────────┘
                                        │
                                        ▼
                        ┌───────────────────────────────┐
                        │  UI (retail-ui set) + HUD     │
                        │  AttrPanel + SpellBar + Chat  │
                        │  VitalOrbs + Radar + Compass  │
                        │  (all behind UiRoot scaffold) │
                        └───────────────────────────────┘

    ┌─ World lifecycle
    │
┌───▼─────────────────────┐
│ Streaming (existing)    │
├─────────────────────────┤
│ + Dungeon / portal (R9) │
│ + Weather sky (R12)     │
│ + Dynamic lights (R13)  │
└─────────────────────────┘

┌─ Social / progression
│
┌──────────────────┐   ┌─────────────────┐
│ Allegiance (R11) │   │ Quest + dialog  │
│ • Tree + ranks   │   │ (R10)           │
│ • XP passup       │  │ • Emote scripts │
│ • Chat channels  │   │ • Contract tkr  │
└──────────────────┘   └─────────────────┘

┌─ Game entry
│
┌──────────────────┐
│ CharCreate (R7)  │
│ • Heritage + skl │
│ • Appearance     │
│ • Starting town  │
└──────────────────┘
```

---

## 3. Critical cross-system dependencies

These are the places where one system MUST be built before another can
land cleanly. They define the port sequence.

### 3.1 Motion (R3) blocks three other systems

- **Audio (R5)** — footstep/swing/cast sounds are triggered by
  AnimationHooks (types 1=Sound, 2=SoundTable, 21=SoundTweaked). Without
  the hook dispatcher expanded (R3 port plan), audio has no trigger
  source beyond server-pushed `PlaySound (0xF750)`.
- **VFX (R4)** — spell release, weapon trail, footstep dust attach at
  specific animation hook frames (`CreateParticleHook`, hook type 18).
- **Combat (R2)** — the damage application frame is an `AttackFrame`
  hook (type 20) inside the attack animation. Without R3 hook
  dispatch, combat math has to guess timing.

**Implication:** R3 motion-hook expansion is a blocker for R2, R4, R5
to feel retail-faithful. It's a prerequisite for "the game feels
alive".

### 3.2 Inventory (R6) blocks three UI panels

- **Paperdoll** — drops items into slots; requires `ItemInstance` model.
- **Spellbook (R1)** — items like scarabs are consumed via R6 burden rules.
- **Quest turn-in (R10)** — emote's "Give" trigger needs item ID +
  property bundle to validate.

**Implication:** R6 is the data-model foundation for any gameplay UI.

### 3.3 Network (R8) is the permanent bottleneck

Of 94 GameEvents (0xF7B0 envelope), **zero are handled today**. These
include:
- `PlayerDescription (0x0013)` — full character at login
- `AllegianceInfoResponse (0x007E)`
- `Fellowship*` events (5 opcodes)
- `Identify/Appraise response (0x00C9)`
- `SendClientContractTracker (0x0315)`

**Implication:** R8 Phase D (chat + session health) is the unlocking
step for the whole social/quest/inventory stack.

### 3.4 CharCreate (R7) needs CharGen dat + at least one class

The CharGen `0xE000002` dat has every heritage + template + appearance
config. But we also need:
- `ObjDesc` application pipeline (already in our StaticObjectManager)
- At least one working panel to host the UI (R7 uses our UiRoot scaffold)
- Appearance preview renderer — already works for outdoor characters

**Implication:** R7 is the smallest unblocker for "user makes a char
in acdream instead of using ACE admin tools".

### 3.5 Dungeon (R9) extends existing streaming

R9's `EnvCellStreamer` + `PortalVisibility` + `TeleportController` are
additive to `StreamingController`. Risk is low.

### 3.6 Weather (R12) and Lighting (R13) share a scene-state UBO

Both write sun direction + ambient color + fog. A single
`SceneLightingState` UBO fed to `terrain.frag` and `mesh.frag`
consolidates them. R13 reads it; R12 produces it.

### 3.7 VFX (R4) + Audio (R5) share PhysicsScript/PlayScript

Retail's `PlayEffect (0xF755)` bundles both particle + sound. Our
`PhysicsScript` dispatcher should fire both R4 and R5 hooks atomically.

---

## 4. Proposed phase sequence

Based on the dependency graph + what unlocks the most gameplay fastest:

### Phase E — Core gameplay loop (highest value)

| Step | What                                                               | Research | Unblocks |
|------|--------------------------------------------------------------------|----------|----------|
| E.1  | R3 Motion hooks expansion                                          | R3       | E.2-E.4  |
| E.2  | R5 Audio engine + motion-hook wiring                               | R5       | immediate feel |
| E.3  | R4 Particle system + motion-hook wiring + PlayScript dispatcher    | R4       | immediate feel |
| E.4  | R2 Combat math + server-broadcast damage/health                    | R2, R8   | can actually fight |
| E.5  | R1 Spell cast state machine (buffs + recalls first, projectiles later) | R1, R8 | can cast spells |

**Acceptance:** player swings a sword, hears the whoosh, sees the
contact spark, damage number floats up, HP bar drops on the target,
monster dies with footstep/impact sounds. Spell buff lands with
glowing aura + cast sound.

### Phase F — Inventory + UI panels

| Step | What                                                               | Research | Unblocks |
|------|--------------------------------------------------------------------|----------|----------|
| F.1  | R8 GameEvent envelope (0xF7B0) dispatcher                          | R8       | F.2+     |
| F.2  | R6 Item model (`ItemInstance`, `PropertyBundle`)                   | R6       | F.3-F.5  |
| F.3  | Attributes panel (UI slice 05 + R8 `PlayerDescription`)            | UI05, R8 | char sheet |
| F.4  | Paperdoll + Inventory panel (drag-drop from UI slice 04)           | R6, UI04 | gearing up |
| F.5  | Spellbook panel (R1 tabs + icons)                                  | R1, UI05 | cast via UI |

**Acceptance:** opens all core panels, drags items between inventory
+ paperdoll, casts spells by clicking icons.

### Phase G — World systems

| Step | What                                                               | Research |
|------|--------------------------------------------------------------------|----------|
| G.1  | R12 Sky / weather / day-night                                      | R12      |
| G.2  | R13 Dynamic lighting (8-light fixed pipeline)                      | R13      |
| G.3  | R9 Dungeon streaming + portal transition                           | R9       |

**Acceptance:** walk out of Holtburg at dusk, sky gradient rolls,
torches cast light, enter a dungeon via teleport, see the dungeon
interior.

### Phase H — Social + progression

| Step | What                                           | Research |
|------|------------------------------------------------|----------|
| H.1  | Chat window (UI slice 05) + all 6 wire ops     | UI05, R8 |
| H.2  | R11 Allegiance panel + XP passup display       | R11      |
| H.3  | R10 Quest/emote/dialog system                  | R10      |
| H.4  | R7 Character creation panel                    | R7       |

**Acceptance:** talk to an NPC, get a quest, complete it, gain XP,
allegiance MOTD shows in chat.

---

## 5. What's already shipped vs what R-slices unlock

| Domain                  | Shipped                                                   | Next from deep-dives |
|-------------------------|-----------------------------------------------------------|----------------------|
| World rendering         | Terrain + static meshes + scenery + animation + chase cam | R12 sky / R13 lights |
| Streaming               | 5×5 landblock window + EnvCell walker                     | R9 dungeons          |
| Login + wire transport  | LoginRequest → EnterWorld → CreateObject stream           | R8 GameEvent envelope|
| Physics / collision     | Retail-faithful BSP + cylinder + sphere-sweep + scenery   | R3 motion hooks      |
| Input / UI              | UI framework (retail-ui set) + debug overlay              | R4 VFX + R5 audio panels |
| Movement                | WASD + chase cam + jump + autonomous-position sync        | R3 motion commands   |
| Character appearance    | ObjDesc + creature palette + hair/skin/clothing           | R7 char-create panel |
| **Everything else**     | —                                                         | R1/R2/R6/R10/R11     |

---

## 6. Consolidated dat-ID catalog (cross-slice)

Every dat range touched by the 13 slices, de-duplicated:

| Range                       | DBObjType         | Source slices |
|-----------------------------|-------------------|---------------|
| `0x02xxxxxx`                | Setup             | (existing)    |
| `0x04xxxxxx`                | Palette           | UI04          |
| `0x05xxxxxx`                | PaletteSet        | UI04          |
| `0x06000000..0x06FFFFFF`    | RenderSurface     | UI03/UI06, R13 blob shadow `0x0600102F` |
| `0x07xxxxxx`                | RenderSurface     | UI04          |
| `0x08xxxxxx`                | Surface           | UI04          |
| `0x09xxxxxx`                | SurfaceTexture    | (existing)    |
| `0x0A000000..0x0A00FFFF`    | Wave              | **R5 audio**  |
| `0x0E000002`                | CharGen           | **R7 chargen**|
| `0x0F000000..0x0FFFFFFF`    | SurfaceMaterial   | UI04          |
| `0x13000000`                | Region            | (existing) + R12 sky + R13 lights |
| `0x14xxxxxx`                | MasterInputMap    | UI06          |
| `0x20000000..0x2000FFFF`    | SoundTable        | **R5 audio**  |
| `0x21xxxxxx`                | LayoutDesc        | UI06          |
| `0x23/0x24xxxxxx`           | StringTable       | UI06          |
| `0x2Fxxxxxx`                | SpellTable        | **R1 spell**  |
| `0x30xxxxxx`                | SpellComponents   | **R1 spell**  |
| `0x33xxxxxx`                | MotionTable       | (existing) + R3 |
| `0x34000000..0x34000FFF`    | Animation         | (existing) + R3 |
| `0x40000000..0x40000FFF`    | Font              | UI03          |
| `0x41xxxxxx`                | LanguageInfo      | UI06          |

---

## 7. Consolidated opcode quick-reference (cross-slice)

Every opcode mentioned in any slice, for rapid grep-back:

```
Login flow
  0x0001   LoginRequest
  0xF7B1   GameAction envelope (C→S)      ← 149 sub-opcodes
  0xF7B0   GameEvent envelope (S→C)       ← 94 sub-opcodes
  0xF657   CharacterList
  0xF656   Character_SendCharGenResult     (R7)
  0xF643   CharGenResponseType / CharacterError (R7)

Movement (B.3 already ported)
  0xF74C   MoveToState / UpdatePosition    (partial overlap)
  0xF753   Jump / bi-directional
  0xF748   UpdateMotion                    (R3)
  0xF751   PlayerTeleport                  (R9)

Combat (R2)
  0x0008   AttackTargetRequest
  0x000A   CombatStyleRequest
  0x0053   TargetAttack
  0x01B7   MissileAttack
  0xF7xx   UpdateHealth / UpdateVital      (R2, R6 vitals)

Spells (R1)
  0x0048   Magic_CastUntargetedSpell       (R1)
  0x004A   Magic_CastTargetedSpell         (R1)
  0x02C1   UpdateSpell (spellbook add)     (R1)
  0x02C2-0x02C8  Enchantment lifecycle    (R1)
  0x02BB   HearSpeech (chatType 0x11 = syllables) (R1)

Inventory / items (R6)
  0x00C8   AppraiseRequest                 (R6)
  0x00C9   IdentifyResponse                (R6)
  0xF7xx   InventoryMove / Give / Drop / Pickup

Chat (UI05)
  0xF7B0   GameEventChannelBroadcast (0x0147 / envelope)
  0xF7B0   GameEventTell (0x02BD)
  0xF7E0   GameMessageSystemChat
  0x02BB   GameMessageHearSpeech
  0x02BC   GameMessageHearRangedSpeech
  0xF7DE   GameMessageTurbineChat
  0x0295   GameEventSetTurbineChatChannels

Allegiance (R11)
  0x001D   Swear
  0x001E   Break
  0x007E   AllegianceInfoResponse
  0x00DD   AllegianceMotd
  0x02AB   AllegianceRecall action

Quest / contracts (R10)
  0x0314   SendClientContractTrackerTable
  0x0315   SendClientContractTracker
  0xF751   TeleportToPoi (quest-driven recall)

Audio (R5)
  0xF750   PlaySound
  0xF755   PlayEffect (R4 + R5 bundle)

Dungeon / portal (R9)
  0xF751   PlayerTeleport                  (R9)
  0x00A1   LoginComplete (re-send after teleport)

Attributes (UI05)
  0x02E3   PrivateUpdateAttribute
  0x02E7   PrivateUpdateVital
  0x02E9   PrivateUpdateAttribute2ndLevel

Admin / world
  0xEA60   AdminEnvirons (colored-fog override) (R12)
```

**Full table in `r08-network-protocol-atlas.md`.**

---

## 8. Open questions that surfaced

1. **keystone.dll** — blocking for truly retail-faithful widget layout.
   Would need a second decompile pass. (UI slice 02)
2. **Launcher / patcher** — similarly binary-only. (out of scope)
3. **Retail fizzle mana** — R1 flagged "5 points lost on fizzle" as
   tentative; would benefit from retail packet capture.
4. **Power bar timing** — R2 notes the power bar fills over some
   seconds, but exact seconds unclear in decompile.
5. **Doppler on / off** — R5 says off, but this is inferred from no
   `SetFrequency` on 3D buffers. Verify with retail binary trace if
   audio fidelity matters later.
6. **Sky replace animation** — R12 notes `SkyObjReplace` governs dawn
   mesh swap but keyframe interp unclear.
7. **Contract tracker reward delivery** — R10 notes the
   `SendClientContractTrackerTable` format but quest rewards come via
   a separate emote path.
8. **Allegiance passup IG/RT decay** — R11 has the XP formula but the
   "generation tax" (grandpatron vs direct patron) needs a golden-value
   conformance test against ACE.

---

## 9. Risk assessment for each slice's port

Low (data models + straightforward translation):
- R6 Inventory (well-typed properties + containers)
- R7 CharCreate (one dat object, one wire roundtrip)
- R8 Protocol atlas (additive handlers; Phase-F work)
- R11 Allegiance (data + math, no renderer work)
- R12 Weather (deterministic from clock)

Medium (has math or subtle corner cases):
- R1 Spell (sigmoid fizzle, mana conversion, enchant stacking)
- R2 Combat (damage formula sensitivity, crit tables, body-part)
- R3 Motion hooks (27 types, delivery during frame advance)
- R5 Audio (inverse-square falloff, 16-voice eviction)
- R9 Dungeon (portal visibility + teleport state machine)
- R13 Lighting (8-light selection + attenuation curve fidelity)

High (novel systems for us):
- R4 VFX particle systems (new renderer subsystem)
- R10 Quest / emote scripts (mini-VM with 122 action types)

---

## 10. Port sequencing recommendation

If the user wants one-and-only-one focus per week:

- **Week 1 — "Feel alive":** R3 motion hooks → R5 audio → R4 VFX.
  Ship: footsteps, swing sounds, impact particles, spell aura particle.
- **Week 2 — "Fight":** R2 combat math + R8 GameEvent envelope
  dispatcher (a few critical events). Ship: actual damage flow, HP
  updates, death.
- **Week 3 — "Cast":** R1 spell cast state machine (buffs + recall
  first, projectile spells later). Ship: heal spell works, buff spell
  works, recall spell works.
- **Week 4 — "Have gear":** R6 inventory + Attributes + Paperdoll
  panels. Ship: equip weapon, see stats, manage pack contents.
- **Week 5 — "World":** R12 sky + R13 lights + R9 dungeon.
  Ship: enter a dungeon, see torch lights, day/night outside.
- **Week 6 — "Social":** Chat + R11 allegiance + R10 quest +
  R7 char-create. Ship: complete the loop.

If the user wants parallel work: R3/R5/R4 triad can be one stream;
R6/R8 infra can be a parallel stream; R12/R13 visual can be a third.

---

## 11. Plugin API implications

The deep-dives surfaced several places where acdream's plugin API
needs to expose state (R6 item, R1 spell, R11 allegiance, R10 quest).
These are all pure data + event streams, no 3D rendering hooks. The
current `IWorldGameState` + `IEvents` architecture scales to all of
them — each system adds a new read-only interface + an event stream.

Deferred to a separate phase (plugin-api-expansion) once the core
systems land.
