Add AppOptions.physicsWorld for explicit physics backend selection - #9266
Merged
Conversation
Lands the public backend-selection API deferred in #9043. A physics backend can now be supplied at application construction: const options = new AppOptions(); options.physicsWorld = new AmmoPhysicsWorld(); - AppBase.init installs the injected world into the rigid body system, which registers itself as the world's contact listener - PhysicsWorld, AmmoPhysicsWorld and NullPhysicsWorld are exported as @Alpha API; the backend contract methods remain internal (@ignore) - Backend constructors are now parameterless (the redundant contactListener option is removed) - Ammo auto-detection is unchanged and skipped when a world is injected - Adds tests covering injection, listener wiring, auto-detect skip, component body creation and world ownership Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Public API reportThis PR changes the public API surface (+11 / −0), per the docs' rules (@ignore / @Private / undocumented are excluded). Show API diff+AmmoPhysicsWorld.constructor()
+AmmoPhysicsWorld.nativeWorld: any
+AppOptions.physicsWorld: PhysicsWorld
+NullPhysicsWorld.constructor()
+NullPhysicsWorld.nativeWorld: any
+PhysicsWorld.constructor()
+PhysicsWorld.nativeWorld: any
+RigidBodyComponentSystem.get physicsWorld(): PhysicsWorld | null
+class AmmoPhysicsWorld extends PhysicsWorld
+class NullPhysicsWorld extends PhysicsWorld
+class PhysicsWorldInformational only — this never fails the build. |
Build size reportThis PR changes the size of the minified bundles.
|
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
@LeXXik @mvaligursky, this is the groundwork needed to offer alternative physics back-ends. It's treeshake-friendly. Let me know if you have any concerns. |
Contributor
|
Looks good. I noticed we don't have an ability to pause the backend (e.g. game menu opened - world freezes). Something like Edit: extracted feature request to #9272 |
mvaligursky
reviewed
Aug 31, 2026
Co-Authored-By: Claude Fable 5 <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.
Description
Follow-up to #9043, which decoupled physics into a backend abstraction but deferred "a public selection API (e.g. via
AppOptions) until a second real backend lands". This PR lands that API now, proven with the existing backends, so that a future backend (e.g. Jolt) becomes purely additive — a new leaf module plus one line of user code, with zero framework changes.What changed
AppOptions.physicsWorld(instance-valued, mirroringsoundManager):AppBase.init()installs it into theRigidBodyComponentSystem, which registers itself as the world's contact listener — users never touch listener plumbing. Injection happens beforeonLibrariesLoaded, so Ammo auto-detection is cleanly skipped when a world is supplied.@alphasurface:PhysicsWorld,AmmoPhysicsWorldandNullPhysicsWorldare exported; the documented API is just the constructors,PhysicsWorld#nativeWorld(the native escape hatch) andRigidBodyComponentSystem#physicsWorld. The backend contract methods (createBody,createShape, joints, raycasts, descriptor typedefs) stay@ignored — implementer documentation lives in the source and the.d.tsretains full types for subclassing, but the docs site and API report only advertise what applications actually call.contactListenerconstructor option was redundant once the system wires the listener on install, so it's removed.AmmoPhysicsWorldnowDebug.asserts with a clear message if constructed before the Ammo library has loaded.off('update')branch inonLibraryLoaded, declared the Ammo world's constructor-assigned internals as tagged class fields so they no longer leak into the generated API reference, and made theRigidBodyComponentSystemclass doc backend-neutral.test/framework/physics/app-options-physics-world.test.mjs— the first tests to constructAppBase+AppOptionsdirectly — covering installation during init, contact listener wiring, auto-detect skip, component body creation through the injected world, the single-install assert and world ownership on destroy.Notes for reviewers
onLibraryLoaded) is untouched and remains the default for the Editor and engine-only apps that load Ammo without setting the option. It becomes the deprecation target for a future major, once explicit injection is the norm.@alphasurface — that's the intended minimal set.nativeWorldfor each world class.Checklist
🤖 Generated with Claude Code