logo
Plunger

pinball

Plunger

Listens toPinballTable
1
Unlock

Install with the CLI:

bjs download Plunger

Plunger

Owns the pinball's ball lifecycle: auto-launch, drain detection, manual re-plunge, plus the table's tilted gravity and Havok substep rate.

What it does

The plunger auto-launches the ball the moment its Havok body appears, re-launches it on drain (when it falls below drainY or rolls past the bottom-edge drain Z), and fires on a trigger key (default Space) for a manual re-plunge. Each launch teleports the ball to spawnPosition and kicks it down-table along +Z at launchVelocityZ with sideways launchJitterX randomness. Once physics is alive it installs the table's tilted scene gravity and Havok's sub-time-step (240 Hz, anti-tunneling), and listens to pinballTable.resized to keep the drain threshold aligned with the table's bottom edge. It can optionally swap the ball's material for a chrome-mirror PBR.

Use it in a scene

A scene is just data — a list of entities, each with its components. At startup the SceneLoader turns this JSON into a live world; edit the file and reload to rebuild it.

Fastest path

bjs download scene Plunger

Pulls this exact scene into your project and runs it — no copy-paste. Add --all to grab the components and assets it needs too.

Or build it from scratch with the bjs CLI:

  1. 1Scaffold a project
    npm create @babylonjsmarket/arcade@latest my-game

    World, renderer, and dev server — ready to run.

  2. 2Install dependencies
    cd my-game && npm install
  3. 3Add Plunger
    bjs download Plunger

    Copies its source into src/ so the scene resolves.

    First time? Run bjs login once.

  4. 4Paste the scene into src/scenes/arcade-room.ts and run
    npm run dev

    SceneLoader builds the world from the JSON; reload to rebuild.

JSON
{
  "Ball": {
    "tags": ["ball"],
    "components": {
      "MeshPrimitive": {
        "primitive": "sphere",
        "diameter": 0.84,
        "position": [0, 0.5, -14],
        "material": { "diffuseColor": [0.95, 0.95, 1.0] }
      },
      "Physics": { "shapeType": "sphere", "motionType": "dynamic", "mass": 1, "restitution": 0.55, "friction": 0.02 }
    }
  },
  "World": {
    "components": {
      "Plunger": {
        "ballTag": "ball",
        "spawnPosition": [0, 0.42, -14.5],
        "gravity": [0, -12, 14],
        "launchVelocityZ": 16,
        "launchJitterX": 2.5,
        "drainY": -3,
        "drainZMargin": 2,
        "triggerKey": "Space"
      }
    }
  }
}

Props

  • ballTag (string, default 'ball') — entity tag identifying the ball.
  • spawnPosition ([x, y, z], default [0, 0.42, -14.5]) — where the ball is teleported on (re)launch.
  • gravity ([x, y, z], default [0, -12, 14]) — scene gravity applied once physics is alive (+Z = down-table).
  • subTimeStepHz (number, default 240) — Havok sub-time-step in Hz; 0 leaves the default.
  • launchVelocityZ (number, default 16) — launch impulse along +Z.
  • launchJitterX (number, default 2.5) — sideways randomness on each launch.
  • drainY (number, default -3) — drain when ball.y falls below this.
  • drainZMargin (number, default 2) — drain when ball.z exceeds half the table depth plus this margin.
  • triggerKey (string, default 'Space') — KeyboardEvent.code that fires the plunger.
  • chromeMaterial (boolean, default true) — swap the ball's material for a chrome-mirror PBR.

Events

  • listens pinballTable.resized — updates the cached table depth so the drain Z stays lined up with the bottom edge.

Dependencies

MeshPrimitive — the ball mesh it teleports and reads positions from. PinballTable — supplies table depth and emits pinballTable.resized for drain-edge tracking.

Notes

  • The chrome material needs an environmentTexture on the scene to actually reflect anything; the host app installs that separately.
  • Launch teleports by driving the body from the mesh, then kicks velocity on the next macro-task so the teleport lands first.
  • The system is non-pauseable (_pauseable = false), so ball lifecycle keeps running even when the world is paused.

More like this

MeshPrimitive
PinballTable
Bumper
CarDrive
FlightIntent
Flipper
Jump
KeyboardInput
KeyboardMover
MouseHole
MouseInput
PinballBuilder
PinballBuilderInput
PinballCamera
PinballLayout
PlayerFlightInput
PlayerInput
PlayerInputBridge
PokerInput
Spinner
TwinStickShooter

Was this page helpful?

We read every note — tell us what's working and what isn't.

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search