DEV Community

Nivando Soares
Nivando Soares

Posted on

Porting Test Drive II from SNES to PC, Part 5: Making scanline validation repo-owned

Porting Test Drive II from SNES to PC, Part 5: Making scanline validation repo-owned

The cleanup thread in this repo is still product work.

That point is easy to miss when a change is small. The commit I closed today, 224057d on 2026-03-19, does not add a new renderer, a new extractor, or a new visible gameplay result. What it does is remove another place where the archaeology loop could silently lean on mutable shared emulator output.

That matters more than it sounds.

The last cleanup checkpoint was only half the job

The previous cleanup commit, d06ac64, moved the boot-probe path onto repo-owned outputs by default.

That was a good checkpoint, but it did not close the whole class of problem.

There was still a committed scanline-validation path that defaulted to Mesen's shared LuaScriptData area:

  • validation/mesen_scanline_step_test.lua
  • tools/capture_visible_mode7_range.py

That meant a helper could still read from a mutable emulator-owned location unless the caller was careful.

In a repo like this, that is a real risk:

  • the same script can be run many times across different frame windows
  • multiple archaeology lanes can be active in parallel
  • old probe JSON can look plausible enough to reuse by mistake
  • automation becomes harder to reason about when "latest file wins"

The whole point of the cleanup track is to make that kind of accidental ambiguity harder.

What changed in this checkpoint

This iteration was intentionally narrow.

The generic Mesen launcher, validation/run_mesen_capture.sh, now prepares the parent directory for TD2_SCANLINE_TEST_OUTPUT_PREFIX before launching the emulator.

That means the scanline probe can be given a repo-owned destination without relying on the caller to pre-create the directory tree.

Then the committed visible-range helper, tools/capture_visible_mode7_range.py, was updated so that it no longer defaults to shared LuaScriptData.

Instead, when you run something like:

python3 tools/capture_visible_mode7_range.py \
  1094 1101 \
  --output tools/out/visible_mode7_1094_1101.json
Enter fullscreen mode Exit fullscreen mode

the helper now derives a repo-owned raw probe prefix beside the aggregate output:

tools/out/visible_mode7_1094_1101_scanline_probe/td2_scanline_step_test.json

It also records that raw probe path in the aggregate JSON payload, so the run is easier to trace later.

That is the important pattern:

  • one command
  • one explicit aggregate output
  • one repo-owned raw probe surface attached to that run

No silent dependence on whatever happened to be left in .mesen-config/Mesen2/LuaScriptData.

Why this matters for archaeology

This project is already juggling several different kinds of evidence:

  • emulator captures
  • bridge extracts
  • direct ROM-derived builders
  • runtime manifests
  • scanline probes
  • contract checks

That is healthy, but only if the repo keeps a strong boundary between:

  • authoritative artifacts
  • scratch intermediates
  • stale leftovers from old experiments

Shared emulator output blurs that boundary.

Repo-owned per-run output sharpens it again.

That pays off immediately in a few ways:

  • validation commands become easier to rerun without cleanup guesswork
  • aggregate JSON can point back to the exact raw probe surface it used
  • it becomes clearer which artifacts belong to the repo's evidence chain
  • future automation can assume less hidden global state

None of that is glamorous, but it is exactly the kind of work that keeps a reverse-engineering-heavy port from becoming fragile.

What this checkpoint does not solve

It is important not to oversell this.

This commit does not finish the validation-output cleanup track.

In particular, it does not yet absorb the newer gameplay-oriented scanline wrapper that is currently sitting in the dirty worktree. That helper is part of active lane work and should be closed as its own checkpoint instead of being folded into a cleanup commit by accident.

So the state after 224057d is:

  • boot-probe output defaults are repo-owned
  • the committed visible-range scanline helper now follows the same policy
  • the broader scanline/gameplay cleanup surface is still open

That is the right level of scope for one iteration.

Where the project stands now

The repo's overall posture is still the same:

  • Lane 1 bank30 unresolved queue closure remains the official top gate
  • Lane 2 tilemap provenance has solid contiguous coverage through 1086..1117
  • Lane 3 gameplay archaeology is active and currently lives deep in visible-phase scanline work
  • the cleanup/refocus track is still running in parallel so those archaeology lanes stay trustworthy

This checkpoint belongs to that last category.

It is small, but it makes the validation surface more deterministic, and that gives the later archaeology results a better floor to stand on.

Next step

The next cleanup-side step is straightforward:

  • push the same repo-owned/per-run policy through the remaining scanline and gameplay wrappers
  • keep trimming lingering doc examples that still assume shared emulator output

After that, the project can keep pressing the more interesting blockers:

  • the 958..977 bootstrap gap
  • the 986+ final-screen composition gap
  • the callback-family replacement work beyond the current intro coverage

That is the shape of progress here.

Not every useful checkpoint produces a new frame.

Some of them make sure the next frame result is actually believable.

Top comments (0)