Captures Phase M (Network Stack Conformance) as a fully-formed phase
ready to be picked up later. Three deliverables:
1. Design spec at docs/superpowers/specs/2026-05-10-phase-m-network-stack-design.md
(~700 lines, 8 sections):
- Bar C completeness target ("wireable on demand"): every wire opcode
a 2013 EoR retail client receives or sends gets a parser/builder +
golden-vector test + typed event in the new layered stack.
- Three-layer architecture: INetTransport / IReliableSession /
IGameProtocol, with WorldSession as a thin behavior consumer.
Concrete C# interface signatures, sub-component decomposition.
- Worktree-branch big-bang migration on claude/phase-m-network-stack;
weekly rebase cadence; single --no-ff merge ships the phase.
- Per-sub-phase entry/exit gates, conformance test plan (golden vectors
+ live capture replay + live ACE smoke), 10-row risk register, scope-
cut order if calendar compresses.
- Cost: 256 hours / ~6.4 weeks single-developer; 4-6 weeks calendar
with subagent parallelization on M.1 + M.6.
2. Opcode coverage matrix at docs/research/2026-05-10-phase-m-opcode-matrix.md
(~284 rows across 5 sections):
- Section 1: 22 transport flags (14 implemented).
- Section 2: 12 optional-header fields (10 partial).
- Section 3: 51 top-level GameMessages (21 implemented).
- Section 4: 103 GameEvent sub-opcodes inside 0xF7B0 (27 parsed,
26 wired).
- Section 5: 96 GameAction sub-opcodes inside 0xF7B1 (24 built,
8 with live callers).
- Roll-up: ~34% complete by raw opcode count. Biggest single
unblocking step is wiring the 16 dead builders in section 5
(Phase B.4 surface — Use / UseWithTarget / Allegiance / Inventory
/ Social / Cast / Appraise).
- Sources cited per row: holtburger (629695a), ACE, named retail
decomp, acdream current state.
- Produced by 4 parallel research agents (one per class). Spot-check
pass owed before M.1 closes.
3. Roadmap update: Phase M section trimmed to summary + status + pointer
to the spec; the previously-tracked M.0 Tier 1 quick-wins are folded
into M.3 / M.4 / M.6 per the spec; M.1 retained as the matrix
construction sub-lane with status note.
Why this shape: the user goal is a complete, layered, testable network
stack that can be wired in as gameplay phases need it — independent of
whether each opcode is yet hooked to game state. The matrix is the
source of truth for "done"; the spec is the architecture the matrix
implements against; the roadmap is the index that points at both.
Decisions captured during the design discussion (in case they need
revisiting):
- Bar C ("wireable on demand") chosen over Bar A (holtburger parity)
or Bar B (named-retail completeness).
- Three layers (INetTransport / IReliableSession / IGameProtocol)
chosen over holtburger's two-layer split.
- Big-bang on a feature branch (worktree) chosen over strangler
pattern; preserves live-ACE testing on main throughout the phase.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
60 KiB
Phase M — Network Opcode Coverage Matrix
Date: 2026-05-10
Status: Initial population complete (4 parallel research agents). Spot-check pass + intentional-divergence ratification owed before M.1 closes.
Companion spec: docs/superpowers/specs/2026-05-10-phase-m-network-stack-design.md
Companion study: docs/research/2026-05-10-holtburger-network-stack-study.md
This matrix is the source of truth for Phase M completeness. Every row defines: what the opcode is, who currently sends/receives it across our three reference sources, what acdream does today, and what Phase M must do. The spec's M.6 work plan reduces to "for every row where acdream today ≠ Phase M target, implement the delta and add tests."
Roll-up
| Section | In-scope | Acdream today | Phase M delta |
|---|---|---|---|
| 1 — Transport flags | 22 | 14 parse / 5 build | 8 |
| 2 — Optional-header fields | 12 | 10 partial | builder + decoder gaps |
| 3 — GameMessage opcodes (top-level) | 51 | 21 implemented | 30 |
| 4 — GameEvent sub-opcodes (inside 0xF7B0) | 103 | 27 parsed / 26 wired | 76 new (~50 deferable to gameplay phases) |
| 5 — GameAction sub-opcodes (inside 0xF7B1) | 96 | 24 built / 8 live callers | 72 new + 16 dead-builder wirings |
| Total | ~284 | ~96 | ~190 |
Roughly 34% complete by raw opcode count. The biggest single Phase-M unblocking step is wiring the 16 dead builders in section 5 (Phase B.4 surface — Use / UseWithTarget / Allegiance / Inventory / Social / Cast / Appraise / etc.).
Cell-value vocabulary
| Code | Meaning |
|---|---|
P |
Parses inbound |
B |
Builds outbound |
PB |
Parses + builds (both directions) |
W |
Wired — typed handler exists AND state is updated by it |
H |
(ACE only) Server has a handler that processes this client-sent opcode |
– |
Not implemented |
N/A |
Not applicable for this side (e.g., server-only message in ACE column) |
? |
Could not determine — needs verification |
Phase M target column:
| Target | Meaning |
|---|---|
PB+W |
Must parse, build (if outbound), wire to typed event by phase end |
PB |
Must parse + build, no wiring required |
P+W |
Inbound only, must parse + dispatch typed event |
B+W |
Outbound only, must build + have a live caller |
B |
Build only, no live caller required (typed for future use) |
–defer:<phase> |
Explicitly deferred to a named gameplay phase |
–skip:<reason> |
Out of scope, with justification |
Section 1 — Transport flags
In-scope: 22. Implemented in acdream: 14 (parse path + 5 build path). Phase M target delta: 8 (4 inbound parse gaps to wire, 4 outbound builders, plus 6 to retire/skip-justify).
| Code | Direction | Name | Named-retail symbol | Holtburger | ACE | acdream today | Phase M target | Notes |
|---|---|---|---|---|---|---|---|---|
0x00000000 |
N/A | None | – | N/A | N/A | N/A | N/A | Identity flag value 1 |
0x00000001 |
both | Retransmission | – | P (set on retx) | PB+W | – | PB+W | We never echo/honor this bit 2 |
0x00000002 |
both | EncryptedChecksum | FlowQueue::EncryptChecksum |
PB | PB+W | PB+W | PB+W | Codec covers in/out + ISAAC |
0x00000004 |
both | BlobFragments | MessageFragment group |
PB+W | PB+W | PB+W | PB+W | Fragment list parsed/built |
0x00000100 |
inbound | ServerSwitch | ClientNet::HandleServerSwitch |
P (size-skip) | PB | P (size-skip) | P+W | Handler missing; just consumes 8 bytes |
0x00000200 |
inbound | LogonServerAddr | – | – | – | – | –defer:M2 | Login-server bounce; no client logic yet 3 |
0x00000400 |
inbound | EmptyHeader1 | CEmptyHeader<0x400,2> |
– | – | – | –skip:dead-flag | Retail struct exists, never sent |
0x00000800 |
inbound | Referral | ClientNet::HandleReferral |
– | B only (server) | – | –defer:M2 | Server-only path until login bounce |
0x00001000 |
both | RequestRetransmit | FlowQueue::TransmitNaks |
PB+W | PB+W | P (size-skip) | PB+W | NAK list parsed but ignored 4 |
0x00002000 |
both | RejectRetransmit | FlowQueue::EnqueueEmptyAck |
P+W | PB | P (size-skip) | P+W | Inbound only (server tells us "no") |
0x00004000 |
both | AckSequence | FlowQueue::EnqueueAcks |
PB+W | PB+W | PB+W | PB+W | Per-packet ack pump shipped |
0x00008000 |
both | Disconnect | Client::Disconnect |
– | P+W | B only | P+W | Inbound parse-and-tear-down missing 5 |
0x00010000 |
outbound | LoginRequest | ClientNet::SendLoginRequest |
B | P+W | B | B | Auth-only, parsed by server 6 |
0x00020000 |
inbound | WorldLoginRequest | CEmptyHeader<0x20000,1> |
– | P (8 bytes) | P (size-skip) | P (size-skip) | Server-only on relay 7 |
0x00040000 |
inbound | ConnectRequest | ClientNet::HandleConnectionRequest |
P+W | B | P+W | P+W | Handshake oracle, ISAAC seeded |
0x00080000 |
outbound | ConnectResponse | ClientNet::SendConnectAck |
B | P+W | B | B | 8-byte cookie echo |
0x00100000 |
inbound | NetError | NetError::UnPack |
– | – | – | P+W | Drop session + surface error to UI |
0x00200000 |
inbound | NetErrorDisconnect | NetError::UnPack |
– | P+W | – | P+W | Same parse, hard-disconnect variant |
0x00400000 |
inbound | CICMDCommand | – | P (size-skip) | P+W | P (size-skip) | –defer:M3 | Server-debug only; not honored by retail clients |
0x01000000 |
inbound | TimeSync | ClientNet::HandleTimeSynch |
P+W | P+W | P+W | P+W | Drives WorldTimeService |
0x02000000 |
inbound | EchoRequest | CEchoRequestHeader::CreateFromData |
P+W (mirrors out) | P+W | P (no reply) | PB+W | Must build EchoResponse mirror 8 |
0x04000000 |
outbound | EchoResponse | – | B | B | – | B | Reply path for incoming EchoRequest |
0x08000000 |
both | Flow | FlowQueue::TransmitNewPackets |
P (size-skip) | P+W | P (size-skip) | –defer:M2 | Throttle hint; safe to ignore until M2 |
Footnotes:
Section 2 — Optional-header fields
In-scope: 12. Implemented in acdream: 12 of 12 sized-skip; 6 of 12 surface decoded fields. Phase M target delta: needs (a) builders for the ones we only parse, (b) ConnectRequest + EchoRequest builder paths for symmetric tests, (c) golden-vector test file.
| Code | Direction | Name | Named-retail symbol | Holtburger | ACE | acdream today | Phase M target | Notes |
|---|---|---|---|---|---|---|---|---|
0x100 |
inbound | ServerSwitch (8 bytes) | UCServerSwitchStruct |
P (skip) | PB | P (skip) | P (decode)+W | Decode serverIp:u32, port:u16, pad:u16 9 |
0x1000 |
inbound | RequestRetransmit (4+N*4) | FlowQueue::TransmitNaks |
PB | PB | P (parsed list) | PB+W | List stored; build path missing |
0x2000 |
inbound | RejectRetransmit (4+N*4) | FlowQueue::CompileEmptyAcks |
P | PB | P (size-skip) | P (decode)+W | List currently consumed without storage |
0x4000 |
both | AckSequence (4 bytes) | FlowQueue::EnqueueAcks |
PB | PB | PB | PB | Stored as AckSequence:u32 |
0x10000 |
outbound | LoginRequest (rest of pkt) | ClientNet::SendLoginRequest |
B | P (full) | B (via LoginRequest.Build) |
B | Variable-length tail; raw bytes hashed |
0x20000 |
inbound | WorldLoginRequest (8 bytes) | CEmptyHeader<0x20000,1> |
– | P (8B peek) | P (size-skip) | P (decode)+W | Decode purpose unknown, store raw |
0x40000 |
inbound | ConnectRequest (32 bytes) | CConnectHeader |
P+W | B (server) | P+W | PB | We need encode path for round-trip tests |
0x80000 |
outbound | ConnectResponse (8 bytes) | – | B | P (8B peek) | B | PB | Decode on inbound test fixtures |
0x400000 |
inbound | CICMDCommand (8 bytes) | – | P (skip) | P (8B) | P (size-skip) | –defer:M3 | Decode + handler deferred |
0x1000000 |
inbound | TimeSync (8 bytes) | CTimeSyncHeader |
P+W | P+W | P+W | PB | Add build for symmetry; double LE |
0x2000000 |
inbound | EchoRequest (4 bytes) | CEchoRequestHeader |
P+W | P+W | P (no reply) | PB+W | Wire to SendEchoResponse builder |
0x8000000 |
both | Flow (6 bytes) | UCFlowStruct |
P (skip) | P+W | P (decode) | –defer:M2 | FlowBytes:u32, FlowInterval:u16 decoded |
Footnotes:
Cross-cutting Phase M deliverables for sections 1+2:
- Goldens fixture file —
tests/AcDream.Core.Net.Tests/Packets/PacketHeaderOptionalTests.csdoes not exist; only indirect coverage viaPacketCodecTestsandConnectRequestTests. M needs one fixture per non-skip flag covering parse + build symmetry. - Typed events — currently the only
WorldSession-side flag-driven event isServerTimeUpdated(fromTimeSync). Phase M target adds:ServerSwitchRequested(ip, port),ServerDisconnect(reason),ServerNetError(NetErrorCode, message),EchoRequested(clientTime)(internal),RetransmitRequested(seqs),RetransmitRejected(seqs). PacketHeaderOptionalstorage gaps —RejectRetransmitlist is consumed but discarded;WorldLoginRequest8-byte body is skipped;CICMDCommand8-byte body is skipped;ConnectResponse8-byte cookie is decoded only insideConnect()'s send path, not on inbound parse. M target: lift each into a typed property onPacketHeaderOptional.- Builder-side parity —
PacketHeaderOptional.Parseexists; there is noPacketHeaderOptional.Build— every outbound flag's body bytes are hand-rolled at the call site (SendAck,Connect,Dispose). Phase M should add a singleBuild(PacketHeaderFlags, body fields)to mirror parse.
Section 3 — GameMessage opcodes (top-level)
In-scope: 51. Implemented in acdream: 21. Phase M target delta: 30.
| Code | Direction | Name | Named-retail symbol | Holtburger | ACE | acdream today | Phase M target | Notes |
|---|---|---|---|---|---|---|---|---|
| 0x0000 | both | None | – | PB | N/A | – | –skip:heartbeat-only | Internal/heartbeat sentinel |
| 0x0024 | inbound | InventoryRemoveObject | – | P | B | – | P+W | Out of bubble or destroyed |
| 0x0197 | inbound | SetStackSize | – | P | B | – | P+W | Container stack size delta |
| 0x019E | inbound | PlayerKilled | – | PB | B | P+W | P+W | victim+killer broadcast |
| 0x01E0 | inbound | EmoteText | CM_Communication::DispatchUI_HearEmote |
PB | B | P+W | P+W | Server-driven 3rd-person emote |
| 0x01E2 | inbound | SoulEmote | CM_Communication::DispatchUI_HearSoulEmote |
PB | B | P+W | P+W | Complex emote w/ animation |
| 0x02BB | inbound | HearSpeech | ClientCommunicationSystem::Handle_Communication__HearSpeech |
PB | B | P+W | P+W | Local chat |
| 0x02BC | inbound | HearRangedSpeech | ClientCommunicationSystem::Handle_Communication__HearRangedSpeech |
PB | B | P+W | P+W | Shouts; same parser as 0x02BB |
| 0x02CD | inbound | PrivateUpdatePropertyInt | ClientObjMaintSystem::Handle_Qualities__PrivateUpdateInt |
PB | B | – | P+W | Owner-only int property |
| 0x02CE | inbound | PublicUpdatePropertyInt | – | PB | B | – | P+W | Broadcast int property |
| 0x02CF | inbound | PrivateUpdatePropertyInt64 | – | PB | B | – | P+W | Owner-only int64 |
| 0x02D0 | inbound | PublicUpdatePropertyInt64 | – | PB | B | – | P+W | Broadcast int64 |
| 0x02D1 | inbound | PrivateUpdatePropertyBool | ClientObjMaintSystem::Handle_Qualities__PrivateUpdateBool |
PB | B | – | P+W | Owner-only bool |
| 0x02D2 | inbound | PublicUpdatePropertyBool | – | PB | B | – | P+W | Broadcast bool |
| 0x02D3 | inbound | PrivateUpdatePropertyFloat | ClientObjMaintSystem::Handle_Qualities__PrivateUpdateFloat |
PB | B | – | P+W | Owner-only float |
| 0x02D4 | inbound | PublicUpdatePropertyFloat | – | PB | B | – | P+W | Broadcast float |
| 0x02D5 | inbound | PrivateUpdatePropertyString | – | PB | B | – | P+W | Owner-only string |
| 0x02D6 | inbound | PublicUpdatePropertyString | – | PB | B | – | P+W | Broadcast string |
| 0x02D7 | inbound | PrivateUpdatePropertyDataID | – | PB | B | – | P+W | Owner-only DataID |
| 0x02D8 | inbound | PublicUpdatePropertyDataID | – | PB | B | – | P+W | Broadcast DataID |
| 0x02D9 | inbound | PrivateUpdatePropertyInstanceID | CM_Qualities::DispatchUI_PrivateUpdateInstanceID |
PB | B | – | P+W | Owner-only InstanceID |
| 0x02DA | inbound | PublicUpdateInstanceID | – | PB | B | – | P+W | Broadcast InstanceID |
| 0x02DB | inbound | PrivateUpdatePosition | CM_Qualities::DispatchUI_PrivateUpdatePosition |
PB | B | – | –defer:F.x | Owner-only position; redundant with 0xF748 |
| 0x02DC | inbound | PublicUpdatePosition | – | PB | B | – | –defer:F.x | Public position; redundant with 0xF748 |
| 0x02DD | inbound | PrivateUpdateSkill | – | PB | B | – | P+W | Owner-only skill XP |
| 0x02DE | inbound | PublicUpdateSkill | – | PB | B | – | P+W | Public skill |
| 0x02DF | inbound | PrivateUpdateSkillLevel | – | PB | B | – | P+W | Owner-only skill base level |
| 0x02E0 | inbound | PublicUpdateSkillLevel | – | PB | B | – | P+W | Public skill base level |
| 0x02E3 | inbound | PrivateUpdateAttribute | ClientObjMaintSystem::Handle_Qualities__PrivateUpdateAttribute |
PB | B | – | P+W | Strength/Stamina/etc base |
| 0x02E4 | inbound | PublicUpdateAttribute | – | PB | B | – | P+W | Public attribute |
| 0x02E7 | inbound | PrivateUpdateVital | – | PB | B | P+W | P+W | Max HP/Stam/Mana — vitals panel |
| 0x02E8 | inbound | PublicUpdateVital | – | PB | B | – | P+W | Public vital |
| 0x02E9 | inbound | PrivateUpdateAttribute2ndLevel | ClientObjMaintSystem::Handle_Qualities__PrivateUpdateAttribute2ndLevel |
PB 10 | B | P+W | P+W | Current-only vital delta |
| 0xEA60 | inbound | AdminEnvirons | CPlayerSystem::Handle_Admin__Environs |
– | B | P+W | P+W | Fog presets / sound cues |
| 0xF625 | inbound | ObjDescEvent | SmartBox::HandleObjDescEvent |
PB | B | P+W | P+W | Per-entity appearance update |
| 0xF643 | inbound | CharacterCreateResponse | – | PB | B | – | –defer:char-creation | Char-creation flow not yet built |
| 0xF653 | outbound | CharacterLogOff | – | PB | P | B | PB+W | Sent on Dispose; ACE accepts |
| 0xF655 | both | CharacterDelete | – | PB | P | – | –defer:char-mgmt | Char-management UI deferred |
| 0xF656 | outbound | CharacterCreate | – | PB | P | – | –defer:char-creation | Char-creation flow not yet built |
| 0xF657 | outbound | CharacterEnterWorld | CM_Login::SendNotice_BeginEnterWorld 11 |
PB | P | B | PB+W | Built; sent during handshake |
| 0xF658 | inbound | CharacterList | CPlayerSystem::Handle_Login__CharacterSet |
PB | B | P+W | P+W | Login char picker |
| 0xF659 | inbound | CharacterError | CPlayerSystem::Handle_CharacterError |
PB | B | – | P+W | Login/restore failures |
| 0xF6EA | both | ForceObjectDescSend | – | PB | P | – | –defer:F.x | Server requests client re-send ObjDesc; rare |
| 0xF745 | inbound | CreateObject (ObjectCreate) | SmartBox::HandleCreateObject |
PB | B | P+W | P+W | Spawn entity in bubble |
| 0xF746 | inbound | PlayerCreate | SmartBox::HandleCreatePlayer |
PB | B | P+W 12 | P+W | Triggers LoginComplete |
| 0xF747 | inbound | DeleteObject (ObjectDelete) | SmartBox::HandleDeleteObject |
PB | B | P+W | P+W | Despawn |
| 0xF748 | inbound | UpdatePosition | CM_Qualities::DispatchUI_UpdatePosition |
PB | B | P+W | P+W | Periodic position sync |
| 0xF749 | inbound | ParentEvent | SmartBox::HandleParentEvent |
PB | B | – | P+W | Equip/wield parent change |
| 0xF74A | inbound | PickupEvent | SmartBox::HandlePickupEvent |
PB | B | – | P+W | Pickup confirmation |
| 0xF74B | inbound | SetState | SmartBox::HandleSetState |
PB | B | – | P+W | Door open/close, container state |
| 0xF74C | inbound | UpdateMotion (Motion) | – | PB | B | P+W | P+W | Animation cycle change |
| 0xF74E | inbound | VectorUpdate | SmartBox::HandleVectorUpdate |
PB | B | P+W | P+W | Remote jump velocity, missile arc |
| 0xF750 | inbound | Sound | SmartBox::HandleSoundEvent |
PB | B | – | P+W | Positional sound trigger |
| 0xF751 | inbound | PlayerTeleport | SmartBox::HandlePlayerTeleport |
PB | B | P+W | P+W | Portal/teleport screen |
| 0xF752 | inbound | AutonomyLevel | CommandInterpreter::SetAutonomyLevel |
P 13 | – | – | P+W | Server tells client physics-trust level |
| 0xF753 | both | AutonomousPosition | CM_Movement::Event_AutonomousPosition |
PB | – | B | PB+W | Outbound built; inbound parser missing |
| 0xF754 | inbound | PlayScript (PlayScriptId) | SmartBox::HandlePlayScriptID |
– | – | P+W 14 | P+W | Inline parser; lightning, spell FX, emotes |
| 0xF755 | inbound | PlayEffect | – | PB | B | – | P+W | Particle/visual scripts; ACE uses for PlayScript wrapper |
| 0xF7B0 | inbound | GameEvent (envelope) | – | PB | B | P+W | P+W | Envelope for sub-opcodes (see §4) |
| 0xF7B1 | outbound | GameAction (envelope) | – | PB | P | B+W | PB+W | Envelope for sub-opcodes (see §5) |
| 0xF7C1 | inbound | AccountBanned | – | – | B | – | –defer:F.x | ACE-only, rarely seen |
| 0xF7C8 | outbound | CharacterEnterWorldRequest | – | PB | P | B | PB+W | Built; sent before 0xF657 |
| 0xF7CC | both | GetServerVersion | Proto_UI::SendAdminGetServerVersion |
– | P | – | –defer:F.x | Admin-only |
| 0xF7CD | both | FriendsOld | – | – | P | – | –defer:F.x | Obsolete; ACE drops it |
| 0xF7D9 | outbound | CharacterRestore | – | PB | P | – | –defer:char-mgmt | Char-management UI deferred |
| 0xF7DB | inbound | UpdateObject | SmartBox::HandleUpdateObject |
PB | B | – | P+W | Heavy re-send of object visual+physics |
| 0xF7DC | inbound | AccountBoot | CPlayerSystem::Handle_AccountBooted |
PB | B | – | P+W | Kicked from server |
| 0xF7DE | both | TurbineChat | CCommunicationSystem::IsUsingTurbineChat |
PB | PB 15 | PB+W | PB+W | Global community chat |
| 0xF7DF | inbound | CharacterEnterWorldServerReady | – | P 16 | B | P+W 17 | P+W | Handshake gate during enter-world |
| 0xF7E0 | inbound | ServerMessage | – | PB | B | P+W | P+W | System message / announcements |
| 0xF7E1 | inbound | ServerName | ECM_Login::SendNotice_WorldName |
PB | B | – | P+W | Shard name during login |
| 0xF7E2 | both | DDD_DataMessage | – | – | – | – | –defer:dat-streaming | DDD download channel (we ship dats locally) |
| 0xF7E3 | both | DDD_RequestDataMessage | – | – | P | – | –defer:dat-streaming | Client requests dat data |
| 0xF7E4 | both | DDD_ErrorMessage | – | – | – | – | –defer:dat-streaming | DDD error channel |
| 0xF7E5 | inbound | DDD_Interrogation | DDD_InterrogationMessage::Serialize |
PB 18 | B | P+W | P+W | Server asks "what dat versions?" |
| 0xF7E6 | outbound | DDD_InterrogationResponse | – | PB | P | B | PB+W | Built; sent in response to 0xF7E5 |
| 0xF7E7 | both | DDD_BeginDDD | – | – | – | – | –defer:dat-streaming | DDD start |
| 0xF7E8 | both | DDD_BeginPullDDD | – | – | – | – | –defer:dat-streaming | DDD pull start |
| 0xF7E9 | both | DDD_IterationData | – | – | – | – | –defer:dat-streaming | DDD chunk iteration |
| 0xF7EA | inbound | DDD_EndDDD | – | – | P | – | –defer:dat-streaming | DDD end signal |
Footnotes:
Caveats and unknowns:
0xF7C1 AccountBannedis in ACE's enum + has aGameMessageAccountBanned.cs, but holtburger has it commented out. Marked–defersince the channel exists in retail but rarely fires.0xF7CC GetServerVersion,0xF7CD FriendsOld: ACE has handlers for them (i.e. accepts them inbound from a client that sends them), but no acdream sends them today. Listed as–defer.0xF619 PositionAndMovement: holtburger documents this as a "ghost" opcode (defined but never emitted by ACE/retail). Excluded from the table — confirmed dead code per holtburger comment + grep on ACE shows noWriter.Writesite.0xF754 PlayScriptIdvs0xF755 PlayEffect: ACE has theScript.csGameMessage tagged withPlayEffect (0xF755), while retail'sSmartBox::HandlePlayScriptIDis the 0xF754 handler. acdream's inline parser atWorldSession.cs:850reads[u32 opcode][u32 guid][u32 scriptId]matching the 0xF754 layout.
Section 4 — GameEvent sub-opcodes (inside 0xF7B0 envelope)
In-scope: 103. Implemented (parsed) in acdream today: 27. Wired (W) in acdream today: 26. Phase M target delta: 76 new parsers + ~50 deferred to later phases.
All rows are inbound direction (GameEvents are server→client only).
| Code | Direction | Name | Named-retail symbol | Holtburger | ACE | acdream today | Phase M target | Notes |
|---|---|---|---|---|---|---|---|---|
| 0x0003 | inbound | AllegianceUpdateAborted | ClientAllegianceSystem::Handle_Allegiance__AllegianceUpdateAborted |
– | W | – | –defer:Allegiance | scope deferred — no allegiance UI yet |
| 0x0004 | inbound | PopupString | ClientCommunicationSystem::Handle_Communication__PopUpString |
W | W | W | W | modal text → ChatLog.OnPopup |
| 0x0013 | inbound | PlayerDescription | CPlayerSystem::Handle_PlayerDescription |
W | W | W | W | full local-player snapshot at login 19 |
| 0x0020 | inbound | AllegianceUpdate | ClientAllegianceSystem::Handle_Allegiance__AllegianceUpdate |
– | W | – | –defer:Allegiance | needs CAllegianceProfile parser |
| 0x0021 | inbound | FriendsListUpdate | CM_Social::SendNotice_UpdateFriendsList |
– | W | – | P+W | FriendDataList; small parser, high UX value |
| 0x0022 | inbound | InventoryPutObjInContainer | – (CM_Inventory) | W | W | W | W | (item, container, slot) — items.MoveItem |
| 0x0023 | inbound | WieldObject | – (CM_Inventory) | W | W | W | W | server-driven equip |
| 0x0029 | inbound | CharacterTitle | CM_Social::SendNotice_AddCharacterTitle |
– | W | – | –defer:Social | gmCharacterTitleUI |
| 0x002B | inbound | UpdateTitle | CM_Social::SendNotice_SetDisplayCharacterTitle |
– | W | – | –defer:Social | titles UI not yet built |
| 0x0052 | inbound | CloseGroundContainer | – (gmInventoryUI) | W | W | P | P+W | parser exists, needs ItemRepository wiring |
| 0x0062 | inbound | ApproachVendor | – (CM_Vendor) | W | W | – | –defer:VendorPanel | needs VendorProfile + ItemProfile list parser |
| 0x0075 | inbound | StartBarber | ClientUISystem::Handle_Character__StartBarber |
– | W | – | –defer:Barber | gmBarberUI not yet built |
| 0x00A0 | inbound | InventoryServerSaveFailed | – (CM_Inventory) | W | W | P | P+W | parser exists; needs revert hook |
| 0x00A3 | inbound | FellowshipQuit | ClientFellowshipSystem::Handle_Fellowship__Quit |
W | W | – | –defer:Fellowship | scope deferred — no fellowship state |
| 0x00A4 | inbound | FellowshipDismiss | ClientFellowshipSystem::Handle_Fellowship__Dismiss |
W | W | – | –defer:Fellowship | scope deferred |
| 0x00B4 | inbound | BookDataResponse | CM_Writing::Event_BookData |
W | W | – | –defer:Books | gmBookUI not yet built |
| 0x00B5 | inbound | BookModifyPageResponse | CM_Writing::Event_BookModifyPage |
– | W | – | –defer:Books | |
| 0x00B6 | inbound | BookAddPageResponse | CM_Writing::SendNotice_BookAddPageResponse |
– | W | – | –defer:Books | |
| 0x00B7 | inbound | BookDeletePageResponse | CM_Writing::SendNotice_BookDeletePageResponse |
– | W | – | –defer:Books | |
| 0x00B8 | inbound | BookPageDataResponse | CM_Writing::SendNotice_BookPageDataResponse |
W | W | – | –defer:Books | |
| 0x00C3 | inbound | GetInscriptionResponse | – | – | W | – | –defer:Books | inscription on caster items |
| 0x00C9 | inbound | IdentifyObjectResponse | ClientUISystem::Handle_Item__AppraiseDone 20 |
W | W | W | W | AppraiseInfoParser feeds ItemRepository |
| 0x0147 | inbound | ChannelBroadcast | ClientCommunicationSystem::Handle_Communication__ChannelBroadcast |
W | W | W | W | (channelId, sender, msg) → ChatLog |
| 0x0148 | inbound | ChannelList | ClientCommunicationSystem::Handle_Communication__ChannelList |
– | W | – | P+W | PackableList; admin/list response |
| 0x0149 | inbound | ChannelIndex | ClientCommunicationSystem::Handle_Communication__ChannelIndex |
– | W | – | P+W | PackableList |
| 0x0196 | inbound | ViewContents | ClientUISystem::OnViewContents |
W | W | – | P+W | server view of remote container — needed for sidepacks |
| 0x019A | inbound | InventoryPutObjectIn3D | – (CM_Inventory) | W | W | P | P+W | parser exists; needs spawn-into-world wiring |
| 0x01A7 | inbound | AttackDone | – | W | W | W | W | combat seq complete |
| 0x01A8 | inbound | MagicRemoveSpell | ClientMagicSystem::Handle_Magic__RemoveSpell |
W | W | W | W | spell removed from spellbook |
| 0x01AC | inbound | VictimNotification | ClientCombatSystem::HandleVictimNotificationEvent |
W | W | W | W | death msg for victim |
| 0x01AD | inbound | KillerNotification | ClientCombatSystem::HandleKillerNotificationEvent |
W | W | W | W | death msg for killer |
| 0x01B1 | inbound | AttackerNotification | ClientCombatSystem::HandleAttackerNotificationEvent |
W | W | W | W | "you hit X" |
| 0x01B2 | inbound | DefenderNotification | ClientCombatSystem::HandleDefenderNotificationEvent |
W | W | W | W | "X hit you" |
| 0x01B3 | inbound | EvasionAttackerNotification | ClientCombatSystem::HandleEvasionAttackerNotificationEvent |
W | W | W | W | "X evaded" |
| 0x01B4 | inbound | EvasionDefenderNotification | ClientCombatSystem::HandleEvasionDefenderNotificationEvent |
W | W | W | W | "you evaded X" |
| 0x01B8 | inbound | CombatCommenceAttack | – | W | W | W | W | empty payload |
| 0x01C0 | inbound | UpdateHealth | CM_Combat::SendNotice_UpdateObjectHealth |
W | W | W | W | (guid, healthPct) → CombatState |
| 0x01C3 | inbound | QueryAgeResponse | ClientCommunicationSystem::Handle_Character__QueryAgeResponse |
– | W | – | P | small string parser; chat panel display |
| 0x01C7 | inbound | UseDone | ClientUISystem::Handle_Item__UseDone |
W | W | P | P+W | parser exists; needs InteractionState wiring |
| 0x01C8 | inbound | AllegianceUpdateDone | – | – | W | – | –defer:Allegiance | |
| 0x01C9 | inbound | FellowshipFellowUpdateDone | ClientFellowshipSystem::Handle_Fellowship__FellowUpdateDone |
W | W | – | –defer:Fellowship | empty payload |
| 0x01CA | inbound | FellowshipFellowStatsDone | ClientFellowshipSystem::Handle_Fellowship__FellowStatsDone |
W | W | – | –defer:Fellowship | empty payload |
| 0x01CB | inbound | ItemAppraiseDone | ClientUISystem::Handle_Item__AppraiseDone |
– | W | – | P | post-IdentifyObjectResponse signal |
| 0x01E2 | inbound | Emote | ClientCommunicationSystem::Handle_Communication__HearEmote 21 |
– | W | – | P | "X waves" — chat broadcast |
| 0x01EA | inbound | PingResponse | ClientUISystem::Handle_Character__ReturnPing |
W | W | P | P+W | parser exists; needs latency/heartbeat wiring |
| 0x01F4 | inbound | SetSquelchDB | ClientCommunicationSystem::Handle_Communication__SetSquelchDB |
– | W | – | –defer:SquelchUI | SquelchDB blob; ignore-list state |
| 0x01FD | inbound | RegisterTrade | ClientTradeSystem::Handle_Trade__Recv_RegisterTrade |
W | W | – | –defer:TradePanel | (guid, accepterGuid, ackTimer) |
| 0x01FE | inbound | OpenTrade | ClientTradeSystem::Handle_Trade__Recv_OpenTrade |
W | W | – | –defer:TradePanel | initiator guid |
| 0x01FF | inbound | CloseTrade | ClientTradeSystem::Handle_Trade__Recv_CloseTrade |
W | W | – | –defer:TradePanel | closer guid |
| 0x0200 | inbound | AddToTrade | ClientTradeSystem::Handle_Trade__Recv_AddToTrade |
W | W | P | –defer:TradePanel | parser exists; needs TradeState |
| 0x0201 | inbound | RemoveFromTrade | ClientTradeSystem::Handle_Trade__Recv_RemoveFromTrade |
– | W | – | –defer:TradePanel | (initiatorGuid, itemGuid) |
| 0x0202 | inbound | AcceptTrade | ClientTradeSystem::Handle_Trade__Recv_AcceptTrade |
W | W | P | –defer:TradePanel | parser exists |
| 0x0203 | inbound | DeclineTrade | ClientTradeSystem::Handle_Trade__Recv_DeclineTrade |
W | W | – | –defer:TradePanel | initiator guid |
| 0x0205 | inbound | ResetTrade | ClientTradeSystem::Handle_Trade__Recv_ResetTrade |
W | W | – | –defer:TradePanel | reset to-trade list |
| 0x0207 | inbound | TradeFailure | ClientTradeSystem::Handle_Trade__Recv_TradeFailure |
W | W | P | –defer:TradePanel | parser exists |
| 0x0208 | inbound | ClearTradeAcceptance | ClientTradeSystem::Handle_Trade__Recv_ClearTradeAcceptance |
W | W | – | –defer:TradePanel | empty payload |
| 0x021D | inbound | HouseProfile | ClientHousingSystem::Handle_House__Recv_HouseProfile |
– | W | – | –defer:Housing | HouseProfile blob |
| 0x0225 | inbound | HouseData | ClientHousingSystem::Handle_House__Recv_HouseData |
– | W | – | –defer:Housing | HouseData blob |
| 0x0226 | inbound | HouseStatus | ClientHousingSystem::Handle_House__Recv_HouseStatus |
– | W | – | –defer:Housing | scalar status code |
| 0x0227 | inbound | UpdateRentTime | ClientHousingSystem::Handle_House__Recv_UpdateRentTime |
– | W | – | –defer:Housing | i32 timestamp |
| 0x0228 | inbound | UpdateRentPayment | ClientHousingSystem::Handle_House__Recv_UpdateRentPayment |
– | W | – | –defer:Housing | HousePaymentList |
| 0x0248 | inbound | HouseUpdateRestrictions | ClientHousingSystem::Handle_House__Recv_UpdateRestrictions |
– | W | – | –defer:Housing | RestrictionDB blob |
| 0x0257 | inbound | UpdateHAR | ClientHousingSystem::Handle_House__Recv_UpdateHAR |
– | W | – | –defer:Housing | HAR blob |
| 0x0259 | inbound | HouseTransaction | ClientHousingSystem::Handle_House__Recv_HouseTransaction |
– | W | – | –defer:Housing | scalar txn code |
| 0x0264 | inbound | QueryItemManaResponse | ClientUISystem::Handle_Item__QueryItemManaResponse |
W | W | P | P+W | parser exists; needs ItemRepository wiring |
| 0x0271 | inbound | AvailableHouses | ClientHousingSystem::Handle_House__Recv_AvailableHouses |
– | W | – | –defer:Housing | PackableList + flag |
| 0x0274 | inbound | CharacterConfirmationRequest | ClientUISystem::Handle_Character__ConfirmationRequest |
W | W | P | P+W | parser exists; needs modal-confirm wiring |
| 0x0276 | inbound | CharacterConfirmationDone | ClientUISystem::Handle_Character__ConfirmationDone |
W | W | – | P+W | (type, contextId); confirms client ACK |
| 0x027A | inbound | AllegianceLoginNotification | ClientAllegianceSystem::Handle_Allegiance__AllegianceLoginNotificationEvent |
– | W | – | –defer:Allegiance | (guid, login/logout flag) |
| 0x027C | inbound | AllegianceInfoResponse | ClientAllegianceSystem::Handle_Allegiance__AllegianceInfoResponseEvent |
– | W | – | –defer:Allegiance | CAllegianceProfile |
| 0x0281 | inbound | JoinGameResponse | ClientMiniGameSystem::Handle_Game__Recv_JoinGameResponse |
– | W | – | –defer:MiniGame | chess/dice/etc — minimal value |
| 0x0282 | inbound | StartGame | ClientMiniGameSystem::Handle_Game__Recv_StartGame |
W | W | – | –defer:MiniGame | empty payload |
| 0x0283 | inbound | MoveResponse | ClientMiniGameSystem::Handle_Game__Recv_MoveResponse |
– | W | – | –defer:MiniGame | minigame move ack |
| 0x0284 | inbound | OpponentTurn | ClientMiniGameSystem::Handle_Game__Recv_OpponentTurn |
– | W | – | –defer:MiniGame | GameMoveData blob |
| 0x0285 | inbound | OpponentStalemate | ClientMiniGameSystem::Handle_Game__Recv_OppenentStalemateState |
– | W | – | –defer:MiniGame | typo preserved (retail name) |
| 0x028A | inbound | WeenieError | ClientCommunicationSystem::Handle_Communication__WeenieError |
W | W | W | W | error code → ChatLog.OnWeenieError |
| 0x028B | inbound | WeenieErrorWithString | ClientCommunicationSystem::Handle_Communication__WeenieErrorWithString |
W | W | W | W | (code, interp) → ChatLog |
| 0x028C | inbound | GameOver | ClientMiniGameSystem::Handle_Game__Recv_GameOver |
– | W | – | –defer:MiniGame | (gameId, winner) |
| 0x0295 | inbound | SetTurbineChatChannels | ClientCommunicationSystem::Handle_Communication__Recv_ChatRoomTracker 22 |
W | W | W | W | per-room ids → TurbineChatState |
| 0x02AE | inbound | AdminQueryPluginList | – (admin tooling) | – | W | – | –skip:admin-only | server-admin path; not retail-emitted to player |
| 0x02B1 | inbound | AdminQueryPlugin | – | – | W | – | –skip:admin-only | |
| 0x02B3 | inbound | AdminQueryPluginResponse | – | – | W | – | –skip:admin-only | |
| 0x02B4 | inbound | SalvageOperationsResult | ClientUISystem::Handle_Inventory__Recv_SalvageOperationsResultData |
– | W | – | –defer:SalvageUI | SalvageOperationsResultData blob |
| 0x02BD | inbound | Tell | – (CM_Communication) | W | W | W | W | direct whisper → ChatLog |
| 0x02BE | inbound | FellowshipFullUpdate | ClientFellowshipSystem::Handle_Fellowship__FullUpdate |
W | W | – | –defer:Fellowship | CFellowship blob |
| 0x02BF | inbound | FellowshipDisband | ClientFellowshipSystem::Handle_Fellowship__Disband |
W | W | – | –defer:Fellowship | empty payload |
| 0x02C0 | inbound | FellowshipUpdateFellow | ClientFellowshipSystem::Handle_Fellowship__UpdateFellow |
W | W | – | –defer:Fellowship | (memberGuid, Fellow, flag) |
| 0x02C1 | inbound | MagicUpdateSpell | ClientMagicSystem::Handle_Magic__UpdateSpell |
W | W | W | W | learned spellId → Spellbook |
| 0x02C2 | inbound | MagicUpdateEnchantment | ClientMagicSystem::Handle_Magic__UpdateEnchantment |
W | W | W | W | Enchantment blob → Spellbook |
| 0x02C3 | inbound | MagicRemoveEnchantment | ClientMagicSystem::Handle_Magic__RemoveEnchantment |
W | W | W | W | (layerId, spellId) |
| 0x02C4 | inbound | MagicUpdateMultipleEnchantments | ClientMagicSystem::Handle_Magic__UpdateMultipleEnchantments |
W | W | – | P+W | PackableList |
| 0x02C5 | inbound | MagicRemoveMultipleEnchantments | ClientMagicSystem::Handle_Magic__RemoveMultipleEnchantments |
W | W | – | P+W | PackableList |
| 0x02C6 | inbound | MagicPurgeEnchantments | ClientMagicSystem::Handle_Magic__PurgeEnchantments |
W | W | W | W | empty payload → Spellbook.OnPurgeAll |
| 0x02C7 | inbound | MagicDispelEnchantment | ClientMagicSystem::Handle_Magic__DispelEnchantment |
W | W | W | W | shared parser w/ MagicRemoveEnchantment |
| 0x02C8 | inbound | MagicDispelMultipleEnchantments | ClientMagicSystem::Handle_Magic__DispelMultipleEnchantments |
W | W | – | P+W | PackableList |
| 0x02C9 | inbound | PortalStormBrewing | ClientUISystem::Handle_Misc__PortalStormBrewing |
– | W | – | P+W | float intensity → ChatLog system message |
| 0x02CA | inbound | PortalStormImminent | ClientUISystem::Handle_Misc__PortalStormImminent |
– | W | – | P+W | float intensity |
| 0x02CB | inbound | PortalStorm | ClientUISystem::Handle_Misc__PortalStorm |
– | W | – | P+W | empty payload — actual storm trigger |
| 0x02CC | inbound | PortalStormSubsided | ClientUISystem::Handle_Misc__PortalStormSubsided |
– | W | – | P+W | empty payload |
| 0x02EB | inbound | CommunicationTransientString | ClientCommunicationSystem::Handle_Communication__TransientString |
W | W | W | W | (msg, chatType) → ChatLog system msg |
| 0x0312 | inbound | MagicPurgeBadEnchantments | ClientMagicSystem::Handle_Magic__PurgeBadEnchantments |
W | W | – | P+W | empty payload |
| 0x0314 | inbound | SendClientContractTrackerTable | ClientUISystem::Handle_Social__SendClientContractTrackerTable |
– | W | – | –defer:Quests | CContractTrackerTable blob |
| 0x0315 | inbound | SendClientContractTracker | ClientUISystem::Handle_Social__SendClientContractTracker |
– | W | – | –defer:Quests | (CContractTracker, flag, flag) |
Footnotes:
Section 5 — GameAction sub-opcodes (inside 0xF7B1 envelope)
In-scope: 96. Implemented (built) in acdream: 24. Live callers in acdream: 8. Phase M target delta: 72 new builders + golden-vector tests.
All rows are outbound direction (GameActions are client→server only).
| Code | Direction | Name | Named-retail symbol | Holtburger | ACE | acdream today | Phase M target | Notes |
|---|---|---|---|---|---|---|---|---|
| 0x0005 | outbound | SetSingleCharacterOption | – | W | H | – | B | Per-option toggle; sibling of 0x01A1 bitmap |
| 0x0008 | outbound | TargetedMeleeAttack | CM_Combat::Event_TargetedMeleeAttack |
W | H | W | B+W | Wired in WorldSession.SendMeleeAttack |
| 0x000A | outbound | TargetedMissileAttack | CM_Combat::Event_TargetedMissileAttack |
W | H | W | B+W | Wired in WorldSession.SendMissileAttack |
| 0x000F | outbound | SetAfkMode | CM_Communication::Event_SetAFKMode |
– | H | – | B | Toggle AFK |
| 0x0010 | outbound | SetAfkMessage | CM_Communication::Event_SetAFKMessage |
– | H | – | B | Custom AFK string |
| 0x0015 | outbound | Talk | CM_Communication::Event_Talk |
W | H | W | B+W | Wired in WorldSession.SendTalk |
| 0x0017 | outbound | RemoveFriend | CM_Social::Event_RemoveFriend |
– | H | – | B | Friends list mutation |
| 0x0018 | outbound | AddFriend | CM_Social::Event_AddFriend |
– | H | – | B | Friends list mutation |
| 0x0019 | outbound | PutItemInContainer | CM_Inventory::Event_PutItemInContainer |
W | H | – | B | Inventory move; high priority |
| 0x001A | outbound | GetAndWieldItem | CM_Inventory::Event_GetAndWieldItem |
W | H | – | B | Equip item |
| 0x001B | outbound | DropItem | CM_Inventory::Event_DropItem |
W | H | – | B | Drop to ground |
| 0x001D | outbound | SwearAllegiance | CM_Allegiance::Event_SwearAllegiance |
W | H | B | B+W | AllegianceRequests dead 23 |
| 0x001E | outbound | BreakAllegiance | CM_Allegiance::Event_BreakAllegiance |
W | H | B | B+W | AllegianceRequests dead 23 |
| 0x001F | outbound | AllegianceUpdateRequest | – | – | H | – | B | Refresh allegiance tree |
| 0x0025 | outbound | RemoveAllFriends | – | – | H | – | B | Clear friends list |
| 0x0026 | outbound | TeleToPklArena | – | W | H | – | B | PK-lite arena recall |
| 0x0027 | outbound | TeleToPkArena | – | – | H | – | B | PK arena recall |
| 0x002C | outbound | TitleSet | – | – | H | – | B | Equip title |
| 0x0030 | outbound | QueryAllegianceName | CM_Allegiance::Event_QueryAllegianceName |
– | H | – | B | – |
| 0x0031 | outbound | ClearAllegianceName | CM_Allegiance::Event_ClearAllegianceName |
– | H | – | B | Officer-only |
| 0x0032 | outbound | TalkDirect | CM_Communication::Event_TalkDirect |
– | H | – | B | Targeted /say (rarely used) |
| 0x0033 | outbound | SetAllegianceName | CM_Allegiance::Event_SetAllegianceName |
– | H | – | B | Monarch-only |
| 0x0035 | outbound | UseWithTarget | CM_Inventory::Event_UseWithTargetEvent |
W | H | B | B+W | InteractRequests dead 23 |
| 0x0036 | outbound | Use | CM_Inventory::Event_UseEvent |
W | H | B | B+W | InteractRequests dead 23 |
| 0x003B | outbound | SetAllegianceOfficer | CM_Allegiance::Event_SetAllegianceOfficer |
– | H | – | B | – |
| 0x003C | outbound | SetAllegianceOfficerTitle | CM_Allegiance::Event_SetAllegianceOfficerTitle |
– | H | – | B | – |
| 0x003D | outbound | ListAllegianceOfficerTitles | CM_Allegiance::Event_ListAllegianceOfficerTitles |
– | H | – | B | – |
| 0x003E | outbound | ClearAllegianceOfficerTitles | CM_Allegiance::Event_ClearAllegianceOfficerTitles |
– | H | – | B | – |
| 0x003F | outbound | DoAllegianceLockAction | CM_Allegiance::Event_DoAllegianceLockAction |
– | H | – | B | Lock recruitment |
| 0x0040 | outbound | SetAllegianceApprovedVassal | CM_Allegiance::Event_SetAllegianceApprovedVassal |
– | – | – | B | – |
| 0x0041 | outbound | AllegianceChatGag | CM_Allegiance::Event_AllegianceChatGag |
– | H | – | B | – |
| 0x0042 | outbound | DoAllegianceHouseAction | CM_Allegiance::Event_DoAllegianceHouseAction |
– | H | – | B | – |
| 0x0044 | outbound | RaiseVital | – | W | H | B | B+W | CharacterActions builder dead 23 |
| 0x0045 | outbound | RaiseAttribute | – | W | H | B | B+W | CharacterActions builder dead 23 |
| 0x0046 | outbound | RaiseSkill | – | W | H | B | B+W | CharacterActions builder dead 23 |
| 0x0047 | outbound | TrainSkill | CM_Train::Event_TrainSkill |
W | H | B | B+W | CharacterActions builder dead 23 |
| 0x0048 | outbound | CastUntargetedSpell | CM_Magic::Event_CastUntargetedSpell |
W | H | B | B+W | CastSpellRequest builder dead 23 |
| 0x004A | outbound | CastTargetedSpell | CM_Magic::Event_CastTargetedSpell |
W | H | B | B+W | CastSpellRequest builder dead 23 |
| 0x0053 | outbound | ChangeCombatMode | CM_Combat::Event_ChangeCombatMode |
W | H | W | B+W | Wired in WorldSession.SendChangeCombatMode |
| 0x0054 | outbound | StackableMerge | CM_Inventory::Event_StackableMerge |
W | H | B | B+W | InventoryActions builder dead 23 |
| 0x0055 | outbound | StackableSplitToContainer | CM_Inventory::Event_StackableSplitToContainer |
W | H | B | B+W | InventoryActions builder dead 23 |
| 0x0056 | outbound | StackableSplitTo3D | CM_Inventory::Event_StackableSplitTo3D |
– | H | B | B+W | InventoryActions builder dead 23 |
| 0x0058 | outbound | ModifyCharacterSquelch | CM_Communication::Event_ModifyCharacterSquelch |
– | H | – | B | Mute one player |
| 0x0059 | outbound | ModifyAccountSquelch | CM_Communication::Event_ModifyAccountSquelch |
– | H | – | B | Mute account |
| 0x005B | outbound | ModifyGlobalSquelch | CM_Communication::Event_ModifyGlobalSquelch |
– | H | – | B | Mute pattern |
| 0x005D | outbound | Tell | – | W | H | W | B+W | Wired in WorldSession.SendTell 24 |
| 0x005F | outbound | Buy | CM_Vendor::Event_Buy |
W | H | – | B | Vendor purchase |
| 0x0060 | outbound | Sell | CM_Vendor::Event_Sell |
W | H | – | B | Vendor sell |
| 0x0063 | outbound | TeleToLifestone | CM_Character::Event_TeleToLifestone |
W | H | B | B+W | InteractRequests builder dead 23 |
| 0x00A1 | outbound | LoginComplete | CM_Character::Event_LoginCompleteNotification |
W | H | W | B+W | Wired in GameWindow.cs:4423 |
| 0x00A2 | outbound | FellowshipCreate | CM_Fellowship::Event_Create |
W | H | B | B+W | SocialActions builder dead 23 |
| 0x00A3 | outbound | FellowshipQuit | CM_Fellowship::Event_Quit |
W | H | B | B+W | SocialActions builder dead 23 |
| 0x00A4 | outbound | FellowshipDismiss | CM_Fellowship::Event_Dismiss |
W | H | B | B+W | SocialActions builder dead 23 |
| 0x00A5 | outbound | FellowshipRecruit | CM_Fellowship::Event_Recruit |
W | H | B | B+W | SocialActions builder dead 23 |
| 0x00A6 | outbound | FellowshipUpdateRequest | CM_Fellowship::Event_UpdateRequest |
W | H | B | B+W | SocialActions builder dead 23 |
| 0x00AA | outbound | BookData | CM_Writing::Event_BookData |
– | H | – | B | Open book contents |
| 0x00AB | outbound | BookModifyPage | CM_Writing::Event_BookModifyPage |
– | H | – | B | Edit page text |
| 0x00AC | outbound | BookAddPage | CM_Writing::Event_BookAddPage |
– | H | – | B | – |
| 0x00AD | outbound | BookDeletePage | CM_Writing::Event_BookDeletePage |
– | H | – | B | – |
| 0x00AE | outbound | BookPageData | CM_Writing::Event_BookPageData |
W | – | – | B | Read one page |
| 0x00B1 | outbound | TeleToPoi | – | – | – | B | B | InventoryActions builder dead; ACE handler unclear 2325 |
| 0x00BF | outbound | SetInscription | CM_Writing::Event_SetInscription |
– | – | – | B | Inscribe item |
| 0x00C8 | outbound | IdentifyObject | CM_Item::Event_Appraise |
W | H | B | B+W | AppraiseRequest builder dead 23 |
| 0x00CD | outbound | GiveObjectRequest | CM_Inventory::Event_GiveObjectRequest |
W | H | B | B+W | InventoryActions builder dead 23 |
| 0x00D6 | outbound | AdvocateTeleport | – | – | H | – | B | GM-only teleport |
| 0x0140 | outbound | AbuseLogRequest | CM_Character::Event_AbuseLogRequest |
– | – | – | B | Player report tool |
| 0x0145 | outbound | AddChannel | CM_Communication::Event_ChannelList |
– | H | B | B+W | SocialActions builder dead 2326 |
| 0x0146 | outbound | RemoveChannel | – | – | H | B | B+W | SocialActions builder dead 23 |
| 0x0147 | outbound | ChatChannel | CM_Communication::Event_ChannelBroadcast |
W | H | W | B+W | Wired in WorldSession.SendChannel; same code as inbound 0x0147 27 |
| 0x0148 | outbound | ListChannels | – | – | – | – | B | – |
| 0x0149 | outbound | IndexChannels | CM_Communication::Event_ChannelIndex |
– | – | – | B | – |
| 0x0195 | outbound | NoLongerViewingContents | CM_Inventory::Event_NoLongerViewingContents |
W | H | – | B | Container UI close |
| 0x019B | outbound | StackableSplitToWield | CM_Inventory::Event_StackableSplitToWield |
W | H | B | B+W | InventoryActions builder dead 23 |
| 0x019C | outbound | AddShortcut | CM_Character::Event_AddShortCut |
– | H | B | B+W | InventoryActions builder dead 23 |
| 0x019D | outbound | RemoveShortcut | CM_Character::Event_RemoveShortCut |
– | H | B | B+W | InventoryActions builder dead 23 |
| 0x01A1 | outbound | SetCharacterOptions | – | – | H | B | B+W | SocialActions builder dead 23 |
| 0x01A8 | outbound | RemoveSpellC2S | CM_Magic::Event_RemoveSpell |
– | H | – | B | Self-cancel buff |
| 0x01B7 | outbound | CancelAttack | CM_Combat::Event_CancelAttack |
W | H | W | B+W | Wired in WorldSession.SendCancelAttack |
| 0x01BF | outbound | QueryHealth | CM_Combat::Event_QueryHealth |
W | H | B | B+W | SocialActions builder dead 23 |
| 0x01C2 | outbound | QueryAge | CM_Character::Event_QueryAge |
– | H | – | B | – |
| 0x01C4 | outbound | QueryBirth | CM_Character::Event_QueryBirth |
– | H | – | B | – |
| 0x01DF | outbound | Emote | CM_Communication::Event_Emote |
W | H | – | B | Custom /e text |
| 0x01E1 | outbound | SoulEmote | CM_Communication::Event_SoulEmote |
W | H | – | B | /soulemote |
| 0x01E3 | outbound | AddSpellFavorite | CM_Character::Event_AddSpellFavorite |
– | H | – | B | Spellbook pin |
| 0x01E4 | outbound | RemoveSpellFavorite | CM_Character::Event_RemoveSpellFavorite |
– | – | – | B | Spellbook unpin |
| 0x01E9 | outbound | PingRequest | – | W | H | B | B+W | SocialActions builder dead; keepalive 23 |
| 0x01F6 | outbound | OpenTradeNegotiations | CM_Trade::Event_OpenTradeNegotiations |
W | H | – | B | Begin trade |
| 0x01F7 | outbound | CloseTradeNegotiations | CM_Trade::Event_CloseTradeNegotiations |
W | H | – | B | Cancel trade |
| 0x01F8 | outbound | AddToTrade | CM_Trade::Event_AddToTrade |
W | H | – | B | Add item to trade |
| 0x01FA | outbound | AcceptTrade | CM_Trade::Event_AcceptTrade |
W | H | – | B | Confirm trade |
| 0x01FB | outbound | DeclineTrade | CM_Trade::Event_DeclineTrade |
W | H | – | B | Reject trade |
| 0x0204 | outbound | ResetTrade | CM_Trade::Event_ResetTrade |
W | H | – | B | Clear pending items |
| 0x0216 | outbound | ClearPlayerConsentList | CM_Character::Event_ClearPlayerConsentList |
– | H | – | B | Resurrection consent |
| 0x0217 | outbound | DisplayPlayerConsentList | CM_Character::Event_DisplayPlayerConsentList |
– | H | – | B | – |
| 0x0218 | outbound | RemoveFromPlayerConsentList | CM_Character::Event_RemoveFromPlayerConsentList |
– | – | – | B | – |
| 0x0219 | outbound | AddPlayerPermission | CM_Character::Event_AddPlayerPermission |
W | H | – | B | Storage / consent perm |
| 0x021A | outbound | RemovePlayerPermission | CM_Character::Event_RemovePlayerPermission |
W | H | – | B | – |
| 0x021C | outbound | BuyHouse | CM_House::Event_BuyHouse |
– | H | – | –defer:Phase Q | Housing — out of M baseline scope |
| 0x021E | outbound | HouseQuery | – | – | H | – | –defer:Phase Q | Housing |
| 0x021F | outbound | AbandonHouse | CM_House::Event_AbandonHouse |
– | H | – | –defer:Phase Q | Housing |
| 0x0221 | outbound | RentHouse | CM_House::Event_RentHouse |
– | – | – | –defer:Phase Q | Housing |
| 0x0224 | outbound | SetDesiredComponentLevel | – | – | – | – | B | Component-buy preference |
| 0x0245 | outbound | AddPermanentGuest | CM_House::Event_AddPermanentGuest_Event |
– | H | – | –defer:Phase Q | Housing |
| 0x0246 | outbound | RemovePermanentGuest | CM_House::Event_RemovePermanentGuest_Event |
– | H | – | –defer:Phase Q | Housing |
| 0x0247 | outbound | SetOpenHouseStatus | CM_House::Event_SetOpenHouseStatus_Event |
– | H | – | –defer:Phase Q | Housing |
| 0x0249 | outbound | ChangeStoragePermission | CM_House::Event_ChangeStoragePermission_Event |
– | H | – | –defer:Phase Q | Housing |
| 0x024A | outbound | BootSpecificHouseGuest | CM_House::Event_BootSpecificHouseGuest_Event |
– | H | – | –defer:Phase Q | Housing |
| 0x024C | outbound | RemoveAllStoragePermission | CM_House::Event_RemoveAllStoragePermission |
– | H | – | –defer:Phase Q | Housing |
| 0x024D | outbound | RequestFullGuestList | CM_House::Event_RequestFullGuestList_Event |
– | – | – | –defer:Phase Q | Housing |
| 0x0254 | outbound | SetMotd | CM_Allegiance::Event_SetMotd |
– | – | – | B | Allegiance message-of-the-day |
| 0x0255 | outbound | QueryMotd | CM_Allegiance::Event_QueryMotd |
– | – | – | B | – |
| 0x0256 | outbound | ClearMotd | CM_Allegiance::Event_ClearMotd |
– | H | – | B | – |
| 0x0258 | outbound | QueryLord | CM_House::Event_QueryLord |
– | – | – | –defer:Phase Q | Housing |
| 0x025C | outbound | AddAllStoragePermission | CM_House::Event_AddAllStoragePermission |
– | – | – | –defer:Phase Q | Housing |
| 0x025E | outbound | RemoveAllPermanentGuests | CM_House::Event_RemoveAllPermanentGuests_Event |
– | H | – | –defer:Phase Q | Housing |
| 0x025F | outbound | BootEveryone | CM_House::Event_BootEveryone_Event |
– | H | – | –defer:Phase Q | Housing |
| 0x0262 | outbound | TeleToHouse | CM_House::Event_TeleToHouse_Event |
– | – | – | –defer:Phase Q | Housing |
| 0x0263 | outbound | QueryItemMana | CM_Item::Event_QueryItemMana |
W | H | – | B | Mana-meter check |
| 0x0266 | outbound | SetHooksVisibility | CM_House::Event_SetHooksVisibility |
– | H | – | –defer:Phase Q | Housing |
| 0x0267 | outbound | ModifyAllegianceGuestPermission | CM_House::Event_ModifyAllegianceGuestPermission |
– | – | – | –defer:Phase Q | Housing |
| 0x0268 | outbound | ModifyAllegianceStoragePermission | CM_House::Event_ModifyAllegianceStoragePermission |
– | – | – | –defer:Phase Q | Housing |
| 0x0269 | outbound | ChessJoin | – | – | H | – | –skip:minigame | Chess |
| 0x026A | outbound | ChessQuit | – | – | H | – | –skip:minigame | Chess |
| 0x026B | outbound | ChessMove | – | – | H | – | –skip:minigame | Chess |
| 0x026D | outbound | ChessMovePass | – | – | H | – | –skip:minigame | Chess |
| 0x026E | outbound | ChessStalemate | – | – | H | – | –skip:minigame | Chess |
| 0x0270 | outbound | ListAvailableHouses | CM_House::Event_ListAvailableHouses |
– | – | – | –defer:Phase Q | Housing |
| 0x0275 | outbound | ConfirmationResponse | CM_Character::Event_ConfirmationResponse |
W | H | – | B | Yes/No popups |
| 0x0277 | outbound | BreakAllegianceBoot | CM_Allegiance::Event_BreakAllegianceBoot |
– | H | – | B | Officer kick |
| 0x0278 | outbound | TeleToMansion | CM_House::Event_TeleToMansion_Event |
W | – | – | –defer:Phase Q | Housing recall |
| 0x0279 | outbound | Suicide | CM_Character::Event_Suicide |
W | – | – | B | /suicide cmd |
| 0x027B | outbound | AllegianceInfoRequest | CM_Allegiance::Event_AllegianceInfoRequest |
– | H | – | B | Tree info |
| 0x027D | outbound | CreateTinkeringTool / SalvageItemsWith | CM_Inventory::Event_CreateTinkeringTool |
W | H | – | B | Salvage UI 28 |
| 0x0286 | outbound | SpellbookFilter | CM_Character::Event_SpellbookFilterEvent |
– | – | – | B | School filter |
| 0x028D | outbound | TeleToMarketPlace | – | W | – | – | B | MP recall |
| 0x028F | outbound | EnterPkLite | – | W | – | – | B | PK-lite toggle |
| 0x0290 | outbound | FellowshipAssignNewLeader | CM_Fellowship::Event_AssignNewLeader |
W | H | – | B | – |
| 0x0291 | outbound | FellowshipChangeOpenness | CM_Fellowship::Event_ChangeFellowOpeness |
– | H | – | B | – |
| 0x02A0 | outbound | AllegianceChatBoot | CM_Allegiance::Event_AllegianceChatBoot |
– | – | – | B | Officer chat-mute |
| 0x02A1 | outbound | AddAllegianceBan | CM_Allegiance::Event_AddAllegianceBan |
– | H | – | B | – |
| 0x02A2 | outbound | RemoveAllegianceBan | CM_Allegiance::Event_RemoveAllegianceBan |
– | – | – | B | – |
| 0x02A3 | outbound | ListAllegianceBans | CM_Allegiance::Event_ListAllegianceBans |
– | – | – | B | – |
| 0x02A5 | outbound | RemoveAllegianceOfficer | CM_Allegiance::Event_RemoveAllegianceOfficer |
– | H | – | B | – |
| 0x02A6 | outbound | ListAllegianceOfficers | CM_Allegiance::Event_ListAllegianceOfficers |
– | – | – | B | – |
| 0x02A7 | outbound | ClearAllegianceOfficers | CM_Allegiance::Event_ClearAllegianceOfficers |
– | – | – | B | – |
| 0x02AB | outbound | RecallAllegianceHometown | CM_Allegiance::Event_RecallAllegianceHometown |
– | – | – | B | Bind to monarch lifestone |
| 0x02AF | outbound | QueryPluginListResponse | CM_Admin::Event_QueryPluginListResponse |
– | – | – | –skip:plugin-c2s | Decal-era plugin probe |
| 0x02B2 | outbound | QueryPluginResponse | CM_Admin::Event_QueryPluginResponse |
– | – | – | –skip:plugin-c2s | Decal-era plugin probe |
| 0x0311 | outbound | FinishBarber | CM_Character::Event_FinishBarber |
– | H | – | B | Char appearance commit |
| 0x0316 | outbound | AbandonContract | CM_Social::Event_AbandonContract |
– | H | – | B | Drop quest |
Footnotes:
Source attribution
- Holtburger —
references/holtburger/at629695a(2026-05-10). Primary client-behavior oracle. - ACE —
references/ACE/Source/ACE.Server/Network/. Server-side authority for GameMessages, GameEvents, GameActions, and accept rules. - Named retail decomp —
docs/research/named-retail/(Sept 2013 EoR PDB + Binary Ninja pseudo-C). Wire-format ground truth for the 2013 client. - acdream current state —
src/AcDream.Core.Net/andsrc/AcDream.App/. Inventoried by parallel agents on 2026-05-10.
Caveats
This is the initial population, produced by four parallel research agents (one per opcode class) on 2026-05-10. Spot-check pass + intentional-divergence ratification is owed before M.1 closes. Specifically:
- A handful of named-retail symbol citations are tentative (marked in footnotes); spot-check by greping
acclient_2013_pseudo_c.txtandsymbols.json. - Holtburger / ACE / acdream cells were determined by reading the actual code (not guessing); when an agent couldn't determine a value, it used
?. The?cells need a follow-up read. - "Dead builder" calls (rows where acdream
Bbut Phase M target isB+W) are based on a grep forWorldSession.Send*patterns andworldSession.Sendcalls insrc/AcDream.App/. Edge cases (call sites in test code, command-bus indirection) may have been missed. - Total opcode count in scope (~284) is approximate; deduplication of cross-section codes (e.g., 0x0147 in §4 and §5) is tracked in footnotes but the headline count treats them as distinct rows.
This matrix lives on as a long-term reference. Phase M.6 implementation tracks progress against it; gameplay phases consuming Phase M will reference the rows they wire as part of their phase acceptance.
-
The
None=0value isn't a wire bit, but it's in our enum so callers can default-initialize headers — keep it. ↩︎ -
ACE sets
Retransmissionwhen re-sending a cached packet; clients should accept it as informational. We currently treat the bit as a no-op (works because we don't dedupe on it). ↩︎ -
A login-server-side handshake step; only relevant when ACE adds login-bounce, which it doesn't today. ↩︎
-
We need to actually retransmit on inbound NAK and need to send NAKs for our own missing inbound. M3 reliability-core phase. ↩︎
-
Inbound
Disconnectmust close the session cleanly and notify upper layers; right now the connection just times out on client side too. ↩︎ -
LoginRequestis a server-decode case but our codec consumes it on encode for hashing. ↩︎ -
Retail server uses this for world-server entry confirmation; the holtburger ref has no parse, ACE writer-side is
Pack. Our consumer just skips 8 bytes for hashing. ↩︎ -
Servers do periodically EchoRequest to the client; we must mirror the 4-byte client-time as an
EchoResponseperFlowQueue::DequeueAcksemantics. ↩︎ -
ServerSwitch struct layout per retail
UCServerSwitchStruct— confirmed via named-retail symbol?CreateFromData@?$COnePrimHeader@$0BAA@$0GA@UCServerSwitchStruct@@@@. M3 needs the IP/port to actually re-target the socket; today we'd silently drop traffic from a relocated server. ↩︎ -
ACE calls 0x02E9
PrivateUpdateAttribute2ndLevel; holtburger calls itPrivateUpdateVitalCurrent(current-only delta). ↩︎ -
Retail-side trigger of the enter-world flow; the wire opcode 0xF657 is constructed from the request. ↩︎
-
PlayerCreate fires LoginComplete when guid matches own char; CreateObject body is parsed for the player too. ↩︎
-
AutonomyLevel is in holtburger's
GameMessageenum + unpack/pack, but its enum value (0xF752) is mapped via opcode dispatch. ↩︎ -
0xF754 PlayScript is parsed inline in
WorldSession.cs:850(no dedicatedMessages/PlayScript.cs); routed toPlayScriptReceivedevent for VFX runtime. ↩︎ -
ACE handles inbound TurbineChat via
TurbineChatHandlerand emits outbound viaGameMessageTurbineChat, hence both directions. ↩︎ -
CharacterEnterWorldServerReady is unit variant in holtburger (no payload); only an opcode marker. ↩︎
-
acdream uses 0xF7DF as a handshake gate (
WorldSession.cs:495), no dedicated parser file. ↩︎ -
DddInterrogation in holtburger is a unit variant — opcode marker only, no payload to parse. ↩︎
-
PlayerDescription has its own dedicated parser (
PlayerDescriptionParser.TryParse) rather than living inGameEvents.cs. Wires intoLocalPlayerState(vitals 7/8/9),Spellbook(learned spells + enchantments),ItemRepository(inventory + equipped), and theonSkillsUpdatedcallback (Run/Jump skills for movement). ↩︎ -
IdentifyObjectResponse uses
AppraiseInfoParser.TryParse(separate file) rather than the simple header-only parser inGameEvents.cs. Returns full property bundle (int / int64 / bool / float / string / DID tables) plus SpellBook list. The retail handlerHandle_Item__AppraiseDone(0x01CB) is the post-arrival completion signal, not the data carrier itself. ↩︎ -
0x01E2 Emote sub-opcode is distinct from
HearEmote(top-level GameMessage 0x02BC); the sub-opcode form is documented in ACE'sGameEventType.csbut the named-retail decomp doesn't expose a dedicated handler — likely re-routed through the chat broadcast path. ↩︎ -
Named retail's
Recv_ChatRoomTrackeris the underlying handler symbol; ACE/Holtburger renamed toSetTurbineChatChannelsfor clarity. Same wire payload (per-room session ids for General/Trade/LFG/Roleplay/Society/Olthoi/Allegiance). ↩︎ -
"Builder dead" = the byte-array builder is implemented in
src/AcDream.Core.Net/Messages/<file>.csbut no caller insrc/AcDream.App/or aWorldSession.Send*wrapper invokes it. Phase M wires these to game-state actions (UI clicks, command bus, key bindings) and adds golden-vector tests against holtburger fixtures. ↩︎ -
ACE's wire field order for Tell is
message FIRST then target(seeChatRequests.BuildTelldoc comment). Sept-2013 PDB has noEvent_Tellsymbol — it routes throughCM_Communication::Event_TalkDirectByNameplus a server-side rename. ↩︎ -
TeleToPoi (0x00B1) is listed in
InventoryActions.csbut not in ACE'sGameActionTypeenum. Cross-reference holtburger to confirm; may be a dead-letter opcode that retail's vendored 2013 ACE branch dropped. Verify before shipping the test vector. ↩︎ -
AddChannel (0x0145) — named-retail's matching symbol is
Event_ChannelList(0x0148 according to retail enum), so the symbol mapping is approximate; AddChannel in pseudo-C may be unsymbolicated. Confirm by grepingacclient_2013_pseudo_c.txtbefore publishing. ↩︎ -
0x0147 ChannelBroadcast is the same numeric code in both directions (outbound GameAction = client sends to channel; inbound GameEvent = server broadcasts to channel members). Listed under outbound here per Section-5 scope; inbound version is in §4. ↩︎
-
ACE GameActionType lists 0x027D as
CreateTinkeringTool; holtburger names the same opcodeSalvageItemsWith. Both behaviors funnel through the salvage UI in retail. Either name is acceptable in acdream; pick one and leave the other as an alias constant. ↩︎