From 92fbf2fd26ba46bbd7e37015187052b217fe0330 Mon Sep 17 00:00:00 2001 From: Delta Team Date: Thu, 25 Jun 2026 11:16:09 -0400 Subject: [PATCH] PR_26175_DELTA_001: optimize runtime tick advance --- .../backlog/BACKLOG_MASTER.md | 3 +- ...formance_Optimization-branch-validation.md | 15 +++++++ ...ce_Optimization-manual-validation-notes.md | 9 ++++ ...ance_Optimization-requirement-checklist.md | 19 ++++++++ ...ime_Performance_Optimization-validation.md | 25 +++++++++++ ...TA_001_Runtime_Performance_Optimization.md | 42 ++++++++++++++++++ .../dev/reports/codex_changed_files.txt | 37 +++++---------- docs_build/dev/reports/codex_review.diff | Bin 212382 -> 11302 bytes src/engine/runtime/runtimeTickLoop.js | 6 ++- tests/engine/RuntimeTickLoop.test.mjs | 13 ++++++ 10 files changed, 140 insertions(+), 29 deletions(-) create mode 100644 docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-branch-validation.md create mode 100644 docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-manual-validation-notes.md create mode 100644 docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-requirement-checklist.md create mode 100644 docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-validation.md create mode 100644 docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization.md diff --git a/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md b/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md index 47a7010d1..8134b4348 100644 --- a/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md +++ b/docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md @@ -243,7 +243,8 @@ Current OWNER clarification: - [ ] Delta - Shared JS consolidation - [ ] Delta - API client consolidation -- [ ] Delta - Runtime performance audit +- [x] Delta - Runtime performance audit + - Completion reference: PR_26175_DELTA_001_Runtime_Performance_Optimization. - [ ] Delta - Engine test coverage improvements - [ ] Delta - Event system audit - [ ] Delta - Controls runtime framework audit diff --git a/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-branch-validation.md b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-branch-validation.md new file mode 100644 index 000000000..2abd50a24 --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-branch-validation.md @@ -0,0 +1,15 @@ +# PR_26175_DELTA_001 Branch Validation + +| Gate | Status | Evidence | +| --- | --- | --- | +| Current branch before work | PASS | `main` | +| Worktree before work | PASS | Clean | +| Local/origin sync before work | PASS | `0 0` after `git pull --ff-only` | +| Team ownership | PASS | Team Delta owns Runtime, Performance, and Runtime test coverage. | +| Work branch | PASS | `PR_26175_DELTA_001_Runtime_Performance_Optimization` | +| Previous Delta PR closed | PASS | No active Delta PR was present before PR_001. | +| Scope boundary | PASS | Runtime tick-loop optimization, focused test, backlog/report artifacts only. | + +## Instruction Reads + +PASS - All files under `docs_build/dev/ProjectInstructions/` were read before implementation. diff --git a/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-manual-validation-notes.md b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-manual-validation-notes.md new file mode 100644 index 000000000..a3188b3b0 --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-manual-validation-notes.md @@ -0,0 +1,9 @@ +# PR_26175_DELTA_001 Manual Validation Notes + +- Confirmed Team Delta ownership covers Runtime, Performance, and Runtime test coverage. +- Confirmed the optimization is limited to fixed-step runtime tick advancement. +- Confirmed `advanceRuntimeTick(...)` now reuses the existing `deltaSeconds` value when present. +- Confirmed legacy tick objects without `deltaSeconds` still advance successfully. +- Confirmed no browser-owned data, API contract, UI, or tool state changes were introduced. +- Confirmed backlog completion reference was added for `Delta - Runtime performance audit`. +- Confirmed source branch disposition should remain `retained`. diff --git a/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-requirement-checklist.md b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-requirement-checklist.md new file mode 100644 index 000000000..3a7ed3b8f --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-requirement-checklist.md @@ -0,0 +1,19 @@ +# PR_26175_DELTA_001 Requirement Checklist + +| Requirement | Status | Notes | +| --- | --- | --- | +| Team Delta ownership only | PASS | Runtime, Performance, and Runtime test coverage are Delta-owned. | +| One PR purpose | PASS | Fixed-step tick-loop performance optimization only. | +| Preserve backward compatibility | PASS | Added legacy tick fallback when `deltaSeconds` is absent. | +| Update backlog | PASS | `Delta - Runtime performance audit` marked complete. | +| Update tool state if applicable | PASS | Not applicable; no tool tile/status changed. | +| Produce governance reports | PASS | Summary, branch validation, checklist, validation lane, manual notes, Codex diff, changed-file list, and ZIP. | +| Runtime validation | PASS | Targeted node checks and runtime tick test passed. | +| No unrelated files | PASS | Changes are limited to runtime tick loop, its focused test, backlog, and reports. | +| No branch deletion | PASS | Source branch retained. | + +## Compatibility Notes + +- `advanceRuntimeTick(...)` preserves the same public tick shape. +- Callers with old tick objects still get a computed `deltaSeconds` value. +- Invalid fixed-delta errors remain unchanged. diff --git a/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-validation.md b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-validation.md new file mode 100644 index 000000000..bca34ff0c --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-validation.md @@ -0,0 +1,25 @@ +# PR_26175_DELTA_001 Validation Lane + +## Commands + +```powershell +node --check src/engine/runtime/runtimeTickLoop.js +node --check tests/engine/RuntimeTickLoop.test.mjs +node tests/engine/RuntimeTickLoop.test.mjs +``` + +## Results + +| Command | Status | +| --- | --- | +| `node --check src/engine/runtime/runtimeTickLoop.js` | PASS | +| `node --check tests/engine/RuntimeTickLoop.test.mjs` | PASS | +| `node tests/engine/RuntimeTickLoop.test.mjs` | PASS | + +## Browser Validation + +SKIP - No browser UI files changed. + +## Playwright Validation + +SKIP - Runtime tick-loop internals are covered by the focused Node runtime test. diff --git a/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization.md b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization.md new file mode 100644 index 000000000..245a36e45 --- /dev/null +++ b/docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization.md @@ -0,0 +1,42 @@ +# PR_26175_DELTA_001_Runtime_Performance_Optimization + +## Summary + +Team Delta completed a focused runtime performance optimization for the fixed-step runtime tick loop. + +The runtime now reuses the precomputed `deltaSeconds` value already stored on a tick when advancing frames. This avoids recalculating the fixed delta seconds on every frame while preserving compatibility for legacy tick objects that do not yet carry `deltaSeconds`. + +## Scope + +- Team: Delta +- Backlog item: `Delta - Runtime performance audit` +- Runtime file changed: `src/engine/runtime/runtimeTickLoop.js` +- Test file changed: `tests/engine/RuntimeTickLoop.test.mjs` +- Backlog updated: `docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md` + +## Runtime Impact + +PASS - Fixed-step runtime advancement behavior remains backward compatible. + +- Existing tick objects from `createRuntimeTickLoop(...)` retain `deltaSeconds`. +- `advanceRuntimeTick(...)` reuses that value. +- Legacy tick objects without `deltaSeconds` still compute a valid fallback. +- Invalid fixed-delta handling is unchanged. + +## Backlog Update + +PASS - `Delta - Runtime performance audit` is marked complete with this PR as the completion reference. + +## Tool State Update + +SKIP - No Build Path tool status or tool tile state changed. This PR affects runtime internals only. + +## Validation Summary + +PASS - Targeted runtime validation completed. + +See `PR_26175_DELTA_001_Runtime_Performance_Optimization-validation.md` for command details. + +## Branch Disposition + +Source branch should be retained after merge unless OWNER later approves branch deletion. diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt index 4cb4ab3d9..729da1632 100644 --- a/docs_build/dev/reports/codex_changed_files.txt +++ b/docs_build/dev/reports/codex_changed_files.txt @@ -1,27 +1,10 @@ -assets/theme-v2/js/gamefoundry-partials.js -assets/theme-v2/js/legal-document-page.js -assets/theme-v2/partials/footer.html -docs_build/dev/reports/PR_26175_OWNER_054-legal-corrected-package.md -docs_build/dev/reports/codex_changed_files.txt -docs_build/dev/reports/codex_review.diff -docs_build/dev/reports/coverage_changed_js_guardrail.txt -docs_build/dev/reports/playwright_v8_coverage_report.txt -legal/community-guidelines.html -legal/community-guidelines.md -legal/cookie-policy.html -legal/cookie-policy.md -legal/cookies-policy.html -legal/copyright-policy.html -legal/copyright-policy.md -legal/disclaimer.html -legal/dmca-policy.html -legal/dmca-policy.md -legal/index.html -legal/index.md -legal/legal-nav.js -legal/privacy-policy.html -legal/privacy-policy.md -legal/terms.html -legal/terms-of-service.html -legal/terms-of-service.md -tests/playwright/tools/RemainingLegalPages.spec.mjs \ No newline at end of file +docs_build/dev/ProjectInstructions/backlog/BACKLOG_MASTER.md / updated +src/engine/runtime/runtimeTickLoop.js / updated +tests/engine/RuntimeTickLoop.test.mjs / updated +docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization.md / added +docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-branch-validation.md / added +docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-requirement-checklist.md / added +docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-validation.md / added +docs_build/dev/reports/PR_26175_DELTA_001_Runtime_Performance_Optimization-manual-validation-notes.md / added +docs_build/dev/reports/codex_changed_files.txt / updated +docs_build/dev/reports/codex_review.diff / updated diff --git a/docs_build/dev/reports/codex_review.diff b/docs_build/dev/reports/codex_review.diff index fdfeac55a30526c21627c2184b6692766d4426d7..d2643ae2b940cb7968ffc425821ef6088b043f46 100644 GIT binary patch literal 11302 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 literal 212382 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 0 + ? tick.deltaSeconds + : tick.fixedDeltaMs / 1000; + return createTickResult({ tick: Object.freeze({ frame: tick.frame + 1, elapsedMs: tick.elapsedMs + tick.fixedDeltaMs, fixedDeltaMs: tick.fixedDeltaMs, - deltaSeconds: tick.fixedDeltaMs / 1000, + deltaSeconds, }), errors: [], }); diff --git a/tests/engine/RuntimeTickLoop.test.mjs b/tests/engine/RuntimeTickLoop.test.mjs index d33d5e7e8..a968c7f3f 100644 --- a/tests/engine/RuntimeTickLoop.test.mjs +++ b/tests/engine/RuntimeTickLoop.test.mjs @@ -19,6 +19,19 @@ export function run() { const nextResult = advanceRuntimeTick(startResult.tick); assert.equal(nextResult.valid, true); assert.deepEqual(nextResult.tick, { frame: 1, elapsedMs: 100, fixedDeltaMs: 100, deltaSeconds: 0.1 }); + assert.equal( + nextResult.tick.deltaSeconds, + startResult.tick.deltaSeconds, + 'Runtime tick advance should reuse the precomputed deltaSeconds value.' + ); + + const legacyTickResult = advanceRuntimeTick({ frame: 2, elapsedMs: 200, fixedDeltaMs: 100 }); + assert.equal(legacyTickResult.valid, true); + assert.deepEqual( + legacyTickResult.tick, + { frame: 3, elapsedMs: 300, fixedDeltaMs: 100, deltaSeconds: 0.1 }, + 'Runtime tick advance should preserve compatibility for ticks without deltaSeconds.' + ); const invalidResult = createRuntimeTickLoop({ fixedDeltaMs: 0 }); assert.equal(invalidResult.valid, false);