v5.1.5 put the whole codebase under the microscope and started working through a six-phase improvement plan. v5.1.6 finishes it — the last of the data-integrity work, and then the part the plan had been building towards: finding everywhere the app was doing the same job several times over, and making it do the job once.
Recording a result used to save your tournament two to four times in a row. Drawing a 32-player bracket used to re-read the entire match history sixty-odd times, once per card on screen. Neither was ever wrong — it was just work nobody asked for, repeated every time you completed a match, assigned a lane, or changed a referee. Now it happens once. The scores, the brackets, the standings are identical to the last decimal; there is simply less happening behind them.
Along the way, a few small things that were wrong turned up and got fixed.
Doing Less, Getting the Same
Four places where the app was quietly repeating itself:
Completing a match saves once. Recording a result touched the saved tournament again and again: once for the result, again after recalculating the live rankings, again if the match set a placement — the Backside Final’s third place, or a Single Elimination bronze match — and again if it finished the tournament. Each of those rewrote everything: every player, every match, plus a redraw of the status panel and the results table. It all happens in one go now. Playing a full 32-player double-elimination tournament went from 127 saves to 63.
Drawing the bracket reads the history once. Every match card asks whether its result can still be undone, and that question used to re-read and re-parse the tournament’s entire history of events — about 63 times per redraw on a full bracket. And the bracket redraws after every lane assignment, every referee change, every completed match. It now reads once and shares the answer with all the cards.
Analytics loads in parallel and stops reloading. The Dashboard, Leaderboard, Players and Matches views used to fetch each tournament’s matches one at a time, waiting for each before asking for the next. They now ask for them all at once. Better still, switching the point mode or toggling the Ranking and Attendance layers only changes how the numbers are multiplied — the matches are the same — so those toggles no longer re-read anything at all. With a dozen tournaments loaded, rendering the four views dropped from 48 database reads to 12, and a toggle from 48 to none.
The status panel stopped re-reading the tournament. The panel on the Tournament page refreshes after every save, and it used to fetch and unpack the entire saved tournament to display a name, a few counts and a status — data the app was already holding.
One more thing simply stopped: the help system had been watching the entire page for changes, waking on every bracket render, every table repaint, every tick of the clock, just to work out which page you were on. The app already knows when it changes page. Now it just says so.
Small Things, Now Right
F1 help matches the page you’re on after a reload. The app reopens on the page you left, but the part that tracked which page that was only started listening half a second later — and so missed it. Reloading straight onto the Tournament page and pressing F1 gave you Setup help until you navigated somewhere else. It now matches from the first press.
The Short Leg Threshold setting reaches the Chalker. The setting lives under CHALKER on the Config page, but until now the Chalker never received it — it judged short legs by its own built-in table while the Tournament Manager awarded the achievement using your configured value. The on-screen badge could disagree with what you were actually credited. The threshold now travels with the rest of the match setup, so the badge and the award always agree. Matches started on the device itself still use the sensible built-in table.
The “BS-FINAL” label looks right on 16-player brackets. Its typeface name had picked up a stray accent somewhere along the way — one character — which was enough to drop the label to a generic fallback font. Fixed, and fixed in a way that keeps it fixed: the three near-identical copies of that label’s drawing code are now one, so the typo has nowhere left to hide.
Export filenames survive awkward tournament names. A tournament called Spring/Fall: Cup now produces a valid, sensibly-named download instead of a broken one.
Safer With Your Data
The match register writes cleanly. The behind-the-scenes register that feeds Analytics now records each completed match in a single, all-or-nothing step. A quick re-entry after an undo, or a hiccup part-way through a delete, can no longer leave it half-updated.
Analytics notices when you correct a finished tournament. Analytics holds the finalized tournaments it has loaded in memory, but nothing told it to let go of them when a match in one of those tournaments was undone or re-entered — possible through the maintenance route for correcting a completed tournament. It could keep showing the old figures until the page was reloaded. Completing and undoing a match now clear that held copy once the change is written.
Previewing a bracket no longer forgets the tournament you were editing. In the Analytics-only deployment, opening a bracket preview used to deactivate whatever tournament you had open — the data was never at risk, but you had to go and reopen it. The preview now puts things back where it found them, and surviving a reload mid-preview no longer risks the read-only preview being mistaken for a real tournament.
One Place, Not Five
The quiet half of this release: the app had grown second and third copies of the same logic in a dozen places, and copies drift. Two of them mattered enough to name.
Whether an undo is allowed, and why it isn’t. Two separate pieces of code worked out whether a completed match could still be undone — one answering yes or no, deciding whether a winner’s name is clickable, the other producing the wording you see on hover and in Match Controls: “Cannot Undo, blocked by FS-3-1 (live).” They had to be kept in step by hand, and once already weren’t: when QR completions arrived, the same fix was needed in both and got made in only one. They now share a single answer, so the button and the explanation cannot disagree.
How player names are matched. Analytics identifies players by name — each tournament stores its own player numbering, so there is nothing else to match on across tournaments. That means every screen has to agree on exactly how a name is tidied up before comparing it, or the same person quietly becomes two people, or a player’s record differs between the Leaderboard and the Players tab. That tidying was written out by hand in twenty places. It is now defined once.
And a long list of smaller ones, all invisible from the outside: the achievement-points formula that lived in five places, two hand-rolled copies of the Chalker score decoder, the referee assign and clear paths, the bracket’s default zoom, the 32-player backside layout, the tournament export. Roughly a thousand lines lighter across this release and the last, with fewer places for the next fix to be missed.
Migration
No migration required. Fully compatible with all existing tournament data, match history, and Analytics. This release changes how much work the app does, not the data it works on. Installed Chalker PWAs refresh to the new version automatically on their next online launch.
Fun fact: every change here was checked by replaying whole tournaments through the old code and the new, side by side, and demanding identical results down to the byte. One of those test harnesses passed cheerfully for an afternoon before anyone noticed it was comparing nothing at all.
NewTon DC Tournament Manager v5.1.6 — One Throw, One Score.