AutoRunnerDriver
The drivers of every car the player isn't driving.
What it does
AutoRunnerDriver works in road space, "how far along" and "how far across", because that is how a driver thinks: stay in lane two, pull alongside, get behind the player and push. Each role decides where across the road it wants to be and how fast it wants to go, then writes throttle, brake and steer onto its car's CarDrive.
| Role | What it does |
|---|---|
civilian | holds its lane at its own pace; follows a slower car, changes lane when there is room, merges when its lane ends |
rammer | catches the player from behind, rides alongside, swerves in |
gunner | holds a lane over and fires a shotgun volley across |
shover | gets behind and alongside and leans on the player toward the edge |
truck | holds the slow lane at a steady pace |
police | drives like a civilian until the player speeds near it or hits it, then gives chase |
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:
- 1Scaffold a project
World, renderer, and dev server — ready to run.
- 2Install dependencies
- 3Add AutoRunnerDriver
Copies its source into src/ so the scene resolves.
First time? Run bjs login once.
- 4Paste the scene into src/scenes/arcade-room.ts and run
SceneLoader builds the world from the JSON; reload to rebuild.
The player's car carries the player tag, which is what attackers look for. A Gunner also needs a shell pool of AutoRunnerProjectile rounds. With no HighwayRoad in the scene, the road is taken to be straight along +Z with three lanes.
Steering by pure pursuit
Every role steers the same way. Pick a point some way up the road at the offset you want, and turn toward it:
A faster car looks further up the road, so the same lane change asks for less wheel and it drifts over instead of jerking.
Attack runs
An attacker closes in fast from behind and matches pace once level. Once level, every attackEvery seconds (give or take 30%), it makes a run lasting attackLength. A rammer swerves in, a shover leans the player toward the nearer edge, and a gunner fires one volley of pellets shells. It gives up once the player is more than giveUpBehind metres ahead, or 45 m behind.
Police
A police car keeps its lane at cruiseSpeed. It starts a chase when the player goes faster than speedLimit within sight metres, ahead or behind, or when the player rams it or shoots it. In a chase it drives like a shover, flashes its roof lights (headlights.beacon.set) and sends autoRunnerDriver.pursuit with on: true.
The chase ends after calmSeconds in a row of the player keeping to the limit, or being out of sight. Out of sight means hidden (a car in the weapons truck is a ghost, and drivers cannot see ghosts) or more than giveUpBehind metres ahead. While the player keeps to the limit, the police car only follows, 12 m back.
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:
- 1Scaffold a project
World, renderer, and dev server — ready to run.
- 2Install dependencies
- 3Add AutoRunnerDriver
Copies its source into src/ so the scene resolves.
First time? Run bjs login once.
- 4Paste the scene into src/scenes/arcade-room.ts and run
SceneLoader builds the world from the JSON; reload to rebuild.
Losing control
Smoke (autoRunnerDriver.blind) makes a driver wander, slow down and hold fire. In a spin-out it lets go of the throttle, brakes lightly and steers half as hard. A car tagged wreck coasts to a stop, and brakes only while it is still rolling, because CarDrive turns a brake held at a standstill into reverse.
Settings
| Field | Default | What it does |
|---|---|---|
role | "civilian" | civilian, rammer, gunner, shover, truck or police. |
cruiseSpeed | 26 | Pace on an empty road, m/s. |
steerGain | 1.7 | How hard the driver steers toward its line. |
sideGap | 5 | Gunner: how far across from the target it rides, metres. |
attackEvery | 2.6 | Seconds between an attacker's runs. |
attackLength | 0.8 | Seconds one run lasts. |
giveUpBehind | 60 | How far ahead the player can get before an attacker gives up, metres. |
speedLimit | 36 | Police: the speed that starts a chase, m/s. |
sight | 45 | Police: how far along the road it spots a speeder, ahead or behind, metres. |
calmSeconds | 3 | Police: seconds of good driving, or out of sight, that end a chase. |
targetTag | "player" | Tag of the car an attacker goes after. |
lane | 0 | Lane a civilian starts in. The spawner sets it. |
shellPool | "shell" | Gunner: the pool its shells come from. |
shellSpeed | 75 | Gunner: shell speed on top of the car's own, m/s. |
shellDamage | 5 | Gunner: damage per shell. |
pellets | 3 | Gunner: shells per volley. |
spread | 0.1 | Gunner: angle between pellets, radians. |
Events
| Event | Payload | Direction |
|---|---|---|
autoRunnerDriver.fired | { entityId, x, z, targetId } | emits |
autoRunnerDriver.pursuit | { entityId, targetId, on } | emits |
headlights.beacon.set | { entityId, on } | emits |
autoRunnerDriver.blind | { entityId, seconds } | listens |
carCollision.hit | { a, b, x, z, closing, dvA, dvB } | listens |
autoRunnerProjectile.hit | { entityId, targetId, owner, kind, x, z, damage } | listens |
Needs
- CarDrive is the car each driver steers. The driver writes its throttle, brake and steer.
- CarCollision tells the driver when its car is spinning, and how long each car is for following gaps. Its hit event is how police notice a ram.
- MeshPrimitive gives every car's position.
- HighwayRoad supplies the lanes, width and curve of the road.
- AutoRunnerProjectile fires a Gunner's shells, and its hit event is how police notice a shot.

















































