Name Reader - Gidntsquia/deadlock-street-brawl-helper GitHub Wiki

Name reader

The app reads three pieces of text on screen: each draft card's item name, the hero name on the loading screen (turned into dark letters on white, 60 px tall, before the read: the raw colour crop read as nothing at 1920x1080), and the "N Re-Roll Remaining" caption. After 0.4.0 these are read by Windows OCR (Windows.Media.Ocr, part of Windows 10 and 11), not Tesseract. Nothing extra is installed and no window opens: the app starts one hidden PowerShell helper when it opens, warms it with one test picture, and sends it each text crop.

How it works

  • electron/nameReader.ts starts winocr-helper.ps1 (shipped next to the app) hidden. The log line reader.ready gives the start time. If the helper exits it is started once more; if it exits again (or never starts) the status line says Name reader not running, cards that are not read show a grey ?, the hero comes from the window or your pick, and the re-roll count uses the glyph shape alone. The app keeps running.
  • The text is matched to item and hero names exactly as before (matchItemName, matchHeroName at 0.85).
  • Tooltips. Hovering a card makes the game draw a tooltip panel beside it, over a neighbour's name line. The panel's text sits off centre in that line (a card's own name is always centred), so the app treats that line as covered: it is not read and the card keeps the item it read before. A card that has never been seen uncovered shows a grey ? and gets its advice the moment it is read uncovered. A read that names the same item as another card is a tooltip title too, and both are read again. Log reason covered on card.name.unsure.

Measured (labelled crops, npm run names:compare)

544 labelled name crops: the five demo frames, the live frames, the 10 OBS video truth stretches at 1280x720 and the stored session crops. 30 are covered by a tooltip (skipped by the rule above), 514 are uncovered.

Engine Wrong Sure (of 514) Cold start Warm p50 Warm p95
Windows OCR 0 98.2 % (9 unsure) 981 ms 6.8 ms 20.3 ms
Tesseract 7 (old) 0 98.1 % (10 unsure) 1135 ms 51.8 ms 67.5 ms

Per size (the five demo frames scaled; 14 labelled cards each; read time per card):

Size Windows OCR sure / wrong Windows OCR p50 / p95 Tesseract sure / wrong Tesseract p50 / p95
1280x720 14 / 0 6.0 / 18.5 ms 14 / 0 49.3 / 70.0 ms
1920x1080 14 / 0 7.2 / 20.3 ms 14 / 0 48.5 / 62.0 ms
2560x1440 14 / 0 8.0 / 19.9 ms 14 / 0 61.5 / 76.3 ms

Cold start: Windows OCR is the helper's start to its first answer (PowerShell and the OCR engine); Tesseract is its worker and model load to its first answer. Warm: 20 reads of each of 10 crops, the first two of each dropped. Measured 2026-10-10 on the development PC (Windows 11, run from WSL). The Tesseract numbers use the same crops through the old reader (--engine tesseract, which needs npm i --no-save tesseract.js@7 for that run only).

Unsure crops (Windows OCR)

All nine are 1280x720 frames from the OBS video truth set, and each gives no item for that frame (the card keeps waiting for a frame that reads, and grey ? only if none does). In the video truth replay every one of these sets is still advised with its right items.

Frame Card Item Reader text Reason
s0#16 middle Toxic Bullets "mage" only part of the line read
s1#58 right Focus Lens (nothing) empty read
s2#10 middle Healing Tempo "lealing Tet" name cut off at both ends
s2#12 middle Healing Tempo "Spilit 108 lealing Te" tooltip text mixed into the line
s2#86 right Runed Gauntlets (nothing) empty read
s2#152 right Eternal Gift "rnml G; '" only part of the line read
s6#44 right Healing Nova (nothing) empty read
s7#2 right Bullet Resist Shredder "let Resist Shred'*" name cut off at both ends
s8#32 right Superior Duration "erior DuW" name cut off at both ends

Advice time on the video truth set

Seconds from a set becoming readable to its advice, per set, replayed frame by frame (4 frames per second, so steps of 0.25 s; each read is allowed to finish before the next frame, so this measures the logic, not the reader's speed). - means the set was not readable for 1 s. The bar is 1.0 s on every stretch (ADVICE_BY in scripts/lib/videoTruth.ts, was 1.5 s). Before = Tesseract with the old tooltip handling, after = Windows OCR with the covered rule.

Stretch Before (Tesseract) After (Windows OCR)
s0 -, -, 0.25 -, -, 0.25
s1 0, 0.25, 0.5, - 0, 0.25, 0.75, -
s2 0.5, 0, 0.75, 0 0.5, -0.25, 0.75, 0
s3 0, 0, -, 0 0, 0, -, 0
s4 0.25, -, 0 1, -, 0
s5 0.25, -2, 0.25 0.25, -2.25, 0.25
s6 -, 0.25, 0.5 -, 0.25, 0.5
s7 1, 0.25, 0 1, 0.25, 0
s8 0, 1, 0.25, 0.25 -0.25, 0.25, 0.25, 0.25
s9 -, 0, 0.25 -, 0, 0.25

A negative value is advice that went up before the labelled readable start (the set was read on a frame the label counts as still settling). s4's first set is 1 s now: its right card is under a tooltip on the first readable frames (s4#10 to 14), so it waits for an uncovered frame instead of trusting a line the tooltip covers. All four rules (right items, advice within the bar, no drop-out, no advice with no set) pass on every stretch.

Download size

The portable exe built with this change is 105.1 MB (105,086,526 bytes); the 0.4.0 release was 125.5 MB. The Tesseract engine and model are gone; the helper script adds 3.8 KB.

Re-measuring

  • npm run names:compare -- --engine winocr scores recorded answers (scripts/fixtures/ocr-recorded/) anywhere; BRAWL_OCR=live reads every crop with the helper again (Windows, or WSL through powershell.exe), BRAWL_OCR=record adds answers for new crops.
  • npx tsx scripts/video-truth-report.ts prints the table above (about 3 min).