acdream/docs/audit/2026-04-13-phase-audit.md
Erik 9e5258152d docs: development workflow + phase-by-phase audit
Adds mandatory decompile→verify→port workflow to CLAUDE.md:
- DECOMPILE FIRST before writing ANY AC-specific code
- Cross-reference against ACE/ACME (interpretation aids)
- Write pseudocode before porting (catches misinterpretations)
- Port faithfully — don't "improve" the retail code
- Conformance test the critical paths
- Integrate surgically — minimum changes to working code
- Phase completion checklist with decompiled-reference citations

Phase audit (docs/audit/2026-04-13-phase-audit.md) reviews all
shipped phases:
- 53% verified (decompiled/ACME conformance)
- 34% from good references (ACE/ACViewer/holtburger)
- 5% guessed (lighting, indoor transitions)
- 8% not AC-specific (streaming, culling)

Key gaps identified:
1. Lighting uses guessed sun direction — should use decompiled AdjustPlanes
2. Indoor transitions disabled — needs decompiled CEnvCell port
3. SceneryGenerator LCG not verified against decompiled code
4. CreateObject parser incomplete
5. Movement messages missing sequence counters

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 13:27:08 +02:00

7.6 KiB

Phase-by-Phase Audit: Decompiled vs Guessed

Every AC-specific algorithm should be ported from the decompiled client or verified against ACME's ClientReference.cs. This audit flags which parts of each shipped phase are properly sourced vs which were guessed and may need re-verification.

Legend:

  • VERIFIED — ported from decompiled code or verified against ACME/ClientReference
  • ⚠️ REFERENCE — ported from ACE/ACViewer/holtburger (good but not decompiled ground truth)
  • GUESSED — written without checking any reference, or reference was inadequate

Phase 1 — Terrain + Plugin Scaffold

Component Status Source Notes
LandblockMesh height indexing (x-major) ACME ClientReference.cs Fixed after initial y-major bug
LandblockMesh triangle split direction ACME ClientReference.cs + AC2D Confirmed via 25,600-cell conformance sweep
LandblockMesh vertex positions ACME ClientReference.GetVertexPosition Matches decompiled ConstructVertices
Height table lookup ACME ClientReference.GetVertexHeight Direct table[byte]
Plugin host (ALC, lifecycle) N/A acdream-specific design Not AC-specific

Phase 2a-2d — Static Meshes + Scenery

Component Status Source Notes
GfxObjMesh.Build (vertex/UV/normal extraction) ⚠️ WorldBuilder ObjectMeshManager Cross-checked against ACME. Winding order opposite from ACME (latent)
GfxObjMesh neg-side polygon emission ⚠️ WorldBuilder ObjectMeshManager acdream is MORE correct than ACME here
SetupMesh.Flatten (multi-part assembly) ⚠️ WorldBuilder + ACViewer Third-fallback frame added from ACME
SceneryGenerator LCG algorithm ⚠️ ACViewer get_land_scenes Constants match but not verified against decompiled
SceneryGenerator road exclusion ACViewer + ACME Post-displacement check added
SceneryGenerator building exclusion ACME GameScene Ported
SceneryGenerator slope filter ACME TerrainGeometryGenerator Ported
EnvCell static objects (interior) ⚠️ ACViewer EnvCell.cs Frames are landblock-local (learned empirically)

ACTION NEEDED: SceneryGenerator LCG constants should be verified against decompiled code.

Phase 3a-3c — Lighting + Terrain Blending

Component Status Source Notes
Directional lighting (Lambert + ambient) Guessed Sun direction/ambient constants are made up. Should check decompiled AdjustPlanes (FUN_00532440)
Per-vertex terrain normals ⚠️ Central differences on heightmap Not from decompiled code. ACME's AdjustPlanes accumulates face normals
Terrain texture blending (TexMerge) ⚠️ WorldBuilder LandSurfaceManager Comprehensive but not verified against decompiled
GetPalCode ACME ClientReference.GetPalCode Exhaustive conformance test (1M combos)
Alpha atlas loading ⚠️ WorldBuilder LandSurfaceManager Functional but not cross-checked

ACTION NEEDED: Lighting should use the decompiled AdjustPlanes algorithm. Terrain normals may differ from retail.

Phase 4 — Networking

Component Status Source Notes
ISAAC keystream ACE golden vectors Clean-room reimplementation, verified
Packet framing / Hash32 / CRC ACE + holtburger cross-check Byte-compatible with live ACE
Fragment assembly ACE + holtburger Sequence-keyed (corrected from ID-keyed)
LoginRequest builder ACE + holtburger Live-tested
ConnectResponse holtburger Port 9001, 200ms delay
CharacterList parser ACE Live-tested
CharacterEnterWorld holtburger Live-tested
DddInterrogationResponse holtburger Language=1, lists=[]
LoginComplete holtburger Fires on PlayerCreate
CreateObject parser ⚠️ ACE Partial — skips many PhysicsData fields
ACK pump holtburger Per-packet, piggybacked
MoveToState builder ⚠️ AC2D + holtburger Missing sequence counters
AutonomousPosition ⚠️ holtburger Missing sequence counters

ACTION NEEDED: CreateObject parser should extract all PhysicsData fields. Movement messages need proper sequence counters.

Phase 5 — Character Appearance

Component Status Source Notes
AnimPartChanges ⚠️ ACE CreateObject format Works but PackedDwordOfKnownType was buggy initially
TextureChanges ⚠️ ACE + acdream investigation Surface→OrigTextureId chain correct
SubPalettes ACViewer IndexToColor Faithful port with range offset
ObjScale ⚠️ ACE PhysicsDescriptionFlag Works

Phase 6 — Animation

Component Status Source Notes
MotionResolver.GetIdleCycle ⚠️ ACE MotionTable Cycle key encoding verified
MotionResolver.GetIdleFrame ⚠️ ACE MotionTable Single-frame extraction
AnimationSequencer (rewritten) Decompiled FUN_005261D0 pseudocode Faithful port of update_internal
AnimationSequencer.SetCycle Decompiled + ACE MotionInterp adjust_motion from ACE:394-428
AnimationSequencer reverse playback Decompiled FUN_005267E0 Fixed frame-swap bug
AnimationSequencer.SlerpRetailClient Decompiled FUN_005360d0 Weight-validation fallback

Phase A — Foundation (Streaming, Culling, Net Thread)

Component Status Source Notes
StreamingRegion N/A acdream-specific Not AC-specific
FrustumCuller N/A Standard graphics algorithm Not AC-specific
LandblockStreamer N/A acdream-specific Sync mode due to DatCollection thread safety
Net receive thread N/A acdream-specific Channels-based

Phase B — Movement

Component Status Source Notes
PhysicsBody (Euler integration) Decompiled FUN_005111d0 Gravity, friction, velocity clamping
PhysicsBody.calc_acceleration Decompiled FUN_00511420 -9.8 gravity
PhysicsBody.calc_friction Decompiled FUN_0050f940 Ground normal + pow decay
MotionInterpreter Decompiled FUN_00529390 etc 10 methods ported
CollisionPrimitives Decompiled chunk_00530000.c 9 functions ported
TerrainSurface.SampleZ ACME ClientReference + decompiled Triangle-aware barycentric, conformance-tested
TerrainSurface split formula Decompiled + AC2D + ACME Both formulas produce identical results
PlayerMovementController ⚠️ Mix of ported + custom Uses ported PhysicsBody but terrain collision is simplified
Indoor transitions Disabled CellPortal detection needs decompiled find_transit_cells
Jump physics ⚠️ ACE MovementSystem.GetJumpHeight Formula from ACE, not decompiled

ACTION NEEDED: Indoor transitions should be ported from decompiled CEnvCell functions. Jump needs decompiled verification.


Summary

Status Count Percentage
VERIFIED (decompiled/ACME) 31 53%
⚠️ REFERENCE (ACE/ACViewer/holtburger) 20 34%
GUESSED (no reference) 3 5%
N/A (not AC-specific) 5 8%

Key gaps to address:

  1. Lighting (AdjustPlanes) — currently guessed
  2. Indoor transitions — disabled, needs decompiled port
  3. SceneryGenerator LCG — needs decompiled verification
  4. CreateObject parser — incomplete PhysicsData extraction
  5. Movement sequence counters — missing from outbound messages