Partial refetch: only draw new tiles, don't clear canvas

With BUFFER_LONG = 1, refetch fires every ~1 tile of motion (every
~8 sec at default speed). With BUFFER = 1 the center shifts by
~1 tile per refetch, so only ~1 net new tile needs fetching each
time (the one at the very front of the new corridor).

Switch to partial refetch:
- Don't clear the canvas before redrawing
- Skip tiles already in groundLoadedTiles (they're still on the
  canvas at the right position from a prior refetch)
- Only newly-positioned tiles are drawn (the ones in the new
  front of the corridor, ahead in flight direction)

Effect: user sees tiles appearing at the front of the corridor in
the direction of travel, not the whole canvas flashing every 8 sec.
With N flight, fetch activity shows up at the top of the screen
(where lng=+12 lands after the axis swap), confirming the flight
direction is correct.
This commit is contained in:
Richard Zink committed 2026-10-08 07:23:14 +02:00
1 parent bfe0a559b5
commit 4cf3c00dfa
1 file changed
+11 -6
+11 -6
View File
@@ -379,12 +379,12 @@ function rebuildGroundMosaic(centerTileX, centerTileY) {
groundCenterTile = { x: centerTileX, y: centerTileY }; groundCenterTile = { x: centerTileX, y: centerTileY };
var halfLong = Math.floor(GROUND_CORRIDOR_LONG / 2); var halfLong = Math.floor(GROUND_CORRIDOR_LONG / 2);
var halfPerp = Math.floor(GROUND_CORRIDOR_PERP / 2); var halfPerp = Math.floor(GROUND_CORRIDOR_PERP / 2);
// Clear with fog colour so we don't get ghosting from old tiles // Partial refetch: don't clear the canvas. Tiles already loaded
// at wrong canvas positions. The shader's edgeFade makes OOB // (from a previous refetch) stay visible. Only new tiles are
// samples blend smoothly to uBg, so the brief fog state during // drawn on top, so fetch activity shows up at the front of the
// tile fetch is invisible. // corridor (in flight direction) instead of flashing the whole
groundCtx.fillStyle = '#7c9aa1'; // canvas. The drawTileAt call hashes by (tileX, tileY) so already-
groundCtx.fillRect(0, 0, groundCanvas.width, groundCanvas.height); // loaded tiles are skipped.
var promises = []; var promises = [];
for (var perp = -halfPerp; perp <= halfPerp; perp++) { for (var perp = -halfPerp; perp <= halfPerp; perp++) {
for (var lng = -halfLong; lng <= halfLong; lng++) { for (var lng = -halfLong; lng <= halfLong; lng++) {
@@ -393,6 +393,11 @@ function rebuildGroundMosaic(centerTileX, centerTileY) {
// camera's actual path, not just the +X axis. // camera's actual path, not just the +X axis.
var dx = Math.round(lng * GROUND_TRAVEL_COS - perp * GROUND_TRAVEL_SIN); var dx = Math.round(lng * GROUND_TRAVEL_COS - perp * GROUND_TRAVEL_SIN);
var dz = Math.round(lng * GROUND_TRAVEL_SIN + perp * GROUND_TRAVEL_COS); var dz = Math.round(lng * GROUND_TRAVEL_SIN + perp * GROUND_TRAVEL_COS);
var tileX = centerTileX + dx;
var tileY = centerTileY + dz;
// Skip tiles already loaded (still drawn at the right canvas
// position from a previous refetch or the initial load).
if (groundLoadedTiles[tileX + '_' + tileY]) continue;
promises.push(drawTileAt(lng, perp, dx, dz, centerTileX, centerTileY)); promises.push(drawTileAt(lng, perp, dx, dz, centerTileX, centerTileY));
} }
} }