Physics#

oj wraps OneJS's 2D physics in a hook that handles the lifecycle. The model, the performance characteristics and the reasoning behind the API shape are all on that page, and this one is only the wrapper. Read that page first if you are doing anything beyond dropping bodies into a box.

usePhysics#

import { usePhysics, View } from "oj"
import { useRef } from "react"

function Sandbox() {
    const host = useRef(null)
    const world = usePhysics(host, {
        gravity: [0, 900],
        bodies: [
            { shape: "circle", radius: 16, position: [100, 0] },
            { shape: "box", size: [400, 20], position: [200, 400], type: "static" },
        ],
    }, (contact) => {
        // called for each contact this frame
    })

    return <View ref={host} style={{ flexGrow: 1 }} />
}

usePhysics(hostRef, config, onCollision?) creates the world on mount, pumps it every frame, and disposes it on unmount. It returns the PhysicsWorld once created and null on the first render, so guard before using it.

Two behaviours worth knowing, both inherited from the underlying design rather than invented here:

The config is read once. Changing the object you pass does not reconfigure a running world, because rebuilding a world from a render would restart the simulation mid-flight. Drive a running world through its methods instead.

Reading is expensive and writing is cheap. The simulation and the writing of positions onto elements both happen in C#, so a hundred bodies cost JavaScript nothing per frame. Pushing bodies around is free. Polling their positions is not, and is the thing that will make it slow.

The collision handler is held in a ref, so a handler that closes over fresh state each render works without re-creating the world.

createPhysicsWorld#

The unmanaged form, for when the world does not belong to a component's lifetime. You create it, you pump it, and you dispose it, exactly as on the physics guide. Reach for it when a world outlives the component that started it, and use the hook otherwise.

When it is unavailable#

Physics needs OneJS.Physics2DBridge in the runtime. When it is missing you get a console line rather than a crash:

[oj] physics is unavailable: OneJS.Physics2DBridge was not found.