Testing Strategy & Playtests
Relevant source files
The following files were used as context for generating this wiki page:
The cyrus project employs a multi-tiered testing strategy to ensure a faithful rebuild of The Elder Scrolls Adventures: Redguard. The original game serves as the primary specification, and testing focuses on achieving visual, audio, and logic parity while maintaining modern hardware performance.
Sources: AGENTS.md:4-8, CONTRIBUTING.md:4-7
Fidelity and Verification Tiers
Every code change undergoes a validation process based on its scope. The project distinguishes between technical limits and player experience. While code must be "faithful by default" regarding visuals and timing, it must not reproduce original technical stalls or low frame rates.
Sources: AGENTS.md:21-27, README.md:120-125
Verification Commands
Verification moves from narrow crate tests to workspace-wide "gates."
| Command | Scope | Purpose |
|---|---|---|
just check | Workspace | Runs publish, generated-map, and formatting checks without compiling. |
just verify <crate> | Crate | Runs crate-specific tests and Clippy (e.g., just verify game). |
just gates | Workspace | Full local verification including lints and all tests. |
cargo test -p <crate> | Module | Narrowest relevant suite during development. |
Sources: AGENTS.md:104-115, crates/cyrus-game/README.md:46-55
Verification Flow
This flowchart represents the progression of a code change through the verification tiers.
The flow ensures that documentation changes bypass heavy compilation while runtime logic faces automated replays.
Sources: AGENTS.md:104-125
Playtesting and Comparisons
Playtesting requires the original GOG installation as the source of truth. Comparison between cyrus and the original game is essential for runtime and fidelity changes.
Sources: AGENTS.md:120-123, README.md:20-25
Entry Points for Testing
To expedite testing, developers use specific entry points to bypass menus or run without a window:
- Skip Startup:
cargo run -p cyrus -- --skip-startupopens the menu directly. - Direct Scene Loading:
cargo run -p cyrus -- --scene STARTloads a specific world. - Headless Mode:
cargo run -p cyrus -- --headless --scene STARTruns without a window for control server tests.
Sources: AGENTS.md:162-167
Manual Comparison Steps
- Identify the world and position in the original game.
- Launch cyrus in the same scene and position using CLI flags or the Model Context Protocol (MCP).
- Use the free camera or inspection tools to compare visuals.
- Record evidence (traces, screenshots) in the relevant issue.
Sources: AGENTS.md:162-171, CONTRIBUTING.md:10-18
Matched Scene Captures
Automated replays use JSON fixtures to produce bit-matched comparisons between the original game, native cyrus, and the browser build.
Sources: dev/fixtures/README.md:1-5
Fixture Structure
JSON fixtures define the parameters for a repeatable comparison:
- World: The target
WORLD.INIentry. - View: A scene-space camera position and quaternion.
- Viewport: Dimensions for the capture.
- Settling Time: Host milliseconds allowed before the capture.
Sources: dev/fixtures/README.md:1-3, 9-11
Replay Process
The just replay <fixture.json> <label> command executes the following sequence:
Replays reject the triplet if the camera pose, image hash, or viewport does not match the measurement in the fixture.
Sources: dev/fixtures/README.md:1-20, 83-90
Domain-Specific Testing
Audio and Surface Testing
The project uses specialized comparison tools for audio fidelity. A dedicated example, surface_audio, runs the static ground query and animation interpreter without a window.
- JSON Audio Fixtures: Define cases with
initial_surface,collision_attribute, andanimation_group. - Step Verification: Records captured surface, signed Q8 position, and fitted decoded channel gain ratios.
- Comparison:
compare-surface-audio.pycompares cyrus reports against original runtime reports.
Sources: crates/cyrus-audio/README.md:73-85, 114-118
Script and Logic Testing
Gameplay logic, such as cheats and script animation hosts, is verified through Rust unit tests. These tests mock the installation or use a redguard symlink to validate:
- Cheat Toggles: Ensuring raw state values persist correctly through
savecheats. - SOUP Integration: Validating script actors and ordinary updates against the specification.
- Animation Tasks: Ensuring simultaneous tasks complete independently.
Sources: crates/cyrus-game/README.md:46-55, crates/cyrus-audio/README.md:32-35
Conclusion
The cyrus testing strategy combines strict local verification gates with automated visual and audio comparisons. By treating the original 1998 game as a living specification, the project ensures fidelity through repeatable fixtures and evidence-based verification. Consistent use of just verify and automated replays maintains parity across native and web platforms.
Sources: AGENTS.md:104-125, dev/fixtures/README.md:1-11