feat: per-level physics config with gravity and simulation step knobs#251
Merged
Conversation
Reshape Config storage to { common, levels } so any config block (today
just physics) can be overridden per level, mirroring how Assets already
handles common vs per-level state. Router pushes the current level into
Config alongside Assets, so getters resolve common merged with the
current level's overrides. Because each level switch already disposes
and re-inits the physics worker, per-level physics flows through the
existing LOAD.AMMO message without extra plumbing.
Physics gains fixedTimeStep (1/60) and maxSubSteps (3) alongside gravity
(default bumped to -30 for game-feel parity with the third-person
controller, which now reads gravity from Config). stepSimulation now
uses Ammo's full signature instead of relying on Bullet defaults that
silently dropped time on long frames.
Drive-by: setConfig was shallow with a buggy else-branch that lost
nested defaults on partial overrides; it now deep-merges, so calls like
setConfig({ physics: { enabled: true } }) preserve path/gravity instead
of clobbering them.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
speed was read in the acceleration/braking branches but declared with const further down the function, so pressing accelerate/brake threw "Cannot access 'speed' before initialization" and crashed the physics worker. Read getCurrentSpeedKmHour() once, above the branches that use it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Camera.getPosition() returns a plain {x,y,z}, which has no lerpVectors,
so SmoothCarFollow threw every frame and the follow camera never tracked
the car. Build a real Vector3 from the camera position and lerp it toward
the desired position.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Collapse isPlainObject arrow function onto a single line to satisfy prettier/prettier eslint rule. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reshape Config storage to { common, levels } so any config block (today just physics) can be overridden per level, mirroring how Assets already handles common vs per-level state. Router pushes the current level into Config alongside Assets, so getters resolve common merged with the current level's overrides. Because each level switch already disposes and re-inits the physics worker, per-level physics flows through the existing LOAD.AMMO message without extra plumbing.
Physics gains fixedTimeStep (1/60) and maxSubSteps (3) alongside gravity (default bumped to -30 for game-feel parity with the third-person controller, which now reads gravity from Config). stepSimulation now uses Ammo's full signature instead of relying on Bullet defaults that silently dropped time on long frames.
Drive-by: setConfig was shallow with a buggy else-branch that lost nested defaults on partial overrides; it now deep-merges, so calls like setConfig({ physics: { enabled: true } }) preserve path/gravity instead of clobbering them.