Skip to content

Commit 68c7a43

Browse files
author
DavidQ
committed
Standardize debug overlay behavior across samples 1707+ by introducing TAB-based cycling to prevent overlay stacking and improve usability.
PR: BUILD_PR_LEVEL_17_48_APPLY_TAB_DEBUG_TO_SAMPLES_1707_PLUS
1 parent 458db78 commit 68c7a43

18 files changed

Lines changed: 585 additions & 85 deletions

docs/dev/CODEX_COMMANDS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
MODEL: GPT-5.3-codex
22
REASONING: high
3-
COMMAND: Implement Sample 1713 as the final reference game using existing engine/sample systems only. Register it in samples/index.html after the repaired 1707-1712 sequence, preserve existing work, keep logic bounded unless truly shared, and package the repo-structured result to <project folder>/tmp/BUILD_PR_LEVEL_17_45_SAMPLE_1713_FINAL_REFERENCE_GAME.zip
3+
COMMAND: Apply TAB-based debug overlay cycling to all samples from 1707 onward using shared debug infrastructure, ensuring only one overlay is visible at a time, preserving gameplay, and package to <project folder>/tmp/BUILD_PR_LEVEL_17_48_APPLY_TAB_DEBUG_TO_SAMPLES_1707_PLUS.zip

docs/dev/COMMIT_COMMENT.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
Implement Sample 1713 as the final reference gameplay sample for the repaired Level 17 sequence, with a complete playable loop, HUD, camera follow, and index integration.
1+
Standardize debug overlay behavior across samples 1707+ by introducing TAB-based cycling to prevent overlay stacking and improve usability.
22

3-
PR: BUILD_PR_LEVEL_17_45_SAMPLE_1713_FINAL_REFERENCE_GAME
3+
PR: BUILD_PR_LEVEL_17_48_APPLY_TAB_DEBUG_TO_SAMPLES_1707_PLUS
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# BUILD
2+
3+
## Instructions for Codex
4+
5+
### Apply Behavior
6+
- Ensure all samples use shared debug overlay controller
7+
- Enable TAB / SHIFT+TAB cycling
8+
9+
### Standardize
10+
- Only one overlay visible
11+
- Same ordering across samples
12+
13+
### Update
14+
- samples/index.html (no structural change, ensure compatibility)
15+
16+
### Constraints
17+
- Do not break gameplay
18+
- Do not duplicate logic per sample
19+
- Use shared debug layer
20+
21+
### Validation
22+
- Open each sample 1707+
23+
- TAB cycles overlays
24+
- No stacking
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# PLAN
2+
3+
## Goal
4+
Apply TAB-based debug overlay cycling to all gameplay samples starting at 1707 through latest.
5+
6+
## Why
7+
Samples currently stack debug overlays making them unusable.
8+
9+
## Scope
10+
- Samples 1707 → latest
11+
- No engine rewrites
12+
- Hook into debug system only

samples/index.html

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -507,13 +507,13 @@ <h2>Phase 17 - Rendering Technique Expansion</h2>
507507
<a class="live" href="./phase-17/1704/index.html" title="Unreal-style textured surfaces with lightweight dynamic lighting cues." data-tags="camera3d, unreal-style, textures, lighting, image-backed, scene, themetokens" data-primary="unreal-texture-lighting">Sample 1704 - Unreal Texture + Lighting</a>
508508
<a class="live" href="./phase-17/1705/index.html" title="Unreal-style skinned character presentation with image-backed animation frames." data-tags="camera3d, unreal-style, image-skinned, animation, character, scene, themetokens" data-primary="unreal-skinned-mesh">Sample 1705 - Unreal Skinned Mesh Demo</a>
509509
<a class="live" href="./phase-17/1706/index.html" title="Minecraft-style filled voxel terrain blocks with visible height variation." data-tags="camera3d, minecraft-style, voxel, terrain, filled-render, scene, themetokens" data-primary="minecraft-voxel-terrain">Sample 1706 - Minecraft Voxel Terrain</a>
510-
<a class="live" href="./phase-17/1707/index.html" title="Minecraft-style voxel chunk-window streaming around a movable camera anchor." data-tags="camera3d, minecraft-style, voxel, chunk-streaming, filled-render, scene, themetokens" data-primary="minecraft-chunk-streaming">Sample 1707 - Minecraft Chunk Streaming</a>
511-
<a class="live" href="./phase-17/1708/index.html" title="Real 3D mini-game loop with movement, hazard interaction, objective scoring, camera follow, and standard 3D debug panels." data-tags="camera3d, gameplay, objective, hazards, debug-panels, scene, themetokens" data-primary="real-gameplay-mini-game">Sample 1708 - Real Gameplay Mini-Game</a>
512-
<a class="live" href="./phase-17/1709/index.html" title="Compares direct axis movement, tank rotation controls, and weighted movement with follow-camera framing." data-tags="camera3d, movement-models, direct-controls, tank-controls, weighted-motion, scene, themetokens" data-primary="movement-models-lab">Sample 1709 - Movement Models Lab</a>
513-
<a class="live" href="./phase-17/1710/index.html" title="Polished gameplay loop variant with mission-state feedback, objective progression, and standard 3D debug panels." data-tags="camera3d, gameplay, polished-loop, objective, hazards, debug-panels, scene, themetokens" data-primary="real-gameplay-mini-game-polished">Sample 1710 - Real Gameplay Mini-Game</a>
514-
<a class="live" href="./phase-17/1711/index.html" title="Movement-models lab variant for sequence alignment with direct, tank, and weighted controls plus follow camera." data-tags="camera3d, movement-models, direct-controls, tank-controls, weighted-motion, scene, themetokens" data-primary="movement-models-lab-sequence">Sample 1711 - Movement Models Lab</a>
515-
<a class="live" href="./phase-17/1712/index.html" title="Gameplay telemetry overlay for mini-game state, speed, collisions, actions, and live FPS trend." data-tags="camera3d, gameplay, telemetry, metrics, debug-overlay, scene, themetokens" data-primary="gameplay-metrics-telemetry">Sample 1712 - Gameplay Metrics & Telemetry</a>
516-
<a class="live" href="./phase-17/1713/index.html" title="Final reference game sample that combines complete mission loop, camera/collision debug output, and runtime telemetry using existing systems only." data-tags="camera3d, gameplay, reference-game, telemetry, debug-panels, mission-loop, scene, themetokens" data-primary="final-reference-game">Sample 1713 - Final Reference Game</a>
510+
<a class="live" href="./phase-17/1707/index.html" title="Minecraft-style voxel chunk-window streaming around a movable camera anchor with TAB-cycled debug runtime overlay." data-tags="camera3d, minecraft-style, voxel, chunk-streaming, filled-render, scene, themetokens" data-primary="minecraft-chunk-streaming">Sample 1707 - Minecraft Chunk Streaming</a>
511+
<a class="live" href="./phase-17/1708/index.html" title="Real 3D mini-game loop with movement, hazard interaction, objective scoring, camera follow, and TAB-cycled debug overlays." data-tags="camera3d, gameplay, objective, hazards, debug-panels, scene, themetokens" data-primary="real-gameplay-mini-game">Sample 1708 - Real Gameplay Mini-Game</a>
512+
<a class="live" href="./phase-17/1709/index.html" title="Compares direct axis movement, tank rotation controls, and weighted movement with follow-camera framing and TAB-cycled overlays." data-tags="camera3d, movement-models, direct-controls, tank-controls, weighted-motion, scene, themetokens" data-primary="movement-models-lab">Sample 1709 - Movement Models Lab</a>
513+
<a class="live" href="./phase-17/1710/index.html" title="Polished gameplay loop variant with mission-state feedback, objective progression, and TAB-cycled debug overlays." data-tags="camera3d, gameplay, polished-loop, objective, hazards, debug-panels, scene, themetokens" data-primary="real-gameplay-mini-game-polished">Sample 1710 - Real Gameplay Mini-Game</a>
514+
<a class="live" href="./phase-17/1711/index.html" title="Movement-models lab variant for sequence alignment with direct, tank, and weighted controls plus TAB-cycled overlays." data-tags="camera3d, movement-models, direct-controls, tank-controls, weighted-motion, scene, themetokens" data-primary="movement-models-lab-sequence">Sample 1711 - Movement Models Lab</a>
515+
<a class="live" href="./phase-17/1712/index.html" title="Gameplay telemetry overlay for mini-game state, speed, collisions, actions, and live FPS trend with TAB-cycled debug views." data-tags="camera3d, gameplay, telemetry, metrics, debug-overlay, scene, themetokens" data-primary="gameplay-metrics-telemetry">Sample 1712 - Gameplay Metrics & Telemetry</a>
516+
<a class="live" href="./phase-17/1713/index.html" title="Final reference game sample that combines complete mission loop, camera/collision debug output, and runtime telemetry with TAB-cycled overlays." data-tags="camera3d, gameplay, reference-game, telemetry, debug-panels, mission-loop, scene, themetokens" data-primary="final-reference-game">Sample 1713 - Final Reference Game</a>
517517
</div>
518518
</section>
519519
<section>

samples/phase-17/1707/VoxelWorldDemoScene.js

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,17 @@ VoxelWorldDemoScene.js
77
import { Scene } from '/src/engine/scene/index.js';
88
import { Theme, ThemeTokens } from '/src/engine/theme/index.js';
99
import { drawFrame, drawPanel } from '/src/engine/debug/index.js';
10+
import {
11+
createTabDebugOverlayController,
12+
getTabDebugOverlayStatusLabel,
13+
isTabDebugOverlayActive,
14+
stepTabDebugOverlayController,
15+
} from '/samples/phase-17/shared/tabDebugOverlayCycle.js';
1016

1117
const theme = new Theme(ThemeTokens);
1218
const WORLD_SIZE = 16;
1319
const CHUNK_SIZE = 4;
20+
const OVERLAY_CHUNK_RUNTIME = 'chunk-runtime';
1421

1522
function clamp(value, min, max) {
1623
return Math.max(min, Math.min(max, value));
@@ -35,6 +42,12 @@ export default class ChunkStreamingVoxelScene extends Scene {
3542
this.lastFilledFaces = 0;
3643
this.lastActiveChunks = 0;
3744
this.heights = this.buildHeights();
45+
this.tabDebugOverlays = createTabDebugOverlayController({
46+
overlays: [
47+
{ id: OVERLAY_CHUNK_RUNTIME, label: 'Chunk Runtime' },
48+
],
49+
initialOverlayId: OVERLAY_CHUNK_RUNTIME,
50+
});
3851
}
3952

4053
buildHeights() {
@@ -100,6 +113,7 @@ export default class ChunkStreamingVoxelScene extends Scene {
100113

101114
step3DPhysics(dt, engine) {
102115
const input = engine.input;
116+
stepTabDebugOverlayController(this.tabDebugOverlays, input);
103117
const step = Math.min(dt, 1 / 30);
104118
const panSpeed = 3;
105119
if (input?.isDown('KeyA')) this.camera.x -= panSpeed * step;
@@ -119,7 +133,7 @@ export default class ChunkStreamingVoxelScene extends Scene {
119133
drawFrame(renderer, theme, [
120134
'Sample 1707 - Minecraft Chunk Streaming',
121135
'Voxel chunk-window streaming keeps nearby terrain active around the camera anchor.',
122-
'Controls: W/A/S/D pan | Up/Down or Q/E chunk radius',
136+
`Controls: W/A/S/D pan | Up/Down or Q/E chunk radius | Debug: Tab/Shift+Tab (${getTabDebugOverlayStatusLabel(this.tabDebugOverlays)})`,
123137
]);
124138

125139
const viewport = this.viewport;
@@ -159,13 +173,15 @@ export default class ChunkStreamingVoxelScene extends Scene {
159173
this.drawBlock(renderer, block.x, block.y, block.z, block.baseRgb);
160174
}
161175

162-
drawPanel(renderer, 620, 34, 300, 188, 'Chunk Runtime', [
163-
`World cells: ${WORLD_SIZE}x${WORLD_SIZE}`,
164-
`Camera: x=${this.camera.x.toFixed(2)} z=${this.camera.z.toFixed(2)}`,
165-
`Chunk radius: ${this.chunkRadius}`,
166-
`Active chunks: ${this.lastActiveChunks}`,
167-
`Blocks drawn: ${blocks.length}`,
168-
`Filled faces: ${this.lastFilledFaces}`,
169-
]);
176+
if (isTabDebugOverlayActive(this.tabDebugOverlays, OVERLAY_CHUNK_RUNTIME)) {
177+
drawPanel(renderer, 620, 34, 300, 188, 'Chunk Runtime', [
178+
`World cells: ${WORLD_SIZE}x${WORLD_SIZE}`,
179+
`Camera: x=${this.camera.x.toFixed(2)} z=${this.camera.z.toFixed(2)}`,
180+
`Chunk radius: ${this.chunkRadius}`,
181+
`Active chunks: ${this.lastActiveChunks}`,
182+
`Blocks drawn: ${blocks.length}`,
183+
`Filled faces: ${this.lastFilledFaces}`,
184+
]);
185+
}
170186
}
171187
}

samples/phase-17/1708/RealGameplayMiniGameScene.js

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ import {
2424
drawWireBox,
2525
stepPhase16ViewToggles,
2626
} from '/samples/phase-16/shared/threeDWireframe.js';
27+
import {
28+
appendTabDebugOverlay,
29+
createTabDebugOverlayController,
30+
getTabDebugOverlayStatusLabel,
31+
isTabDebugOverlayActive,
32+
setTabDebugOverlayActive,
33+
stepTabDebugOverlayController,
34+
} from '/samples/phase-17/shared/tabDebugOverlayCycle.js';
2735

2836
const theme = new Theme(ThemeTokens);
2937

@@ -32,6 +40,10 @@ const READY_STATE = 'ready';
3240
const RUNNING_STATE = 'running';
3341
const WON_STATE = 'won';
3442
const LOST_STATE = 'lost';
43+
const OVERLAY_RUNTIME = 'runtime';
44+
const OVERLAY_CAMERA = 'camera';
45+
const OVERLAY_COLLISION = 'collision';
46+
const OVERLAY_PHASE16 = 'phase16';
3547

3648
function clamp(value, min, max) {
3749
return Math.max(min, Math.min(max, value));
@@ -111,6 +123,15 @@ export default class RealGameplayMiniGameScene extends Scene {
111123
providerMap,
112124
enabled: true,
113125
});
126+
this.tabDebugOverlays = createTabDebugOverlayController({
127+
overlays: [
128+
{ id: OVERLAY_RUNTIME, label: 'Mini-Game Runtime' },
129+
{ id: OVERLAY_CAMERA, label: '3D Camera Summary' },
130+
{ id: OVERLAY_COLLISION, label: '3D Collision Overlays' },
131+
{ id: OVERLAY_PHASE16, label: 'Phase16 Overlay' },
132+
],
133+
initialOverlayId: OVERLAY_RUNTIME,
134+
});
114135
}
115136

116137
addEvent(text) {
@@ -191,6 +212,24 @@ export default class RealGameplayMiniGameScene extends Scene {
191212
this.syncCamera();
192213
}
193214

215+
registerDebugOverlay(overlayId, label, { makeActive = false } = {}) {
216+
appendTabDebugOverlay(this.tabDebugOverlays, {
217+
id: overlayId,
218+
label,
219+
});
220+
if (makeActive) {
221+
setTabDebugOverlayActive(this.tabDebugOverlays, overlayId);
222+
}
223+
}
224+
225+
isDebugOverlayActive(overlayId) {
226+
return isTabDebugOverlayActive(this.tabDebugOverlays, overlayId);
227+
}
228+
229+
getDebugOverlayStatusLabel() {
230+
return getTabDebugOverlayStatusLabel(this.tabDebugOverlays);
231+
}
232+
194233
pushCollisionRow(overlayId, kind, state, enabled = true) {
195234
this.debugCollisionRows.push({
196235
overlayId,
@@ -413,6 +452,7 @@ export default class RealGameplayMiniGameScene extends Scene {
413452
const dt = Math.max(0, Math.min(0.05, Number(dtSeconds) || 0));
414453
this.elapsed += dt;
415454
const input = engine?.input;
455+
stepTabDebugOverlayController(this.tabDebugOverlays, input);
416456

417457
stepPhase16ViewToggles(this.viewState, input);
418458

@@ -465,7 +505,7 @@ export default class RealGameplayMiniGameScene extends Scene {
465505
drawFrame(renderer, theme, [
466506
'Sample 1708 - Real Gameplay Mini-Game (Polished)',
467507
'Deploy, collect data cores, survive sentry patrols, and complete mission objectives.',
468-
'Start: Space/Enter | Move: W A S D | Camera yaw: Q/E or Left/Right | Restart after match: R | Camera mode: C',
508+
`Start: Space/Enter | Move: W A S D | Camera yaw: Q/E or Left/Right | Restart: R | Overlay: Tab/Shift+Tab (${this.getDebugOverlayStatusLabel()})`,
469509
]);
470510

471511
const viewport = this.viewport;
@@ -599,7 +639,10 @@ export default class RealGameplayMiniGameScene extends Scene {
599639
max: this.roundSeconds,
600640
barColor: '#38bdf8',
601641
});
602-
renderer.drawText('Camera mode: C | Debug overlay: V', 64, 166, { color: '#e2e8f0', font: '11px monospace' });
642+
renderer.drawText(`Camera mode: C | Overlay cycle: Tab/Shift+Tab (${this.getDebugOverlayStatusLabel()})`, 64, 166, {
643+
color: '#e2e8f0',
644+
font: '11px monospace',
645+
});
603646
renderer.drawText('Move: W A S D | Yaw: Q/E or Left/Right', 64, 182, { color: '#e2e8f0', font: '11px monospace' });
604647

605648
const statePulse = 0.5 + Math.sin(this.statePulse * 3.2) * 0.5;
@@ -637,20 +680,28 @@ export default class RealGameplayMiniGameScene extends Scene {
637680
: `Status: ${this.gameState}.`,
638681
]);
639682

640-
drawPanel(renderer, 620, 414, 300, 120, 'Mini-Game Runtime', [
641-
`Entities: obstacles=${this.obstacles.length} sentries=${this.enemies.length}`,
642-
`Remaining cores: ${this.cores.filter((core) => !core.collected).length}`,
643-
`Player: x=${this.player.x.toFixed(2)} z=${this.player.z.toFixed(2)}`,
644-
`Collision overlays: ${this.lastCollisionCount}`,
645-
`Camera mode: ${this.viewState.cameraMode}`,
646-
]);
683+
if (this.isDebugOverlayActive(OVERLAY_RUNTIME)) {
684+
drawPanel(renderer, 620, 414, 300, 120, 'Mini-Game Runtime', [
685+
`Entities: obstacles=${this.obstacles.length} sentries=${this.enemies.length}`,
686+
`Remaining cores: ${this.cores.filter((core) => !core.collected).length}`,
687+
`Player: x=${this.player.x.toFixed(2)} z=${this.player.z.toFixed(2)}`,
688+
`Collision overlays: ${this.lastCollisionCount}`,
689+
`Camera mode: ${this.viewState.cameraMode}`,
690+
]);
691+
}
647692

648-
this.renderStandardDebugPanel(renderer, PANEL_3D_CAMERA, 620, 34, 300, 150, 7);
649-
this.renderStandardDebugPanel(renderer, PANEL_3D_COLLISION, 620, 194, 300, 210, 9);
693+
if (this.isDebugOverlayActive(OVERLAY_CAMERA)) {
694+
this.renderStandardDebugPanel(renderer, PANEL_3D_CAMERA, 620, 34, 300, 150, 7);
695+
}
696+
if (this.isDebugOverlayActive(OVERLAY_COLLISION)) {
697+
this.renderStandardDebugPanel(renderer, PANEL_3D_COLLISION, 620, 194, 300, 210, 9);
698+
}
650699

651-
drawPhase16DebugOverlay(renderer, viewport, this.viewState, [
652-
`Match state: ${this.gameState}`,
653-
'Standard 3D camera/collision debug panels rendered from provider snapshots',
654-
]);
700+
if (this.isDebugOverlayActive(OVERLAY_PHASE16)) {
701+
drawPhase16DebugOverlay(renderer, viewport, this.viewState, [
702+
`Match state: ${this.gameState}`,
703+
'Standard 3D camera/collision debug panels rendered from provider snapshots',
704+
]);
705+
}
655706
}
656707
}

0 commit comments

Comments
 (0)