Gameplay Authority Replay Fixtures And Drift Gates
Purpose
Gameplay authority replay fixtures prove that recorded or constructed authority outcomes still produce the expected command audit, wire-facing snapshots, gameplay facts, quest projection, and mob encounter state. Use them when an authority resolver, mutation id, replay adapter, quest projection, transport payload, or pack/export gate changes.
The runner is deterministic and domain-level. It does not start a game server or re-execute database writes. Server-edge tests first normalize live service output into the shared fixture shape, then use the same runner to compare stable facts.
Steps
-
Choose the fixture kind that matches the boundary under test.
ReplayFixtureKindUse it for GameplayAuthorityJsonA persisted GameplayAuthorityReplayFixturewith explicit steps and expected audit, wire, state, and quest values.RawCommandAuditJsonFull recorded command_auditrows that the loader rehydrates into deterministic replay steps.BuiltInGameplayAuthorityA fixture constructor in gameplay_authority_replay.rsfor gameplay, dialogue, service, quest, or trigger flows.BuiltInMobEncounterA constructor covering normalized spawn, aggro, leash, reset, death, reward, actor, and gameplay-state behavior. ServerEdgeInlineA fixture assembled inside a game-server test from service output, such as combat respawn. GateCommandAn aggregate command that runs an owning replay test family. It describes a gate step, not one data fixture. RuntimeReplayA protocol, scene-preview, cutscene, or other replay command outside the gameplay-authority fixture runner. -
Keep the schema and identity stable. Persisted gameplay, raw command-audit, mob encounter, and manifest schemas are currently version
1. Give every fixture a non-empty, stablefixture_id; use the same id in its manifest descriptor and diagnostics. -
Author deterministic inputs and expected values.
- A direct gameplay fixture supplies initial gameplay state, quest catalog/input, ordered steps, expected audit records, optional expected wire snapshots, expected authority state, and expected quest snapshot.
- A raw command-audit fixture supplies full server row context.
command_type,request_id,action_kind, session/account/character/realm fields, source and target zones, and mutation-id tags must be non-empty. Tile and revision fields are retained as source context, while the normalized replay assertions live in audit, wire, state, and quest projections. - A mob fixture supplies initial actor/state, ordered encounter steps, expected events, final authority state, and final actor.
- A server-edge fixture should be built from
GameplayAuthorityReplayOutcomeInput,GameplayAuthorityReplayAuditRecordInput, or the shared wire input adapter instead of inventing a second normalized DTO.
-
Model acceptance and replay independently.
- An accepted gameplay step applies both
preview_effectsandauthority_effects; the runner then compares the two resulting states. - A rejected gameplay step still produces an audit record and wire snapshot, but applies neither effect set. If no wire snapshot is supplied, the derived snapshot reflects the unchanged authority state.
replayeddescribes where the authority result came from. It does not suppress fixture effects. An accepted, replayed step still advances the deterministic replay to the recorded result.- Rejected mob steps are skipped entirely: they do not update actor state, apply effects, or append the event.
- An accepted raw audit row must have a replayable payload: mutation ids that derive gameplay effects, explicit preview or authority effects, or an explicit wire snapshot. Rejected rows may contain only audit context because they do not mutate state.
- An accepted gameplay step applies both
-
Register the fixture in the static
REPLAY_FIXTURE_DESCRIPTORSmanifest. Setid,label,kind, repo-relativepathwhen file-backed,consumers,gate_profiles, optionalcommand, and human-readableassertions. Useworld-domain-replayfor gameplay data fixtures andpack-exportfor descriptors that should contribute a command to the pack/export plan.Manifest registration is discovery and gate metadata, not dynamic execution. The raw-audit test iterates all manifest entries of kind
RawCommandAuditJson, but direct JSON, built-in, mob, and server-edge fixtures still need an owning test that loads or constructs them and calls the correct runner. A descriptor contributes to pack/export only when it has both thepack-exportprofile and a command; the existingworld-domain-gameplay-authority-replaygate command runs the domain replay test family. -
Run the narrow replay tests first.
cargo test -p aether-world-domain gameplay_authority_replay cargo test -p aether-game-server gameplay_action_service_output_replays_server_audit_and_transport_effects cargo test -p xtask replay_fixture_specs_drive_gate_commands_outputs_and_assertions -
Inspect the assembled replay gate before running the full pack/export workflow.
cargo run -p xtask -- pack-export-gate --root . --out target/pack-export-gate --plan --format markdown cargo run -p xtask -- pack-export-gate --root . --out target/pack-export-gate
Expected Outputs
A clean gameplay report has no mismatches, no validation issues, and is_clean() == true. Its actual audit records, wire snapshots, authority state, and authority quest snapshot match the fixture; preview state and quest projection also match authority.
Gameplay drift becomes a blocking PreviewAuthorityParity validation error targeted at gameplay_authority_replay_fixture:<fixture_id>:
| Drift | Issue id | Compare |
|---|---|---|
| Audit | gameplay_authority_replay.audit_drift |
Expected and normalized command audit records. |
| Wire | gameplay_authority_replay.wire_snapshot_drift |
Expected and normalized authority wire snapshots. |
| State | gameplay_authority_replay.state_drift |
Preview versus authority and authority versus the golden final state. |
| Quest | gameplay_authority_replay.quest_snapshot_drift |
Preview versus authority and authority versus the golden quest snapshot. |
Mob reports use mob_encounter_authority_replay.event_drift for event changes and mob_encounter_authority_replay.state_drift for actor or shared gameplay-state changes. Their target kind is mob_encounter_authority_replay_fixture. Mismatch entries include stable serialized expected and actual values for test and CI output.
Common Mistakes
- Adding a descriptor but no test that executes the new direct, built-in, mob, or server-edge fixture.
- Marking a descriptor
pack-exportwithout a command and expecting it to create a gate command by itself. - Treating
replayed: trueas "do not apply effects" instead of as authority-result provenance. - Giving an accepted raw audit row only opaque mutation ids, such as an NPC label, with no derivable effects or wire payload. The loader rejects it with
needs replay payload. - Expecting currency mutation ids to change
GameplayConditionState. They are syntax-checked, but currency results belong in the explicit wire snapshot. - Omitting server audit context, using malformed
item:quantitymutation ids, or changing a fixture schema version without changing the loader contract. - Updating golden expected values immediately after a failure without deciding whether authority behavior, preview behavior, or the fixture is actually stale.
Recovery Paths
For a fixture-load error, fix schema version, empty identity fields, malformed mutation ids, or the missing accepted-step payload before investigating drift. Use raw_command_audit_fixture_reports_missing_replay_payload and raw_command_audit_fixture_rejects_malformed_currency_mutation_ids as boundary examples.
For audit drift, compare command type, request id, action kind, accepted/replayed flags, normalized mutation ids, and message. For wire drift, inspect the edge adapter and explicit snapshots. For state drift, compare preview and authority effects at the first differing accepted step. For quest drift, compare the fixture's quest catalog/input and the final gameplay facts before changing the expected projection.
If a behavior change is intentional, update the owning constructor or JSON, its expected values, manifest entry, and execution test together. Rerun the domain replay test, the relevant server-edge test, the xtask descriptor test, and finally the pack/export replay step. Do not repair a code regression by changing only the golden output.