Three paths that stopped being true when the packages split - #280
Merged
Conversation
Each is a default that was correct when there was one root, and that the move to four packages made wrong. All three fail SILENTLY, which is why they survived: none of them is on a path CI takes. **`browser/driver.ts` pointed at the front door.** `APP_URL` falls back to a local dev server, and the fallback stayed 5173 when Titanic's page moved to its own root on 5174. A bare `npx tsx taoot/tests/browser/playthrough.ts` therefore asked the site for a `play/` it does not serve and got the sibling signpost — a 404 page explaining which server to start, which is a puzzling thing for a suite to try to boot a game out of. CI never saw it, because `browser.yml` passes `APP_URL` explicitly. Now 5174, and verified by running `menu-movie.ts` with the variable unset: it boots, plays `menu.mov` and clicks its regions. **`flowmap.ts` looked for `gamefiles` beside the wrong directory** — twice, and the second one matters more than the first. `rootDir` defaulted to the bare string, which is resolved against the WORKING DIRECTORY and named a path that no longer exists from the repository root; it now goes through `gamefilesRoot()`, which resolves from the file and honours `TAOOT_GAMEFILES` the way everything else in that directory already did. The second is that the publish step computed the repository root as ONE level up from `taoot/tools/`, from when the tool lived in `tools/`. So `docs/public` was looked for at `taoot/docs/public`, and the whole publish sits behind `existsSync` — a wrong path is indistinguishable from "you have no docs checkout", the run reports success for everything else it wrote, and the interactive flow map quietly stopped being regenerated at the move. Same for `node_modules`: a workspace package's own directory holds its symlinks and none of the hoisted dependencies, so the vendor copy could not have found cytoscape either. **`dumpscripts.ts` assumed a rip at the root.** It is a shared tool, so it may not import a game to find one — the default is discovered instead: the two environment variables the runner sets, then each game's `gamefiles/` resolved from this file, and a named error rather than a stack trace when there is none. It answers the same from any working directory now, and reads Dust's disc as happily as Titanic's. The docs written last week described these as known-stale and told the reader to work around them; those passages are updated to describe what the code does instead. Not included, deliberately: running the two tools rewrites `shipgraph.gen.ts` and the flow map's `DATA`, and both come out different here because this machine has seven trees installed where whoever last generated them had fewer — `demo` in particular is a different cut of the game and not a translation. Regenerating them is a real change to what the navigator reads, and it should be its own commit made on purpose rather than a side effect of fixing a path. Verified: `npm test` 534/534, `npm run test:playthrough` 30/30, `tsc --noEmit` clean, the VitePress build clean, and the three tools exercised from two working directories each. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
dhobi
added a commit
that referenced
this pull request
Aug 23, 2026
…ne edition (#281) Two things, and the second is the one with a decision in it. ## The comments A source comment naming a path is documentation, and it rots the same way — so this is the same sweep #279 did for `docs/`, run over the code. Not by memory: a scan pulled every path-shaped token out of every comment in the four packages and `tools/`, resolved each against the filesystem, and only what failed to resolve was touched. Most of what it found was idiomatic shorthand and correct (`df/savegame.ts`, `nav/dials.ts`, a served `editors/tracks.html`); what was left was one shape, in twenty-odd places. `engine/<x>.ts` used to name the runtime directory. `engine/` is the whole package now, so every one of those reads as a file that is not there. Inside the package they are `runtime/<x>.ts`, matching the `df/<x>.ts` shorthand already used beside them; outside it they are spelled out. The same move sent `bug-report.ts` to `site/`, `mklangstg.ts` into `taoot/tools/`, the editors into `site/editors/`, and `masks.ts` out of the playthrough and into the runtime — where `session.ts` was still pointing at its old home, which is now a reference from the engine into a game's test directory for a file that sits next to it. Two that were not path drift: - `tools/gif.ts` credited `tools/mkintromov.ts`, which was renamed and moved to `taoot/tools/mknightdive.ts`; - `proptrace.ts` explained what it replaced by naming `taoot/tests/browser/iface.ts`, which is in no commit — a throwaway probe that was never checked in. The account is worth keeping and the path is not. And `dust/src/main.ts` opened by saying the page has "no engine, no interpreter, no editions, no saves" while importing `GameHost`, the save browser and two audio sinks. That was true of the experiment and stopped being true as the experiment worked: it boots off the disc through the same host Titanic uses, plays the intro films through the engine's own `MoviePlayer`, and saves `.rtd` through the shared browser. What is left of the original is the standalone set walker, which `start()` keeps as the FALLBACK for a boot that cannot produce a viewer — so the "every frame decoded up front" section now says which half of the page it is about, because the game does not pay that cost. ## The flow map reads one tree, and says which `flowmap.ts` emits two things that are COMMITTED: `shipgraph.gen.ts`, which the playthrough navigator walks, and the interactive map under `docs/public/`. Its input was the whole rip, so its output was a function of which editions the person running it had installed. On a seven-tree install that is 326 trips against `en`'s 271 — scripts are deduplicated by content, but the trees are not all the same game, and `demo` is a different CUT that contributes trips the full game has not got. So the default is one tree now, via `activeLanguage()`: `TAOOT_LANG` when set, `en` when not, a path argument to override, and the generated header records which tree it read so the next regeneration is comparable to this one. Regenerated deliberately on that footing, and the result is the reassuring one: **the graph data is byte-identical to what was committed** — 271 trips, 214 fully understood, the header line the only diff — and the flow map's own output does not change at all. The committed artifacts were always `en`; nothing had drifted, and there was no way to reproduce them until #280 fixed the publish path. Now there is, and it is pinned. Verified: `npm test` 534/534, `npm run test:playthrough` 30/30, `tsc --noEmit` clean, `build:dust` clean, `dust/tests/browser/built-layout.ts` good across four viewports. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #279, which documented these rather than changing them. Each is a default that was correct when there was one root, and that the move to four packages made wrong. All three fail silently — none is on a path CI takes, which is why they survived.
taoot/tests/browser/driver.tspointed at the front doorAPP_URLfalls back to a local dev server, and the fallback stayed 5173 when Titanic's page moved to its own Vite root on 5174. A barenpx tsx taoot/tests/browser/playthrough.tsasked the site for aplay/it does not serve and got the sibling signpost — a 404 page explaining which server to start, which is a puzzling thing for a suite to try to boot a game out of.CI never saw it:
browser.ymlpassesAPP_URLexplicitly, which is also why the default could rot without a red tick anywhere.Verified by running
menu-movie.tswith the variable unset — it boots, playsmenu.movand clicks its regions:taoot/tools/flowmap.tslooked beside the wrong directory — twicerootDirdefaulted to the bare string"gamefiles", resolved against the working directory, naming a path that no longer exists from the repository root. It now goes throughgamefilesRoot(), which resolves from the file and honoursTAOOT_GAMEFILES— as everything else in that directory already did.The second one matters more. The publish step computed the repository root as one level up from
taoot/tools/, from when the tool lived intools/. Sodocs/publicwas looked for attaoot/docs/public, and the whole publish sits behindexistsSync— a wrong path is indistinguishable from "you have no docs checkout", the run still reports success for everything else it wrote, and the interactive flow map quietly stopped being regenerated at the move.git logondocs/public/flow-map/shows one commit, the initial import.Same bug for
node_modules: a workspace package's own directory holds its symlinks and none of the hoisted dependencies, so the vendor copy could not have found cytoscape either.Before / after, same command:
tools/dumpscripts.tsassumed a rip at the rootIt is a shared tool — it works on any rip because it takes one as an argument — so it may not import a game to find one. The default is discovered instead: the two environment variables the runner sets, then each game's
gamefiles/resolved from this file, and a named error rather than a stack trace when there is none.taoot/, no argsdust/gamefilesno rip found: pass one as the first argument, or set TAOOT_GAMEFILES / DUST_GAMEFILES., exit 1Docs
#279 described all three as known-stale and told the reader to work around them (
export APP_URL=…, spelling outtaoot/gamefilesin every example). Those passages now describe what the code does.ci.md's "the dev server does not get port 5173" is now 5174, which is the port the runner actually has to stay off.Not included, deliberately
Running the two tools rewrites
taoot/tests/playthrough/nav/shipgraph.gen.tsand the flow map'sDATA, and both come out different here — 271 → 326 trips — because this machine has seven trees installed where whoever last generated them had fewer.demoin particular is a different cut of the game, not a translation, so it contributes genuinely different scripts.That makes regeneration a real change to what the playthrough navigator reads, and it depends on which editions the generating machine happens to have. It should be its own commit, made on purpose, rather than a side effect of fixing a path. Both files are reverted here.
Verified
npm test534/534 ·npm run test:playthrough30/30 ·tsc --noEmitclean · VitePress build clean · all three tools exercised from two working directories each.🤖 Generated with Claude Code