simvx.core.physics.backends¶
Precedence (most specific wins)¶
An explicit
PhysicsRoot(backend=...)override on the node.The project / App-level
physics_backendsetting (GeneralConfig,.simvx/config.json).An auto-discovered installed native backend package.
The pure-Python :class:
~simvx.core.physics.builtin.BuiltinPhysicsdefault.
Only the resolution lives here; the consumers (PhysicsRoot and the tree’s
default world) call :func:resolve_world_factory / :func:resolve_world_factory_2d
to get a ready-to-call :data:~simvx.core.physics.root.WorldFactory for the
chosen backend. This keeps backend choice out of the resolution walk in
root.py (which only finds which world a node belongs to, never which kind).
Auto-discovery (precedence 3)¶
A native backend self-registers on import, mirroring the engine’s miniaudio
“installed -> used” model. The probe (:func:_try_import_native_backends) unions
two routes: (a) the in-core pymunk (Chipmunk2D) 2D module, imported directly, and
(b) any out-of-tree package advertising a simvx.physics.backends entry point
(e.g. simvx-physics-jolt), discovered via :mod:importlib.metadata and
register()-ed. Either route calls :func:register_backend to add itself to
- data:
_REGISTRY; once registered a backend is both auto-discoverable (3) and addressable by name (2 / 1). When no native backend is installed the registry holds only"builtin"and every level collapses to Builtin.
Auto-discovery (3) never wins over an explicit Builtin choice: an explicitly
requested "builtin" resolves at 1 / 2 before 3 is consulted, so an
installed native backend is opt-in for the default, not a silent replacement.
A backend further controls whether auto-discovery may pick it at all via
- attr:
BackendEntry.auto_default. pymunk follows the “installed -> used” model (auto_default=True) and so wins auto-discovery for 2D; a gameplay-affecting 3D solver like Jolt registersauto_default=False: it stays name-addressable (1 / 2) but installing it does not change the default 3D backend.
Auto-discovery is PER DIMENSION¶
The registry is one flat namespace but a backend may implement only one half of
it, so :func:_auto_discovered_native takes the dimension it is choosing for and
never offers a backend that cannot serve it. Without that, a machine with pymunk
installed picks "pymunk" for a 3D world, finds no 3D factory, and falls back
to Builtin while warning about a choice nothing asked for; and a 3D-only backend
that registered second could never win 3D at all, because the one flat answer is
registration order and pymunk is imported first.
Backend selection: the single place a physics backend is chosen.
Module Contents¶
Classes¶
A registered physics backend: its name + 3D / 2D world factories. |
Functions¶
Register a physics backend so it is name-addressable and auto-discoverable. |
|
Resolve the backend NAME by precedence: explicit > setting > auto > builtin. |
|
Return the 3D :data: |
|
Return the 2D :data: |
Data¶
API¶
- simvx.core.physics.backends.log¶
‘getLogger(…)’
- simvx.core.physics.backends.BUILTIN¶
‘builtin’
- class simvx.core.physics.backends.BackendEntry[source]¶
A registered physics backend: its name + 3D / 2D world factories.
A native backend registers one of these via :func:
register_backend. A backend may support only one dimension; the missing factory isNoneand resolution for that dimension falls through to Builtin rather than failing, so a 3D-only native backend never breaks a 2D scene. The fall-through warns when the backend was explicitly requested (node override or project setting) and logs at debug from auto-discovery, which has no business picking a backend for a dimension it cannot serve.Attributes: name: The token used in
physics_backendconfig /PhysicsRoot(backend=). world_factory: Builds a 3D world for a given gravity, orNone. world_factory_2d: Builds a 2D world for a given gravity, orNone. A missing factory does not fail resolution for that dimension: an explicitly requested backend degrades to Builtin with a warning, and from auto-discovery it degrades silently, since a backend that cannot serve the dimension is not a choice for it. native:Truefor an installed native backend (auto-discoverable),Falsefor the always-present Builtin (never auto-selected over a native one; it is the final fallback). auto_default: WhenTrue(the miniaudio “installed -> used” model, used by pymunk), the backend may win auto-discovery and become the default for every dimension it serves. WhenFalsethe backend is still name-addressable (via a node override or the project setting) but never auto-selected: installing it does NOT change the default backend. A gameplay-affecting 3D solver swap (Jolt) sets thisFalseso it is strictly explicit opt-in.- name: str¶
None
- world_factory: simvx.core.physics.root.WorldFactory | None¶
None
- world_factory_2d: simvx.core.physics.root.WorldFactory2D | None¶
None
- native: bool¶
True
- auto_default: bool¶
True
- simvx.core.physics.backends.register_backend(entry: simvx.core.physics.backends.BackendEntry) None[source]¶
Register a physics backend so it is name-addressable and auto-discoverable.
The single plug point for a future native backend (Jolt, pymunk): the native package calls this on import to add itself, mirroring miniaudio’s “installed -> used” model. Re-registering the same name replaces the entry (idempotent for re-import).
"builtin"is reserved as the fallback name.Args: entry: The :class:
BackendEntryto register.Raises: ValueError: If
entry.nameis"builtin"(reserved) or empty.
- simvx.core.physics.backends.resolve_backend_name(explicit: str | None, setting: str | None, *, dimension: int | None = None) str[source]¶
Resolve the backend NAME by precedence: explicit > setting > auto > builtin.
Args: explicit: A
PhysicsRoot(backend=...)override, orNoneif unset. setting: The project/Appphysics_backendconfig value, orNone/ empty if unset. dimension: 2 or 3 to restrict auto-discovery to backends that serve that dimension, orNonefor the dimension-agnostic answer. It affects level 3 only: an explicit name or project setting is honoured whatever it can serve, so a backend named for a dimension it does not implement still reaches the warned fall-through in :func:resolve_world_factory.Returns: The resolved backend name (a key of :data:
_REGISTRY). An explicit / setting value that names an unknown backend logs a warning and falls back to the next level (auto, then Builtin) rather than raising: a missing optional native backend degrades to Builtin, it does not crash the game.
- simvx.core.physics.backends.resolve_world_factory(explicit: str | None = None) simvx.core.physics.root.WorldFactory[source]¶
Return the 3D :data:
WorldFactoryfor the resolved backend.Applies the full precedence (explicit > project setting > auto > Builtin) and returns the chosen backend’s 3D factory. If the chosen backend has no 3D factory (a 2D-only native backend), falls back to Builtin’s 3D factory, warning when the backend was explicitly requested (a node override or project setting naming it) and logging at debug from auto-discovery, where a backend that cannot serve 3D is not a 3D choice at all.
Args: explicit: A
PhysicsRoot(backend=...)override, orNone.Returns: A callable
(gravity: Vec3) -> PhysicsWorld.
- simvx.core.physics.backends.resolve_world_factory_2d(explicit: str | None = None) simvx.core.physics.root.WorldFactory2D[source]¶
Return the 2D :data:
WorldFactory2Dfor the resolved backend.2D sibling of :func:
resolve_world_factory. Falls back to Builtin’s 2D factory when the chosen backend has no 2D factory (a 3D-only native backend), with the same tier-dependent logging: warned for an explicit request, debug from auto-discovery.Args: explicit: A
PhysicsRoot2D(backend=...)override, orNone.Returns: A callable
(gravity: Vec2) -> Physics2DWorld.
- simvx.core.physics.backends.__all__¶
[‘BUILTIN’, ‘BackendEntry’, ‘register_backend’, ‘resolve_backend_name’, ‘resolve_world_factory’, ‘re…