Action

An action sequence is triggered by an object or condition to make things happen. There are many types of actions, such as capture, create, destroy, and win.

For example, if a transport lands on a planet, it triggers a capture action that changes the planet’s owner. Then, if a condition sees the ownership change, it could trigger a win action, ending the level in victory for the new owner.

1   What, Where, When, How

1.1   What

In any given action, there are two objects with different roles:

  • A subject object. The subject object is normally the one acting in an action. When a missile collides with a ship, the missile is the subject object. When a transport lands on a planet, the transport is the subject object.
  • A direct object. The direct object is usually the one acted upon by the action. When a missile collides with a ship, the ship is the direct object. When a transport lands on a planet, the planet is the direct object.

Most actions are defined in terms of what they do to these objects. In a capture action, the subject object captures the direct object.

Actions can also be reflexive. This swaps the roles of the subject object and direct object. In a reflexive capture action, the subject object is captured by the direct object.

1.2   Where

Actions take place at a location. Normally, this is the center of the direct object (or subject object if reflexive). When a missile collides with a ship, the location is at the center of the ship.

One exception: when a weapon fires, that action takes place at the weapon’s positions on the firing ship, rather than the center of the ship.

1.3   When

Every condition has an associated action. If the condition becomes true, it executes its action with its subject object and direct object.

An object can have up to six different actions. It is always the subject object for its own actions, but the direct object depends on the action:

Action subject object direct object
create.action self self
destroy.action self self
expire.action self self
expire.action (land) self object’s target
collide.action self collided object
activate.action self self
activate.action (weapon) self nearest foe
arrive.action self object’s target

1.4   How

All actions come in arrays, which together make up an action sequence. Actions in a sequence execute one after another until the whole sequence has executed.

If there is a delay action, that postpones the remainder of the sequence until the delay duration finishes.

It’s possible for an action from one sequence to trigger another action sequence. In this case, the second action sequence will run to completion, and then the first action sequence will resume. For example, if a gun’s activate.action creates a bullet and gunsmoke, then the bullet’s create.action will run before the gun creates the gunsmoke.

2   Definition

An action is a procyon value with the following fields, plus any fields appropriate to its type:

Field Req? Type
type yes age”, “assume”, “cap_speed”, “capture”, “check”, “cloak”, “condition”, “create”, “delay”, “destroy”, “disable”, “energize”, “equip”, “fire”, “flash”, “group”, “heal”, “hold”, “key”, “land”, “message”, “morph”, “move”, “occupy”, “pay”, “play”, “push”, “remove”, “reveal”, “score”, “select”, “spark”, “spin”, “target”, “thrust”, “warp”, “win”, or “zoom
reflexive no boolean
if no filter
override no override

2.1   reflexive

If reflexive is true, then the roles of the subject object and direct object are swapped.

For example, if an missile hits a ship and explodes, its collide action needs a create action to create the explosion and a remove action to remove the missile. The create action should be reflexive, so that the explosion is centered on the missile, not the ship. The remove action should also be reflexive, so that it removes the missile, not the ship.

2.2   if

Each action can have filters set on it. If the direct object does not match an action’s filters, the action sequence skips that action. The following fields are supported:

Field Req? Type
tags no tags
owner no “any”, “same”, or “different”
attributes no attributes

If override.direct is used, the filters apply to the new direct object. However, reflexive doesn’t make the filters apply to the subject object; they still apply to the direct object.

For example, a transport’s “arrive” action specifies:

if:
  tags:   {planet: true}
  owner:  "different"

This ensures that the transport only attempts to land on a hostile planet. It will never:

  • land on a station, flak drone, ship, or other non-planet, because of the tag filter, or
  • land on a friendly planet, because of the owner filter.

(use of the attributes [1] field is not recommended. It exists only for compatibility with some Hera-created scenarios)

2.3   override

Field Req? Type
subject no object reference
direct no object reference

Executes the action on a different subject object or direct object from the default. This can be used in level-specific actions to operate on a level’s initial objects.

For example, in Hornet’s Nest, overrides are used to order both escort ships to attack. One action’s override.subject is the first escort, and the following action’s override.subject is the second escort.

Overrides only affect their own action. Subsequent actions in the action sequence use the original objects.

3   Types

There are many different types of actions. Most actions have additional fields according to their type. The action types are:

Type Description
age modifies the time before an object expires
assume turns an object into an initial object
cap_speed modifies an object’s max_velocity
capture modifies an object’s owner
check causes conditions to be re-checked
cloak makes an object invisible
condition enables or disable conditions
create creates objects
delay delays execution of an action sequence
destroy destroys an object
disable impairs an object’s controls
energize modifies an object’s energy
equip modifies an object’s weapon
fire triggers an object’s weapon
flash causes the player’s screen to flash
group executes multiple actions
heal modifies an object’s health
hold orders an object to hold position
key enables or disable a player’s controls
land causes an object to land on its target
message displays a message to the player
morph changes an object from one type to another
move modifies an object’s location
occupy modifies the occupation count of an object
pay modifies a player’s money
play plays a sound
push modifies an object’s velocity
remove removes an object from existence
reveal shows a hidden initial object
score modifies a player’s score counters
select selects the screen and line of a player’s computer
slow decreases an object’s velocity
spark creates a sparkly visual effect
speed modifies an object’s velocity
spin imparts spin to an object
stop zeroes an object’s velocity
target orders an object to target another object
thrust imparts thrust to an object
warp causes an object to enter warp speed
win ends the level in victory or loss
zoom sets the player’s zoom level

3.1   age

Field Req? Type
relative no boolean
value yes range of durations

Modifies the direct object’s expire.after.age. Picks a random duration from value. If relative is true, adds that duration to the object’s age. Otherwise, sets the object’s age to that duration.

3.2   assume

Field Req? Type
which yes integer

Causes the direct object to become an initial object. Adds the first counter of the first player to which, and gives the object the resulting initial object number.

Warning

Assume actions were created for the tutorial and are not well-suited to other uses. Talk to antares-dev before using.

3.3   cap_speed

Field Req? Type
value no speed

Sets the direct object’s max_velocity. If value is null, then sets the direct object’s max_velocity to its default value.

3.4   capture

Field Req? Type
player no index of a player

Changes the owner of the direct object:

3.5   check

Causes all conditions to be re-checked, possibly triggering their own action sequences.

Checking conditions isn’t free, so this action should only be used when it’s likely that a condition became true, such as after modifying a player’s score. [2]

Check actions have no additional fields.

3.6   cloak

Causes the direct object to become invisible. The cloak action can affect any object, even one that doesn’t have a cloaking device. The object will decloak if it uses its pulse or beam weapon, but not if it uses its special weapon.

Cloak actions have no additional fields.

3.7   condition

Field Req? Type
enable no array of indexes of conditions
disable no array of indexes of conditions

Enables all of the conditions listed in enable and disables the ones in disable. This can be used to script a situation in which events need to happen in sequence.

For example, if the player needs to visit two planets in a specific order, there could be two conditions, with the latter disabled. Upon visiting Example Alpha, the first condition would enable the second. Upon visiting Example Beta, the second condition would declare victory. (if the order doesn’t matter, using the score action might be easier)

Condition indexes are tied to a particular level, so the condition action should generally be used by other conditions, not by objects.

3.8   create

Field Req? Type
base yes name of an object
count no range of integers
relative_velocity no boolean
relative_direction no boolean
inherit no boolean
distance no distance
within no “circle” or “square”
legacy_random no boolean

Creates count new objects of type base, centered on the direct object.

If count is null, creates 1 new object. If count is a range, picks a count randomly within the range, and creates nothing if the result is ≤0. For example, count: {begin: 1, end: 6} means to randomly create at least 1 and at most 5 new objects. count: {begin: -4, end: 2} means to create a new object with a 1 in 6 chance.

If relative_velocity is true, adds the current velocity of the direct object to that of the new objects. If relative_direction is true, adds the current direction of the direct object. Guns should set relative_direction when creating their projectiles. Turrets should set autotarget on their projectiles and not set relative_direction.

If inherit is set, the new object’s is ordered to target the direct object’s target. Otherwise, the new object is ordered to target the direct object. If the object is neutral or its target.order is false, then its target is cleared.

If distance is set, the new objects will be created at random distances up to the given amount.

(use of the within [3] and legacy_random [4] fields is not recommended. They exist only for compatibility with some Hera-created scenarios)

3.9   delay

Field Req? Type
duration yes duration

Postpones further processing of the current action sequence until duration has passed. [5]

Warning

Use sparingly. The delay action is potentially expensive. It can slow the game down or eat up memory due to the extra cost of maintaining the action queue.

3.10   destroy

Destroys the direct object. If the direct object has a destroy.action, executes its destroy.action. Then, unless the direct object’s destroy.die is true, removes it from existence.

Destroy actions have no additional fields.

3.11   disable

Field Req? Type
duration yes range of durations

Impairs control of the direct object for some length of time. Only meaningful for objects that think and attempt to control their movement (including players’ flagships). While control is impaired, there’s a chance that a pressed or released key might not register.

Takes a random duration in duration and divides it by the direct object’s mass. The direct object’s controls are impaired for this long. If the direct object’s controls were already impaired, the old remaining duration is replaced by the new duration.

If the remaining time an object is disabled is d, the likelihood that a key will fail to register is (d – ¼) ÷ d. Turning is disabled for the full duration.

For example, a Zerbilite’s collide.action has a disable action with duration: {begin: "0s", end: "3s"}. If a Zerbilite collides with an Ishiman carrier (mass: 2.0), it will disable the carrier for up to 1.5 seconds. If it disables the carrier for the full 1.5 seconds, the carrier will initially ignore ⅚ of keypresses, and regain control over time.

3.12   energize

Field Req? Type
value yes integer

Increases the current energy of the direct object by value. If that would increase the object’s energy past full, the balance is added to the object’s battery.

3.13   equip

Field Req? Type
which yes “pulse”, “beam”, or “special”
base yes name of an object

Replaces one of the direct object’s weapons. Sets the weapon which to base, restoring it to full ammunition.

Warning

Untested and unsupported, for now. Talk to antares-dev before using.

3.14   fire

Field Req? Type
which yes “pulse”, “beam”, or “special”

Fires one of the direct object’s weapons. Fails if the direct object is not able to fire the weapon (insufficient ammo or energy, weapon fired too recently, or no weapon equipped in that slot).

3.15   flash

Field Req? Type
duration yes duration
color yes color

Causes the player’s entire screen to flash. Overlays the screen with a solid color for the duration.

3.16   group

Field Req? Type
of yes array of actions

Groups together multiple actions. Actions in the group are all affected by the if, and override of the group.

Group actions should never be reflexive (it would work, but be confusing).

3.17   heal

Field Req? Type
value yes integer

Adds value to the direct object’s health.

Positive values heal the direct object. Health is capped at the direct object’s maximum.

Negative values cause the direct object to take damage. If the direct object’s health would be decreased below 0, it is destroyed.

Note

For damage-dealing projectiles, it is usually better to set collide.damage on the projectile, instead of dealing damage from its collide.action.

3.18   hold

Removes the direct object’s target and causes it to maintain its current position.

Hold actions have no additional fields.

3.19   key

Field Req? Type
enable no array of keys
disable no array of keys

Enables or disables the use of certain keys by the player. enable or disable is a list of strings that name keys. Some of the keys, like "mouse" are not really keys, but other kinds of player input that can be disabled.

By default, all keys are enabled.

Note

Key actions were created for the tutorial. While there may be other uses, please talk to antares-dev before using, as there may be better options.

Key Action
Ship keys
"up" Accelerate
"down" Decelerate
"left" Turn Counter-clockwise
"right" Turn Clockwise
"pulse" Fire Weapon 1
"beam" Fire Weapon 2
"special" Fire/Activate Special
"warp" Warp
Command keys
"select_friend" Select Friendly
"select_foe" Select Hostile
"select_base" Select Base
"target" Target
"order" Order to Go
"zoom_in" Scale In
"zoom_out" Scale Out
"comp_up" Computer Previous
"comp_down" Computer Next
"comp_accept" Computer Accept/Select/Do
"comp_back" Computer Cancel/Back Up
Shortcut keys
"zoom_shortcut" Zoom to 1:1/1:2/1:4/1:16/Closest Hostile/Closest Object/All
Virtual keys
"comp_message" Use computer’s “Messages” screen
"comp_special" Use computer’s “Special Orders” screen (including “Transfer Control” shortcut)
"comp_build" Use computer’s “Build” screen
"send_message" Send messages with “return” key [6]
"mouse" Select objects with mouse

3.20   land

Field Req? Type
speed yes integer

Causes the direct object to land at its target. The object will shrink to nothingness, after which it will execute its expire.action with its target as the direct object.

Used (with reflexive) in the arrive.action for transports landing on planets or ships going through jump gates.

3.21   message

Field Req? Type
id no integer
pages yes array of strings

Displays message text at the bottom of the player’s screen. Each string in pages is a page of text that the player will see.

Strings can contain formatting characters like \\i.

id is optional. It is used only by the message condition.

3.22   morph

Field Req? Type
base yes name of an object
keep_ammo no boolean

Changes the base type of the direct object. The object is reset and recreated with the defaults from base, preserving only:

  • Owner
  • Velocity and orientation
  • Health, energy, and battery
  • Cloaking (if active)
  • Weapon ammunition (if keep_ammo is true)

Warning

Don’t change an object’s fundamental type (ray to rotation, animation to device, etc.)

The morph action can be used in many ways to create complicated behaviors. It can:

  • Create an extended destruction sequence. In The Mothership Connection, the Cantharan gateship’s destroy.action morphs the gateship into a form that creates lots of smaller explosions before finally expiring.
  • Activate a disabled object. In Captivating, the Bazidanese battleship starts in a “disabled” form and morphs into an active form when freed.
  • Disable an active object. In Capture the Flagpod, a Grolk cruiser’s destroy.action morphs it into an inactive form and teleports it to a tractor moor.
  • Enable or disable interactions. In Shoplifter 1, the Obish transport morphs between a form that can pick up prisoners and a form that can’t, depending on whether the transport is full.

3.23   move

Field Req? Type
origin no “level”, “subject”, “direct”
to no point
distance no distance
within no “circle” or “square”

Modifies the location of the direct object. The new location is relative to an origin, one of:

  • "level" (the default), the center (0, 0) of the level,
  • "subject", the location of the subject object, or
  • "direct", the location of the direct object.

(in a reflexive action, modifies the location of the subject object, but "subject" and "direct" still have their original meanings)

Offsets the new location by to. This offset takes the scenario’s rotation into account. This is typically used with origin: "subject" to place an object at an absolute location.

If distance is set, the new location will additionally be offset by a random distance up to the given amount.

(use of the within [3] field is not recommended. It exists only for compatibility with some Hera-created scenarios)

3.24   occupy

Field Req? Type
value yes integer

Adds value to the occupation count of the direct object for the owner of the subject object. Requires that the direct object sets:

When a player’s occupation count on an object reaches occupy_count, that player takes control over the object. This is used in the factory scenario when EVATs take over stations.

3.25   pay

Field Req? Type
value yes money
player no index of a player

Adds value to a player’s cash reserves. If value is negative, reduces the player’s cash (but not below zero). If player is null, pays the direct object’s owner. If player is non-null, pays player.

3.26   play

Field Req? Type
priority yes integer from 0 to 5 inclusive
persistence yes duration
absolute no boolean
volume yes integer from 0 to 255 inclusive
sound no name of a sound
any no array of {sound: "name of sound}

Plays a sound. If sound is non-null, plays that sound. Otherwise, picks a sound at random from any.

Plays the sound at the given volume. Unless absolute is true, the sound’s origin is centered on the direct object. The sound’s volume is reduced proportionately to the player flagship’s distance from the sound’s origin. absolute sounds play at full volume no matter how far away the player’s flagship is.

Antares has a limited number of sound channels to play sounds with. priority and persistence affect how it decides when to stop a sound and allow a more important or recent sound to take over the channel. Higher priority makes it more likely that a sound will play, and longer persistence means it will be longer before another sound can take over its channel. The exact rules are:

  • if the same sound is already playing at the same or lower volume, stop it and take over its channel. Otherwise,
  • if any sound is playing at a lower volume, stop it and take over its channel. Otherwise,
  • if any sound is playing at a lower priority, stop it and take its channel. Otherwise,
  • if any sounds have been playing for longer than their persistence, stop and take the channel of the sound that is furthest past its persistence.

If Antares can’t find a suitable channel per the above rules, the sound doesn’t play.

3.27   push

Field Req? Type
value no speed

Modifies the velocity of the direct object, applying the change in the direction that the subject object is facing.

If value is non-null, sets the direct object’s direction to match the direct object, and its speed to value (like the Cantharan gateship’s Shrikeolator).

If value is null, treats the push like a collision (like the Elejeetian Cruiser’s Onas Pulse):

  1. Takes the difference between the two objects’ velocity.
  2. Divides that change by the mass of the direct object.
  3. Adds the modified difference to the direct object’s velocity.
  4. Caps the direct object’s speed to its max_velocity.

See also: slow, speed, and stop.

3.28   remove

Removes the direct object from existence. Does not execute its destroy action.

Remove actions have no additional fields.

3.29   reveal

Field Req? Type
initial yes array of indexes of initials

Reveals the hidden initial objects specified by initial.

“Revealing” actually means creating the object, so revealing an object executes its create action.

3.30   score

Field Req? Type
counter yes counter
value yes integer

Adds value to the score counter. If counter.player is null, modifies the score of direct object’s owner.

3.31   select

Field Req? Type
screen yes “main”, “build”, “special”, “message”, or “status”
line yes integer

Selects the given screen and line number in the player’s computer.

3.32   slow

Field Req? Type
value yes number

Decreases the velocity of the direct object, without changing its direction. Multiplies the current velocity by value. For example, value: 0.75 means to decrease its current velocity by one quarter.

See also: push, speed, and stop.

3.33   spark

Field Req? Type
count yes integer
hue yes hue
velocity yes number
age yes duration

Creates count single-pixel visual effects, centered on the direct object and shooting away at speed up to velocity. If there is no direct object, they are created at the center of the screen. Up to 125 sparks may exist on-screen at any given time.

The sparks are hue-colored. They are initially bright and fade over time. After they have been around for the duration age, they disappear.

3.34   speed

Field Req? Type
value yes speed
relative no boolean

Modifies the velocity of the direct object, without changing its direction. If relative is true, adds value to the object’s current velocity. Otherwise, sets its velocity to value.

See also: push, slow, and stop.

3.35   spin

Field Req? Type
value yes range of numbers

Spins the direct object. Requires that:

  • The direct object can turn (turn_rate is not null), and
  • either:
    • the direct object is non-thinking, or
    • the direct object is disabled.

Picks a random turn velocity from value and sets it on the direct object. If a disabled direct object regains control, it will stop spinning.

Almost always used together with the disable action.

3.36   stop

Sets the velocity of the direct object to zero. This is equivalent to a slow or speed action with a value of 0.

Stop actions have no additional fields.

See also: push, slow, and speed.

3.37   target

Sets the subject object’s target to the direct object.

Target actions have no additional fields.

3.38   thrust

Field Req? Type
value yes range of accelerations

Sets the current thrust of the direct object. Only meaningful for non-thinking objects; thinking objects control their own thrust.

3.39   warp

Causes the direct object to enter warp. There is no delay or energy cost.

Warp actions have no additional fields.

3.40   win

Field Req? Type
player no index of a player
next no name of a level
text yes string

Ends the level, displaying text in the mission debriefing.

In a solo level, if player is the human player, declares victory for the player. If next is non-null, unlocks that level and continues the game. If next is null, ends the game in victory.

In a solo level, if player is a non-human player, ends the level in defeat. The player will be given the option to retry or exit. next is ignored.

In a net level, declares victory for player. next is ignored.

3.41   zoom

Field Req? Type
value yes “2:1”, “1:1”, “1:2”, “1:4”, “1:16”, “foe”, “object”, or “all”

Sets the player’s zoom level to value.

4   Footnotes

[1]TODO(sfiera): document.
[2]The check action is new to Antares. In Ares, conditions were checked at the end of any action sequence with a message or score action, but there wasn’t otherwise a way of re-checking conditions.
[3](1, 2) In Ares, random distances were within a square: the random point within distance d would be placed within (x±d, y±d). In such a square, the points in the corners have a cartesian distance much greater than d. Antares defaults to a circle instead, so that the resulting distance is actually within d, but preserves compatibility in the factory scenario by using the square logic.
[4]Normally, if count is a range, then Antares rolls a die to determine how many objects to count. legacy_random tells Antares to roll a die even if count is a fixed number. Preserving compatibility with Ares requires ensuring that the same dice are rolled in the same order.
[5]The delay action is new to Antares. In Ares, every action could have a delay (though almost none did).
[6]As of Antares 0.9.0, sending messages with the “return” key doesn’t work at all, though.