Skip to content

Commit 2570b89

Browse files
author
DavidQ
committed
Level 18.7 overlay integration with mission system.
Enable Mission Feed overlay to reflect live mission state.
1 parent 5b7ca54 commit 2570b89

7 files changed

Lines changed: 113 additions & 41 deletions

File tree

docs/dev/CODEX_COMMANDS.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ MODEL: GPT-5.4-codex
22
REASONING: medium
33

44
COMMAND:
5-
Add overlay diagnostics tooling:
6-
- Log overlay index and stack state
7-
- Add optional debug toggle
8-
- Ensure zero impact when disabled
9-
- Do not change overlay behavior
5+
Integrate overlay system with mission system:
6+
- Connect Mission Feed overlay to mission state updates
7+
- Ensure live updates reflect correctly
8+
- Preserve existing overlay behavior
109

1110
Package ZIP to <project folder>/tmp/

docs/dev/COMMIT_COMMENT.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Level 18.6 overlay diagnostics and debug tooling.
2-
Add visibility into overlay state and cycle behavior.
1+
Level 18.7 overlay integration with mission system.
2+
Enable Mission Feed overlay to reflect live mission state.
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[ ] Diagnostics output correct state
2-
[ ] Toggle enables/disables logs
3-
[ ] No performance impact when disabled
4-
[ ] No behavior change
1+
[ ] Mission Feed updates with state
2+
[ ] Overlay cycle unaffected
3+
[ ] No regression in other overlays
4+
[ ] Stable behavior

docs/pr/BUILD_PR.md

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,31 @@
1-
# BUILD_PR_LEVEL_18_6_OVERLAY_DIAGNOSTICS_DEBUG_TOOLING
1+
# BUILD_PR_LEVEL_18_7_OVERLAY_MISSION_SYSTEM_INTEGRATION
22

33
## PLAN
44

55
### Purpose
6-
Introduce lightweight diagnostics and debug tooling for overlay system to aid validation and future debugging.
6+
Integrate overlay system with mission system so Mission Feed and related overlays respond to mission state changes.
77

88
### Goals
9-
- Provide visibility into overlay state
10-
- Expose current stack + index
11-
- Enable debug logging toggle
9+
- Sync Mission Feed overlay with mission state
10+
- Ensure overlay updates reflect live mission progress
11+
- Maintain overlay cycle behavior
1212

1313
---
1414

1515
## BUILD
1616

1717
### Scope
18-
- Add diagnostic hooks (non-invasive)
19-
- Add debug output for:
20-
- Current overlay index
21-
- Active stack
22-
- Cycle key events
23-
- Optional debug toggle (no UI change required)
24-
- No behavior change
18+
- Hook overlay system into mission state updates
19+
- Ensure Mission Feed overlay reflects current mission data
20+
- No changes to overlay positioning or cycling
21+
- No UI redesign
2522

2623
### Test Steps
27-
1. Enable diagnostics
28-
2. Cycle overlays
29-
3. Verify logs show correct state transitions
30-
4. Disable diagnostics
24+
1. Trigger mission updates
25+
2. Verify Mission Feed overlay updates
26+
3. Cycle overlays and confirm consistency
27+
4. Confirm no regression in other overlays
3128

3229
### Expected
33-
- Clear debug visibility
34-
- No runtime impact when disabled
30+
- Mission Feed reflects live state
31+
- Overlay system remains stable

samples/phase-17/1708/RealGameplayMiniGameScene.js

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ const WON_STATE = 'won';
4747
const LOST_STATE = 'lost';
4848
const DEBUG_OVERLAY_CONFIG = getRequiredLevel17OverlayStackConfig('1708');
4949

50+
function formatMissionStatusLabel(gameState) {
51+
return gameState === RUNNING_STATE
52+
? 'Status: mission active.'
53+
: gameState === READY_STATE
54+
? 'Status: waiting for deploy.'
55+
: `Status: ${gameState}.`;
56+
}
57+
5058
function clamp(value, min, max) {
5159
return Math.max(min, Math.min(max, value));
5260
}
@@ -89,6 +97,7 @@ export default class RealGameplayMiniGameScene extends Scene {
8997
this.pickupBursts = [];
9098
this.hitFlash = 0;
9199
this.pickupFlash = 0;
100+
this.missionFeedState = null;
92101

93102
this.resetMatch({ toReady: true });
94103

@@ -161,6 +170,7 @@ export default class RealGameplayMiniGameScene extends Scene {
161170
this.addEvent('Ready: press Space/Enter to deploy.');
162171
}
163172

173+
this.refreshMissionFeedState();
164174
this.syncCamera();
165175
}
166176

@@ -169,6 +179,7 @@ export default class RealGameplayMiniGameScene extends Scene {
169179
this.gameState = RUNNING_STATE;
170180
this.resultMessage = 'Mission active. Collect cores and avoid sentries.';
171181
this.addEvent('Mission started.');
182+
this.refreshMissionFeedState();
172183
}
173184

174185
setCamera3D(camera3D) {
@@ -203,6 +214,26 @@ export default class RealGameplayMiniGameScene extends Scene {
203214
return getTabDebugOverlayActiveId(this.tabDebugOverlays);
204215
}
205216

217+
buildMissionFeedLiveLine() {
218+
return `live=objective ${this.score}/${this.targetScore} hull=${this.health}/${this.maxHealth} t=${this.timeLeft.toFixed(1)}s`;
219+
}
220+
221+
refreshMissionFeedState() {
222+
this.missionFeedState = {
223+
statusLabel: formatMissionStatusLabel(this.gameState),
224+
liveLine: this.buildMissionFeedLiveLine(),
225+
};
226+
return this.missionFeedState;
227+
}
228+
229+
getMissionFeedStateSnapshot() {
230+
const state = this.missionFeedState || this.refreshMissionFeedState();
231+
return {
232+
statusLabel: state.statusLabel,
233+
liveLine: state.liveLine,
234+
};
235+
}
236+
206237
pushCollisionRow(overlayId, kind, state, enabled = true) {
207238
this.debugCollisionRows.push({
208239
overlayId,
@@ -364,25 +395,29 @@ export default class RealGameplayMiniGameScene extends Scene {
364395

365396
evaluateRoundState() {
366397
if (this.gameState !== RUNNING_STATE) {
398+
this.refreshMissionFeedState();
367399
return;
368400
}
369401
if (this.score >= this.targetScore) {
370402
this.gameState = WON_STATE;
371403
this.resultMessage = `Objective complete: ${this.score}/${this.targetScore} cores captured.`;
372404
this.addEvent('Mission complete.');
405+
this.refreshMissionFeedState();
373406
return;
374407
}
375408
if (this.health <= 0) {
376409
this.gameState = LOST_STATE;
377410
this.resultMessage = 'Mission failed: hull integrity depleted.';
378411
this.addEvent('Mission failed: hull integrity depleted.');
412+
this.refreshMissionFeedState();
379413
return;
380414
}
381415
if (this.timeLeft <= 0) {
382416
this.gameState = LOST_STATE;
383417
this.resultMessage = 'Mission failed: timer expired before objective completion.';
384418
this.addEvent('Mission failed: timer expired.');
385419
}
420+
this.refreshMissionFeedState();
386421
}
387422

388423
updateFeedback(dtSeconds) {
@@ -437,6 +472,7 @@ export default class RealGameplayMiniGameScene extends Scene {
437472

438473
this.lastCollisionCount = this.debugCollisionRows.length;
439474
this.updateFeedback(dt);
475+
this.refreshMissionFeedState();
440476
this.syncCamera();
441477
}
442478

@@ -542,11 +578,7 @@ export default class RealGameplayMiniGameScene extends Scene {
542578
renderer.drawRect(viewport.x, viewport.y, viewport.width, viewport.height, `rgba(34, 211, 238, ${alpha})`);
543579
}
544580

545-
const missionStatus = this.gameState === RUNNING_STATE
546-
? 'Status: mission active.'
547-
: this.gameState === READY_STATE
548-
? 'Status: waiting for deploy.'
549-
: `Status: ${this.gameState}.`;
581+
const missionFeedState = this.getMissionFeedStateSnapshot();
550582

551583
const debugStack = createBottomRightDebugPanelStack(renderer);
552584
this.debugOverlayStack = debugStack;
@@ -564,7 +596,8 @@ export default class RealGameplayMiniGameScene extends Scene {
564596
} else if (activeOverlayId === OVERLAY_MISSION_FEED) {
565597
drawStackedDebugPanel(renderer, debugStack, 326, 160, 'Mission Feed', [
566598
...this.eventFeed,
567-
missionStatus,
599+
missionFeedState.liveLine,
600+
missionFeedState.statusLabel,
568601
]);
569602
} else if (activeOverlayId === OVERLAY_MISSION_READY) {
570603
const isWin = this.gameState === WON_STATE;

samples/phase-17/1710/RealGameplayMiniGameScene.js

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ const WON_STATE = 'won';
4747
const LOST_STATE = 'lost';
4848
const DEBUG_OVERLAY_CONFIG = getRequiredLevel17OverlayStackConfig('1710');
4949

50+
function formatMissionStatusLabel(gameState) {
51+
return gameState === RUNNING_STATE
52+
? 'Status: mission active.'
53+
: gameState === READY_STATE
54+
? 'Status: waiting for deploy.'
55+
: `Status: ${gameState}.`;
56+
}
57+
5058
function clamp(value, min, max) {
5159
return Math.max(min, Math.min(max, value));
5260
}
@@ -89,6 +97,7 @@ export default class RealGameplayMiniGameScene extends Scene {
8997
this.pickupBursts = [];
9098
this.hitFlash = 0;
9199
this.pickupFlash = 0;
100+
this.missionFeedState = null;
92101

93102
this.resetMatch({ toReady: true });
94103

@@ -161,6 +170,7 @@ export default class RealGameplayMiniGameScene extends Scene {
161170
this.addEvent('Ready: press Space/Enter to deploy.');
162171
}
163172

173+
this.refreshMissionFeedState();
164174
this.syncCamera();
165175
}
166176

@@ -169,6 +179,7 @@ export default class RealGameplayMiniGameScene extends Scene {
169179
this.gameState = RUNNING_STATE;
170180
this.resultMessage = 'Mission active. Collect cores and avoid sentries.';
171181
this.addEvent('Mission started.');
182+
this.refreshMissionFeedState();
172183
}
173184

174185
setCamera3D(camera3D) {
@@ -203,6 +214,26 @@ export default class RealGameplayMiniGameScene extends Scene {
203214
return getTabDebugOverlayActiveId(this.tabDebugOverlays);
204215
}
205216

217+
buildMissionFeedLiveLine() {
218+
return `live=objective ${this.score}/${this.targetScore} hull=${this.health}/${this.maxHealth} t=${this.timeLeft.toFixed(1)}s`;
219+
}
220+
221+
refreshMissionFeedState() {
222+
this.missionFeedState = {
223+
statusLabel: formatMissionStatusLabel(this.gameState),
224+
liveLine: this.buildMissionFeedLiveLine(),
225+
};
226+
return this.missionFeedState;
227+
}
228+
229+
getMissionFeedStateSnapshot() {
230+
const state = this.missionFeedState || this.refreshMissionFeedState();
231+
return {
232+
statusLabel: state.statusLabel,
233+
liveLine: state.liveLine,
234+
};
235+
}
236+
206237
pushCollisionRow(overlayId, kind, state, enabled = true) {
207238
this.debugCollisionRows.push({
208239
overlayId,
@@ -364,25 +395,29 @@ export default class RealGameplayMiniGameScene extends Scene {
364395

365396
evaluateRoundState() {
366397
if (this.gameState !== RUNNING_STATE) {
398+
this.refreshMissionFeedState();
367399
return;
368400
}
369401
if (this.score >= this.targetScore) {
370402
this.gameState = WON_STATE;
371403
this.resultMessage = `Objective complete: ${this.score}/${this.targetScore} cores captured.`;
372404
this.addEvent('Mission complete.');
405+
this.refreshMissionFeedState();
373406
return;
374407
}
375408
if (this.health <= 0) {
376409
this.gameState = LOST_STATE;
377410
this.resultMessage = 'Mission failed: hull integrity depleted.';
378411
this.addEvent('Mission failed: hull integrity depleted.');
412+
this.refreshMissionFeedState();
379413
return;
380414
}
381415
if (this.timeLeft <= 0) {
382416
this.gameState = LOST_STATE;
383417
this.resultMessage = 'Mission failed: timer expired before objective completion.';
384418
this.addEvent('Mission failed: timer expired.');
385419
}
420+
this.refreshMissionFeedState();
386421
}
387422

388423
updateFeedback(dtSeconds) {
@@ -437,6 +472,7 @@ export default class RealGameplayMiniGameScene extends Scene {
437472

438473
this.lastCollisionCount = this.debugCollisionRows.length;
439474
this.updateFeedback(dt);
475+
this.refreshMissionFeedState();
440476
this.syncCamera();
441477
}
442478

@@ -542,11 +578,7 @@ export default class RealGameplayMiniGameScene extends Scene {
542578
renderer.drawRect(viewport.x, viewport.y, viewport.width, viewport.height, `rgba(34, 211, 238, ${alpha})`);
543579
}
544580

545-
const missionStatus = this.gameState === RUNNING_STATE
546-
? 'Status: mission active.'
547-
: this.gameState === READY_STATE
548-
? 'Status: waiting for deploy.'
549-
: `Status: ${this.gameState}.`;
581+
const missionFeedState = this.getMissionFeedStateSnapshot();
550582

551583
const debugStack = createBottomRightDebugPanelStack(renderer);
552584
this.debugOverlayStack = debugStack;
@@ -564,7 +596,8 @@ export default class RealGameplayMiniGameScene extends Scene {
564596
} else if (activeOverlayId === OVERLAY_MISSION_FEED) {
565597
drawStackedDebugPanel(renderer, debugStack, 326, 160, 'Mission Feed', [
566598
...this.eventFeed,
567-
missionStatus,
599+
missionFeedState.liveLine,
600+
missionFeedState.statusLabel,
568601
]);
569602
} else if (activeOverlayId === OVERLAY_MISSION_READY) {
570603
const isWin = this.gameState === WON_STATE;

tests/runtime/Phase17RealGameplaySample.test.mjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,16 @@ function assertGameplayLoopAndDebugPanels() {
144144
const missionFeedRenderer = createRendererProbe();
145145
scene.render(missionFeedRenderer);
146146
assert.equal(missionFeedRenderer.texts.some((text) => text.includes('Mission Feed')), true, 'G should cycle to mission feed panel.');
147+
assert.equal(
148+
missionFeedRenderer.texts.some((text) => text.includes('live=objective')),
149+
true,
150+
'Mission Feed should include live mission-state metrics.'
151+
);
152+
assert.equal(
153+
missionFeedRenderer.texts.some((text) => text.includes('Status: won.')),
154+
true,
155+
'Mission Feed should reflect the latest mission state update.'
156+
);
147157

148158
pressOverlayCycle(scene);
149159
const missionReadyRenderer = createRendererProbe();

0 commit comments

Comments
 (0)