logo
AutoRunnerProjectile

vehicle · vehicle-combat

AutoRunnerProjectile

1
Unlock

Install with the CLI:

bjs download AutoRunnerProjectile

AutoRunnerProjectile

Pooled rounds for a road war, from a tracer bullet to a falling bomb.

What it does

A round is a pooled entity with a MeshPrimitive and an AutoRunnerProjectile. AutoRunnerProjectileSystem moves it, steers a missile at its target, drops a bomb, and checks the line the round travelled this frame against everything it may hurt.

KindHow it flies
bulletstraight and fast; stopped by bulletproof armour
shellslower pellets a Gunner fires sideways
missilespeeds up and turns toward its quarry at turnRate; bursts
bombfalls under gravity; bursts on the road

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

    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
{
  "BulletBlueprint": {
    "tags": ["round"],
    "components": {
      "Pool": { "name": "bullet", "size": 80 },
      "MeshPrimitive": {
        "primitive": "box",
        "width": 0.13,
        "height": 0.13,
        "depth": 2,
        "material": { "emissiveColor": [1, 0.72, 0.2] }
      },
      "AutoRunnerProjectile": {
        "kind": "bullet",
        "life": 0.7,
        "damage": 7,
        "targets": ["car"]
      }
    }
  }
}

A gun fires with one call from AutoRunnerProjectile.defs:

TypeScript
launchProjectile(world, 'bullet', { x, y: 1, z, vx, vz, owner: car.id });

It returns null when the pool is not up yet (pools appear a frame after the scene loads), and the gun skips that shot. The spec can also carry vy, a damage for this one round, and a missile's first target.

Hits along the path

A fast round moves further in one frame than a car is wide. Test only where it ends up and it skips clean through. So the test runs along the whole path, fattened by the round's radius:

TypeScript
/** Does the segment (x0,z0)→(x1,z1), fattened by `r`, touch the box? */
export function segmentHitsBox(
  x0: number, z0: number, x1: number, z1: number, r: number,
  bx: number, bz: number, heading: number, hw: number, hl: number,
): boolean {
  // ...
  return clip(a0, a1, -hl - r, hl + r) && clip(b0, b1, -hw - r, hw + r);
}
text
player bullet: 150 m/s + the car's speed, ÷ 60 frames = 2.5 m a frame or more
car width:     1.9 m

Cars are tested as their CarCollision boxes. Anything tagged air is tested as a circle.

Missile turns

A missile can only turn so fast:

TypeScript
  const max = turnRate * dt;
  const turn = Math.max(-max, Math.min(max, err));
text
tightest turn radius = maxSpeed ÷ turnRate = 110 ÷ 2.6 ≈ 42 m

A helicopter that turns inside that circle makes the missile miss. With no target given, a missile with a seekTag picks the nearest match within 220 m and about 69° either side of its nose.

Blast falloff

A burst hurts everything it may hurt inside explodeRadius, except the target it struck, which already took the full hit. It sends one autoRunnerProjectile.hit per target it catches, then one autoRunnerProjectile.exploded.

TypeScript
export function blastDamage(damage: number, d: number, radius: number): number {
  if (radius <= 0 || d >= radius) return 0;
  return damage * (1 - (d / radius) * 0.7);
}
text
bomb, damage 45, radius 5.5:   on top 45 · halfway out 29 · just inside the edge 14 · past it 0

The distance counts from roughly the car's near side, not its centre.

Who can be hit

A target needs Health and one of the round's targets tags. It must be on the road for a ground round, or tagged air for an air round. Rounds never hit their owner, a pool blueprint, or a car tagged ghost, and a bomb higher than 2.4 m passes over cars until it comes down. Armour tagged bulletproof sends a round that is not piercing away as a ricochet, with no damage.

Settings

FieldDefaultWhat it does
kind"bullet"bullet, shell, missile or bomb.
life0.9Seconds before it is put away. A missile with a burst radius bursts when it runs out.
damage6Damage to the target it strikes, and the most a burst does.
radius0.35How fat the round is for hit tests, metres.
targets["car"]Tags it can hurt.
airfalseCan hit air targets.
groundtrueCan hit things on the road.
piercingfalseGoes through bulletproof armour.
explodeRadius0Burst radius, metres. 0 is no burst.
thrust60Missile: speed gained per second, m/s².
maxSpeed110Missile: top speed, m/s.
turnRate2.6Missile: fastest turn, rad/s.
seekTag""Missile: the tag it hunts when it has no target.
gravity14Bomb: downward pull, m/s².

Events

EventPayloadDirection
autoRunnerProjectile.launched{ entityId, kind, owner, x, z }emits
autoRunnerProjectile.hit{ entityId, targetId, owner, kind, x, z, damage }emits
autoRunnerProjectile.ricochet{ entityId, targetId, owner, kind, x, z }emits
autoRunnerProjectile.exploded{ entityId, owner, kind, x, z, radius, ground }emits
autoRunnerProjectile.ended{ entityId, kind, x, z, reason }, reason is hit, ricochet, ground or expiredemits
health.damage{ entityId, damage }emits

Needs

  • MeshPrimitive holds each round's pose, and the size of a target with no CarCollision.
  • CarCollision gives each car's box for the hit test, and how much damage the car takes.
  • CarDrive gives each car's heading, so its box points the right way.
  • Health decides who can be hurt. A target with no hit points left is skipped.

More like this

AutoRunnerDirector
AutoRunnerDriver
CarCollision
CarDrive
Health
MeshPrimitive
RoadAudio
RoadFX
RoadHazard
AiDriver
AiPilot
Asteroid
AutoRunnerBomber
AutoRunnerHUD
AutoRunnerWeapons
BoatMode
BoatWater
Bullet
CarPaint
ContactDamage
ContactImpulse
DayNightCycle
Headlights
HighwayRoad
HighwaySpawner
MachineGun
Missile
MissileLauncher
OilBlob
Parts
RoadCamera
RoadSpawner
RoadTreadmill
RoadsideScenery
ShipLoadout
SmokeScreen
SupplyTruck
SurfacePatch
TrafficConvoy
TwinStickEnemy
WeaponsVan

Was this page helpful?

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

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search