Parity Workflow Overview
The parity workflow has four phases:Recover Structure and Intent
Use static analysis (Ghidra, IDA, Binary Ninja) to understand the original code.Source of truth:
analysis/ghidra/maps/ contains authoritative name and type mappings.Validate Ambiguous Behavior
Use runtime evidence (Frida, WinDbg) to clarify ambiguous decompilations.Evidence location:
analysis/frida/ contains capture artifacts and traces.Port Behavior
Implement behavior in
src/ with deterministic simulation contracts.Key requirement: Maintain float32 precision and operation ordering.Static Analysis
Static analysis reveals structure, but not always exact behavior.Ghidra Analysis
Authoritative decompiles live inanalysis/ghidra/raw/, regenerated from name/type maps:
analysis/ghidra/maps/name_map.json- Function and variable namesanalysis/ghidra/maps/data_map.json- Data structure layouts
Never edit raw decompile files directly. Edit the maps, then regenerate.
Reading Decompiles
Decompiles show structure, not exact behavior:float10indicates x87 extended precision intermediate values- Final values are spilled back to
float(f32) storage - Constants like
1.5707964(π/2) must be preserved exactly
Runtime Evidence
When decompilation is ambiguous, use runtime evidence.Frida Captures
Frida instruments the running native binary to capture state:$CRIMSON_FRIDA_DIR (default: C:\share\frida on Windows).
Importing Captures
On Linux/WSL, import captures from Windows:Differential Playbook
Followdocs/frida/differential-playbook.md for capture-driven parity work:
- Record a deterministic gameplay session in the native binary
- Replay the same inputs through the rewrite’s headless oracle
- Compare state checkpoints field-by-field
- Isolate the first sustained mismatch
- Fix the root cause
- Re-run verification
Porting Behavior
Once behavior is understood, port it to the rewrite.Deterministic Contracts
All gameplay code must be deterministic:- Same seed → same RNG sequence
- Same inputs → same outputs
- No timing-dependent behavior
- No floating randomness
Float32 Precision
Zig Native Math
The Zig runtime provides canonical native-style math helpers: Location:crimson-zig/src/runtime/native_math.zig
Verification
Verify parity using multiple evidence pathways.Deterministic Tests
Lock in discovered behavior with deterministic tests:Replay Verification
Replays are deterministic recordings of gameplay sessions:- Initial seed
- Input sequence (keyboard/mouse)
- Expected final state (score, wave, RNG checksum)
Capture Verification
Compare rewrite behavior against Frida-captured native state:- Loads native state checkpoints from capture
- Runs rewrite with same seed/inputs
- Compares state field-by-field at each checkpoint
- Reports first sustained divergence
Parity Bug Investigation Workflow
When parity diverges:Isolate Mismatch
Isolate the first sustained mismatch and identify the subsystem.Look for:
- First checkpoint where values diverge
- Subsystem responsible (movement, RNG, collision)
- Pattern of divergence (immediate, gradual, chaotic)
Fix Root Cause
Fix the root cause (not the symptom).Common root causes:
- Wrong float constant (normalized vs native)
- Wrong operation order (changes rounding)
- Wrong f32 spill point (too early/late)
- Misread decompile (wrong branch condition)
Re-Run
Re-run the same capture/replay and confirm the mismatch moves/disappears for the right reason.Success patterns:
- Mismatch disappears entirely
- Mismatch moves to later checkpoint (proves earlier fix)
Differential Sessions
Parity investigation sessions are documented indocs/frida/differential-sessions/:
differential-playbook.md- General methodologysession-01.mdthroughsession-NN.md- Specific investigation logs
- Capture artifact SHA
- Initial divergence point
- Investigation process
- Root cause analysis
- Fix verification
Best Practices
Start with Evidence
Start with Evidence
Don’t guess behavior from decompiles alone. Use captures and replays to validate.
Fix Root Causes, Not Symptoms
Fix Root Causes, Not Symptoms
Don’t add “just in case” guards. Find why the divergence occurs.
Document Evidence
Document Evidence
Link tests back to decompile lines and capture sessions.
Preserve Native Math
Preserve Native Math
Keep float32 constants, operation ordering, and spill points as-is unless proven safe to change.
One Subsystem at a Time
One Subsystem at a Time
Keep parity fixes focused. Don’t mix unrelated changes.
Next Steps
Float Parity Policy
Master float32 precision requirements
Testing Guide
Write deterministic parity tests
Tooling Guide
Explore analysis tools and scripts
Verification Process
Complete verification workflow