Environment: /chatt?diorama&walk, reported 2026-08-12 against the #701 spawn fix.
Actual: the bike sometimes relocates on its own — you leave it somewhere, and later it
is not where you left it.
Expected: a parked bike stays parked until you ride it.
Root cause: the walk controller silently rebuilds
src/twin/TwinCanvas.client.tsx, tryBuildWalk():
if (!buildings || !terrain || !groundAt) return;
walkCtrlRef.current?.dispose(); // <- no "already built" guard
const ctrl = EmbodiedController.fromMeshes(...);
...
ctrl.teleport(sx, sy, sz);
ctrl.parkBike(sx, sy, sz);
There is no guard against rebuilding. Every call disposes the live controller and
constructs a new one, which re-runs parkBike(spawn) — so the bike snaps back to the spawn
point. From wherever you had left it, that reads exactly as "it got pulled somewhere else."
tryBuildWalk is invoked from three places, any of which can fire more than once:
#701 added the third trigger. It was necessary (the sampler had to be able to complete
the build when it arrives last, which is what fixed the 33 m underground spawn), but it
increased the number of ways a rebuild can happen. Worth stating plainly rather than
discovering later.
EmbodiedController also seeds bikePos_ from config.spawn ?? {0,0,0} in its constructor
(src/lib/cod/player/EmbodiedController.ts:222-227), and fromMeshes is called with no
spawn, so between construction and parkBike() the bike is briefly at the world origin.
Probably invisible today, but it is a second reason the bike's position is not stable across
a rebuild.
Also worth checking
The player is teleported to spawn by the same code path (ctrl.teleport). If rebuilds are
happening mid-play, the player should be snapping back too — either that is also happening
and has been read as something else, or something about the ordering makes the bike the
visible symptom. Worth confirming which, because it distinguishes "rebuild fires
occasionally" from "only the bike's position is unstable."
Fix sketch
Make the build idempotent: return early when a controller already exists and its inputs have
not changed, rather than dispose-and-rebuild on every callback. If a genuine rebuild is ever
needed (new terrain), preserve the player and bike poses across it instead of re-seeding both
to spawn.
Verification
Park the bike well away from spawn, walk a few hundred metres, wait through any late asset
loads, and confirm it has not moved. Instrument the number of EmbodiedController builds per
session — the expected count is one.
Environment:
/chatt?diorama&walk, reported 2026-08-12 against the #701 spawn fix.Actual: the bike sometimes relocates on its own — you leave it somewhere, and later it
is not where you left it.
Expected: a parked bike stays parked until you ride it.
Root cause: the walk controller silently rebuilds
src/twin/TwinCanvas.client.tsx,tryBuildWalk():There is no guard against rebuilding. Every call disposes the live controller and
constructs a new one, which re-runs
parkBike(spawn)— so the bike snaps back to the spawnpoint. From wherever you had left it, that reads exactly as "it got pulled somewhere else."
tryBuildWalkis invoked from three places, any of which can fire more than once:handleTerrainMesh— on the terrain mesh callbackhandleBuildingsMesh— on the buildings mesh callbackhandleGroundReady— added by fix: walk mode — spawn, collision, trajectory, and a way to say where you are #701, when the elevation sampler publishes#701 added the third trigger. It was necessary (the sampler had to be able to complete
the build when it arrives last, which is what fixed the 33 m underground spawn), but it
increased the number of ways a rebuild can happen. Worth stating plainly rather than
discovering later.
EmbodiedControlleralso seedsbikePos_fromconfig.spawn ?? {0,0,0}in its constructor(
src/lib/cod/player/EmbodiedController.ts:222-227), andfromMeshesis called with nospawn, so between construction andparkBike()the bike is briefly at the world origin.Probably invisible today, but it is a second reason the bike's position is not stable across
a rebuild.
Also worth checking
The player is teleported to spawn by the same code path (
ctrl.teleport). If rebuilds arehappening mid-play, the player should be snapping back too — either that is also happening
and has been read as something else, or something about the ordering makes the bike the
visible symptom. Worth confirming which, because it distinguishes "rebuild fires
occasionally" from "only the bike's position is unstable."
Fix sketch
Make the build idempotent: return early when a controller already exists and its inputs have
not changed, rather than dispose-and-rebuild on every callback. If a genuine rebuild is ever
needed (new terrain), preserve the player and bike poses across it instead of re-seeding both
to spawn.
Verification
Park the bike well away from spawn, walk a few hundred metres, wait through any late asset
loads, and confirm it has not moved. Instrument the number of
EmbodiedControllerbuilds persession — the expected count is one.