Rewrite status (Python + raylib)¶
This page tracks the current code-level state of the rewrite under src/, and the
largest remaining parity gaps vs the classic Windows build (v1.9.93) documented in
docs/crimsonland-exe/.
Last reviewed: 2026-05-03
What you can run today¶
uv run crimson- Full boot flow (splash + company logos) -> main menu.
- Play Game / Options / Statistics / Mods menu flows.
- Survival / Rush / Quests / Typ-o-Shooter / Tutorial are all wired and playable.
- Game over -> high score entry (Survival/Rush/Typ-o), and quest completion/failure flows.
uv run crimson --preserve-bugsto re-enable known native quirks for parity/diff work.uv run crimson view <name>for debug views and sandboxes.uv run crimson spawn-plan <template_id>anduv run crimson quests <level>for spawn/script inspection.- Net bring-up tooling:
uv run crimson relay serve --bind 0.0.0.0 --port 31993uv run crimson net host --mode survival --players 2 --relay-host <ip> --relay-port 31993uv run crimson net join --code <invite> --relay-host <ip> --relay-port 31993uv run crimson net host --mode survival --players 2 --netcode lockstep --host <ip> --port 31993uv run crimson net join --netcode lockstep --host <ip> --port 31993cd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net host --mode survival --players 2 --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net join --code <invite> --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair delay-first-guest-input --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair reorder-first-guest-input --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair drop-first-guest-input --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair force-guest-resync --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair guest-reconnect --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair guest-reconnect-resync --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair guest-double-reconnect --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair guest-triple-reconnect --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair guest-double-reconnect-resync --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair guest-triple-reconnect-resync --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair jitter-burst --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair bidirectional-jitter-burst --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair guest-reconnect-bidirectional-jitter-burst --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair guest-double-reconnect-bidirectional-jitter-burst --format jsoncd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig net smoke-rollback --impair guest-triple-reconnect-bidirectional-jitter-burst --format json- The native Zig
net host/joinsurface now reportsruntime_supported=truefor rollback sessions, and the native smoke command exercises an in-process relay plus host/guest live rollback exchange, including delayed-input, reordered-input, dropped-input, repeated and bidirectional jitter recovery without resync, guest-requested resync snapshot, relay-token guest self-reconnect with post-reconnect input continuity, double and triple guest reconnect, a longer reconnect-then-resync path that accepts fresh guest input after the applied snapshot, double- and triple-reconnect-then-resync recovery, and bidirectional jitter after one, two, or three reconnect cycles. The desktop network lobby now opens and backs out through the same native panel timeline as the Python shell. Remaining network work is broader stress and lobby parity, not first launch support.
- The native Zig
- Asset tooling:
cd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig-asset-smoke <assets-dir>- The installed native smoke tool validates
crimson.paq, JAZ/TGA/JPEG image decoding, runtime texture specs, and small-font width data.
- The installed native smoke tool validates
cd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig-asset-extract <game-dir> <assets-dir>- The installed native extractor walks
.paqfiles, preserves the Python extractor's<assets-dir>/<paq-stem>/...layout, writes raw payloads, and converts decoded JAZ/TGA entries to PNG.
- The installed native extractor walks
- Desktop shell:
cd crimson-zig && zig build --prefix zig-out && ./zig-out/bin/crimson-zig-window- The installed native desktop shell starts the boot/menu/gameplay product flow;
--demostarts with shareware demo limits enabled.
- The installed native desktop shell starts the boot/menu/gameplay product flow;
- Replay tooling:
uv run crimson replay play <replay.crd>uv run crimson replay verify <replay.crd>uv run crimson replay info <replay.crd>(core timeline by default;--verboseadds extra context events;--format jsonemits schema-versioned timeline payload)uv run crimson replay benchmark <replay.crd>(default--mode headless, optional--mode render)uv run crimson replay render <replay.crd>(ffmpeg-backed 60fps MP4 export, quality via--crf/--preset)uv run crimson replay verify-checkpoints <replay.crd>uv run crimson replay diff-checkpoints <expected> <actual>- Original/capture differential tooling (via structural traces):
uv run scripts/frida/gameplay_diff_capture_host.py --raw-path <capture.jsonl> --output-dir <dir>uv run crimson dbg record <replay.crd> --impl python --out <trace.py.cdt>uv run crimson dbg record <replay.crd> --impl zig --out <trace.zig.cdt>crimson-zig dbg record <replay.crd> --out <trace.zig.cdt>crimson-zig dbg health <trace.cdt> --format jsoncrimson-zig dbg tick <trace.cdt> <tick> --jsoncrimson-zig dbg entity <trace.cdt> <entity_uid> --jsoncrimson-zig dbg query <trace.cdt> "entities where uid == 0" --jsoncrimson-zig dbg verifycrimson-zig config --path <crimson.cfg> --format jsoncrimson-zig status --path <game.cfg> --format jsoncrimson-zig quests <level> --format json --seed <seed>crimson-zig quests <level> --show-plancrimson-zig spawn-plan <template_id> --json(add--no-demo-mode-activeto include runtime burst effects)uv run crimson dbg health <trace.cdt>uv run crimson dbg tick <trace.cdt> <tick>uv run crimson dbg entity <trace.cdt> <entity_uid>uv run crimson dbg query <trace.cdt> "entities where uid == 0"uv run crimson dbg diff <expected.cdt> <actual.cdt>uv run crimson dbg bisect <expected.cdt> <actual.cdt>uv run crimson dbg focus <expected.cdt> <actual.cdt> --tick <n>
Zig native port status¶
- Zig native-port details now live on a dedicated page:
docs/rewrite/zig-verifier.mdcrimson-zig/is being tracked as a full native port effort, not a verifier side project.- This page remains focused on overall rewrite (Python + raylib) status and major parity gaps, while the Zig page tracks the native-port surface directly.
Coverage map (rewrite vs classic)¶
Front-end (menus + screens)¶
- Main menu (state
0): implemented, including timeline/layout behavior and terrain/sign-shadow rules. - Code:
src/crimson/screens/menu.py - Ref:
docs/crimsonland-exe/main-menu.md - Zig now routes root menu selections and demo-idle attract launch through the native close timeline before dispatch.
- Play Game panel (state
1): implemented (mode buttons, player-count dropdown, tooltips, debug-gated F1 times-played overlay). - Code:
src/crimson/game/__init__.py(PlayGameMenuView) - Ref:
docs/crimsonland-exe/play-game-menu.md - Quest select menu (state
0x0b): implemented (quest list, stage icons, hardcore gating, debug-gated counts overlay and F5 unlock shortcut). - Code:
src/crimson/game/__init__.py(QuestsMenuView) - Ref:
docs/crimsonland-exe/quest-select-menu.md - Options panel (state
2): implemented for core sliders + controls workflow. - Code:
src/crimson/screens/panels/options.py,src/crimson/screens/panels/controls.py,crimson-zig/src/window_options.zig - Implemented: SFX/music/detail/mouse sliders, UI info toggle, display config editing, controls entry and interactive rebinding flow. Zig now routes Options/Controls navigation through the native 300 ms panel close timeline before dispatching Back or Controls actions.
- Statistics hub (state
4): implemented with child panels. - Code:
src/crimson/screens/panels/stats.py - Child views: high scores, weapons database, perks database, credits.
- Code:
src/crimson/game/__init__.py,src/crimson/screens/panels/databases.py,src/crimson/screens/panels/credits.py,crimson-zig/src/window_statistics.zig - Zig now gates the hub buttons until the native 300 ms open timeline completes and closes both the hub and child panels before dispatching descendant or Back actions.
- Demo / attract mode: implemented (variant sequencing, upsell flow, trial overlay during gameplay).
- Code:
src/crimson/demo.py,src/crimson/ui/demo_trial_overlay.py - Ref:
docs/crimsonland-exe/demo-mode.md,docs/crimsonland-exe/screens.md - Game over / high score entry (state
7): implemented for Survival/Rush/Typ-o. - Code:
src/crimson/ui/game_over.py,src/crimson/persistence/highscores.py,src/crimson/game/__init__.py - Zig now animates game-over/results panels through the native open/close slide timeline, keeps high-score/button hitboxes aligned with the moving panel, routes Play Again, High scores, and Main Menu actions through the native close timeline before dispatch, returns Back from result-launched high scores to the results screen, and clears that stacked results screen before Play a game opens Play Game.
- Quest results (state
8) / quest failed (state0x0c): implemented. - Code:
src/crimson/ui/quest_results.py,src/crimson/game/__init__.py,crimson-zig/src/window_main.zig - Zig quest-completion results show the resolved weapon/perk unlock names after the final-time breakdown completes, honor the completed-results keyboard shortcuts, and route the final quest end-note screen through the native 300 ms open/close timeline before dispatching its follow-up action.
- Pause menu: implemented.
- Code:
src/crimson/screens/pause_menu.py,crimson-zig/src/window_pause_menu.zig - Zig now routes pause-menu Back, Options, and Quit actions through the native close timeline before dispatch.
- Mods menu (state
0x14path from main menu): implemented as a panel and filesystem DLL discovery UI; plugin loading/runtime is still not implemented. - Code:
src/crimson/screens/panels/mods.py,src/crimson/screens/menu.py - Ref:
docs/crimsonland-exe/mods.md - Zig now routes Mods, Other Games, Network Session, and live Network Lobby panel Back/Launch actions through the native panel timeline before dispatch.
- Scope policy for Mods and Other Games/shareware ads: out of scope for the rewrite target.
- Rationale: native DLL plugin runtime is not practical to support in the Python rewrite architecture.
- Rewrite stance: keep menu-shell UX compatibility where useful, but do not implement native DLL mod loading/execution or Other Games ad/runtime flows.
- Secrets / extras: implemented, including the Alien Zoo Keeper credits secret flow.
- Code:
src/crimson/screens/panels/alien_zookeeper.py,src/crimson/screens/panels/credits.py
Gameplay¶
- Core world sim:
GameWorldis the active runtime container (players, creatures, projectiles, bonuses/perks, FX, terrain renderer). - Code:
src/crimson/game_world.py - Playable modes: Survival, Rush, Quests, Typ-o-Shooter, Tutorial are all wired through the shared gameplay framework.
- Code:
src/crimson/modes/*.py - Quest content: tiers 1-5 are present and script-driven through runtime builders.
- Code:
src/crimson/quests/tier*.py,src/crimson/quests/runtime.py - Multiplayer: local 2-4 player input-frame flow is implemented for Survival/Rush/Quest.
- Code:
src/crimson/modes/base_gameplay_mode.py,src/crimson/local_input.py - Rollback-primary netplay: relay protocol v5 + relay service + rollback runtime are in-tree and selected by default for network sessions.
- Code:
src/crimson/net/relay_protocol.py,src/crimson/net/relay_service.py,src/crimson/net/rollback_runtime.py,src/crimson/net/rollback.py,src/crimson/game/loop_view.py - v5 adds end-to-end
rb_resync_request/begin/chunk/commitfields (request_id, checksum, codec, snapshot tick), 5s link timeout + dedicated 250ms ping cadence, and reconnect/resync completion hooks. - Docs:
docs/rewrite/netplay-rollback.md,docs/rewrite/lan-lockstep.md - Progression/unlocks/persistence: quest unlock indices, mode play counters, and status persistence are wired.
- Code:
src/crimson/persistence/save_status.py,src/crimson/gameplay.py - Content breadth: rewrite tables and runtime paths cover full weapon/perk/quest content, with ongoing parity validation focused on edge-case behavior/timing through differential captures.
Audio¶
- Audio routing (
AudioRouter) is implemented and wired for gameplay events. - Code:
src/crimson/audio_router.py - Includes per-creature death SFX routing, hit/explosion variants, weapon fire/reload mapping, and gameplay music triggers.
Verification and parity evidence¶
- Ground renderer parity is fixture-tested against runtime dumps.
- Doc:
docs/rewrite/terrain.md - Test:
tests/test_ground_dump_fixtures.py - Deterministic step pipeline parity (live update vs replay/headless execution) is covered with canonical tick and checkpoint/state parity tests.
- Tests:
tests/test_step_pipeline_parity.py,tests/test_replay_runners_survival.py,tests/test_replay_runners_rush.py,tests/test_replay_runners_quest.py - Code:
src/crimson/sim/sessions.py,src/crimson/sim/tick_runner.py,src/crimson/sim/driver/playback_driver.py - Network protocol/runtime behavior is covered by unit and wiring tests.
- Tests:
tests/test_relay_protocol.py,tests/test_relay_service.py,tests/test_rollback_core.py,tests/test_rollback_resync_v5.py,tests/test_net_runtime_heartbeat.py,tests/test_net_runtime_rollback.py,tests/test_net_runtime_resync.py,tests/test_net_runtime_modes.py,tests/test_net_reconnect.py,tests/test_net_runtime_lockstep_fallback.py,tests/test_net_cli.py,tests/test_net_ui_flow.py, plus lockstep suitestests/test_lan_protocol.py,tests/test_lan_lockstep_host.py,tests/test_lan_lockstep_client.py - Replay-side checkpoint differential comparison is reusable via CLI and library helpers.
- Code:
src/crimson/dbg/checkpoint_diff.py - Command:
uv run crimson replay diff-checkpoints <expected> <actual> - Replay timeline extraction now has a versioned JSON surface for analytics/web infographics.
- Code:
src/crimson/sim/driver/replay_info.py,src/crimson/cli/replay.py - Command:
uv run crimson replay info <replay.crd> --format json --json-out <path> - Capture import and trace diagnostics are managed via the decoupled
dbgtrace suite. - Code:
src/crimson/dbg/* - Documentation:
docs/frida/differential-playbook.md - Tooling includes health, structural diffs across implementations, bisection, and focus trace.
- Capture-only triage workflow is documented here:
docs/frida/differential-playbook.md
4-player extension policy¶
- Exact parity target: native
1/2player behavior. - Deterministic extension target:
3/4players follow the same per-player rules without perturbing1/2outcomes. - Current examples:
- Survival/Rush high-score ownership remains player-0-centric.
- Quest final-time life bonus aggregates all players for
3/4runs while preserving native1/2behavior.
Biggest remaining parity gaps (vs v1.9.93)¶
- Ongoing deep parity validation
- Deterministic parity infrastructure is in place; remaining gaps are mostly capture-backed edge-case timing and branch-order issues.
- This status page intentionally avoids tick/session-specific examples that go stale quickly.
- Current active probes and per-SHA outcomes are tracked in
docs/frida/differential-sessions.md. - Rollback stress hardening + lockstep fallback maintenance
- Rollback is now the default path, and Zig has native delayed-input, reordered-input, dropped-input, repeated jitter, guest-requested resync, relay-token guest self-reconnect, reconnect-then-resync with fresh guest input after the applied snapshot, multi-reconnect, and multi-reconnect jitter smoke cases. Longer reconnect/resync stress still needs broader multi-cycle scenario coverage across long sessions.
- Legacy lockstep fallback remains available and must continue to receive compatibility maintenance while rollback remains primary.
Out of scope for this rewrite¶
- Native DLL mods/plugin runtime
- We do not plan to support loading/executing original DLL mods from Python.
- Other Games/shareware ad flows
- Shareware ad/runtime paths are not part of the parity target.
- Native online-score submission
- Local high-score tables stay supported, but we do not target original online score submission.
- Direction: use a more advanced headless verification system for score legitimacy/parity evidence.