Skip to content
PLLAY Vision AI

The broadcast becomes the data feed.

Video in, settlement decision out. Frames are sampled, the regions an adapter declares are read, a reconciler argues the reads against each other across time, and what survives is one candidate with a confidence tier. The tier decides what is allowed to happen to money — and three of the four tiers decline to pay.

01Broadcast

A recorded VOD today; the live source exists but has never been run.

02Frame sampling

Frames pulled on the adapter's declared cadence, not every frame.

03Per-region OCR

Only the boxes the adapter declares are read, gated by a presence probe.

04Reconciler

Debounce and guards across frames — one bad frame cannot become an outcome.

05Candidate

At most one per game: a score, a winner, and a confidence tier.

06Settlement gate

Vision proposes. The gate disposes, and applies the tier as a ceiling.

How this was measured

These are bench results, not production results.

Everything below comes from an internal accuracy harness run against recorded video — publicly available match uploads, cited by clip id. It is not a sample of live traffic, because there is none: PLLAY Vision has never been run against a live stream. A bench of recorded footage is a weaker claim than production volume, and publishing it as what it is beats implying what it isn't.

The harness
  • Each clip runs the full pipeline, not a replay of a saved read — the same extractor, reconciler, and gate the service uses.
  • The run exits non-zero if, and only if, a wrong auto-settlement occurred. A single wrong payout fails the run outright; nothing else can.
  • Every trial writes a row: clip id, adapter, tier, outcome, and the reason. That file is what this page reads at build time.
  • Processing takes 2.4s–19 minutes of wall clock per clip. This is a batch process. Nothing here is real-time, and nothing here settles anything.
What “correct” means here

Correct means the system behaved as designed — which includes refusing. A trial that declined to settle ambiguous footage is correct. A trial that returned the winner but flagged it for review is correct.

So the totals below are deliberately never shown as a ratio. A correct/total fraction would read as an accuracy rate, and it is not one — it would count every refusal as a success in a way that flatters the number.

38
recorded trials
0
wrong auto-settlements

A wrong auto-settlement is the only failure that costs a user money: an automatic settle that paid the wrong side.

The record

Where every trial landed.

One tier settles. The other three are the product. A system that pays out confidently when it is right is ordinary; a system that reliably refuses when it is unsure is the thing worth building, and the only thing worth trusting with a pool of other people's stakes.

AUTOSettles

Terminal score stable, high-confidence, and unanimous. The only tier that can move money.

31
CONFIRMStaged for review

Readable, but not clean enough to pay on: two signals disagree, or a scoreboard read leaned on a low-confidence frame or recovered from lost continuity. Downgraded, never auto-paid.

1
VOIDRefunded

The terminal state has no winner. Stakes are returned rather than guessed at.

2
HOLDNothing happens

No candidate cleared the bar at all. Silence is recorded as silence, never read as an outcome.

4

31 settled · 7 declined · 0 paid the wrong side

The refusals

The trials that declined to pay.

These are the most informative rows in the record, so they are named individually rather than summarised. In each case the footage was readable enough that a less careful system would have produced an answer.

CONFIRMmadden-walkoff-dual

FINAL banner score disagrees with in-game bar (read discrepancy) -> hold for confirmation

madden26_ea_broadcast.json · clip Ukxgys0alBs

VOIDcs2-tie

voided (terminal score is a tie -> void_and_refund)

cs2_matchresult.json · clip xBJMU3WYn_I

HOLDcs2-faceit-hold

no candidate (safe) — EXPECTED for this clip

cs2_matchresult.json · clip tPjEdpdRQGQ

HOLDmadden-ot-cut

no candidate (safe) — EXPECTED for this clip

madden26_ea_broadcast.json · clip XBhsOfXEDa4

HOLDdota-team-lobby

no candidate (safe) — EXPECTED for this clip

dota2_victory.json · clip rgQU28d2y9s

HOLDr6-splash-only-hold

no candidate (safe) — EXPECTED for this clip

r6_result.json · clip dlUFN2avVxs

VOIDow2-draw-void

voided (terminal score is a tie -> void_and_refund)

ow2_result.json · clip UjT_U_7GP68

A branded overlay it would not guess

On a tournament-platform broadcast, the end banner names the winning team rather than printing the result word the adapter was calibrated for. The wider banner fragments across detections and the read falls below the confidence floor, so nothing settles. The point of view player's team had in fact won — a confident wrong read here would have paid out.

Closing this is a new calibrated adapter for that overlay, not looser matching logic. Loosening the matcher is how a system starts guessing.

Footage that ends too early

Several refusals share one cause: the upload cuts before the screen that actually declares the result. A game-winning play is visible, the celebration is visible, and the terminal frame never arrives. The system holds.

One of them is a win whose upload ends on a flavour-texted victory splash that is deliberately excluded as a read surface, because its wording varies. Holding is the designed behaviour, not a miss.

Benchmarked titles

14 games with a measured record.

Grouped by the identifier each adapter declares for itself, so a title with more than one calibrated overlay is one row here and its adapter files are both named. Coverage is uneven on purpose — a title is added by finding footage of both outcomes, not by writing a plausible adapter and assuming.

GameAdaptersTrialsSettledDeclined
overwatch-2ow2_result.json541
league-of-legendslol_result.json440
cs2cs2_matchresult.json312
fortnitefortnite_result.json330
maddenmadden26_ea_broadcast.json, madden26_final_banner.json312
rainbow-six-sieger6_result.json321
rocket-league-sideswipesideswipe_winner.json330
apex-legendsapex_result.json220
dota2dota2_victory.json211
nba2knba2k26_broadcast.json220
pubgpubg_result.json220
rocket-leaguerocketleague_winner.json220
valorantvalorant_result.json220
warzonewarzone_summary.json220
Benchmarked is not the same as an adapter existing

There are 22 adapter files in the repository. 15 of them have trials on the record above. The remaining 7 have never been run against footage — some are placeholders written ahead of a game's release, some are superseded calibrations kept for reference. They are not supported titles and are not counted as any.

arena_dodge_v1.jsongta_race_result.jsonmadden_26.jsonmadden_27.jsonmadden26_g4_postgame.jsonmadden26_tnp_yt1072.jsonmadden27_final_banner.json
The adapter model

A new title is mostly a new config file.

An adapter is a JSON file describing where on screen to look and what the words there mean: normalised boxes, the token vocabulary that maps to an outcome, and the reconciler thresholds that guard it. Supporting a broadcast overlay is calibration against real frames rather than an engineering project — with an honest caveat: the engine has occasionally had to change, and each time it was because a game exposed a genuinely new settlement shape rather than a new layout.

Result-screen only
13

The end screen is the only evidence stream. A presence probe gates every frame cheaply, and when the result banner appears its wording maps to a winner. Most titles are this shape, because most end screens simply name the outcome.

Scorebug and banner
2

Sports broadcasts carry a running score as well as a final card, giving two independent readings of the same fact. That redundancy is what makes the disagreement guard possible: when the two do not agree, the settlement is downgraded rather than resolved in favour of whichever read looked stronger.

Region kinds in use
final_banner_presentfinal_banner_score_awayfinal_banner_score_homefinal_banner_winner_textfinal_banner_winner_text_centerfinal_banner_winner_text_centregame_clockquarterscore_awayscore_bug_presentscore_hometeam_away_abbrteam_home_abbr

Every region declared across the 15 benchmarked adapters. There is nothing here that reads chat, a kill feed, or player identity — the settlement path looks at scoreboards, result banners, and the clock, and at nothing else.

How each region is read
clocknumericpresencetext

A presence probe answers only “is the overlay on screen”, so frames showing a replay, a cutscene, or an advert cost almost nothing and contribute nothing. Text regions must match a declared token to count; a value the adapter does not recognise becomes nothing rather than a guess.

The full ledger

All 38 trials.

The complete record, in the order the harness ran it. Clip identifiers are the public uploads each trial was run against, so any row here can be checked against the footage it came from.

Open the full record →
TrialAdapterClipOutcomeTierProcessing
madden-walkoff-bannermadden26_final_banner.jsonUkxgys0alBs32-34 awayAUTO42.2s
madden-walkoff-dualmadden26_ea_broadcast.jsonUkxgys0alBs32-34 awayCONFIRM119s
nba2k-houmilnba2k26_broadcast.jsonvw6h2mrWkRY135-126 homeAUTO708.2s
cs2-tiecs2_matchresult.jsonxBJMU3WYn_IVOIDVOID428s
cs2-win-povcs2_matchresult.jsonWZQ2uQq8tjk1-0 homeAUTO164.5s
cs2-faceit-holdcs2_matchresult.jsontPjEdpdRQGQHOLDHOLD465.9s
dota-dire-victorydota2_victory.jsonjRRDQ5VOR6E0-1 awayAUTO2.4s
fortnite-winfortnite_result.jsonHK3Wd-w2SJI1-0 homeAUTO1089.5s
fortnite-lossfortnite_result.jsonIp4FwkQwZrQ0-1 awayAUTO868.8s
madden-ot-cutmadden26_ea_broadcast.jsonXBhsOfXEDa4HOLDHOLD519.9s
dota-team-lobbydota2_victory.jsonrgQU28d2y9sHOLDHOLD611.6s
nba2k-minokcnba2k26_broadcast.json2lqbuJhcxso34-38 awayAUTO480.9s
warzone-winwarzone_summary.jsonvAkzIZCL2iI1-0 homeAUTO1153.6s
warzone-losswarzone_summary.json99-OtWZK7Rs0-1 awayAUTO1054.5s
valorant-win-surrendervalorant_result.jsonASjWottDK6s1-0 homeAUTO433s
valorant-lossvalorant_result.jsonqjOIE4UBZhQ0-1 awayAUTO307.3s
rocketleague-blue-winrocketleague_winner.json2KyScgSWUqM1-0 homeAUTO167s
rocketleague-orange-winrocketleague_winner.jsonXoDgXubVawM0-1 awayAUTO223.8s
fortnite-loss-ch6fortnite_result.jsonJieJN4Bjrpk0-1 awayAUTO937.5s
apex-winapex_result.jsonWFBCi-ta1681-0 homeAUTO888.8s
apex-lossapex_result.jsonXFq3wYbI9JM0-1 awayAUTO26s
lol-win-720lol_result.jsono4dsmNKsSIA1-0 homeAUTO51.9s
lol-win-1080lol_result.jsonlFXLzuvlTpM1-0 homeAUTO51.4s
lol-defeat-720lol_result.json13gF_JO-FjE0-1 awayAUTO72.5s
lol-defeat-1080lol_result.jsonYORYLUNLJw40-1 awayAUTO76.5s
r6-victory-1080r6_result.jsonlqZ-uH-jDHM1-0 homeAUTO234.9s
r6-defeat-720r6_result.jsonA0YDZ7k4-9w0-1 awayAUTO136s
r6-splash-only-holdr6_result.jsondlUFN2avVxsHOLDHOLD98.8s
pubg-win-chickendinnerpubg_result.jsonUrOwJPNqj_s1-0 homeAUTO221.9s
pubg-loss-betterluckpubg_result.jsonizzLxN2jhRE0-1 awayAUTO212.9s
ow2-victory-1080ow2_result.jsonUjT_U_7GP681-0 homeAUTO8.9s
ow2-defeat-1080ow2_result.jsonUjT_U_7GP680-1 awayAUTO8.8s
ow2-draw-voidow2_result.jsonUjT_U_7GP68VOIDVOID9.5s
ow2-defeat-720ow2_result.jsonKKDWc2zpPCw0-1 awayAUTO66.3s
ow2-defeat-1080-bow2_result.json5h-8Ajy5tK80-1 awayAUTO84s
sideswipe-away-169sideswipe_winner.jsonhhXtXyKGOsA0-1 awayAUTO120.2s
sideswipe-home-209sideswipe_winner.jsonqbQTl9JS_k81-0 homeAUTO13.9s
sideswipe-away-209sideswipe_winner.jsonqbQTl9JS_k80-1 awayAUTO12.2s
What is real, and what is not

The gates were built before the automation.

The honest summary is that the safety machinery is finished and the automation is not. The queue, the audit trail, the off switch, and the rule that this service can only ever propose a settlement are all in place — and nothing is deployed behind them. That ordering was deliberate, and stating it plainly is more useful than a launch date.

Live

The pipeline and its guards

Frame sampling, per-region OCR, and the reconciler run end to end today. Every guard the offline suites cover runs on every trial in the record above.

Live

The durable job queue

A vision_jobs table and a claim function exist in the database, so runs can be queued and claimed rather than executed by hand from a laptop.

Live

The off switch, shipped off

Autonomous settlement is gated behind a platform config flag that ships disabled. The gate was built before the automation it gates, deliberately.

Live

Propose-only by construction

The worker process never calls a settlement function. It writes a verdict and hands it to the resolution layer, which treats the tier as a ceiling on what may happen next.

Next

Shadow mode

One worker, running against live footage, writing verdicts to the audit log and settling nothing. Comparing those verdicts against what actually settled is the only honest way to earn the right to automate.

Next

Deployment

There is no container image and no deploy configuration for the vision service anywhere in the codebase, and continuous integration runs only the offline suites. It runs where an engineer runs it, and nowhere else.

Potential

Live ingest

A live frame source is written and unit-tested against the reconciler's wall-clock guards. Nothing calls it. PLLAY Vision has never been pointed at a live stream.

No pilot is open, no availability is being offered, and no date is being given for any of the above. The next honest milestone is shadow mode, and until its verdicts have been compared against real settlements there is nothing further to claim.

See it run

Watch a real run, frame by frame.

A single trial from the record above, played back against the reconciler's own log — what it saw, when it changed its mind, and why it landed where it did.