Skip to content

Commit e798800

Browse files
committed
Use the individual commit comment generated for each PR. Do not squash PR_26152_258 through PR_26152_265 into a single commit.
1 parent 8891cd3 commit e798800

21 files changed

Lines changed: 1776 additions & 0 deletions
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# PR_26152_264 Engine V2 Config Driven Proof Scene
2+
3+
## Scope
4+
5+
- Added config-driven proof scene coordinator.
6+
- Manifest loads the existing manifest-driven playable scene.
7+
- Validates gameplay integration for terrain, objects, environment, inventory, combat, objectives, UI, win/lose outcomes, and save/load/continue.
8+
- No samples.
9+
- No tool dependency.
10+
- No hard-coded game behavior.
11+
12+
## Files
13+
14+
- `src/engine/runtime/engineV2ConfigDrivenProofScene.js`
15+
- `tests/engine/EngineV2ConfigDrivenProofScene.test.mjs`
16+
- `tests/engine/EngineV2FeatureCompleteFixture.mjs`
17+
18+
## Validation
19+
20+
- PASS: `node tests/engine/EngineV2ConfigDrivenProofScene.test.mjs`
21+
22+
## Notes
23+
24+
- Proof scene rejects when Engine V2 manifest extension data is missing.
25+
- Proof scene rejects when save/load validation fails.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# PR_26152_260 Engine V2 Effect Runtime
2+
3+
## Scope
4+
5+
- Added manifest-driven particle/effect processing.
6+
- Supported effect types: explosion, dust, snow, rain, fire, smoke, sparkles, hit, and pickup.
7+
- No hard-coded effect behavior.
8+
- No Tools, Samples, Marketplace, or Publishing changes.
9+
10+
## Files
11+
12+
- `src/engine/runtime/engineV2EffectRuntime.js`
13+
- `tests/engine/EngineV2EffectRuntime.test.mjs`
14+
- `tests/engine/EngineV2FeatureCompleteFixture.mjs`
15+
16+
## Validation
17+
18+
- PASS: `node tests/engine/EngineV2EffectRuntime.test.mjs`
19+
20+
## Notes
21+
22+
- Effect requests must reference manifest effect definitions.
23+
- Unsupported effect types reject visibly.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# PR_26152_265 Engine V2 Feature Complete Closeout
2+
3+
## Scope
4+
5+
- Closed the Engine V2 feature-complete-enough lane for this stack.
6+
- Confirmed the targeted Engine V2 slices pass together.
7+
- No Tools, Samples, Marketplace, or Publishing changes.
8+
9+
## Validation
10+
11+
- PASS: `node tests/engine/EngineV2StateMachineRuntime.test.mjs`
12+
- PASS: `node tests/engine/EngineV2UiRuntime.test.mjs`
13+
- PASS: `node tests/engine/EngineV2EffectRuntime.test.mjs`
14+
- PASS: `node tests/engine/EngineV2ModifierStack.test.mjs`
15+
- PASS: `node tests/engine/EngineV2SaveLoadValidation.test.mjs`
16+
- PASS: `node tests/engine/EngineV2ConfigDrivenProofScene.test.mjs`
17+
18+
## Remaining Engine Gaps
19+
20+
- Multiplayer remains boundary-only and unimplemented.
21+
- Future Toolbox rebuild should wait until the proof-scene behavior remains passing under user visual and runtime validation.
22+
23+
## Samples
24+
25+
- Not touched.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# PR_26152_261 Engine V2 Modifier Stack
2+
3+
## Scope
4+
5+
- Added deterministic runtime modifier stack.
6+
- Combines terrain, object, environment, status effect, equipment, ability, and rule modifiers.
7+
- Validates ordered resolution using explicit base values.
8+
- No Tools, Samples, Marketplace, or Publishing changes.
9+
10+
## Files
11+
12+
- `src/engine/runtime/engineV2ModifierStack.js`
13+
- `tests/engine/EngineV2ModifierStack.test.mjs`
14+
- `tests/engine/EngineV2FeatureCompleteFixture.mjs`
15+
16+
## Validation
17+
18+
- PASS: `node tests/engine/EngineV2ModifierStack.test.mjs`
19+
20+
## Notes
21+
22+
- Missing base values reject visibly.
23+
- Input modifier order does not affect deterministic resolution.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# PR_26152_263 Engine V2 Multiplayer Boundary
2+
3+
## Scope
4+
5+
- Defined multiplayer boundary only.
6+
- No multiplayer implementation.
7+
- No runtime behavior changes.
8+
- No Tools, Samples, Marketplace, or Publishing changes.
9+
10+
## Boundary
11+
12+
- Local: in scope for current Engine V2 proof-scene runtime.
13+
- Shared screen: future lane; must be manifest-driven and deterministic.
14+
- Network: future lane; must remain separate from local runtime state mutation until an explicit networking PR.
15+
- Turn based: future lane; must define state handoff and determinism before implementation.
16+
17+
## Rules
18+
19+
- Multiplayer state must not leak into current save/load validation unless explicitly declared in a future PR.
20+
- Network/session behavior must not be hidden inside local runtime slices.
21+
- Engine V2 proof scene remains local-only for this stack.
22+
23+
## Validation
24+
25+
- PASS: `git diff --check`
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# PR_26152_262 Engine V2 Save Load Validation
2+
3+
## Scope
4+
5+
- Added save, shutdown, load, and continue validation.
6+
- Validates inventory, equipment, scene state, objectives, health, position, and runtime state restore.
7+
- Composes the existing Engine V2 save-state model.
8+
- No Tools, Samples, Marketplace, or Publishing changes.
9+
10+
## Files
11+
12+
- `src/engine/runtime/engineV2SaveLoadValidation.js`
13+
- `tests/engine/EngineV2SaveLoadValidation.test.mjs`
14+
- `tests/engine/EngineV2FeatureCompleteFixture.mjs`
15+
16+
## Validation
17+
18+
- PASS: `node tests/engine/EngineV2SaveLoadValidation.test.mjs`
19+
20+
## Notes
21+
22+
- Shutdown state must not retain runtime surfaces before load.
23+
- Missing restore keys reject visibly.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# PR_26152_258 Engine V2 State Machine Runtime
2+
3+
## Scope
4+
5+
- Added manifest-driven state transition processing for object, scene, UI, door, interaction, and combat state scopes.
6+
- No game-specific state logic.
7+
- No Tools, Samples, Marketplace, or Publishing changes.
8+
9+
## Files
10+
11+
- `src/engine/runtime/engineV2StateMachineRuntime.js`
12+
- `tests/engine/EngineV2StateMachineRuntime.test.mjs`
13+
- `tests/engine/EngineV2FeatureCompleteFixture.mjs`
14+
15+
## Validation
16+
17+
- PASS: `node tests/engine/EngineV2StateMachineRuntime.test.mjs`
18+
19+
## Notes
20+
21+
- Invalid state scopes reject visibly.
22+
- Condition-gated transitions reject when required conditions are not matched.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# PR_26152_259 Engine V2 UI Runtime
2+
3+
## Scope
4+
5+
- Added manifest-driven game UI command generation.
6+
- Supported game UI widgets: health bar, score, inventory, dialogue, quest tracker, timer, status, and pause menu.
7+
- This is game UI only, not Toolbox UI.
8+
- No Tools, Samples, Marketplace, or Publishing changes.
9+
10+
## Files
11+
12+
- `src/engine/runtime/engineV2UiRuntime.js`
13+
- `tests/engine/EngineV2UiRuntime.test.mjs`
14+
- `tests/engine/EngineV2FeatureCompleteFixture.mjs`
15+
16+
## Validation
17+
18+
- PASS: `node tests/engine/EngineV2UiRuntime.test.mjs`
19+
20+
## Notes
21+
22+
- Widget sources must be explicitly declared and present in runtime state.
23+
- Unsupported UI widget types reject visibly.
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/*
2+
Toolbox Aid
3+
David Quesenberry
4+
06/03/2026
5+
engineV2ConfigDrivenProofScene.js
6+
*/
7+
8+
import { createFirstManifestDrivenPlayableScene } from "./firstManifestDrivenPlayableScene.js";
9+
import { resolveEngineV2Inventory } from "./engineV2InventorySystem.js";
10+
import { processRuntimeDamage } from "./runtimeDamageProcessing.js";
11+
import { processEngineV2Objectives } from "./engineV2ObjectiveSystem.js";
12+
import { evaluateRuntimeOutcomes } from "./runtimeOutcomeProcessing.js";
13+
import { resolveEngineV2GameUi } from "./engineV2UiRuntime.js";
14+
import { validateEngineV2SaveLoadFlow } from "./engineV2SaveLoadValidation.js";
15+
16+
export const ENGINE_V2_PROOF_SCENE_ERRORS = Object.freeze({
17+
MANIFEST_INVALID: "ENGINE_V2_PROOF_SCENE_MANIFEST_INVALID",
18+
PLAYABLE_SCENE_FAILED: "ENGINE_V2_PROOF_SCENE_PLAYABLE_SCENE_FAILED",
19+
EXTENSIONS_MISSING: "ENGINE_V2_PROOF_SCENE_EXTENSIONS_MISSING",
20+
INVENTORY_FAILED: "ENGINE_V2_PROOF_SCENE_INVENTORY_FAILED",
21+
COMBAT_FAILED: "ENGINE_V2_PROOF_SCENE_COMBAT_FAILED",
22+
OBJECTIVES_FAILED: "ENGINE_V2_PROOF_SCENE_OBJECTIVES_FAILED",
23+
OUTCOMES_FAILED: "ENGINE_V2_PROOF_SCENE_OUTCOMES_FAILED",
24+
UI_FAILED: "ENGINE_V2_PROOF_SCENE_UI_FAILED",
25+
SAVE_LOAD_FAILED: "ENGINE_V2_PROOF_SCENE_SAVE_LOAD_FAILED",
26+
});
27+
28+
export function runEngineV2ConfigDrivenProofScene({ manifest, inputEvents, saveDefinition }) {
29+
const errors = [];
30+
31+
if (!isRecord(manifest)) {
32+
errors.push(createProofSceneError(ENGINE_V2_PROOF_SCENE_ERRORS.MANIFEST_INVALID, "Config-driven proof scene requires manifest object.", "manifest"));
33+
}
34+
35+
if (!Array.isArray(inputEvents)) {
36+
errors.push(createProofSceneError(ENGINE_V2_PROOF_SCENE_ERRORS.MANIFEST_INVALID, "Config-driven proof scene requires inputEvents array.", "inputEvents"));
37+
}
38+
39+
if (!isRecord(saveDefinition)) {
40+
errors.push(createProofSceneError(ENGINE_V2_PROOF_SCENE_ERRORS.MANIFEST_INVALID, "Config-driven proof scene requires saveDefinition object.", "saveDefinition"));
41+
}
42+
43+
if (errors.length > 0) {
44+
return createProofSceneResult({ scene: null, frame: null, validation: null, errors });
45+
}
46+
47+
const playableResult = createFirstManifestDrivenPlayableScene(manifest, inputEvents);
48+
49+
if (!playableResult.valid) {
50+
return createProofSceneResult({
51+
scene: null,
52+
frame: null,
53+
validation: null,
54+
errors: remapErrors(playableResult.errors, ENGINE_V2_PROOF_SCENE_ERRORS.PLAYABLE_SCENE_FAILED),
55+
});
56+
}
57+
58+
const extensions = manifest.engineV2;
59+
60+
if (!isRecord(extensions)) {
61+
return createProofSceneResult({
62+
scene: null,
63+
frame: null,
64+
validation: null,
65+
errors: [createProofSceneError(ENGINE_V2_PROOF_SCENE_ERRORS.EXTENSIONS_MISSING, "Proof scene manifest requires engineV2 extension data.", "manifest.engineV2")],
66+
});
67+
}
68+
69+
const inventoryResult = resolveEngineV2Inventory(extensions.inventory);
70+
71+
if (!inventoryResult.valid) {
72+
return createProofSceneResult({ scene: null, frame: null, validation: null, errors: remapErrors(inventoryResult.errors, ENGINE_V2_PROOF_SCENE_ERRORS.INVENTORY_FAILED) });
73+
}
74+
75+
const damageResult = processRuntimeDamage(extensions.combat);
76+
77+
if (!damageResult.valid) {
78+
return createProofSceneResult({ scene: null, frame: null, validation: null, errors: remapErrors(damageResult.errors, ENGINE_V2_PROOF_SCENE_ERRORS.COMBAT_FAILED) });
79+
}
80+
81+
const objectiveRuntimeState = {
82+
...extensions.objectives.runtimeState,
83+
scores: {
84+
...extensions.objectives.runtimeState.scores,
85+
...extensions.outcomes.runtimeState.scores,
86+
},
87+
};
88+
const objectiveResult = processEngineV2Objectives({
89+
...extensions.objectives,
90+
runtimeState: objectiveRuntimeState,
91+
});
92+
93+
if (!objectiveResult.valid) {
94+
return createProofSceneResult({ scene: null, frame: null, validation: null, errors: remapErrors(objectiveResult.errors, ENGINE_V2_PROOF_SCENE_ERRORS.OBJECTIVES_FAILED) });
95+
}
96+
97+
const outcomeResult = evaluateRuntimeOutcomes(extensions.outcomes);
98+
99+
if (!outcomeResult.valid) {
100+
return createProofSceneResult({ scene: null, frame: null, validation: null, errors: remapErrors(outcomeResult.errors, ENGINE_V2_PROOF_SCENE_ERRORS.OUTCOMES_FAILED) });
101+
}
102+
103+
const uiRuntimeState = {
104+
...extensions.ui.runtimeState,
105+
inventoryStates: inventoryResult.inventoryStates,
106+
healthRecords: damageResult.healthRecords,
107+
scores: extensions.outcomes.runtimeState.scores,
108+
};
109+
const uiResult = resolveEngineV2GameUi({
110+
uiDefinitions: extensions.ui.uiDefinitions,
111+
runtimeState: uiRuntimeState,
112+
});
113+
114+
if (!uiResult.valid) {
115+
return createProofSceneResult({ scene: null, frame: null, validation: null, errors: remapErrors(uiResult.errors, ENGINE_V2_PROOF_SCENE_ERRORS.UI_FAILED) });
116+
}
117+
118+
const runtimeState = {
119+
...extensions.saveLoad.runtimeState,
120+
inventory: inventoryResult.inventoryStates,
121+
state: {
122+
...extensions.saveLoad.runtimeState.state,
123+
objectives: objectiveResult.objectiveStates,
124+
health: damageResult.healthRecords,
125+
runtime: {
126+
...extensions.saveLoad.runtimeState.state.runtime,
127+
matchedOutcomes: outcomeResult.matchedOutcomes,
128+
},
129+
},
130+
};
131+
const saveLoadResult = validateEngineV2SaveLoadFlow({
132+
saveDefinition,
133+
runtimeState,
134+
shutdownState: extensions.saveLoad.shutdownState,
135+
loadRequest: extensions.saveLoad.loadRequest,
136+
continueRequest: extensions.saveLoad.continueRequest,
137+
});
138+
139+
if (!saveLoadResult.valid) {
140+
return createProofSceneResult({ scene: null, frame: null, validation: null, errors: remapErrors(saveLoadResult.errors, ENGINE_V2_PROOF_SCENE_ERRORS.SAVE_LOAD_FAILED) });
141+
}
142+
143+
return createProofSceneResult({
144+
scene: playableResult.scene,
145+
frame: playableResult.frame,
146+
validation: Object.freeze({
147+
inventory: inventoryResult,
148+
combat: damageResult,
149+
objectives: objectiveResult,
150+
outcomes: outcomeResult,
151+
ui: uiResult,
152+
saveLoad: saveLoadResult,
153+
}),
154+
errors,
155+
});
156+
}
157+
158+
function createProofSceneResult({ scene, frame, validation, errors }) {
159+
return Object.freeze({
160+
valid: errors.length === 0,
161+
scene,
162+
frame,
163+
validation,
164+
errors: Object.freeze(errors),
165+
});
166+
}
167+
168+
function remapErrors(errors, code) {
169+
return errors.map((error) => Object.freeze({ code, message: error.message, path: error.path }));
170+
}
171+
172+
function createProofSceneError(code, message, path) {
173+
return Object.freeze({ code, message, path });
174+
}
175+
176+
function isRecord(value) {
177+
return value !== null && typeof value === "object" && !Array.isArray(value);
178+
}

0 commit comments

Comments
 (0)