19 KiB
Scanner IK Progress Report - 2026-07-07
This report summarizes the scanner/OCR work toward the current target: scan the first 100 artifacts with accuracy at least as good as Inventory Kamera and speed equal to or better than Inventory Kamera, without memory reads, hooks, injection, game-file modification, or unsafe in-game actions.
Executive Summary
The scanner has moved from a fragile OCR-first prototype toward an Inventory-Kamera-style artifact scanner:
- Artifact scan is now the first-class path.
- Auto-scan starts only after a validated artifact inventory/detail preflight.
- Main-game, Paimon-menu, primary-screen, unsupported-layout, missing-grid, and missing-detail states block before OCR/store/review work.
- OCR uses a fast artifact profile that skips low-value fields and derives slot, set, and main-stat value through lookup constraints when safe.
- The OCR worker pool, field crop split, page model, scroll model, and direct detail-change verification now mirror the relevant IK design choices more closely.
- Diagnostics now preserve state evidence, timings, screenshots where useful, entry events, focus/input events, preflight failures, and scan-loop reasons.
- A live soak runner now measures throughput and quality, compares current vs. IK-traineddata engines, and refuses to run against stale Electron builds.
The current-vs-IK-traineddata comparison proof is now captured. On 2026-07-08,
npm run scan:goal:compare:validated passed with
outputs/live-soak/2026-07-08T18-38-35/scan-performance-assessment.json.
At limit=100, current won the qualified comparison with 100/100 parsed,
0 review, 0 misses, 378 ms/artifact active average, and 37800 ms
projected time for 100 artifacts. ik-traineddata was not qualified at
limit=100 because it parsed 97/100, had 5 review and 3 misses. The
separate 3 artifacts/second target is still not proven.
What Changed
Lookup and validation
scripts/generate-genshin-data.cjswas extended into a stricter lookup package generator.src/lib/genshinLookup.tsprovides pure matching and validation for sets, pieces, slots, stats, characters, aliases, GOOD keys, source version, and validation summaries.- Auto-scan preflight blocks if the lookup package is invalid.
Why this matters:
IK succeeds partly because raw OCR is not trusted by itself. The app now follows the same principle: OCR text is normalized, matched, constrained, and derived against a canonical package before it is accepted.
OCR and parser pipeline
- Artifact detail crops are split into field-specific regions: name, slot, main-stat label, main-stat value, level, substats, set effects, equipped/footer, lock, and rarity.
- Fast auto-scan profile skips lower-value OCR work: set effects, main-stat value crop, crop images, full-frame payloads, and inventory preview payloads. The equipped footer remains in real artifact-read captures when its marker is visible, because ownership now matters for phase 1 validation. Preflight and poll captures still skip OCR/crops/lock-state work. The slot crop remains in the fast path because it materially improved real-read quality.
- Slot, set, and main-stat value are derived when lookup, slot rules, and level constraints make that safe.
- Field-specific Tesseract PSM/whitelist cleanup and preprocessing are used.
- OCR crops are passed as PNG buffers internally instead of Base64 DataURLs.
- Exact visual duplicate skipping is disabled in the hottest path; duplicate handling now primarily uses parsed artifact signatures so OCR is not skipped solely from a crop fingerprint collision.
Why this matters:
The fast path spends OCR only on fields that materially change the artifact identity or review decision. That is closer to IK's queued crop model than a manual-debug capture that OCRs every visible thing.
Engine comparison and benchmark path
/scanner/ocr/warmup?engine=current|ik-traineddatawarms OCR workers./scanner/benchmark-ocr?engine=current|ik-traineddata|comparebenchmarks the same visible artifact crops.- Auto-scan accepts
ocrEngine: "current" | "ik-traineddata". scripts/live-soak.ps1supports:npm run scan:goalnpm run scan:goal:currentnpm run scan:goal:iknpm run scan:goal:comparenpm run scan:goal:compare:validatednpm run scan:goal:compare:validated:waitnpm run scan:iterate:compare:validatednpm run scan:iterate:compare:validated:waitnpm run scan:live:preflightnpm run scan:live:preflight:wait
scan-performance-assessment.jsonranks runs by quality first and speed second, and records whether the 100-artifact result is a complete current-vs-IK comparison throughgoal100Decisionandgoal100.comparisonComplete.
Important rule:
A fast engine cannot win if it has too many misses or too much review. A qualified winner must finish cleanly, parse the requested count, keep miss rate at or below 2%, and keep review rate at or below 15%.
Auto-scan entry and safety
- The normal auto button runs a guided start:
- focus Genshin,
- run a lightweight no-OCR preflight,
- if artifact detail is visible, use visible-inventory mode,
- otherwise try direct
B -> artifact tab -> first artifact tile, - if needed, fall back to the IK-style ESC/B inventory sequence,
- start OCR only after artifact grid and detail card pass preflight.
- Entry captures are state evidence only. They do not create review samples, store artifacts, or run artifact OCR before the detail preflight passes.
- Entry waits now poll for state readiness instead of always sleeping the full fixed delay.
- Scan loop also rechecks the same safety boundary after each click and scroll.
Why this matters:
The previous failure mode was dangerous from a product-quality point of view: when the game was not in artifact inventory, the scanner could still take screenshots and try to read artifacts. The current path is explicitly blocked outside the artifact inventory/detail state.
Scan loop and speed
- Grid model uses IK's 32-artifact visible page concept (
8 x 4) instead of clicking the risky lower band. - Last/partial page planning bottom-aligns like IK, avoiding unnecessary duplicate reads after scroll.
- Detail-change verification now uses the artifact OCR capture itself instead of a separate card-ready capture before OCR.
- Scroll readiness uses inventory fingerprint polling: max 760 ms, 80 ms polls, changed pages may proceed after 100 ms.
- Store/review writes are held out of the click/capture/OCR hot path. The latest source batches artifact store writes before the final summary instead of issuing one save/reload cycle per artifact.
- Auto-scan artifact captures skip Electron source enumeration in the hot path and call the GDI capture helper directly.
- Focus is done once at scan start; hot-loop captures do not refocus every tile.
Why this matters:
IK uses fixed waits around 200 ms after selecting inventory items and 100 ms after fast scrolls. The app now keeps those as safety ceilings/acceptance points while allowing earlier continuation when visual evidence is ready.
Diagnostics and logging
- Scanner diagnostics now capture timeline events for runtime, focus, keypress, entry captures, tab clicks, first-tile clicks, preflight, OCR/skips, grid, counts, detail/page fingerprints, and failure reasons.
/scanner/statuspublishes recent diagnostic evidence.- Review sample output is compact by default so Vite does not watch large Base64 payloads during live soak runs.
- The live runner writes timestamped JSON snapshots, CSV summaries, transcript,
benchmark data, and performance assessment files under
outputs/live-soak/.
Why this matters:
Future scanner bugs can be debugged from captured evidence instead of relying only on a human description of what appeared on screen.
Vorgehensweise
- Read the local Inventory Kamera reference under
work/Inventory_Kamera. - Copy the proven concepts, not the entire implementation: 32 artifact targets per page, fixed coordinate ratios, queued OCR work, short item/scroll waits, read-only inventory navigation, and Tesseract traineddata comparison.
- Harden the app's own architecture around those concepts: pure lookup API, parser derivation, renderer scan orchestration, Electron capture/OCR boundary, sidecar input helper, and diagnostics.
- Add tests before trusting behavior: lookup validation, parser derivation, auto-entry planning/preflight, card-ready gates, page planning, scan-loop blocking, OCR eval corpus.
- Add live tooling before claiming performance: bounded probes, stale-build gate, benchmark endpoint, soak runner, CSV/JSON assessment, and quality-first comparison.
Tests and Evidence
Latest repo validation after the recent changes:
| Check | Result |
|---|---|
PowerShell parse for scripts/live-soak.ps1 |
Passed |
npm run scan:assessment:test |
Passed |
npm run lint |
Passed |
| Focused scanner tests | Passed |
npm test |
Passed, 171 tests |
| OCR eval seed corpus | 100% exact match, 100% field accuracy, 100% critical fields |
npm run build |
Passed |
git diff --check |
Passed |
Live evidence already collected:
- Probe click changed artifact detail successfully.
- Limit 2 live auto-scan completed with 2/2 parsed and 0 misses.
- Limit 20 live soak completed on the first visible page.
- Limit 45 live soak crossed into a scrolled page.
- On 2026-07-08,
/scanner/start?entry=visible-inventory&limit=50&engine=currentcompleted50/50parsed and stored,0review,0duplicates,0misses,2pages,61765 mselapsed,1235 ms/artifact,averageCaptureMs: 186, andaverageOcrMs: 162. - A deferred single-write flush experiment also completed
50/50, but regressed to63616 msbecausewriteFlushMswas8163; the source now uses batch persist instead, pending a fresh elevated live measurement. - After direct GDI hot-path optimization, a 20-artifact run completed
20/20parsed,19stored,0review,1duplicate,0misses,7966 mselapsed,398 ms/artifact,averageCaptureMs: 193, andaverageOcrMs: 167. - A 45-artifact direct-GDI run completed
45/45parsed,42stored,0review,3duplicates,0misses,2pages,18625 mselapsed,414 ms/artifact,averageCaptureMs: 187, andaverageOcrMs: 162. - A 100-artifact direct-GDI run on signature
2026-07-08-direct-gdi-hotpathcompleted100/100parsed,97stored,0review,3duplicates,0misses,4pages,42064 mselapsed,421 ms/artifact,averageCaptureMs: 179, andaverageOcrMs: 154. npm run evalpassed after the speed work with23/23exact-match cases,100%field accuracy, and100%critical fields.- The 3 artifacts/second target is now prepared in code but not live-proven:
artifact hot-path captures omit detail preview payloads, and stats expose
capture roundtrip/overhead timing. A qualifying 20-artifact run must finish in
<= 6667 mswith 0 misses and no silent OCR quality regression. - Follow-up 3/s attempts on 2026-07-08 fixed the false review trigger caused by
omitted detail previews. The best clean
limit=20run reached7285 ms(364 ms/artifact, about2.75 artifacts/second) with20/20parsed,0review, and0misses. The final stable run on2026-07-08-direct-gdi-reviewfixcompleted20/20with0review,0misses, and7973 mselapsed (399 ms/artifact). Detail-region capture, 5 OCR workers, DataURL buffer decode, and substatPSM.SINGLE_COLUMNwere tested and rejected as slower than the direct-GDI baseline. - Final current-vs-IK-traineddata comparison on 2026-07-08:
npm run scan:goal:compare:validatedpassed. Evidence file:outputs/live-soak/2026-07-08T18-38-35/scan-performance-assessment.json,createdAt: 2026-07-08T18:41:11.6120957+02:00.goal100Decisionwasqualified-comparison: winner=current;goal100.comparisonCompletewas true.currentcompleted100/100parsed,97stored,0review,0misses,4pages,378 ms/artifactactive average.ik-traineddatacompleted97/100parsed,92stored,5review,3misses and was rejected for parsing fewer artifacts than requested. - The review queue now has a bounded corpus-growth workflow:
npm run eval:review-candidateswrites a deduplicated, Git-ignored worklist tooutputs/review-eval-candidates/. This separates complete modern OCR samples from stale captures and prevents the parser's own guess from being promoted to ground truth without human confirmation. After manual checking,npm run eval:prepare-confirmedturns one candidate plus explicit expected labels into a paste-ready confirmed corpus snippet.
Current live limitation:
- The fast path and current-vs-IK-traineddata 100-artifact comparison are proven in the current live environment. 3 artifacts/second is not proven; remaining speed work needs a larger OCR or capture-pipeline change, not more click tuning.
- The visible-inventory ownership/lock extension is also live-proven in this
environment: equipped footer reads for
CitlaliandLinnea, unlockedlocked: false, positive lockedlocked: true, and locked/equipped persistence all passed on 2026-07-09.
Inventory Kamera Comparison
| Area | Inventory Kamera | Current app status |
|---|---|---|
| Safe scope | Reads inventory through screen/click automation | Same safety boundary: screen capture and read-only input only |
| Entry | ESC/B inventory navigation and tab click | Direct B path plus IK-style fallback, with preflight guards |
| Page model | 32 artifact items per page | 32 safe targets (8 x 4) implemented |
| Last page | Bottom-aligned partial page after scroll | Implemented in page planner |
| Item wait | About 200 ms fixed wait | No separate wait capture; OCR capture verifies changed detail |
| Scroll wait | About 100 ms fast wait after scroll | Fingerprint polling, accepts changed page after 100 ms |
| OCR model | Native Tesseract worker queue and custom traineddata | Tesseract.js pool with current and IK-traineddata comparison path |
| Capture hot path | Direct window/screen capture without source-list scan per item | Direct GDI capture in auto-scan artifact loop |
| Field parsing | OCR plus game-data lookup | OCR plus generated lookup, GOOD keys, aliases, slot/stat constraints |
| Quality gate | Mature behavior by design and user history | Explicit benchmark/soak quality gates added |
| Diagnostics | Logs/screenshots in IK flow | Diagnostics timeline plus JSON evidence bundle |
| 100-artifact proof | Reference target | Qualified current-vs-IK comparison captured; current won with 100/100, 0 review, 0 misses, 37.8s projected |
What is theoretically better than before:
- The app no longer spends OCR on invalid screens.
- It no longer treats click count as scanner success.
- It can prove whether
currentorik-traineddatawins on the same capture set instead of changing engines blindly. - It can reject fast-but-wrong results automatically.
- It can identify whether the bottleneck is OCR, capture, card readiness, or scroll readiness.
What is not yet proven better than IK:
- Native Tesseract speed is not integrated as the default.
- 3 artifacts/second is not proven.
- Native Inventory Kamera outside this app was not re-run in the same session;
the completed comparison is against the bundled
ik-traineddatascan engine.
Theoretical Runtime Flow
For short iteration while tuning:
- Start current elevated app with
npm run dev:adminand confirm UAC. - Run
npm run scan:iterate:compare:validated:waitfrom a visible artifact inventory when starting directly after UAC, ornpm run scan:iterate:compare:validatedif preflight already passes. - Inspect
scan-performance-assessment.json, review samples, and timings if the 20-artifact comparison fails quality gates.
For the intended 100-artifact comparison:
- Start current elevated app with
npm run dev:adminand confirm UAC. - Verify
/health.appBuild.signaturematcheselectron/main.ts. - Warm current and IK-traineddata OCR workers.
- Run a small bounded probe from the artifact inventory.
- Run
npm run scan:goal:compare:validated:waitdirectly after UAC, ornpm run scan:goal:compare:validatedif preflight already passes. - For each engine and limit (
2, 5, 20, 45, 100):- focus Genshin once,
- verify lookup and layout,
- verify artifact grid and detail card,
- click one safe grid target,
- poll detail fingerprint,
- skip duplicate visuals,
- OCR only the fast artifact crop set,
- parse through lookup constraints,
- queue store/review writes,
- scroll with inventory fingerprint polling,
- stop on repeated pages, invalid surfaces, blocked input, OCR timeout, or repeated misses.
- Write CSV, JSON snapshots, transcript, benchmark report, and performance assessment.
- Declare a winner only if the 100-artifact run is qualified by quality.
Expected bottleneck sequence:
- If OCR dominates, compare
currentvsik-traineddata, crop count, and worker pool size. - If capture dominates, reduce payload construction and preview/crop image work.
- If card-ready dominates, tune the detail fingerprint gate.
- If scroll-ready dominates, tune page fingerprint polling and scroll notches.
What Is Better Than Before
- Auto-scan is artifact-detail gated; no more blind OCR from main gameplay or menu screens.
- Paimon/menu detection blocks before scan-loop OCR or writes.
- The normal button is one coherent guided flow instead of a separate "get to inventory first, then scan" workflow.
- The app has a real lookup layer instead of raw OCR plus scattered hardcoded assumptions.
- The scanner can compare OCR engines without changing the default blindly.
- Performance reports now include quality decisions, not just elapsed time.
- Diagnostics are concrete enough for later self-troubleshooting.
- Stale elevated runtime is detected before live soak, avoiding false evidence.
Risks and Remaining Work
- Keep
currentas the default OCR engine for now; it won the qualified current-vs-IK-traineddata live comparison. - If pursuing 3 artifacts/second, focus on capture/OCR pipeline changes rather than click timing.
- Grow the eval corpus with confirmed real review samples before tightening parser thresholds further.
- Repeat equipped/locked live samples in later sessions if confidence or UI behavior changes, but the first positive locked proof has passed.
- Keep recommendations secondary until scanner quality remains stable across repeated live sessions and the result rail, artifact inventory, and detail evaluation flow are implemented.
- Treat current speed as acceptable for the next product phase; prioritize artifact content extraction and review-safe value scoring before another broad speed pass.
Definition of Done for the IK Target
The goal is complete only when current evidence proves all of these:
- The app is running the latest runtime signature.
- The 100-artifact scan finishes cleanly.
- Parsed count is at least 100.
- Miss rate is at or below 2%.
- Review rate is at or below 15%.
- The run is equal to or faster than the recorded IK reference or the selected IK-traineddata/native baseline on the same machine and inventory setup.
- The evidence bundle is saved under
outputs/live-soak/. - Any chosen default OCR engine is backed by the same-capture benchmark.