logo
Rollover

pinball

Rollover

1
Unlock

Install with the CLI:

bjs download Rollover

Rollover

Lane switches that light up.

What it does

The top lanes are a row of switches the ball rolls over on its way down. Each one lights when the ball crosses it. Light them all and the row pays out and goes dark.

A rollover has no physics body, so the ball rolls straight over. When the ball crosses a lane:

  • It pays points, lit or not.
  • If the lane was dark, it lights: the mesh glows litColor, and the group's pattern goes out on rollover.changed.
  • If that was the last dark lane, it says rollover.complete, pays groupPoints, and the whole group goes dark again.

Lanes fire once per pass. The ball has to leave a lane before it can score there again.

Lane change

The flipper buttons slide the lit lanes sideways. With three lanes lit as L L _, the right flipper makes it _ L L, and again makes it L _ L. The light that falls off one end comes round the other, so pressing a button never costs the player a lane. A good player keeps moving the dark lane under the ball.

Lanes are ordered left to right by their x position. The keys are read from keyboard.keydown on the bus, which Flipper sends.

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

    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
{
  "Lane_1": {
    "components": {
      "MeshPrimitive": {
        "primitive": "cylinder",
        "diameter": 0.7,
        "height": 0.04,
        "position": [-3.4, 0.02, -30.5],
        "material": {
          "diffuseColor": [0.4, 0.3, 0.2],
          "emissiveColor": [0.08, 0.05, 0.02]
        }
      },
      "Rollover": { "group": "top", "points": 250, "groupPoints": 2500 }
    }
  }
}

Add Lane_2 and Lane_3 the same way in the same group, and put short PinballWall guides between them.

Props

  • group (string, default "lanes"). Lanes with the same name light and complete together.
  • points (number, default 250). Paid each time the ball crosses.
  • groupPoints (number, default 2500). Paid when every lane in the group is lit.
  • ownerEntity (string, default "Player"). Who gets the points.
  • hitRadius (number, default 0.7). Distance on the table (x, z) from the lane's centre that counts as crossing.
  • litColor ([r, g, b], default [1, 0.75, 0.2]). Glow when lit. Dark lanes go back to their own material glow.
  • rotateLeftKey, rotateRightKey (key codes, defaults "ShiftLeft" and "ShiftRight"). Slide the lit lanes. The first lane in a group decides the keys for the group.

Events

Emits:

  • rollover.changed, { group, index, lit }. index is the lane crossed, or -1 for a lane change or the group going dark. lit is every lane, left to right.
  • rollover.complete, { group, count }.
  • score.add, { ownerEntity, points }.

Listens to:

  • keyboard.keydown, { code }. Lane change.

Dependencies

MeshPrimitive on the same entity. Score to count the points. The ball needs the ball tag.

The lane maths

  • The pattern logic is in Rollover.core.ts: lightLane and rotateLit.
  • A slide that changes nothing (all dark, or all lit) says nothing.

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