Templates

Creating new objects from scratch is complicated, but using an existing template is simple. The factory scenario includes many templates to make it easier to create new objects.

1   Ships

Ships fall into three broad categories:

Name Shape Examples
tpl/warship Triangle tpl/fighter, tpl/cruiser, tpl/schooner, tpl/hvc, tpl/gunship, tpl/hvd, tpl/defdrone
tpl/capship Diamond tpl/carrier
tpl/utilship Plus tpl/transport, tpl/engineer, tpl/aslttran

And most ships come from a standard ship class:

Cls Name turn vel warp mass price build time energy health Example
1 tpl/fighter 3.0 6.0 no 0.8 ¤3.0 3s 100 600 ish/fighter
3 tpl/cruiser 2.0 5.0 yes 1.0 ¤5.0 5s 1000 1000 ish/cruiser
3 tpl/schooner 3.0 7.0 yes 1.0 ¤5.0 5s 750 1000 ish/schooner
3 tpl/hvc 2.0 5.0 yes 1.0 ¤7.5 7.5s 1000 1000 ish/hvc
5 tpl/gunship 1.2 4.0 yes 1.2 ¤11.0 10s 3000 2000 ish/gunship
7 tpl/hvd 2.0 4.5 yes 1.45 ¤32.5 32.5s 2000 2000 ish/hvd
9 tpl/defdrone 5.0 0.35 no 1.0 ¤5.0 5s 1500 1000 ish/defdrone
7 tpl/carrier 1.0 3.0 yes 2.0 ¤22.5 30s 5000 5000 ish/carrier
9 tpl/transport 2.0 3.0 no 1.1 ¤4.0 11s 250 1000 ish/transport
9 tpl/engineer 2.0 3.0 no 1.1 ¤4.0 11s 800 200 ish/engineer
9 tpl/aslttran 2.0 3.0 no 1.1 ¤10.0 11s 1200 800 ish/aslttran

To declare a new ship, start with the template line. At a minimum, new ships should set rotation.sprite, rotation.frames, weapons, and shield_color. They should also have a portrait, if possible:

template:      "tpl/cruiser"
portrait:      "fed/cruiser"
shield_color:  "white"
weapons:
  pulse:
    base:  "dev/photorp/turret"
    positions:
      * {x: 0, y: -40}
  beam:
    base:  "dev/phaser/turret"
    positions:
      * {x: 0, y: -20}
rotation:
  sprite:  "fed/cruiser"
  frames:  {begin: 0, end: 24}

Depending on how powerful a race is, it might also make sense to override health, energy, turn_rate, max_velocity, warp_speed, or other default values.

2   Projectiles

Name Appearance Examples
tpl/anipulse animation dev/fullerene/pulse, sfx/energy
tpl/rotpulse rotation dev/fusion/pulse
tpl/missile rotation dev/cm/missile, dev/amissile/missile
tpl/ray ray dev/tspace/beam, dev/trazer/beam
tpl/bolt bolt dev/pk/ish/beam, dev/conc/pellet

To declare a new projectile, start with the template line. The most important fields for a projectile are its max_velocity, expire.after.age, and collide.damage. It’s also usually a good idea if its collide.action removes itself after impact.

Beyond those fields, a new projectile needs to have an appearance:

Here’s a basic definition for an animated pulse (tpl/anipulse):

template:      "tpl/anipulse"
long_name:     "Photon Torpedo"
short_name:    "PHOTORP"
max_velocity:  8.0
animation:
  sprite:  "dev/photorp"
  frames:  {begin: 0, end: 6}
  speed:   0.01
expire:
  after:
    age:  "1.0s"
create:
  action:
    * type:         "play"
      sound:        "dev/photorp"
      priority:     3
      persistence:  "0.3s"
      volume:       255
collide:
  damage:  400
  action:
    * type:       "create"
      reflexive:  true
      base:       "sfx/explosion/energy"
    * type:       "remove"
      reflexive:  true

It’s usually good to play the fire sound as part of its create.action, so that the same sound will play for that projectile, no matter what weapon is firing.

3   Weapons

Weapons are equipped by ships. There are four sub-categories of weapons. Most of the differences between weapons are determined by their projectiles, so the sub-categories are mostly about how CPU pilots handle the weapons.

  • Guns are used to attack enemies in front of a ship.
  • Turrets are used to attack enemies all around a ship.
  • Devices are used for defense or transportation, rather than attack.
  • Specials are never fired automatically by CPU pilots.
Name Examples
tpl/gun dev/pk/ish/gun, dev/fusion/rgun
tpl/turret dev/laser/turret, dev/pp/twin
tpl/device dev/stealth/item, dev/repulser/turret
tpl/special dev/assault/ish, dev/assault/can

When creating a weapon, the important things to declare are the name, device fields, and activate.action:

template:    "tpl/gun"
long_name:   "Photon Torpedo Launcher"
short_name:  "PHOTORP"
device:
  ammo:       20
  fire_time:  "1.0s"
  range:      480.0
  speed:      10.0
activate:
  action:
    * type:                "create"
      reflexive:           true
      base:                "dev/photorp/pulse"
      relative_velocity:   true
      relative_direction:  true

Note how some of the values have been copied from the example projectile above:

In the common case, where projectiles have a constant velocity, these calculations should work as-is. If projectiles speed up or slow down, then they may need to be adjusted.

4   Waypoints

Fixed locations that the player can select are called waypoints. There are three sub-categories of waypoints:

  • Planets can build ships and be captured by transports.
  • Structures can be shot at and destroyed.
  • Stations can be neutralized and captured by assault transports.
Name Examples
tpl/waypoint loc/jumpgate
tpl/planet loc/planet, loc/moon
tpl/structure loc/power, aud/etc/device
tpl/station loc/bunker, loc/outpost

Before creating a new waypoint, consider whether the object needs to act differently, or just look different. For example, the Gaitori Habitat Station in The Stars Have Ears and the Salrilian Battlestation in The Left Hand are actually just Bunker Stations with an override.sprite.

5   Decoration

Decorations make the game look interesting but aren’t interactive. There are two sub-categories:

  • Effects are drawn over ships’ sprites. They usually disappear when their animation completes.
  • Scenery is drawn under ships. Sometimes it disappears; other times it sticks around.
Name Examples
tpl/effect sfx/explosion/large, sfx/warp/in
tpl/scenery loc/sun, loc/jump/node, sfx/jump/large

For example, a new explosion needs an animation.sprite, animation.frames, and animation.speed, and should expire.after.animation:

template:    "tpl/effect"
long_name:   "Photon Torpedo Explosion"
short_name:  "P EXPLSN"
animation:
  sprite:  "sfx/explosion/photon"
  frames:  {begin: 0, end: 10}
  speed:   0.15
expire:
  after:  {animation: true}
create:
  action:
    * type:         "play"
      reflexive:    true
      sound:        "sfx/explosion/small"
      priority:     3
      persistence:  "0.35s"
      volume:       255

It’s usually good to play the explosion sound as part of its create.action, so that the same sound will play for that explosion, no matter what object is exploding.

6   Hazards

Hazards are non-thinking objects that collide with ships and otherwise cause trouble.

Name Examples
tpl/hazard sfx/debris/a, ast/regular/big, ast/nasty

7   Miscellaneous

Some objects don’t fit neatly into the categories above:

  • EVATs are mostly ship-like, but can’t be selected and expire after a while. They have special behavior for occupying stations.
  • Rotations have a different appearance depending on their direction, but don’t fit neatly into any other categories (like ships, projectiles or EVATs).
  • Drones are mostly ship-like, but are animations instead of rotations.
Name Examples
tpl/rotation loc/flak, dev/holo/decoy
tpl/evat ish/evat, can/evat
tpl/drone zrb/spawn