logo
By Lawrence

5 minutes

Lock On

Guns only work up close. Two fighters weave around you now, and your only weapon is a stream of tracers you aim by hand. A missile could reach across the arena — but a missile that flies straight ahead is only a slow bullet. The lock is what makes it dangerous: a choice the ship holds each frame about which enemy is yours. No missile fires this lesson; first the ship has to pick a target and hold onto it.

Add the launcher to the player stack

The launcher is one line on the player. Add it to Player's component stack. Put it next to the gun and the loadout from earlier:

"Player": {
  "tags": ["player"],
  "components": {
    "ShipLoadout": { "loadout": "spaceplane" },
    "MachineGun": {},
    "MissileLauncher": {}
  }
}

Empty braces means use the defaults, and the default loadout is infinite ammo — stored as a string, for a reason worth seeing.

MissileLauncher.core.ts holds pure data: how much ammo is left, how long until the next launch, and which enemy sits in the crosshairs.

From the launcher's core:

src/components/MissileLauncher/MissileLauncher.defs.ts
export const AMMO_INFINITY = 'infinity';

export interface MissileLauncherInput {
  /** Missiles remaining, OR the literal string `'infinity'` for an unlimited
   *  supply. The string sentinel exists so JSON save/load doesn't degrade
   *  Infinity to null. */
  ammo?: number | typeof AMMO_INFINITY;
  fireCooldown?: number;
  lockedTargetId?: string | null;
  lockedDistance?: number;
}

export const DEFAULT_MISSILE_LAUNCHER_PARAMS: Required<MissileLauncherInput> = {
  ammo: Number.POSITIVE_INFINITY,
  fireCooldown: 0,
  lockedTargetId: null,
  lockedDistance: 0,
};

One field needs a closer look: ammo. An unlimited loadout is Number.POSITIVE_INFINITY, and JSON can't store that — JSON.stringify(Infinity) becomes null, which reloads as 0, an empty launcher. So the saved form uses a sentinel string, 'infinity', and the component turns it back into a real Infinity on load:

Continue reading

Unlock the Full Course

Every lesson, the runnable examples, and the finished build — yours to keep.

$9one-time

Was this page helpful?

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

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search