logo
PinballRamp

pinball

PinballRamp

1
Unlock

Install with the CLI:

bjs download PinballRamp

PinballRamp

A ramp for a pinball table, built from where it starts, where it ends and how high it goes.

What it does

You give it three things: the mouth on the playfield (from), the top (to), and how high the top is (rise). On its first frame it builds a tilted floor with a rail down each side. Each piece is a box with a static Physics body. The ball rolls up under its own speed, so a weak shot rolls back down.

The slope comes straight from those numbers. Pinball Tower's left ramp runs from [-5.6, 22] to [-6.2, 9] and rises 2.4. That is 13.01 across the table and 2.4 up, a slope of 10.4 degrees, on a floor 13.23 long.

The floor sits half its thickness low, so its top face meets the playfield exactly at the mouth. Put the box's middle on the slope instead and the mouth is a step half a thickness high, and the ball hits it like a kerb.

When the ball gets within madeRadius of the top, it says pinballRamp.made and score.add. That distance is measured in 3D, so a ball rolling under the top of the ramp does not count. It fires once per trip: the ball has to leave the top before it can make the ramp again.

What happens at the top is up to you. Set endStop and a bar across the top sends the ball back down. Or put a WireRail there to carry it away.

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.

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 PinballRamp
    bjs download PinballRamp

    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
{
  "Ramp_Left": {
    "components": {
      "PinballRamp": {
        "from": [-5.6, 22],
        "to": [-6.2, 9],
        "rise": 2.4,
        "points": 1000
      }
    }
  },
  "Ramp_Practice": {
    "components": {
      "PinballRamp": {
        "from": [0, 6],
        "to": [0, -8],
        "rise": 2.4,
        "endStop": true,
        "color": [1, 0.45, 0.8]
      }
    }
  }
}

The ball needs the ball tag. Up the table is -Z, so to usually has the smaller z.

Props

  • from ([x, z], default [0, 4]). The mouth, on the playfield.
  • to ([x, z], default [0, -4]). The top.
  • rise (number, default 2). How high the top is above the playfield.
  • width (number, default 1.8). Floor width between the rails. The ball is 0.84 across.
  • thickness (number, default 0.15). Floor thickness.
  • railHeight (number, default 0.7). Rail height above the floor.
  • endStop (boolean, default false). A bar across the top.
  • points (number, default 1000). Paid to ownerEntity for each made ramp.
  • ownerEntity (string, default "Player"). The Score bucket to pay.
  • madeRadius (number, default 1.2). How close to the top the ball must get.
  • color ([r, g, b], default [0.35, 0.75, 1]). Floor colour.
  • railColor ([r, g, b], default [0.85, 0.9, 1]). Rail colour.
  • alpha (number, default 0.55). Floor see-through, 0 to 1. A see-through floor casts no shadow.

Events

Emits:

  • pinballRamp.made, { entityId, ballId, points }. The ball reached the top.
  • score.add, { ownerEntity, points }. At the same moment.

Dependencies

Notes

  • The pieces are child entities named <id>_floor, <id>_rail0, <id>_rail1 and <id>_stop. Remove the ramp and they go too.
  • After a made ramp, the ball must get 2.5 × madeRadius from the top before the next one counts.

More like this

Was this page helpful?

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

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search