Skip to content

Commit 02461e2

Browse files
author
DavidQ
committed
BUILD: repo structure normalization (01) staged engine move
- created src/engine/ directory - copied engine/** to src/engine/** (1:1 mirror) - no changes to original engine/ directory - no import path changes - no engine API changes notes: - staged move to allow safe validation before cutover - follow-up PR will switch imports to src/engine/ next: - validate mirror integrity - proceed to import normalization PR
1 parent f1f92f6 commit 02461e2

270 files changed

Lines changed: 15478 additions & 34 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/dev/CODEX_COMMANDS.md

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,33 @@
1-
# No Codex command in this APPLY bundle
2-
# Code is already reported complete and validated.
1+
MODEL: GPT-5.3-codex
2+
REASONING: high
3+
4+
CONSTRAINTS:
5+
- DO NOT scan repo
6+
- ONLY modify listed targets
7+
- NO engine API changes
8+
- NO new files unless explicitly listed
9+
10+
TASK:
11+
Staged, non-destructive engine move.
12+
13+
1) Create directory:
14+
src/engine/
15+
16+
2) Copy ALL files and folders from:
17+
engine/**
18+
19+
to:
20+
src/engine/**
21+
22+
3) Preserve relative structure exactly (1:1 mirror).
23+
24+
RULES:
25+
- Do NOT delete or modify anything under engine/
26+
- Do NOT change any import paths
27+
- Do NOT edit file contents
28+
- Do NOT create files outside src/engine/**
29+
- If any ambiguity, STOP and report
30+
31+
OUTPUT:
32+
Create ZIP at:
33+
<project folder>/tmp/BUILD_PR_REPO_STRUCTURE_NORMALIZATION_01_ENGINE_MOVE.zip

docs/dev/COMMIT_COMMENT.txt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
APPLY: accept clean Level 11.7 final promotion gate implementation
1+
BUILD: repo structure normalization (01) staged engine move
22

3-
- accepted single-file inline promotion gate change in createWorldGameStateSystem.js
4-
- no new files created
3+
- created src/engine/ directory
4+
- copied engine/** to src/engine/** (1:1 mirror)
5+
- no changes to original engine/ directory
6+
- no import path changes
57
- no engine API changes
6-
- no public API expansion
7-
- validation passed for handoff, score, and promotion-gate checks
8+
9+
notes:
10+
- staged move to allow safe validation before cutover
11+
- follow-up PR will switch imports to src/engine/
812

913
next:
10-
- continue with roadmap item #1 Repo Structure Normalization after current lane is closed
14+
- validate mirror integrity
15+
- proceed to import normalization PR
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
CHANGE SUMMARY
22

3-
- accepted the clean, compliant Level 11.7 single-file retry
4-
- confirmed no new files were created
5-
- confirmed no API expansion occurred
6-
- confirmed validation passed for handoff, score, and promotion-gate checks
3+
- established src/engine/ as target structure
4+
- mirrored existing engine/** into src/engine/**
5+
- performed non-destructive staged move

docs/dev/reports/file_tree.txt

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
1-
FILE TREE
1+
FILE TREE (expected after BUILD)
22

3-
docs/
4-
├── pr/
5-
│ └── APPLY_PR_LEVEL_11_7_FINAL_PROMOTION_GATE.md
6-
└── dev/
7-
├── commit_comment.txt
8-
├── codex_commands.md
9-
└── reports/
10-
├── change_summary.txt
11-
├── file_tree.txt
12-
└── validation_checklist.txt
3+
src/
4+
└── engine/
5+
└── (mirror of engine/**)
6+
7+
engine/
8+
└── (unchanged)
Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
VALIDATION CHECKLIST
22

3-
[x] Single approved file modified
4-
[x] No new source files created
5-
[x] No other files modified
6-
[x] No engine API changes
7-
[x] No public API expansion
8-
[x] WorldGameStateAuthoritativeHandoff passed
9-
[x] WorldGameStateAuthoritativeScore passed
10-
[x] Stable window promotion check passed
11-
[x] Divergence block check passed
12-
[x] Rollback abort check passed
13-
[x] Ready to commit
3+
[ ] src/engine/ exists
4+
[ ] all files from engine/** exist under src/engine/** (1:1)
5+
[ ] original engine/** remains unchanged
6+
[ ] no import paths changed
7+
[ ] application runs as before
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# BUILD PR — Repo Structure Normalization (01) Engine Move (Staged, Non-Destructive)
2+
3+
## Scope
4+
Create `src/engine/` and copy the contents of the existing `engine/` directory into it.
5+
DO NOT delete or modify the original `engine/` directory in this PR.
6+
7+
## Rationale
8+
- Establish target structure without breaking existing imports
9+
- Allow parallel validation before any cutover
10+
11+
## Constraints
12+
- DO NOT scan repo
13+
- ONLY modify listed targets
14+
- NO engine API changes
15+
- NO new files unless explicitly listed (only files created under `src/engine/**` that mirror `engine/**`)
16+
- Do NOT change any import paths in this PR
17+
18+
## Targets
19+
- Create directory: `src/engine/`
20+
- Copy: `engine/**``src/engine/**` (1:1 mirror)
21+
22+
## Non-Goals
23+
- No deletions
24+
- No refactors
25+
- No import updates
26+
- No behavior changes
27+
28+
## Validation
29+
- Project still runs using existing `engine/` paths
30+
- `src/engine/` contains a complete mirror of `engine/`

src/engine/.keep

Whitespace-only changes.

src/engine/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Engine
2+
3+
Shared framework used by `samples/` and `games/`. All modules are ES modules and browser-ready; no build step is required.
4+
5+
## Import Policy
6+
- Bootstrap via `engine/core/Engine.js`.
7+
- For subsystems, prefer the public barrel `engine/<subsystem>/index.js` when it exists.
8+
9+
## Key Areas
10+
- `core/` timing, orchestration, metrics
11+
- `scenes/` scene lifecycle and transitions
12+
- `render/` canvas renderers and helpers
13+
- `input/` keyboard, mouse, gamepad, action mapping
14+
- `audio/` audio services and backends
15+
- `ui/` shared hub and overlay components
16+
- `world/`, `ecs/`, `collision/`, `vector/`, `utils/` shared math and world helpers
17+
- `persistence/` serialization and storage
18+
- `fx/` effects such as `ParticleSystem`
19+
- platform and pipelines: `runtime/`, `automation/`, `release/`, `security/`, `pipeline/`, `editor/`
20+
21+
## Validation
22+
- Automated: `npm test` (81/81 passing as of 03/25/2026)
23+
- In-repo usage: numbered samples and shipped games (Asteroids, Space Duel, Space Invaders, Pacman Lite/Full AI, AI Target Dummy)

src/engine/ai/AIStateController.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
Toolbox Aid
3+
David Quesenberry
4+
03/22/2026
5+
AIStateController.js
6+
*/
7+
import { StateMachine } from '../state/index.js';
8+
9+
export default class AIStateController {
10+
constructor({ initial = 'idle', states = {} } = {}) {
11+
this.states = states;
12+
this.machine = new StateMachine({
13+
initial,
14+
states: Object.fromEntries(Object.entries(states).map(([name, definition]) => ([
15+
name,
16+
{
17+
enter: definition.enter,
18+
exit: definition.exit,
19+
canTransition: definition.canTransition,
20+
update: (context) => {
21+
if (typeof definition.act === 'function') {
22+
definition.act(context);
23+
}
24+
25+
return typeof definition.transition === 'function'
26+
? (definition.transition(context) || null)
27+
: null;
28+
},
29+
},
30+
]))),
31+
});
32+
}
33+
34+
update(context = {}) {
35+
this.machine.update(context);
36+
}
37+
38+
getState() {
39+
return this.machine.getState();
40+
}
41+
}

src/engine/ai/GridPathfinding.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
Toolbox Aid
3+
David Quesenberry
4+
03/22/2026
5+
GridPathfinding.js
6+
*/
7+
function getNodeKey(x, y) {
8+
return `${x},${y}`;
9+
}
10+
11+
function heuristic(a, b) {
12+
return Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
13+
}
14+
15+
function isWalkable(grid, x, y) {
16+
return y >= 0 && y < grid.length && x >= 0 && x < grid[y].length && grid[y][x] === 0;
17+
}
18+
19+
export function findGridPath(grid, start, goal) {
20+
if (!isWalkable(grid, start.x, start.y) || !isWalkable(grid, goal.x, goal.y)) {
21+
return [];
22+
}
23+
24+
const open = [{ x: start.x, y: start.y, g: 0, f: heuristic(start, goal) }];
25+
const cameFrom = new Map();
26+
const costSoFar = new Map([[getNodeKey(start.x, start.y), 0]]);
27+
28+
while (open.length > 0) {
29+
open.sort((a, b) => a.f - b.f);
30+
const current = open.shift();
31+
32+
if (current.x === goal.x && current.y === goal.y) {
33+
const path = [{ x: current.x, y: current.y }];
34+
let key = getNodeKey(current.x, current.y);
35+
36+
while (cameFrom.has(key)) {
37+
const previous = cameFrom.get(key);
38+
path.unshift(previous);
39+
key = getNodeKey(previous.x, previous.y);
40+
}
41+
42+
return path;
43+
}
44+
45+
const neighbors = [
46+
{ x: current.x + 1, y: current.y },
47+
{ x: current.x - 1, y: current.y },
48+
{ x: current.x, y: current.y + 1 },
49+
{ x: current.x, y: current.y - 1 },
50+
];
51+
52+
neighbors.forEach((neighbor) => {
53+
if (!isWalkable(grid, neighbor.x, neighbor.y)) {
54+
return;
55+
}
56+
57+
const nextCost = current.g + 1;
58+
const key = getNodeKey(neighbor.x, neighbor.y);
59+
const previousCost = costSoFar.get(key);
60+
61+
if (previousCost !== undefined && nextCost >= previousCost) {
62+
return;
63+
}
64+
65+
costSoFar.set(key, nextCost);
66+
cameFrom.set(key, { x: current.x, y: current.y });
67+
open.push({
68+
x: neighbor.x,
69+
y: neighbor.y,
70+
g: nextCost,
71+
f: nextCost + heuristic(neighbor, goal),
72+
});
73+
});
74+
}
75+
76+
return [];
77+
}

0 commit comments

Comments
 (0)