Skip to content

How It Was Built Part 2

baddo edited this page Sep 28, 2026 · 1 revision

Part of How OpenShaker was built

Part 2: how we worked

Who did what

  • The maintainer set the goals, sat in the chair, drove every test lap, reported what they felt and made the decisions: no game mods; no ACE helper for HaptiConnect; always on, and later an on/off switch; exact parity, loudness included; no forwarding; the name, the license and no recorded audio in the app; and when to publish.
  • Several parts of the method were the maintainer's ideas: learn from recordings of HaptiConnect's output; "train off actual game output", not synthetic test signals; compare with spectrograms; and replay ACE into HaptiConnect's own Assetto Corsa plugin.
  • Claude (an AI model made by Anthropic) read HaptiConnect's logs and program strings, wrote the code and the tests, measured every recording and explained each step. The maintainer asked for that explicitly: "can you give me a why so I can visualize how this works".
  • Later the work was split across several Claude sessions, each owning one part (the app, matching HaptiConnect, Trackmania, the release) and one coordinating them. Written handoff notes carried the state from one session to the next.

The chair rules

  • Only the maintainer runs, quits and relaunches their apps, picks HaptiConnect's output and launches games. Claude asks first and never ends a program of theirs unasked. Standing permission is possible: "close and reopen the app when needed".
  • Nothing may steal focus or pop up a window, because the maintainer may be in a fullscreen game.
  • Before restarting the maintainer's running copy, Claude checks that no game is running. Once it waited for a Trackmania drive to finish.
  • The messages show the rhythm: "I'm in the chair", "on track", "FM at menu", "ACE done".

How claims were checked

  • Tests that fake the system (next section).
  • Independent reviews, with every finding verified again before it counted:
    • a pre-publish audit, which found the unplug bug, an unsaved Master level and a startup failure that showed nothing;
    • a parity audit, which found the channel bug and the missing limiter;
    • a review of the code written to match HaptiConnect, which found 15 confirmed bugs, each fixed with a test that keeps it fixed. Examples: a packet clock that went backwards froze the road rumble; 12-per-second timers drifted on logs with four-decimal clocks; one bad number could silence the whole mix;
    • a four-reviewer check, which found ports left blocked;
    • an adversarial review of a logged Trackmania drive, which found the respawn crashes;
    • a skeptic agent that worked out the Horizon kerb answer again from scratch.
  • Tests of the tests. The 14 bugs a review found in the new slider code were put back one at a time in a scratch copy, and the tests caught every one (Sliders).
  • Random-data tests of every packet reader (Bad data).
  • Held-out drives. Tuning was always checked on laps left out of the fitting.
  • Dry runs. Settings migrations ran first on a copy of the maintainer's real settings, with backups.
  • Tested docs. A test checks every link, anchor and picture in these documents.
  • Fact-checks. An independent agent checked the first draft of HOW_IT_WAS_TUNED against the logs and found 6 wrong and 12 overstated claims; a second check before the release tightened more. HaptiConnect's timing was measured before it was published. This page started as an outline that a separate reviewer checked against the sources: 23 corrections and 19 missing items, all applied here. Two more checks then went through every quote and every number on this page against the original chats, notes and code.

Tests that fake the system

September 18

Problem. A test in another project on the same PC really ended processes by name. Every run of it silently killed any other console Python on the PC, including an OpenShaker test run, which just vanished. OpenShaker's own tests could also briefly steal keyboard focus.

What we found.

  • Three OpenShaker test files wrote and deleted real values in the user's registry, including a fake old startup entry. A hidden, read-only check from outside Claude's sandbox found no leftovers, because the sandbox had kept those writes to itself.
  • Even a hidden test window can grab the foreground.
  • One half-closed test window stayed behind, and later tests' slider values silently attached to it and did nothing.

Fix. A standing rule for every session: tests never touch real processes, the registry, audio devices, the running app's ports, the Start menu or the user's files.

  • Fakes stand in for all of them: an in-memory registry, temporary settings folders, free random ports, fake processes and fake audio.
  • Test windows are off-screen, transparent, and hand the focus straight back. In 23 checks, then 81, no test window ended up in front.
  • Two flaky tests were made deterministic.

When the AI got it wrong

Being candid here is part of the transparency promise.

  • Most of the bugs on this page were in Claude's own code: the BeamNG pedals read from the wrong place since the first day, Forza's surface value clipped at 1.0, one game's settings leaking into the next (about 12 dB), "Save" freezing the calibration into the user's settings, the silent fallback to the default output, and defaults frozen into the settings file. The exclusive-stream trap only became the normal case after Claude made the app start with Windows; in Claude's words: "That's now the normal case, because I made it auto-start".
  • It claimed work it hadn't done. Claude told the maintainer the window fixes were made and "verifying now". They weren't; it had only started reading the files. The handoff note it wrote next says so under "Current state, honestly", and the next session opened with the correction (Is the GUI finished?).
  • It promised no console window. On September 10 Claude said the shortcut "opens the window with no console". A command window then appeared, twice (The command window).
  • It misdiagnosed the test-tone bug as an amplifier fault, until the maintainer's "Demo works" report cracked it.
  • It started writing a BeamNG mod nobody asked for, and dropped it when the maintainer objected. In Claude's own words, the mod was "the shortest path from where the code stood, not the best one" (No game mods).
  • It named the wrong company as HaptiConnect's maker in the README. An audit caught it: HaptiConnect is The Guitammer Company's.
  • It trusted early test signals too far. Several first readings of HaptiConnect, from test signals and from the first real laps, were wrong and had to be measured again (HOW_IT_WAS_TUNED, Chapter 2).
  • It thought a channel fix had worked when it hadn't. The real fix came ten days later (Left channel only).
  • It ended its own shell with a process filter that matched itself.
  • Its installer build emptied the output folder and deleted an old, superseded test installer. A backup existed.
  • An older OpenShaker build left a rate cap in Data Sender's settings, which later caused data blackouts in Trackmania (A blackout every second).
  • Its own first draft of the tuning write-up had 6 wrong claims and 12 overstated ones, caught by the fact-check above.

Traps in Claude's own workspace

Problem. Several wrong turns came from Claude's tools, not from the app. Claude runs inside the Claude desktop app's sandbox on Windows.

What we found, each one checked:

  1. The sandbox quietly redirects installs under AppData, so the maintainer's programs couldn't see them. That caused the numpy crash.
  2. It redirects the user's registry too, so Claude couldn't turn on "Start with Windows" or add a Start menu entry directly.
  3. HaptiConnect started from Claude's shell bound no ports. It has to be started through Windows Explorer.
  4. A recording run from Claude's shell read the sandbox's stale copy of the settings.
  5. Claude's shell mangles backslashes in inline scripts, so scripts are written to a file first.
  6. A process filter matched itself, and Claude ended its own shell.
  7. Claude couldn't remove HaptiConnect's Startup shortcut, so it asked the maintainer.

Fix. The lessons went into the handoff notes: nothing the user runs lives under AppData; the app registers itself; and anything that must act as the user runs through a hidden script started by Windows Explorer.

The maintainer's hands caught what the meters missed

  • "Should I be feeling the playback? Because I don't": a crashed replay tool (more).
  • "a little powerful": saved settings overriding the calibration (more).
  • "The volume on our version is still higher": the left-channel discovery, which was found twice (more).
  • "when I press test tone I get no vibration": the exclusive-stream trap (more).
  • "it shakes a lot" at idle: HaptiConnect's own BeamNG preset (more).
  • "I didn't really notice curbs": a clipped surface value and a buzz pitched too high (more).
  • "our model definitely has more noise while driving in a straight line": the muddy first version, diagnosed by the maintainer (more).


<- Part 1: why OpenShaker exists | Contents | Part 3: the problems, chapter by chapter ->

Clone this wiki locally