Skip to content

Commit 84ab23b

Browse files
author
DavidQ
committed
Fix stuck left/right steering behavior in Sample 1605 driving controls with targeted validation<BUILD_PR_LEVEL_17_9_SAMPLE_1605_DRIVING_CONTROL_FIX>
1 parent 5c996d5 commit 84ab23b

8 files changed

Lines changed: 129 additions & 69 deletions

docs/dev/CODEX_COMMANDS.md

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,10 @@ MODEL: GPT-5.3-codex
22
REASONING: high
33

44
COMMAND:
5-
Create BUILD_PR_LEVEL_17_8_SAMPLES_1605_TO_1608_CORE_TRACK.
5+
Create BUILD_PR_LEVEL_17_9_SAMPLE_1605_DRIVING_CONTROL_FIX.
66

77
Goal:
8-
Complete the remaining core Phase 16 / 3D sample track by implementing samples 1605 through 1608 as one testable package.
9-
10-
Context:
11-
- 1601 is visible
12-
- 1602 and 1604 visibility defects were fixed
13-
- targeted Phase 16 visibility sanity passes
14-
- targeted smoke for 1601-1604 passes
8+
Fix Sample 1605 - 3D Driving Sandbox so left/right steering no longer gets stuck.
159

1610
Constraints:
1711
- one PR purpose only
@@ -20,32 +14,20 @@ Constraints:
2014
- no zip output from Codex
2115
- keep 2D and networking untouched
2216
- do not modify start_of_day
23-
- preserve prior Phase 16 samples unless a shared safe improvement is required
2417

2518
Implement:
26-
1. Add and wire up:
27-
- samples/phase-16/1605
28-
- samples/phase-16/1606
29-
- samples/phase-16/1607
30-
- samples/phase-16/1608
31-
2. Reuse existing shared Phase 16 helpers where stable.
32-
3. Ensure each sample has visible 3D output on first load and one clear teaching purpose:
33-
- 1605 driving sandbox
34-
- 1606 physics playground
35-
- 1607 space shooter
36-
- 1608 dungeon crawler
37-
4. Update samples/index.html so these are live entries when implemented.
38-
5. Extend the existing targeted Phase 16 runtime sanity only if needed and keep it surgical.
19+
1. Inspect samples/phase-16/1605/DrivingSandbox3DScene.js.
20+
2. Fix the steering/input-state bug causing left/right navigation to stick.
21+
3. Preserve current visible 3D output and forward/reverse behavior.
22+
4. Add or extend the smallest targeted behavioral sanity check if useful.
3923

40-
Validation:
41-
- verify 1605 visible on load
42-
- verify 1606 visible on load
43-
- verify 1607 visible on load
44-
- verify 1608 visible on load
45-
- verify intended controls function for each sample
46-
- run targeted smoke for 1601-1608
47-
- confirm no 2D regression in targeted checks
48-
- confirm no networking regression in targeted checks
24+
Validate:
25+
- verify left turn works while held
26+
- verify right turn works while held
27+
- verify steering stops when released
28+
- verify opposite turn can be engaged immediately
29+
- verify sample still renders on load
30+
- run targeted smoke for 1605
4931
- update:
5032
- docs/dev/reports/change_summary.txt
5133
- docs/dev/reports/validation_checklist.txt

docs/dev/COMMIT_COMMENT.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Complete the remaining core Phase 16 sample track for 1605 through 1608 with targeted validation<BUILD_PR_LEVEL_17_8_SAMPLES_1605_TO_1608_CORE_TRACK>
1+
Fix stuck left/right steering behavior in Sample 1605 driving controls with targeted validation<BUILD_PR_LEVEL_17_9_SAMPLE_1605_DRIVING_CONTROL_FIX>
Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
1-
Applied scope:
2-
- implemented Phase 16 core track samples 1605 through 1608:
3-
- 1605: 3D driving sandbox (throttle/steer + AABB track blockers)
4-
- 1606: 3D physics playground (gravity, bounce, impulses, damping)
5-
- 1607: 3D space shooter (lane movement, projectiles, asteroid hits)
6-
- 1608: 3D dungeon crawler (maze traversal, relic gate unlock, exit)
7-
- wired launcher entries in samples/index.html from planned to live for 1605-1608
8-
- reused shared 3D wireframe helper path for rendering consistency
9-
- extended Phase16VisibilitySanity.test.mjs surgically to include 1605-1608:
10-
- visibility on load checks
11-
- one control/function assertion per new sample
1+
Observed issue:
2+
- Sample 1605 renders and loads
3+
- steering behavior gets stuck left/right
4+
5+
Applied fix:
6+
- isolated steering correction in samples/phase-16/1605/DrivingSandbox3DScene.js
7+
- removed reverse-dependent steering inversion so A/D turn direction remains consistent
8+
- preserved 1605 rendering path and forward/reverse speed model
9+
- extended existing targeted runtime sanity in tests/runtime/Phase16VisibilitySanity.test.mjs with 1605 steering behavior checks:
10+
- left hold
11+
- right hold
12+
- release stop
13+
- immediate opposite engagement
14+
- reverse motion
1215

1316
Validation outcome:
1417
- PASS Phase16VisibilitySanity
15-
- PASS launch smoke (samples 1601-1608): PASS=8 FAIL=0
18+
- PASS launch smoke (sample 1605): PASS=1 FAIL=0
1619
- PASS EngineTiming (targeted 2D regression check)
1720
- PASS MultiplayerNetworkingStack (targeted networking regression check)
Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
11
# Launch Smoke Report
22

3-
Generated: 2026-04-15T20:18:43.439Z
3+
Generated: 2026-04-15T20:27:13.340Z
44

5-
Filters: games=false, samples=true, tools=false, sampleRange=1601-1608
5+
Filters: games=false, samples=true, tools=false, sampleRange=1605-1605
66

77
| Status | Type | Label | Path | Notes | Steps |
88
| --- | --- | --- | --- | --- | --- |
9-
| PASS | sample | 1601 | samples\phase-16\1601\index.html | | npm install --prefix ./tmp ws → npm run test:launch-smoke |
10-
| PASS | sample | 1602 | samples\phase-16\1602\index.html | | npm install --prefix ./tmp ws → npm run test:launch-smoke |
11-
| PASS | sample | 1603 | samples\phase-16\1603\index.html | | npm install --prefix ./tmp ws → npm run test:launch-smoke |
12-
| PASS | sample | 1604 | samples\phase-16\1604\index.html | | npm install --prefix ./tmp ws → npm run test:launch-smoke |
13-
| PASS | sample | 1605 | samples\phase-16\1605\index.html | | npm install --prefix ./tmp ws → npm run test:launch-smoke |
14-
| PASS | sample | 1606 | samples\phase-16\1606\index.html | | npm install --prefix ./tmp ws → npm run test:launch-smoke |
15-
| PASS | sample | 1607 | samples\phase-16\1607\index.html | | npm install --prefix ./tmp ws → npm run test:launch-smoke |
16-
| PASS | sample | 1608 | samples\phase-16\1608\index.html | | npm install --prefix ./tmp ws → npm run test:launch-smoke |
9+
| PASS | sample | 1605 | samples\phase-16\1605\index.html | | npm install --prefix ./tmp ws → npm run test:launch-smoke |
Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
1-
Phase 16 core track checklist
2-
[x] 1605 visible on load
3-
[x] 1606 visible on load
4-
[x] 1607 visible on load
5-
[x] 1608 visible on load
6-
[x] 1605 controls function
7-
[x] 1606 controls function
8-
[x] 1607 controls function
9-
[x] 1608 controls function
10-
[x] targeted smoke 1601-1608 passes
1+
Sample 1605 driving control checklist
2+
[x] left turn works while held
3+
[x] right turn works while held
4+
[x] steering stops on release
5+
[x] opposite direction can engage immediately
6+
[x] forward/reverse still function
7+
[x] sample renders visibly on load
8+
[x] targeted smoke for 1605 passes
119
[x] no 2D regression observed in targeted checks
1210
[x] no networking regression observed in targeted checks
1311

1412
Execution evidence:
1513
- PASS Phase16VisibilitySanity
16-
- Launch smoke targeted run: --samples --sample-range=1601-1608
17-
- Launch smoke result: PASS=8 FAIL=0 TOTAL=8
14+
- Launch smoke targeted run: --samples --sample-range=1605-1605
15+
- Launch smoke result: PASS=1 FAIL=0 TOTAL=1
1816
- PASS EngineTiming (2D baseline targeted check)
1917
- PASS MultiplayerNetworkingStack (network baseline targeted check)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# BUILD PR: 17.9 Sample 1605 Driving Control Fix
2+
3+
## Purpose
4+
Fix the behavioral defect in Sample 1605 - 3D Driving Sandbox where navigation gets stuck turning left or right.
5+
6+
## Observed Runtime Symptom
7+
- sample loads
8+
- 3D renders
9+
- driving controls are not correct
10+
- turning appears to stick on left/right instead of behaving like normal held-input steering
11+
12+
## Scope
13+
Surgically correct 1605 driving input/state behavior only.
14+
15+
## In Scope
16+
- samples/phase-16/1605/DrivingSandbox3DScene.js
17+
- minimal targeted test update if needed
18+
- docs/dev/reports/* validation updates
19+
20+
## Out of Scope
21+
- no changes to 1606-1608 unless a truly shared safe helper defect is proven
22+
- no engine-wide input changes
23+
- no 2D or networking changes
24+
- no repo-wide scanning
25+
- no zip output from Codex
26+
27+
## Likely Failure Areas To Inspect
28+
- left/right turn state not clearing when key is released
29+
- one-sided steering accumulator not recentering
30+
- input polling using stale state
31+
- mutually exclusive left/right handling not resolved correctly
32+
- heading/turn velocity damping missing or sign-clamped incorrectly
33+
34+
## Required Fix Direction
35+
Implement the smallest valid correction so:
36+
- left turn works while held
37+
- right turn works while held
38+
- steering stops when released
39+
- opposite direction can be engaged immediately
40+
- forward/reverse behavior remains intact
41+
42+
## Acceptance Criteria
43+
- [ ] 1605 no longer sticks turning left
44+
- [ ] 1605 no longer sticks turning right
45+
- [ ] steering responds correctly to press/hold/release
46+
- [ ] forward/reverse still function
47+
- [ ] sample remains visible and playable
48+
- [ ] targeted Phase 16 sanity still passes where affected
49+
- [ ] no 2D regression introduced
50+
- [ ] no networking regression introduced
51+
52+
## Validation
53+
- targeted behavioral check for 1605 steering release/reset
54+
- targeted smoke for 1605
55+
- update docs/dev/reports/change_summary.txt
56+
- update docs/dev/reports/validation_checklist.txt

samples/phase-16/1605/DrivingSandbox3DScene.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,7 @@ export default class DrivingSandbox3DScene extends Scene {
138138

139139
this.speed = clamp(this.speed, -this.maxReverseSpeed, this.maxForwardSpeed);
140140
if (Math.abs(this.speed) > 0.1) {
141-
const steeringDirection = this.speed >= 0 ? 1 : -1;
142-
this.heading += steer * this.turnRate * steeringDirection * dt;
141+
this.heading += steer * this.turnRate * dt;
143142
}
144143

145144
velocity.x = Math.sin(this.heading) * this.speed;
@@ -206,4 +205,3 @@ export default class DrivingSandbox3DScene extends Scene {
206205
]);
207206
}
208207
}
209-

tests/runtime/Phase16VisibilitySanity.test.mjs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,36 @@ function assertDrivingVisibilityAndInput() {
128128
const startZ = car.z;
129129
scene.step3DPhysics(1 / 60, { input: makeInput(['KeyW']) });
130130
assert.equal(car.z > startZ, true, 'Driving sample W input should advance car forward.');
131+
132+
const startHeading = scene.heading;
133+
for (let i = 0; i < 4; i += 1) {
134+
scene.step3DPhysics(1 / 60, { input: makeInput(['KeyW', 'KeyA']) });
135+
}
136+
const afterLeftHeading = scene.heading;
137+
assert.equal(afterLeftHeading < startHeading, true, 'Driving sample A hold should turn left.');
138+
139+
scene.step3DPhysics(1 / 60, { input: makeInput(['KeyW']) });
140+
const afterReleaseHeading = scene.heading;
141+
scene.step3DPhysics(1 / 60, { input: makeInput(['KeyW']) });
142+
assert.equal(scene.heading, afterReleaseHeading, 'Driving sample steering should stop when A/D is released.');
143+
144+
scene.step3DPhysics(1 / 60, { input: makeInput(['KeyW', 'KeyD']) });
145+
assert.equal(scene.heading > afterReleaseHeading, true, 'Driving sample D should engage immediately after left release.');
146+
const afterImmediateRightHeading = scene.heading;
147+
148+
for (let i = 0; i < 3; i += 1) {
149+
scene.step3DPhysics(1 / 60, { input: makeInput(['KeyW', 'KeyD']) });
150+
}
151+
assert.equal(scene.heading > afterImmediateRightHeading, true, 'Driving sample D hold should continue turning right.');
152+
153+
const beforeReverseHeading = scene.heading;
154+
scene.step3DPhysics(1 / 60, { input: makeInput(['KeyS', 'KeyD']) });
155+
assert.equal(scene.heading > beforeReverseHeading, true, 'Driving sample D should still steer right while reversing.');
156+
157+
for (let i = 0; i < 120; i += 1) {
158+
scene.step3DPhysics(1 / 60, { input: makeInput(['KeyS']) });
159+
}
160+
assert.equal(scene.speed < 0, true, 'Driving sample S input should produce reverse motion.');
131161
}
132162

133163
function assertPhysicsPlaygroundVisibilityAndInput() {

0 commit comments

Comments
 (0)