Max Silverstein

golfcoach

A practice coach that reads a golf simulator's own log files and never writes to them.

In development · Local only

golfcoach reads three simulator outputs through a read-only boundary — FSX Play Unity's Player.log for club delivery, GSPro's currentRound.dat for ball flight and spin, and swing-camera clips — and never writes back to those directories. Parsers normalize that data into golfcoach's own SQLite store. Miss clustering and a strokes-gained cost model then produce one ranked practice priority. This diagram documents that pipeline; it is not a validated diagnosis.

System diagram · golfcoach

Built
Aug 2026
Role
Solo
Stack
Python · SQLite · stdlib only
Status
in development
Published figures as of
2026-09-04

A Foresight launch monitor already measures every shot. What it does not do is tell you what your misses have in common, what they cost you in strokes, or which single thing is worth practicing. This reads the files the simulator already writes and answers those questions.

Problem and failure definition

The simulator belongs to my father, it lives in his garage, and it works today. The failure mode that mattered was not a wrong analysis — it was breaking his machine. Stated plainly at the outset: I would rather not build this at all than risk damaging the setup.

That turned a preference into an architectural constraint. The tool reads files the simulator has already written, after or alongside a session, and keeps its own copy. It is never in the path of a shot, and it writes nothing to any simulator directory.

System

Two readers, because the two applications record different halves of the shot. FSX Play’s Unity log carries club delivery — speed, face angle, path, attack angle, impact location. GSPro’s round file carries ball flight — launch angle, spin, spin axis. Swing-camera clips are copied out before the simulator clears them.

Everything lands in SQLite. There are no dependencies: the tool is Python standard library only, because the simulator PC runs an embeddable Python distribution where installing packages is an unwelcome intervention on a machine that currently works.

Analyzers group misses, price them with a strokes-gained cost model, and rank what to work on. A local web view serves the report to a phone on the same network.

Verification

Validated twice against the real simulator, with zero writes to any simulator directory confirmed after each session. The read-only guarantee is covered by tests rather than left to discipline, following the same standard laid out in how work on this site is verified.

The suite is large — 673 tests collected — and it protects specific failure boundaries: parser behavior against malformed and truncated log lines, shot deduplication across overlapping reads, cost-model arithmetic, and the read-only invariant itself.

This repository is local-only, with no remote, which is why there is no source link above. The appendix below is published in its place, and lays out what those 673 tests actually cover.

Result

Capture, shot record, findings, the strokes-gained cost model, the analyzers, and the phone-served report are built and running on real launch-monitor data.

Limits

This is not finished, and its central claim is not yet earned. Ground-truth validation has begun and has not cleared its own bar — the commit log records the first ground-truth label and why it does not count as passing. Until that resolves, the diagnoses are plausible rather than demonstrated.

It has also never been run against a genuinely representative practice session. Everything captured so far is data-collection swings, which are not how anyone actually practices, so the miss clusters describe a corpus that may not resemble real play.

There are no users but me, no accuracy metric against a coach’s assessment, and no claim that the advice improves anyone’s golf.

Appendix: what the tests actually cover

The suite reads and asserts against four file formats. FSX Play writes club-delivery data — clubhead speed, face angle, swing path, attack angle, impact location — into a Unity Player.log, one line per shot, interleaved with whatever else Unity happens to log that session. GSPro writes ball-flight data — launch angle, spin rate, spin axis — into its own currentRound.dat. Swing-camera clips land as .avi files in a directory the simulator rotates through as sessions accumulate. The tool’s own SQLite store is the fourth format under test, since a parser that reads correctly but writes a corrupt record back out is still a failure.

The read-only invariant is asserted as a property every parser and analyzer has to satisfy, not checked once and left alone. As of 2026-09-04, every parser and analyzer path exercised by the suite opens files under either simulator’s directory tree in read-only mode, checked against the same malformed, truncated, and duplicate-read inputs used to test parsing and deduplication, rather than as one isolated test. That is a property confirmed over the inputs the suite actually exercises — malformed lines, truncated files, and duplicate reads — not a proof that no input could ever cause a writable open.

The 673 collected tests sort into four groups. The largest is parser behavior against malformed input — truncated lines, out-of-range field values, and a log file that ends mid-write because the source application was killed rather than closed normally. A second group covers shot deduplication: the same shot can appear twice if a session file is read more than once, and these tests check that re-reading a file already captured does not duplicate the shot record. A third group is strokes-gained cost arithmetic — given a lie, a distance, and an outcome, the cost model has to charge the right number of strokes relative to a baseline, and these tests pin that arithmetic down against known cases rather than trusting the formula on inspection. The fourth group is the read-only invariant described above.

A representative report ranks a handful of miss groups by strokes-gained cost rather than by how often each occurs, so a miss that happens rarely but costs a lot outranks one that happens constantly but costs almost nothing. The specific groups and their costs vary session to session — that variation is the point. A report that always surfaced the same advice would be describing golf in general, not this data.