logo
Headlights

vehicle · vehicle-combat

Headlights

1
Unlock

Install with the CLI:

bjs download Headlights

Headlights

Lights for every car that come on as it gets dark.

What it does

A renderer can light each surface with only a few real lights. So the player's car (real: true) gets two real spot lights that light the road, the trees and the other cars. Every car, the player's too, also gets:

  • a beam painted on the road ahead, a fan of light added on top of the tarmac, which is how a headlight looks from above;
  • two glowing lenses;
  • two red tail lamps that brighten while the car brakes.

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

    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
{
  "Player": {
    "components": {
      "MeshPrimitive": {
        "primitive": "box",
        "width": 1.9,
        "height": 1,
        "depth": 4.2
      },
      "CarDrive": {},
      "Headlights": {
        "real": true,
        "beamStrength": 0.35,
        "forward": 2.0,
        "side": 0.7
      }
    }
  }
}

Put a plain "Headlights": {} on traffic blueprints. Call registerHeadlightsExtension(adapter) at bootstrap. Without it, a real car still gets two spot lights, but no car gets beams, lenses or tail lamps.

Coming on at dusk

The System hears darkness from dayNight.changed and turns it into a light level with a smooth ramp:

TypeScript
export function lightLevel(darkness: number, onAt: number, fullAt: number): number {
  if (fullAt <= onAt) return darkness >= onAt ? 1 : 0;
  const t = Math.max(0, Math.min(1, (darkness - onAt) / (fullAt - onAt)));
  return t * t * (3 - 2 * t);
}

With the defaults, darkness 0.4 gives a level of 0.16. Darkness 0.5 gives 0.5. The lights ease in rather than snap on.

Range falloff

Real light fades with the square of the distance. A headlight bright enough to reach far down the road that way would blind the car's own bonnet. So the plugin gives its spot lights a set range instead: the beam fades out at that distance. The lenses are glossy glass. The beam on the road is light, so it is unlit and added on top.

Light bar

A car with "beacon": true gets a red and blue light bar on its roof. It stays dark until headlights.beacon.set turns it on. Then the two halves take turns, each with a quick double flash:

TypeScript
  const phase = (((t * rate) % 1) + 1) % 1;
  const lit = (a: number) => (phase >= a && phase < a + 0.15) || (phase >= a + 0.25 && phase < a + 0.4);
  return { red: lit(0) ? 1 : 0, blue: lit(0.5) ? 1 : 0 };

At the default beaconRate one cycle takes 0.71 s. Red flashes twice in the first half and blue twice in the second, day or night. Each flash lays a round red or blue glow on the road, washRadius metres in radius. The glow is painted on like the beam. It is not a real light, because the sun, the sky and the player's headlights already use up the few each surface can take.

Pools and ghosts

A pooled car that parks hides its lights, and they come back when the car does. A car tagged as a ghost by CarCollision (riding in a truck, or waiting to respawn) shows no lights.

Settings

FieldDefaultWhat it does
realfalseTwo real spot lights (for the player's car).
color[1, 0.94, 0.8]Colour of the real lights.
intensity2.4Real lights: strength.
range60Real lights: reach, metres.
angle0.95Real lights: full cone, radians.
exponent5Real lights: edge hardness.
beamLength20Painted beam: length, metres.
beamWidth10Painted beam: far width, metres.
beamStrength0.55Painted beam: strength, 0 to 1.
forward2.0Lamps sit this far forward of the car's centre.
side0.68Lamps sit this far either side of the centre.
height0.7Lamp height.
rear2.05Tail lamps sit this far behind the centre.
onAt0.3Darkness at which the lights start to come on.
fullAt0.7Darkness at which they are fully on.
beaconfalseA roof light bar, red on the left and blue on the right (police).
beaconHeight1.45Height of the roof, metres.
beaconWidth0.42Half the light bar's width, metres.
beaconRate1.4Flash cycles a second.
washRadius7Radius of the light bar's coloured glow, metres.

Events

EventPayloadDirection
dayNight.changed{ entityId, hour, darkness, phase }listens, reads darkness
headlights.beacon.set{ entityId, on }listens, switches that car's light bar flashing or off

Needs

  • MeshPrimitive: where each car is.
  • CarDrive: the car's heading, and its brake and speed for the brake lamps.
  • CarCollision: its ghost tag, which hides the lights.

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