# Battle Effect Web Reference Capture

This project now has a local-only pipeline for the remaining battle effect
fidelity gap.

The current web runner can render EXE-derived actor/effect rows, but that does
not prove original-game pixel fidelity.  The missing oracle is an aligned set of
original runtime frames.  This tool captures the web side of that comparison so
the original captures can be added later.

## Generate Web Reference Frames

Run under Xvfb in the exe.dev VM:

```bash
xvfb-run -a python3 tools/capture_battle_effect_web_reference.py --scope first-pass
```

Output is intentionally local and ignored by git:

- `captures/battle_effect_pixel_oracle/<row>/web_reference/tick_XXXXX.png`
- `data/battle_effect_capture_manifest.json`

The manifest records `webReferenceCapture` paths and leaves `originalCapture`
blank.  After original game frames are captured and cropped/aligned to the same
preview frame semantics, fill in each `originalCapture` path and run:

```bash
python3 tools/build_battle_effect_capture_checklist.py
python3 tools/compare_battle_effect_pixel_oracle.py
python3 tools/build_battle_skill_goal_audit.py
```

The checklist reports original/web readiness separately and checks that a web
reference directory contains the expected number of PNG frames for its captured
ticks.

When both sides are present, `tools/compare_battle_effect_pixel_oracle.py`
also writes local diff PNGs under `captures/battle_effect_pixel_oracle/<row>/diff/`
and records original/web/diff paths in `out/battle_effect_pixel_compare_report.json`.
If a thumbnail review page is needed locally, pass `--html-out
out/battle_effect_pixel_compare_report.html`.

The comparator's success/failure paths can be checked without original runtime
captures:

```bash
python3 tools/verify_battle_effect_pixel_compare_selftest.py
```

## Import Original Runtime Frames

When original frames are captured into row directories, use the import helper
instead of editing the manifest by hand:

```bash
python3 tools/prepare_battle_effect_original_capture_dirs.py --scope first-pass --write
python3 tools/import_battle_effect_original_captures.py /path/to/original-captures --scope first-pass --dry-run
python3 tools/import_battle_effect_original_captures.py /path/to/original-captures --scope first-pass --copy
```

For the full oracle, use `--scope full`.

`tools/prepare_battle_effect_original_capture_dirs.py` creates ignored
row-specific `original/` directories plus small `capture_request.json` and
`README.txt` files.  Drop original runtime PNG frames into those directories,
then run the import helper against the generated root.

The helper accepts raw row ids and sanitized row ids:

- `/path/to/original-captures/ataho_0x0b/original/*.png`
- `/path/to/original-captures/ataho_0x0b/*.png`
- `/path/to/original-captures/ataho:0x0b/original/*.png`
- `/path/to/original-captures/ataho:0x0b/*.png`

`--copy` stores PNGs under ignored `captures/battle_effect_pixel_oracle/`
directories and writes those local paths into
`data/battle_effect_capture_manifest.json`.  The helper reports frame-count
mismatches against the current web-reference capture count when that count is
known.

## Scope

- `--scope first-pass` captures the 8 representative rows from
  `out/battle_effect_pixel_oracle_plan.json`.
- `--scope full` captures all 52 rows that still require an original pixel
  oracle.
- The default `--tick-mode samples` captures deterministic active effect ticks
  exposed by `battle_skill_timeline_review.html`.
- Use `--tick-mode range` only when a row needs every tick from `tickMin` to
  `tickMax`; this can generate many files.

## Completion Meaning

This tool does not complete the goal by itself.  It only prepares the web-side
reference frames.  The goal remains incomplete until original runtime captures
exist and `tools/compare_battle_effect_pixel_oracle.py` can compare them.
