fix(client): the Atlas was replaying a cache from a build that no longer existed (T-1239)
Ferrath's Global map drew no rivers at native resolution: 375 courses arrived and 0 were drawn. The report suspected the D-261 length cull or the water truncation. Both were innocent, and so was the renderer. The client served the canvas from its own disk cache (T-1183). Every payload for GJ820Bc predated T-1237 (4e503c356), which replaced one-course-per-D8-hop with one-course-per-river -- so the map was drawing 375 hop fragments whose longest run was 106 km, all of them under D-261's read-as-a-line floor. Same build, same scenario, same 3440x1440, cache the only difference: stale courses=375 runs=180 longest=6.0px (~106 km) drawn=0 cold courses=73 runs=23 longest=93.2px (~1,644 km) drawn=18 It looked resolution-dependent because it wasn't a resolution at all: 960x540 resolves to an 814x407 canvas, a key never cached, so it missed and re-derived correctly. 3440x1440 resolves to 1080x540, which had an entry from 2026-08-06. During the stale capture the server logged no course production whatsoever -- the canvas never came from it. The cache's only invalidation signal is project.yaml's version, and4e503c356changed how canvases are generated without touching it, so hop-shaped entries stayed valid. All 13 stale entries are stamped 0.4.5. 0.4.6 forces them to miss; that, not clearing a local directory, is what repairs a player's Atlas. The harness let this hide for eight days, in two ways now fixed. It ran against the developer's persistent user:// cache, so a capture could render a canvas built by a build that no longer existed -- and any golden shot in that window silently inherited it; user:// is now isolated per run. And it sent server stderr to /dev/null via an already-unlinked mktemp file, so no tracing from a capture was ever reachable; the log now lives at .cache/visual-server.log. The capture readout gained runs= and longest= between courses= and drawn=, because "375 arrived, 0 drawn" is not one fact but three stages, and telling them apart is what turned a guess between two suspects into a measurement. Follow-ups filed: T-1241 (current_schema_version() returns its ?.?.? fallback in an exported build, so a shipped game never invalidates on version at all) and T-1242 (nothing enforces the generation-change/version-bump pairing -- this is the fourth bump forced after the fact). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -781,6 +781,21 @@ fn invent_courses_for_canvas(
|
||||
});
|
||||
}
|
||||
|
||||
// T-1239: the network is built once per body on the fixed GRID_W x GRID_H
|
||||
// working grid, so these counts MUST NOT vary with canvas extent. They were
|
||||
// observed to (73 courses at one viewport, 375 at another), which is only
|
||||
// visible if the pre-crop network size is logged next to the post-crop wire
|
||||
// size — the client can only ever see the latter.
|
||||
tracing::info!(
|
||||
river_cells = river_network.river_cells.len(),
|
||||
paths = paths.len(),
|
||||
courses = courses.len(),
|
||||
longest_path_cells = paths.iter().map(|p| p.cells.len()).max().unwrap_or(0),
|
||||
ta_w = ta.w,
|
||||
ta_h = ta.h,
|
||||
"step canvas: river course production"
|
||||
);
|
||||
|
||||
courses
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user