Repository navigation
Releases
v1.6.9 - Legend per game, fewer misread names
Legend per game, fewer misread names
Legend played, per game
The tracker already asks Apex Legends Status for each squadmate's RP every ~45 seconds. The same answer says which legend they have selected, which during a match is the legend they're playing. That's now saved with each game, for everyone on your roster.
- The CSV gets a new
legendcolumn, and the database gets one too once the owner runssupabase_migration_legend.sqlin the Supabase SQL editor. Until then, games still sync; the legend just stays in the CSV. - The dashboard shows each player's legend on Match History, and the player cards list their most-played legends with games, average damage and kills.
- It's only for roster players (not randoms), and only for games the tracker was running for. If you start it late, that game may have no legend. If someone's EA privacy setting hides their online status, ALS can't see their legend either. Older games can't be filled in.
- This uses the same web API calls as RP tracking. Nothing touches the game.
Misread names
- Your own card. The summary always shows you in the middle card, so a middle name that misreads (a game logged as "FK" instead of yzRobo) now logs as you. The tracker works out who plays on the PC from your recent games, or you can set Your roster name in All settings. It won't do this when ALS shows you weren't in a match, so someone else playing on your PC under another account still logs under their own name.
- Club tags and capitals.
[TAG] yzRoboandYZROBOnow count as yzRobo. - Name changes. When a squadmate with an account ID changes their Apex name, ALS reports the new name and the tracker logs their games under their roster name. For anyone without an ID, add
"name_aliases": {"NewName": "RosterName"}to config.json. - One- and two-letter reads no longer get matched to a roster name just because the name starts with that letter.
"PUB" on ranked games
When the tracker misses the ranked badge (for example when started mid-session), the app's Last line used to say PUB even after the RP check proved the game was ranked. It now switches to RANKED and shows each player's RP once that check finishes. The database was already right; only the app's label was stale.
How it was tested
New unit tests cover the legend choice (latest in-match reading; readings from the previous game or a teammate's next game are dropped), the restart case, the middle-card fallback and when it must not fire, club tags, capitals, renames, the CSV column upgrade, syncing to a database without the new column, and the Last line update. The legend reading was checked live on 2026-11-07: ALS reported Wraith for yzRobo and Lifeline for NameJFK, both confirmed by the players. The middle-card setting and the one-time CSV upgrade were run on a copy of the stream PC's real CSV (1,056 rows unchanged; only the legend column added). The whole flow hasn't yet run end to end against a live game.
Update
Use the in-app update, or download ApexTracker_share.zip, close the tracker, and replace the program files. Keep your existing config.json and .env.
v1.6.8 - Reliability: fewer missed games, no silent failures
Reliability release: fewer missed games, no silent failures
A full review of the scanner against the stream PC's logs and the whole match database turned up several ways games were missed or logged wrong without any warning. This release fixes them, and makes anything that still goes wrong visible in the app.
Missed or wrong games
- #10-#20 with 10+ squad kills. The header is right-aligned, so a two-digit kill total pushes the placement left out of its box. #10 and #20 read as 0 and the game was never logged; #11-#19 logged as 1-9 (e.g. a 12th place stored as 2nd). The placement box now follows the total-kills number. Verified on a real #10 game the old build lost, plus 28 composited headers (#1-#20 with 0, 1, 11 and 13 kills).
- 1-kill games had no squad total. A lone gold
1never OCRs, so about 1 in 9 games showed 0 squad kills. The total is now taken from the players' kills when the header can't be read (never over a value that was read). - Native 16:9 profile revive/respawn. The boxes cut the top off the digits, so revive 1 read as 7 or blank and respawn 0 as 6. Existing installs are corrected automatically (only if the shipped values are still there; hand-calibrated boxes are left alone).
Nothing fails silently any more
- A summary that won't log is flagged. If a summary is on screen but hasn't logged after 15 s, the app shows a red warning with the reason so you can press Capture. If it leaves the screen unlogged, the frame and the reason are saved to
debug\unlogged\and the app shows "Missed a summary at …". A quick tab-away that comes back and logs is not counted. - RP tracking status is shown. No ALS key, a rejected key, or ALS being unreachable used to look exactly like normal tracking while every game logged without RP. The app now says when RP is off or failing, and the "Last" line notes a game that logged without RP.
- Errors no longer end the watch. An exception in one pass used to stop tracking for the rest of the night while the app still looked alive. The watch now recovers and shows the error (red while it repeats).
- CSV open in Excel. A locked CSV used to lose the match from both the CSV and Supabase. The match now still syncs to Supabase and waits in
apex_matches_unsaved.csvuntil the CSV can be written. Open CSV now opens a copy so it can't lock the file. - Supabase down. A failed insert is queued in
apex_matches_unsynced.jsonland retried with the next match. - Debug-log notes for RP resolution and Supabase errors (the windowed build used to discard them).
RP on games two squadmates both logged
When two trackers log the same game, the database keeps the first copy and deletes the second. If the deleted copy was the one with RP, that game lost its RP. On the owner's tracker (service key), the RP is now written to the surviving copy, matched by the whole match's placement, kills and damage.
How it was tested
The placement, squad-total and revive/respawn fixes were run against every real summary frame we have (only the intended values changed). Both watch loops were run end to end on a replayed summary, including a summary that never logs and a quick tab-away. The locked-CSV side file, the Supabase retry queue and the cross-PC RP fallback were tested against fakes, not yet against a real locked file or the live database trigger.
Update
Use the in-app update, or download ApexTracker_share.zip, close the tracker, and replace the program files. Keep your existing config.json and .env.
v1.6.7 - Fix phantom extra digit from card art
Fix: phantom extra digit from card art (e.g. 768 damage logged as 7,687)
Each player card's character art sits to the right of the stat column and can reach into the damage and Kills / Assists / Knocks boxes. When the art has a bright vertical edge there, OCR reads it as an extra trailing digit: 768 → 7687 damage, 1 → 11 knocks. The old white-pixel filter couldn't remove art that is itself bright, and the K/A/Kn line had no filter at all.
- Before reading damage and K/A/Kn, the tracker now cuts the box at the first wide empty gap after the number. Values are left-aligned with at most ~9px between characters at 1080p, and the art starts 44px or more past the text (measured on 7 real summary screens), so the cut sits at 20px (scaled to your resolution).
- If there's no such gap, the box is read exactly as before. Worst case is no change, never a clipped digit.
- Verified by painting an art-like vertical stroke ~50px past the text on a real summary: the old reader produced
2,616→26161and2/5/2→2/5/21, and the new one reads every value correctly. All reference screenshots still read 100%. - No frame of an actual bad read was available, so this fixes the mechanism the code already documented rather than replaying a captured failure.
- New
test_trim_trailing_art.py(source only).
Update
Use the in-app update, or download ApexTracker_share.zip, close the tracker, and replace the program files. Keep your existing config.json and .env.
v1.6.6 - Fix summary screens that were never logged
Fix: summary screens with a fused K/A/Kn line were never logged
The game's italic slashes on the Kills / Assists / Knocks line sometimes OCR as the digit 1, so 7 / 7 / 7 reads as 71717. That gives 71,717 kills, which fails the sanity check (more than 75 is impossible), so the tracker treated the screen as "still rendering" and retried. Every retry read the same frame the same way, so the match was dropped silently, even with the summary on screen for minutes. This happened to a ranked win on 2026-10-25.
- When the K/A/Kn line comes back with fewer than three numbers, the tracker now tries reading the
1s as slashes (71717→ 7/7/7,101213→ 10/2/3). - It only accepts a split when exactly one reading gives three believable stats. Ambiguous reads (e.g.
111111, which could be 11/1/1, 1/11/1 or 1/1/11) are still not guessed. They stay unread and get retried as before. - Clean reads with three numbers are unchanged. The 4 reference screenshots still read 100%.
- New
test_parse_kak.py(source only) covers the live case, partial fusions and the ambiguous cases.
Roster
config.json adds HeckaTrix to known_names and als_uids (1011198512420). The updater keeps your existing config.json, so on an existing install add him in Settings → roster (name HeckaTrix, UID 1011198512420), then Save and Stop → Start.
Update
Use the in-app update, or download ApexTracker_share.zip, close the tracker, and replace the program files. Keep your existing config.json and .env.
v1.6.5 - Fix RP attributed to the wrong match
Fix: RP showing on the wrong match
ALS often posts a match's RP a few seconds before the tracker reads the summary screen. The RP resolver only looked for changes after that moment, so it skipped each game's own result and grabbed the next game's. That shifted RP by one match, and if a game was missed, its RP landed on the previous match.
- The starting RP now comes from the last reading taken just before the match's result could post, and the RP change is searched for from that point.
- A quick game the tracker never logged no longer gets added into the next match (e.g. -43 and -48 showing as -91 on one row).
- Early leavers (RP posting minutes before the summary screen) are still handled by the baseline chain.
- Replaying the full 11-day stream-PC ledger: 87/88 matches get the right RP, vs 50/88 before.
New: repair_rp_from_ledger.py (source only)
Fixes per-match RP already in Supabase using an rp_ledger.jsonl from the PC that runs the tracker. It previews by default, and --apply writes the changes after saving a backup.
Update
Download ApexTracker_share.zip, close the tracker, and replace the program files. Keep your existing config.json and .env.
v1.6.4 - consistent RP + reliability fixes
v1.6.4 — consistent RP + reliability fixes
Fixes the two things that made RP look/feel unreliable, plus two capture/log
issues found in the debug logs.
RP now reads correctly
starting_rpreflects the real baseline. When the tracker corrects a stale
snapshot (a squadmate's RP posts before the summary is read), it now writes the
corrected start value too — so a resolved game never shows the confusing
"start == end but +362 change" anymore. The change was always right; the start
column was stale. It's consistent now.
Faster, finer, quieter
- Poll interval auto-bumps 120s → 30s on older installs. Updates keep your
config.json, so setups from before v1.6 were still polling every 2 minutes —
too coarse, so back-to-back games' RP piled into one reading. 30s catches
results as they settle. (Only the old default is changed; a custom value is
kept. You can also set it in Settings → ALS poll interval.) - OBS Virtual Camera recovers ~5x faster from a stalled feed (~8–12s instead
of ~60s). A feed stall landing on a summary was dropping whole games; this
catches the summary while it's still on screen. - Stopped a debug-log quirk that wrote a bogus "session start" line every RP
sweep (made normal runs look like constant restarts).
No changes to detection, OCR, capture modes, or match logging.
Update
Click Update now in the app, or download ApexTracker_share.zip, unzip,
run Start Tracker.bat. Settings + history kept.
v1.6.3 - reliable RP for early-leavers
v1.6.3 — reliable RP for early-leavers / instant-requeue
Fixes the per-player RP flakiness (TCremer22 was the worst case): a player who
dies early and instantly re-queues is perpetually "in a match", and EA/ALS
serves a player's stale pre-match RP while they're in a match. So their RP
sat frozen for several games and then lurched in one step — which got recorded
as a false 0 or a blank, while squadmates who played the match out resolved
cleanly.
Fix: the tracker already logged the in-match flag but ignored it. A 0 is now
only recorded once the player's RP is seen settled in the lobby (out of a
match), not while they're still mid-game serving a stale number. If a player's
realtime status is hidden (EA privacy), behaviour is unchanged.
This eliminates the false 0s and lets a real result land once RP settles.
Games whose results genuinely collapse into a single reading (an instant-requeuer
who never sits in the lobby) still resolve as honest blanks — that's a limit of
what ALS exposes, not something any tracker can split.
Builds on v1.6.2 (reject bad ALS readings, persistent baseline chain).
Update
Click Update now in the app, or download ApexTracker_share.zip, unzip,
run Start Tracker.bat. Settings and history are kept.
v1.6.2 - RP reliability fixes
v1.6.2 — RP reliability fixes
Diagnosed from a week of live data: some tracked players got a 0 out of
nowhere, one row had an impossible −243, a fast back-to-back pair both got
the same −65, and a couple of rows carried literal 0 RP totals. Three
root causes, three fixes:
Fixed
- Bogus ALS readings are now rejected. EA/ALS occasionally serves
rankScore: 0for a player who very much has RP. That glitch used to poison
the baseline, fake a "season reset", and fabricate deltas. It now counts as a
failed poll — the tracker keeps the last good reading. - Baselines are chained across matches, durably (new
rp_chain.json). The
next match's baseline is corrected against the previous match's observed
end value. This fixes two real bugs from the data:- fast back-to-back games no longer attribute the same RP movement to both
matches (the second game's snapshot froze before the first game's RP had
propagated); - a squadmate who dies and leaves early no longer gets a false 0 (their RP
posts before the summary screen is read, so the old baseline already
contained their gain).
The chain survives restarts and even a cleared pending queue.
- fast back-to-back games no longer attribute the same RP movement to both
- A 0 is only recorded with pre-match evidence. If the tracker never
observed the baseline before the match ended (e.g. it was started on the
summary screen), a flat reading proves nothing — the match resolves as an
honest blank instead of a fabricated 0. This kills the
"first game of the night is always 0" bug. - Last-ditch sanity: nothing beyond a believable single-game loss and no
zero/negative RP totals can ever be written, whatever upstream produced them.
Install / update
Click Update now in the app, or download ApexTracker_share.zip, unzip
anywhere, and run Start Tracker.bat. Settings and match history are kept.
v1.6.1 - window scroll fix
v1.6.1 — window scroll fix
Fixes a layout regression in v1.6.0: the new per-player session-RP status panel
made the main window taller than its fixed height, and the main window (unlike the
settings dialog) didn't scroll — so the bottom row, including "Check for
updates", got clipped off the bottom with no way to reach it.
The whole window now scrolls (mouse wheel or the scrollbar) and its height is
clamped to your screen, so everything is reachable on any screen size or DPI
scaling. No other changes from v1.6.0.
(Everything from v1.6.0 still applies: RP tracking v2 — always-on RP ledger,
self-healing session RP, resolve-time classification. If you sync to the shared
dashboard, the owner must have run supabase_migration_rp_v2.sql.)
Install
Download ApexTracker_share.zip, unzip anywhere, and run Start Tracker.bat
(or ApexTrackerUI.exe). No Python needed.
v1.6.0 - RP tracking v2 (session RP + resolve-time classification)
RP tracking v2 — live session RP + resolve-time classification
The biggest change to RP tracking since it launched. Instead of deciding a match's
RP the moment it's logged, the tracker now records every ALS reading to a
durable local ledger and classifies each match's RP afterward, from real evidence.
A missed ranked-badge read can no longer lose a game's RP.
New
- Live session RP. The status panel and console heartbeat now show each
squadmate's current rank and a self-healing session RP (net gain/loss this
session) — the same number as end-of-night RP minus start-of-night RP. It
self-corrects, so a stale or missed reading never throws it off. - RP is collected for every match. The ranked badge is now a hint, not a
gate: if it's missed on a real ranked game, an observed RP change still proves
the match was ranked and records the delta (previously that RP was lost). - Net-zero games resolve. A ranked loss pinned at a division floor (0 RP) is
confirmed by stable readings instead of hanging unresolved. - Honest blanks. Two games that collapse into one reading, or anything that
spans a season reset, are left blank rather than guessed — no made-up numbers. - Stuck-match visibility. If a match sits unresolved abnormally long, the
heartbeat now tells you (with the details), so you know without digging. - Faster ALS polling (30s), a season-reset guard, and a new inspectable
rp_ledger.jsonlthat answers "why did this match get this number" after the fact.
Deprecated
als_assume_zero_on_timeoutis now ignored — the new zero-confirm logic replaces
it and is safer (it won't stamp a false 0 on a slow-propagating game or a pub).
Dashboard sync
If you push stats to the shared dashboard, the project owner must run
supabase_migration_rp_v2.sql once (it lets the resolver update the ranked
flag after insert). Owner builds work without it; friend builds need it to store
the flag.
Install
Download ApexTracker_share.zip, unzip anywhere, and run Start Tracker.bat
(or ApexTrackerUI.exe). No Python needed. Paste your own free ALS API key in
Settings to enable rank/RP tracking.