HOW IT IS VERIFIED
Nine deterministic validators drive the real modules headlessly and assert on structure rather than screenshots:
· exact frame counts and phase chains for every part
· byte hashes of every extracted asset against the release
· bit-exact reproduction of the original’s arithmetic, including
its Microsoft C random number generator
· each music gate re-derived from the S3M itself
· transitions that should be seamless are pixel-diffed across the
boundary and must come out at zero
· the hidden part’s mirror: its bottom half must equal its top
half from exactly 32 frames earlier, flipped
Every one of those runs silent, so there is one more that plays real audio and measures the visual clock against the audio engine’s reported position — the only check that can see audio/visual drift.
WHAT IS ACTUALLY UNDER TEST
The port’s part modules touch no DOM at all — not one reference to document or window between them. The host module owns the screen, the clock and the phase machine; a part is pure arithmetic over a byte array. So a validator does not test a copy or a harness rebuild of the part:
globalThis.fetch = async url => readFromDisk(url); const m = await import(‘../panic.js’);
The one browser thing a part does use is fetch(), to pull its own assets — so the validator points that at the filesystem, and imports. What runs under test is the same file the browser runs. There is no test build, and nothing to keep in sync.
AND WHAT IT IS CHECKED AGAINST
Not the port’s own earlier output, which would only prove it had not changed. The oracle is written inside the validator: an independent transcription of the original C or assembly, done from the source a second time. validate_panic.mjs transcribes SHUTDOWN.C in VGA byte addresses — 65536 addresses across 4 planes, rep movsw as it actually moved, plus a CRTC fetch model built from TWEAK.ASM — and then requires every frame, 0 to 130, to match the port exactly.
Two independent readings of the same 1993 source have to agree byte for byte, or one of them is wrong. That is the whole idea, and it is why the checks assert on structure instead of screenshots.
Run them with node tools/validate_*.mjs from unreal2/.