Conformance
Test environment
Conformance tests operate on a legally supplied original data directory. They do not require an earlier engine. Tests SHOULD use fresh temporary save prefixes, a deterministic input clock, a controllable random source, and muted audio with logical completion enabled.
An engine SHOULD report its supported profile from Compatibility contract: data, shipped game, or full interpreter.
Data-profile tests
The parser test suite MUST establish all of the following:
DD1.DATyields 369 ordered entries with the extension population listed in Resources.- Every member expands to its declared size and consumes its complete stored payload. Raw and compressed members are both exercised.
- All 37 palettes are 768 valid six-bit RGB components.
- All 143 artwork members have a valid 12-byte descriptor table and contiguous pixel blocks.
- All 41 effects decode to their exact declared sample counts without unused bytes.
- All 32 XMIDI members have valid IFF bounds and a terminating event.
- The 21 maps cover levels A–G and difficulties E/N/D and are each 768 bytes.
- All four translations and eight banks join to 319 logical records with the bank counts and companion lengths specified in Text.
- Every
BINcode region decodes without an invalid instruction or operand overrun.CP2.BINhas code0000..1D54and a 256-byte data trailer;ROOM3.BINhas code ranges0000..0335,0C96..1753, and1768through its end. - Original saves are accepted only at the exact index and state sizes.
Malformed-input fixtures SHOULD cover overflowed offsets, truncated strings, invalid LZW phrases, cyclic dictionary references, invalid frame tables, wrong output counts, IFF chunk overruns, descriptor spans outside companions, bad branch targets, division by zero, and short saves. Every rejection MUST be bounded and atomic.
VM tests
A full-interpreter suite MUST encode and run at least one legal instance of
every opcode 01 through 91, including both BH and BHH paths for each
BHs opcode and both inline and FF-offset forms for every p opcode. It
MUST verify:
- little-endian operand reads and exact next-instruction offsets;
- signed comparison, multiply, divide, remainder, threshold, and 16-bit wrap;
- variable byte-offset validation and flag-bank mapping;
- absolute branches, nested calls, callback targets, and cooperative waits;
- mutable
BINbyte and word reads/writes; - display, action, dialogue, navigation, map, palette, text, and audio effects;
- all five no-ops and every command marked unused by shipped content; and
- deterministic suspension and resumption around input, animation, and audio.
Random-source coverage MUST accept every initial state in 0..65535, including
the endpoints whose first outputs are 6,924 and 27,106. Starting from state 1,
it MUST check the prefix 19511, 30543, 10098, 22502, 1941, 10629. It MUST
interleave opcodes 82, 8E, and 91 to prove that each advances the one
shared state exactly once and that the latter two use the returned value’s low
byte. One X component test MUST prove that 20 left-then-right swaps consume
exactly 40 values.
Full-interpreter coverage MUST also exercise opcode 8B and the transient
status timer it starts. It MUST distinguish one post-VM status draw when 8B
creates the timer from the usual two status draws for an already-active timer,
verify that an expiring refresh still advances once, and verify that clearing
flag 36 freezes the timer without advancing the stream. A batching test MUST
also show that one update carrying delta seven makes two status draws, while
seven separate delta-one updates make fourteen; comparison replays must retain
the same boundary sequence.
Movement-controller coverage MUST distinguish intermediate-edge arrival from
final idle state. It MUST verify continuous walking phase across a multi-edge
route, the final 0x0200 phase reset, active destination replacement without
restarting the current edge, and replanning after arrival. It MUST cover the
224-unit horizontal frame-20 and toward/away frame-19 turn poses, prove that a
horizontal/depth change has no special pose, and exercise opcode 53 plus an
unreachable request as minimum same-node traversals. Route-search tests MUST
accept a 20-edge path, reject a 21-edge path, preserve edge insertion and
endpoint order, and exercise competing equal-length routes. Tests MUST also
cover the distinct initial and state-five departure ordering, synchronous
same-slot callbacks through a yield or return, directional-edge-before-node
arrival, arrival-time start then retarget behavior, and retained-destination
persistence across opcode 53 and scene replacement. A nested same-slot test
MUST prove that a callback delay does not pause the already-running outer
invocation, and that the outer yield publishes its cursor and cumulative
delay.
The shipped-game profile may omit execution tests for unused opcodes but MUST still decode their operand lengths so tooling can safely traverse a resource.
Scenario tests
At minimum, an end-to-end implementation SHOULD automate or manually verify:
| Scenario | Required observation |
|---|---|
| Startup | Logo, title, introduction, difficulty selection, and first hall are reachable. |
| Input | Keyboard and pointer choose the same scene actions and modal rows. |
| Study | A wrong selector follows failure; the expected selector follows success in every translation. |
| Map | Moving marks the proper exploration bit; F2 does not change it. |
| Station | Get Verse sets the intended descriptor state and displays its reference. |
| Trap | Correct adjacent-door study clears parameter B; failure follows scene logic. |
| Combat | Attack/Defend/Retreat/Combat dispatch to script targets; retreat preserves the cell. |
| Difficulty | One loss site applies half, normal, and fourfold faith loss. |
| Leech | Victory changes kind 6 to A and transfers B to A. |
| Zapper | Victory ends at faith 10000 and changes the cell to B. |
| Save | Normal and quick saves round-trip state; restore resumes checkpoint rather than arbitrary live dialogue. |
| Crew gate | Six victims cannot depart; seven victims can. |
| Pylon | Correct study completes one variable; wrong study enters OVER. |
| Tower | Incomplete pylons fail; correct final answer reaches WIN; wrong reaches OVER. |
Rendering and audio comparisons
Exact host RGB framebuffer bytes are not required after scaling, but the unscaled indexed 320×200 composition SHOULD be suitable for golden-image comparison at stable scene points. Tests SHOULD separately verify opaque zero, transparent zero, both flips, clipping, origin offsets, native and non-native scale, hidden objects, list order, palette rotation, and blackout.
A real-time presentation test SHOULD exercise the normal approximately 120 Hz cadence for at least one second and verify that its elapsed deltas total 2,880 units without any routine batch reaching 30 units. A synthetic or shipped multi-step animation with 30- and 40-unit intervals SHOULD verify that every authored frame is submitted under that cadence. A separate long-stall case MAY resolve several records into one presented frame, matching the reference’s capped catch-up behavior.
Audio tests compare decoded ABT sample bytes and XMI event sequences before host resampling or synthesis. Different audio backends MAY produce different analog output. Muting effects MUST not change the frame or VM update on which an audio wait completes under the test clock. A frontend that synthesizes or converts music SHOULD exercise every identifier in its configured family and confirm that each resource produces a nonempty, non-silent sequence that can be stopped, replaced, and looped independently of effects.
Save interoperability
A state written by a conforming engine in original-format mode MUST be readable by another conforming engine. Tests ignore bytes after the first NUL in fixed string buffers and the four pointer bytes of each text descriptor, but compare every other byte or logical field. Loading a rejected save MUST leave a hash of the complete running game state unchanged.
Completion criterion
Shipped-game conformance means the complete objective described in The game and its objective can be completed from a new session in all three difficulties without engine-specific data patches. Save/load, both input methods, every room class, all seven combat programs, all translations, the Unibot graph, both Tower outcomes, and normal exit must remain usable.