# Table of Contents

1. General
   1. What is This?
   2. Running a Script
   3. Units
   4. Net Games and Films
   5. Loading Collections
   6. Persistence
2. Triggers
   1. calculate_level_completion_state
   2. cleanup
   3. end_refuel
   4. got_item
   5. idle
   6. init
   7. item_created
   8. light_activated
   9. light_switch
   10. monster_damaged
   11. monster_kamikazed
   12. monster_killed
   13. pattern_buffer
   14. platform_activated
   15. platform_switch
   16. player_damaged
   17. player_killed
   18. player_revived
   19. postidle
   20. projectile_created
   21. projectile_detonated
   22. projectile_switch
   23. start_refuel
   24. tag_switch
   25. terminal_enter
   26. terminal_exit
3. Using Tables
   1. Custom Fields
   2. Index
   3. is_ Functions
4. Tables
   1. Annotations
   2. Cameras
   3. Effects
   4. Endpoints
   5. Ephemera
   6. Game
   7. Goals
   8. ItemStarts
   9. Items
   10. Level
   11. Lights
   12. Lines
   13. Media
   14. MonsterStarts
   15. Monsters
   16. Music
   17. Platforms
   18. PlayerStarts
   19. Players
   20. Polygons
   21. Projectiles
   22. Scenery
   23. Sides
   24. SoundObjects
   25. Tags
   26. Terminals
5. Types and Mnemonics
   1. Ambient Sounds
   2. Collections
   3. Completion States
   4. Control Panel Classes
   5. Control Panel Types
   6. Damage
   7. Difficulty
   8. Effects
   9. Ephemera Quality
   10. Faders
   11. Fog Modes
   12. Game Types
   13. Item Kinds
   14. Item Types
   15. Light Functions
   16. Light Presets
   17. Light States
   18. Media
   19. Monster Actions
   20. Monster Classes
   21. Monster Modes
   22. Monsters
   23. Overlay Colors
   24. Platform Types
   25. Player and Team Colors
   26. Polygons
   27. Projectiles
   28. Scenery
   29. Scoring Modes
   30. Side Types
   31. Sounds
   32. Texture Types
   33. Transfer Modes
   34. Weapons
6. Example Icon

# General

## What is This?

This is a reference for writing Lua scripts to work in Aleph One. It lists every trigger and table available to Lua scripts. It is expected that Lua functionality will grow in Aleph One, and as it does, so will this document. Not everything here is completely documented, and any help fixing that would be appreciated.

This is not a reference for Lua itself - see lua.org for that.

## Running a Script

There are three ways to get a script to run - by embedding it in a level, by selecting a solo script in the Environment Preferences, or by selecting a script at the gather network game dialog.

To embed a script in a level, use a tool such as Atque. Use embedded Lua scripts only for map specific features, not for modifying game types. For instance, it may be tempting to embed the latest version of the Lua CTF script in a map designed only for playing CTF; however, this would prevent the user from using a later version of CTF if it were to come out, or from using another net script that works on CTF maps. Some older scenarios use Lua scripts in TEXT resources, but this is no longer recommended since they are not transmitted in net games.

To use a solo script, check the "Use Solo Script" box in Environment Preferences, and choose the script file to use.

To use a script via the network game dialog, put then script in a text file with the extension .lua. Then, at the gather network game dialog, select "use script", then select your script file.

## Units

The unit for distance we use is World Units (WU) These are the same values you’d see in Forge or with F10 location display, and 1/1024 of what A1 uses internally and what you’d see in Pfhorte.

Units for speed are . . . well let’s say they’re messy. :) Lua speeds are expressed in World Units per tick (a tick is 1/30 of a second). Forge claims to use WU per sec, but it actually uses 0.87890625 WU per sec (which equals 30 internal units per tick). The following example illustrates the various conversions:

- Actual: 7.5 World Units per second
- A1 internal: 256 units per tick (7.5 * 1024 / 30)
- Lua: 0.25 WU per tick (7.5 / 30)
- Forge: 8.53 "WU per second" ((7.5 * 1024 / 30) / 30)

## Net Games and Films

Aleph One net games distribute a set of player inputs, which are applied to each distributed game world or to the game world in the film being played back. There is a separate copy of the Lua script running on each player’s machine. This means that in order to prevent net games from going out of sync, or films from playing back incorrectly, each of the separately running Lua scripts needs to manipulate the world the exact same way.

For example, if one player’s Lua script creates a monster, that monsters actions in the game are controlled by the random seed established at the beginning of the game. So, the other players’ scripts must create the same monster the same way, or the net game will go out of sync.

Usually this is not a problem, as long as scripters avoid functions marked with the "local player" tag, and the two local random functions, which will return different results on different machines. The `global_random` and `random` functions will return the same number on different machines, as long as they are called the same number of times, so they are safe to use for net games.

These rules apply to film playback as well; films will only play back if scripts behave exactly the same way as when the film was recorded

A few accessors, such as Ephemera and Fog were designed to be used on a "local player" basis without breaking films or net. For instance, it would be safe to programmatically disable fog when a player zooms in by checking `Players.local_player.zoom_active`--because the mere presence of fog will not cause a net game or film to go out of sync. Likewise, Ephemera can be created based on the Ephemera.quality setting, which will vary from machine to machine. A script that only uses Ephemera can be turned on and off and film playback will be unaffected.

When using local-safe accessors like Ephemera and Fog, it is important to use the matching `random_local` function, because it will not affect the progression of the ordinary random functions.

If this is confusing to you, it would be safest simply to avoid using anything marked with the "local player" tag, as well as the two local random functions and Ephemera.

## Loading Collections

A Lua script can ask for the engine to load collections it might otherwise not load; for instance, in order to be able to spawn defenders and compilers on a map that might not have them otherwise, add the indices for those collections to the global table CollectionsUsed:

    CollectionsUsed = { 10, 16 }

## Persistence

Lua scripts are only active during a single level. If the user jumps to a new level, or restores from a saved game, the script is restarted in a clean state.

It is now possible to pass data across level jumps, by using the Game.restore_passed() function. This function will restore any custom fields (see the "Custom Fields" section of "Using Tables" below) in the Players or Game tables that were set immediately prior to the last level jump. Note that in order for data to survive multiple level jumps, Game.restore_passed() must be called after each level jump. Game.restore_passed() will not restore data from saved games.

It is also possible to restore data from saved games. The Game.restore_saved() function will restore all custom fields in use at the time the game was saved.

Only numbers, strings, booleans, and tables (including Aleph One’s built-in userdata tables) can be restored.

# Triggers

These are functions scripts can define which Aleph One will call at specific times or events. For example, to regenerate health: Triggers = {} function Triggers.idle() for p in Players() do if p.life < 150 and not p.dead then p.life = p.life + 1 end end end Calling Triggers = {} at the beginning of the script removes the compatibility triggers installed for old Lua scripts, speeding up execution of new scripts.

Triggers
  .calculate_level_completion_state() 20240712

    replaces the classic completion state calculation

  .cleanup()

    at end of the level

    primarily this is intended as a last chance for changing netgame scores before the postgame carnage report.

  .end_refuel(class, player, side)

    whenever a player stops using a refuel panel

  .got_item(type, player)

    whenever a player picks up an item

    also whenever a player gets an item when a script calls .items.add()

  .idle()

    at each tick, before physics and such

  .init(restoring_game)

    at beginning of level

    - restoring_game: true if restoring from a saved game
  .item_created(item)

    whenever an item is created and placed on the ground (or floating) somewhere

    does not trigger on initial item placement because the initial item placement is done before Lua becomes initialised.

  .light_activated(light)

    whenever a light is activated or deactivated

  .light_switch(light, player, side)

    whenever a player uses a light switch

    not called when a projectile (e.g., fists) toggles a light switch

    side is only valid in version 20111201 and newer

  .monster_damaged(monster, aggressor_monster, damage_type, damage_amount, projectile) 20100118

    whenever a monster is damaged, but before it dies if applicable. The monster’s vitality may be negative when this trigger is called. Ther monster’s vitality will be tested again after this trigger returns, so a script may prevent a monster’s death

    - aggressor_monster: the monster that caused the damage (can be nil)
    - damage_type: e.g. "fists"
    - damage_amount: the amount recently subtracted from the monster’s vitality
    - projectile: the projectile that delivered the damage (can be nil)
  .monster_kamikazed(monster) 20240712

    whenever a monster kamikazes

  .monster_killed(monster, aggressor_player, projectile)

    whenever a monster dies

    - aggressor_player: player who killed it (can be nil)
    - projectile: projectile that delivered the final blow (can be nil)

    called after a monster has taken lethal damage, but before it’s removed from the monster list

    you can use this to find out when a monster created with new_monster dies, but a monster discovered by Polygons.monsters() may have already taken lethal damage, so you may need to check for that case when using Polygons.monsters()

  .pattern_buffer(side, player)

    whenever a player uses a pattern buffer

  .platform_activated(polygon)

    whenever a platform is activated or deactivated

  .platform_switch(polygon, player, side)

    whenever a player uses a platform switch

    - polygon: polygon of the platform being toggled

    not called when a projectile (e.g., fists) toggles a platform switch

    side is only valid in version 20111201 and newer

  .player_damaged(victim, aggressor_player, aggressor_monster, damage_type, damage_amount, projectile)

    whenever a player has taken damage, but before he dies if applicable. The player’s suit energy or oxygen may be negative when this trigger is called; if it still is when the trigger returns, it will be set to 0. The player’s suit energy is tested again after this trigger returns, so a script may prevent a player’s death

    - aggressor_player: player who got the kill (can be nil)
    - aggressor_monster: monster that got the kill (can be nil)
    - damage_type: e.g. "fists"
    - damage_amount: the amount recently subtracted from the player. If "oxygen drain", damage_amount was assessed against player’s oxygen; otherwise against player’s suit energy
    - projectile: the projectile that delivered the damage (can be nil)
  .player_killed(player, aggressor_player, action, projectile)

    whenever a player dies

    - aggressor_player: the player who killed player, possibly himself (suicide) (can be nil)
    - action: dying soft, dying hard, or dying flaming
    - projectile: the projectile that delivered the final blow (can be nil)
  .player_revived(player)

    whenever a player revives (presumably only happens in a netgame)

  .postidle()

    at each tick, after physics and such, but before rendering

  .projectile_created(projectile) 20150619

    whenever a projectile is created

  .projectile_detonated(type, owner, polygon, x, y, z, t 20210408)

    whenever a projectile detonates, after it has done any area of effect damage

    t can be a side, polygon_floor, polygon_ceiling, monster, scenery, polygon; see Polygon:check_collision for info on how to decode. It can also be nil, in the rare case a projectile detonates without hitting something

  .projectile_switch(projectile, side) 20111201

    whenever a projectile toggles a switch

    - projectile: projectile that toggled the switch
    - side: side containing switch being toggled
  .start_refuel(class, player, side)

    whenever a player starts to use a refuel panel

  .tag_switch(tag, player, side)

    whenever a player uses a tag switch

    not called when a projectile (e.g., fists) toggles a tag switch

    side is only valid in version 20111201 and newer

  .terminal_enter(terminal, player)

    whenever a player starts using a terminal

  .terminal_exit(terminal, player)

    whenever a player stops using a terminal

# Using Tables

There are numerous tables (technically, userdata) defined in Aleph One which scripts can use to access objects in the game. A complete list is below.

Unless otherwise specified, these tables are only valid inside the trigger calls listed above. Attempting to use them in the main body of a script may cause an error in this version or a future version of Aleph One.

## Custom Fields

In a real Lua table, you can set any field you want. In order to help troubleshooting, Aleph One’s userdata tables will only accept the fields listed in the documentation below. However, by prepending an underscore, custom fields can be indexed. These custom fields will be associated with the object until it is destroyed.

    Players[0]._favorite_flavor = "chocolate"

## Index

Each table has a read-only .index variable, that corresponds to the engine’s internal index.

    =Players[0].index
    0

## is_ Functions

Aleph One installs a set of boolean functions that can be used to recognize each of the userdata table types. For example, `is_monster(Monsters[1])` returns true. Each of these functions begins with the "is_" prefix.

# Tables

### Annotations

  number of map annotations

Annotations()

  iterates through all annotations

Annotations.new(polygon, text [, x] [, y])

  returns a new annotation

Annotations[index]
  .polygon

    polygon this annotation is associated with

    can be nil

    an annotation is only shown when its polygon is visible on the overhead map

  .text

    annotation text (64 characters max)

  .x

  .y

### Cameras

  number of cameras

Cameras()

  iterates through all cameras

Cameras.new()

  returns a new uninitialized camera

  make sure to add path points and angles before activating the camera

Cameras[index]
  :activate(player)

    activate camera for player

  :clear()

    deletes all path points and angles

  :deactivate()

    deactivates camera

  .path_angles
    :new(yaw, pitch, time)

      adds a path angle

  .path_points
    :new(x, y, z, polygon, time)

      adds a path point

### Effects

  maximum number of effects

Effects()

  iterates through all valid effects

Effects.new(x, y, height, polygon, type) 20111201

  returns a new effect

Effects[index]
  :delete() 20111201

    removes effect from map

  .facing 20111201

    direction effect is facing

  :play_sound(sound) 20111201

    play sound coming from this effect

  .polygon (read-only) 20111201

    polygon the effect is in

  :position(x, y, z, polygon) 20111201

    sets position of effect

  .type (read-only) 20111201

    type of effect

  .x (read-only) 20111201

  .y (read-only) 20111201

  .z (read-only) 20111201

### Endpoints

  number of endpoints in level

Endpoints()

  iterates through all endpoints in the level

Endpoints[index]
  .x (read-only)

  .y (read-only)

### Ephemera 20210408

Ephemera are a render-only version of Effects. They were designed to be a lightweight way to add effects such as precipitation or decals. They do not use any global random functionality, and they don’t interact at all with other objects in the world, so they are safe to turn on and off without affecting net game sync and film playback (see "Net Games and Films").

Ephemera are not saved or restored in saved games, so it is up to the Lua script to serialize them and persist them if desired; and to recreate them upon resume. Likewise, ephemera custom fields are not saved/restored using `Level.restored_saved()`

All ephemera functions are "local player"

# Ephemera

  maximum number of ephemera

Ephemera()

  iterates through all valid ephemera

Ephemera.new(x, y, z, polygon, collection, sequence, facing)

  returns a new ephemera

Ephemera.quality (read-only)

  user’s ephemera quality setting

  it is up to the script’s discretion how many ephemera to create / maintain, based on this quality setting; if set to off, ephemera are not rendered regardless of how many the script creates

Ephemera[index]
  .clut_index

    color table of this ephemera

  .collection

    shape collection of this ephemera

  .end_when_animation_loops

    if set, ephemera is removed once animation finishes

  :delete()

    removes ephemera from the level

  .enlarged

    ephemera is rendered 25% bigger

  .facing

    direction the ephemera is facing

  :position(x, y, z, polygon)

    sets position of ephemera

  .polygon (read-only)

    polygon this ephemera is in

  .rendered (read-only)

    whether this ephemera was recently rendered

    you can use this to skip updating ephemera that aren’t currently visible

  .shape_index

    shape index of ephemera

    Anvil calls this sequence

  .tiny

    ephemera is rendered 50% size

  .valid (read-only)

    whether ephemera is still valid

  .x (read-only)

  .y (read-only)

  .z (read-only)

### Game

Game
  .autosave() 20250302

    saves the game without prompting the user, if possible

    solo only

  .dead_players_drop_items 20150619

    whether dead players drop items

  .deserialize(s) 20200830

    deserializes s and returns the original Lua value

    see Game.serialize

  .difficulty (read-only)

    the difficulty level

  .global_random(n)

    returns a random number between 0 and n-1 from Aleph One’s original random number generator

  .kill_limit (read-only)

    the game kill limit, or 0 if there is none

  .local_random(n)

    returns a random number between 0 and n-1 from Aleph One’s original random number generator

    use only for local player effects (see Net Games and Films)

  .monsters_replenish 20111201

    whether monsters spawn or not; in a net game, this corresponds to the "Aliens" checkbox

    this can suppress initial monster placement, if set to false directly when the script is loaded

  .nonlocal_overlays 20200830

    When false, only the local player’s overlays are used, and only prints to the local player will be displayed. When true, the overlays and prints of whatever player is currently being viewed will apply. This defaults to false for compatibility with scripts that depend on the old behavior.

  .over (write-only)

    Use this variable to override the game’s default scoring behavior. If set to false, the game will not end due to a score limit. If set to true, the game ends immediately. If left unset or if set to nil, the game will end if a score limit is reached. (Note that you cannot prevent the game from ending due to a time limit.)

  .player 20250829

    In Tag games, the player who is It. In Kill the Man With the Ball or Rugby games, the player who is carrying the ball

    writing to this will only work in Tag games

  .proper_item_accounting 20100118

    When true, the current item counts on the map are updated properly when Lua deletes map items and changes player inventories. This defaults to false to preserve film playback with older scripts. New scripts that manipulate items should always set this to true.

  .random(n)

    returns a random number between 0 and n-1 using a good random number generator

  .random_local(n) 20210408

    returns a random number between 0 and n-1 using a good random number generator

    use only for local player effects (see Net Games and Films)

  .replay (read-only) 20221126

    is the script being run during a film replay

    use sparingly; altering the world differently during a replay than during live playback will cause the replay go out of sync

  .restore_passed() 20090909

    tries to restore any Player or Game custom fields from before the last level jump; returns true if custom fields were successfully restored

    if successful, overwrites all existing Player or Game custom fields

  .restore_saved() 20090909

    tries to restore any custom fields from the saved game; returns true if custom fields were successfully restored

    if successful, overwrites all existing custom fields

  .save()

    saves the game (as if the user had activated a pattern buffer)

    solo only

  .scoring_mode

    the current scoring mode (if the gametype is "custom")

  .serialize(v) 20200830

    serializes v into a binary string

    only numbers, strings, booleans, and tables (including Aleph One’s built-in userdata tables) can be serialized

  .ticks (read-only)

    ticks since game started

  .time_remaining (read-only)

    the number of ticks until the game ends, or nil if there is no time limit

  .type (read-only)

    whether the game is EMFH, KOTH, etc.

  .version (read-only)

    the date version of the local player’s engine

    for example, "20071103"

### Goals

  number of saved map objects (of all types)

Goals()

  iterates through all goals

Goals[index]
  .facing (read-only) 20111201

    direction goal is facing

  .polygon (read-only) 20111201

    polygon the goal is in

  .id (read-only) 20111201

    ID number of goal

  .x (read-only) 20111201

  .y (read-only) 20111201

  .z (read-only) 20111201

    from floor or ceiling

### ItemStarts

  number of map objects in the level

ItemStarts()

  iterates through all item starting locations in the level

ItemStarts[index]
  .facing (read-only) 20111201

    direction item is initially facing

  .from_ceiling (read-only) 20111201

    whether item location z is from ceiling

  .invisible (read-only) 20111201

    whether item will teleport in

  .polygon (read-only) 20111201

    item starting location polygon

  .type (read-only) 20111201

    type of item

  .x (read-only) 20111201

  .y (read-only) 20111201

  .z (read-only) 20111201

    from floor or ceiling

### Items

  maximum number of map objects

Items()

  iterates through all valid items

Items.new(x, y, height, polygon, type)

  returns a new item

Items[index]
  :delete()

    removes item from map

  .facing

    direction item is facing

  :play_sound(sound)

    play sound coming from this item

  .polygon (read-only)

    polygon the item is in

  :position(x, y, z, polygon) 20090909

    sets position of item

  :teleport_in() 20240712

    teleports item in

    can fail silently if there are not enough effects slots

  :teleport_out() 20240712

    teleports item out

    can fail silently if there are not enough effects slots

  .type (read-only)

    type of item

  .visible 20240712

  .x (read-only)

  .y (read-only)

  .z (read-only)

### Level

Level
  .calculate_completion_state() 20081213

    returns whether level is finished, unfinished, or failed

    does not call the trigger, so it can be used in the trigger

  .completed (read-only) 20111201

    check this in Triggers.cleanup() to determine whether the player(s) teleported out

  .extermination (read-only) 20081213

    whether level has extermination flag set

  .exploration (read-only) 20081213

    whether level has exploration flag set

  .fog
  .underwater_fog
    .active
    .present

      whether fog is present

    .affects_landscapes

      whether fog affects landscapes

    .color

      values range from 0.0 to 1.0

      .b

        blue

      .g

        green

      .r

        red

    .depth

      fog depth in WU

    .landscape_mix 20231125

      amount of fog to mix into landscape

      values range from 0.0 to 1.0

    .mode 20231125

      linear, exp, or exp2

    .start 20231125

      fog start in WU

      only applies to linear fog

  .low_gravity (read-only)

    whether level is low gravity

  .magnetic (read-only)

    whether level is magnetic

  .name (read-only)

    level name

  .index (read-only) 20150619

    level index in the map file (starting from 0)

  .map_checksum (read-only) 20150619

    checksum of map file

  .rebellion (read-only)

    whether level is rebellion

  .repair (read-only) 20081213

    whether level has repair flag set

  .rescue (read-only) 20081213

    whether level has rescue flag set

  .retrieval (read-only) 20081213

    whether level has retrieval flag set

  .stash[key] 20200830

    reads/writes values to a stash shared between all running Lua scripts

    keys/values must be strings

  .vacuum (read-only)

    whether level is vacuum

### Lights

  number of lights in level

Lights()

  iterates through all lights in the level

Lights.new( [light_preset])

  returns a new light

Lights[index]
  .active

    whether light is active

  .tag 20100118

    tag of light

  .initial_phase 20100118

    phase the light starts with

  .initially_active 20100118

    whether the light was initially active

  .intensity (read-only) 20100118

    current intensity for this light (range: 0-1)

  .states[light_type]
    .delta_intensity 20100118

      random intensity change for this state

    .delta_period 20100118

      random period change for this state

    .intensity 20100118

      intensity for this state

    .light_function 20100118

      light function for this state

    .period 20100118

      period for this state

### Lines

  number of lines in level

Lines()

  iterates through all lines in the level

Lines[index]
  .clockwise_polygon (read-only)
  .cw_polygon (read-only)

    polygon on clockwise side of line

  .clockwise_side (read-only)
  .cw_side (read-only)

    clockwise side of line

  .counterclockwise_polygon (read-only)
  .ccw_polygon (read-only)

    polygon on counterclockwise side of line

  .counterclockwise_side (read-only)
  .ccw_side (read-only)

    counterclockwise side of line

  .decorative 20210408

    projectiles always pass the transparent sides of decorative lines

  .endpoints[n]

    returns line endpoint n

  .has_transparent_side (read-only) 20080707

    whether one of the line’s sides has a transparent texture

  .highest_adjacent_floor (read-only) 20080707

    height of higher adjacent polygon floor

  .length (read-only)

    the length of this line

    this might not be accurate, if someone used Chisel’s stretch plugin

  .lowest_adjacent_ceiling (read-only) 20080707

    height of lower adjacent polygon ceiling

  .solid (read-only) 20080707

    whether line is solid

  .visible_on_automap 20150619

    whether line is revealed on local player’s automap

### Media

  number of media (liquids) on the level

Media()

  iterates through all media on the level

Media.new() 20210408

  returns a new liquid

Media[index]
  .direction 20100118

    direction of media

  .height (read-only) 20100118

    height of media

  .high 20100118

    high tide of media

  .light 20100118

    light that controls this media’s tide

  .low 20100118

    low tide of media

  .speed 20100118

    speed of media

  .type (read-only)

    type of media

  .type 20100118

    type of media

### MonsterStarts

  number of map objects in the level

MonsterStarts()

  iterates through all monster starting locations in the level

MonsterStarts[index]
  .blind (read-only) 20111201

    whether monster is activated by sight

  .deaf (read-only) 20111201

    whether monster is activated by sound

  .facing (read-only) 20111201

    direction monster is initially facing

  .from_ceiling (read-only) 20111201

    whether monster location z is from ceiling

  .invisible (read-only) 20111201

    whether monster will teleport in when activated

  .polygon (read-only) 20111201

    monster starting location polygon

  .type (read-only) 20111201

    type of monster

  .x (read-only) 20111201

  .y (read-only) 20111201

  .z (read-only) 20111201

    from floor or ceiling

### Monsters

  maximum number of monsters

Monsters()

  iterates through all valid monsters (including player monsters)

Monsters.new(x, y, height, polygon, type)

  returns a new monster

Monsters[index]
  :accelerate(direction, velocity, vertical_velocity) 20081213

    accelerates monster

  .action (read-only)

    current AI action of the monster

  .active

    whether monster has been activated

  :attack(target)

    instructs monster to attack target

  .blind 20210408

    monster is blind

    only valid before monster activates

  :damage(amount [, type])

    damages monster

    if no type is specified, fist damage is dealt

  .deaf 20210408

    monster is deaf

    only valid before monster activates

  :delete() 20210408

    deletes monster

  .external_velocity 20090909

    monster’s current external velocity (always in the opposite direction of facing)

  .facing
  .yaw

    direction the monster is facing

  .life
  .vitality

    the monster’s vitality

    monsters that haven’t spawned or teleported in yet don’t have vitality

  .mode (read-only)

    current AI mode of the monster

  :move_by_path(polygon)

    instructs monster to move to polygon

    monsters get distracted easily en route

    once it gets there, it probably won’t choose to stay

  .player (read-only)

    if monster is a player monster, the player; otherwise, nil

  :play_sound(sound)

    plays sound coming from this monster

  .polygon (read-only)

    polygon this monster is in

  :position(x, y, z, polygon)

    sets position of monster

  .teleports_out 20210408

    monster teleports out when deactivated

  .type (read-only)

    type of monster

  .valid (read-only)

    whether monster is still valid

  .vertical_velocity 20090909

    monster’s current vertical external velocity

  .visible

    whether monster is visible (e.g. has teleported in)

    this has nothing to do with whether monsters are cloaked (like invisible S’pht) or not

    only writable before the monster is activated

  .x (read-only)

  .y (read-only)

  .z (read-only)

### Music

  maximum number of music channels active simultaneously

Music()

  iterates through all the music channels

Music.new(track [, volume] [, loop]) 20231125

  returns a new music channel

  volume is decimal [0 - 1] and is 1 if not specified

  loop is enabled by default

Music.clear()

  clears the level playlist

Music.fade(duration)

  fades out the currently playing track and clears the playlist

Music.play(track1 [, track2] [, ...])

  appends all of the specified tracks to the end of the playlist

Music.stop()

  stops level music and clears the playlist

Music.valid(track1 [, track2] [, ...])

  for every track passed, return true if it exists and is playable and false otherwise

Music[index]
  :play() 20231125

    plays the music

    if the music was stopped, restarts it

  :stop() 20231125

    stops the music

  :fade(volume [, duration] [, stop_after_fade]) 20231125

    fades the music

    it will fade in until volume is reached. volume is decimal [0 - 1]

    duration unit is seconds and is 1 if not specified

    stop_after_fade is disabled by default, if set to true if the volume reaches 0 while fading the music will automatically stop

  .volume 20231125

    the volume of the music

    volume is decimal [0 - 1]

  .active (read-only) 20231125

    returns true if the music is still playing

### Platforms

  number of platforms on the level

Platforms()

  iterates through all platforms in the level

Platforms[index]
  .activates_adjacent_platforms_at_each_level 20210408

    platform will activate adjacent platforms at each elevation it comes to (ie.,at floor level and ceiling level)

  .activates_adjacent_platforms_when_activating 20210408

    when activating, this platform activates adjacent platforms

  .activates_adjacent_platforms_when_deactivating 20210408

    when deactivating, this platform activates adjacent platforms

  .activates_light 20210408

    activates floor and ceiling lightsources while activating

  .activates_only_once 20210408

    cannot be activated a second time

  .active

    whether platform is currently active

  .cannot_be_externally_deactivated 20210408

    when active, can only be deactivated by itself

  .ceiling_height

    current ceiling height of platform

  .comes_from_ceiling (read-only) 20210408

    platform lowers from ceiling

  .comes_from_floor (read-only) 20210408

    platform rises from floor

  .contracting

    direction platform is moving or will move when active

  .contracts_slower 20210408

    will move slower when contracting than when extending

  .deactivates_adjacent_platforms_when_activating 20210408

    when activating, this platform deactivates adjacent platforms

  .deactivates_adjacent_platforms_when_deactivating 20210408

    when deactivating, this platform deactivates adjacent platforms

  .deactivates_at_each_level 20210408

    this platform will deactivate each time it reaches a discrete level

  .deactivates_at_initial_level 20210408

    this platform will deactivate upon returning to its initial position

  .deactivates_light 20210408

    deactivates floor and ceiling lightsources while deactivating

  .delays_before_activation 20210408

    whether or not the platform begins with the maximum delay before moving

  .does_not_activate_parent 20210408

    does not reactive its parent (the platform which activated it)

  .door 20100118

    platform is a door

  .extending

    direction platform is moving or will move when active

  .extends_floor_to_ceiling (read-only) 20210408

    there is no empty space when the platform is fully extended

  .floor_height

    current floor height of platform

  .initially_active (read-only) 20210408

    otherwise inactive

  .has_been_activated 20210408

    in case platform can only be activated once

  .initially_extended (read-only) 20210408

    high for floor platforms, low for ceiling platforms, closed for two-way platforms

  .locked 20100118

    platform is locked

    this flag doesn’t actually do anything

  .maximum_ceiling_height (read-only) 20220115

    greatest height a platform's ceiling can ever rise

  .maximum_floor_height (read-only) 20220115

    greatest height a platform's floor can ever rise

  .minimum_ceiling_height (read-only) 20220115

    least height a platform's ceiling must rise

  .minimum_floor_height (read-only) 20220115

    least height a platform's floor must rise

  .monster_controllable

    whether platform can be controlled by monsters

  .player_controllable

    whether platform can be controlled by players

  .polygon (read-only)

    polygon of this platform

  .reverses_direction_when_obstructed 20210408

    platform reverses direction when obstructed

  .secret 20100118

    platform is secret

    secret platforms aren’t shown on the overhead map

  .speed

    platform speed

  .tag 20221126

    tag of platform

  .type 20100118

    type of this platform

    the only thing the engine uses type for is the platform’s sound

  .uses_native_polygon_heights (read-only) 20210408

    uses native polygon heights during automatic min,max calculation

### PlayerStarts

  number of map objects in the level

PlayerStarts()

  iterates through all player starting locations in the level

PlayerStarts[index]
  .facing (read-only) 20111201

    player starting location facing

  .from_ceiling (read-only) 20111201

    whether player starting location z is from ceiling

  .polygon (read-only) 20111201

    polygon player starting location is in

  .team (read-only) 20111201

    which team starts at this player starting location

  .x (read-only) 20111201

  .y (read-only) 20111201

  .z (read-only) 20111201

    from floor or ceiling

### Players

  number of players in the game

Players()

  iterates through all players in the game

Players.print(message)

  prints message to all players’ screens

Players.local_player (read-only) 20200830

  the local player

  normally, you shouldn’t need this--you’ll just make the game go out of sync

Players[index]
  :accelerate(direction, velocity, vertical_velocity)

    accelerates player

  .action_flags

    only valid when read/written in idle()

    disabled when the player is viewing a terminal

    latched action flags are only true the first tick the key is held down

    .action_trigger

      respawns, or activates platforms/doors/control panels

      latched

    .aux_trigger 20231125

      formerly microphone button; now dedicated to Lua scripts

    .cycle_weapons_backward

      switches to previous weapon

      latched

    .cycle_weapons_forward

      switches to next weapon

      latched

    .left_trigger

      fires primary trigger

    .right_trigger

      fires secondary trigger

    .toggle_map

      toggles the overhead map

      latched

  :activate_terminal(terminal)

    activates terminal

  .color

    color of player (shirt color, if teams are enabled)

  .compass
    :all_off()

      turns all compass quadrants off, disables beacon

    :all_on()

      turns all compass quadrants on, disables beacon

    .beacon

      whether to use the beacon

    .lua

      whether Lua is controlling the compass

    .ne
    .northeast

      whether north east compass quadrant is active

    .nw
    .northwest

      whether north west compass quadrant is active

    .se
    .southeast

      whether south east compass quadrant is active

    .sw
    .southwest

      whether south west compass quadrant is active

    .x

      beacon location

    .y

      beacon location

  .crosshairs
    .active (local player)

      whether crosshairs are visible

      if you wish to stop the user from toggling the crosshairs, you must set the state every tick

  :damage(amount [, type])

    inflicts damage on player

    - type: if unspecified, crush damage is delt
  .dead (read-only)

    whether player is dead

  .deaths

    deaths not caused by players

  .direction
  .yaw

    direction player is facing

    this is the direction in which this player will run; for their aim, use .head_direction

  .disconnected

    whether player dropped out of the game

  .energy
  .life

    amount of suit energy player has (150 is normal red health)

  .elevation
  .pitch

    angle player is looking up or down

  .external_velocity
    .i
    .x

    .j
    .y

    .k
    .z

  .extravision_duration

    extravision time remaining

  .feet_below_media (read-only)

    whether player is standing in liquid

  :fade_screen(type)

    fades player’s screen

  :find_action_key_target()

    if player is in range of a platform or control panel, returns a platform or side; otherwise returns nil

    you can check the type of the return with is_polygon() and is_side()

  :find_target( [penetrate_media] 20220115)

    returns t, x, y, z, polygon, where t is the side, polygon_floor, polygon_ceiling, monster, scenery, or polygon (if the target is the surface of a liquid, and penetrate_media is false) the player is looking at; and x, y, z, and polygon are the point the player is looking at

    you can check the type of t with is_side(), is_polygon_floor(), is_polygon_ceiling(), is_monster(), is_scenery(), and is_polygon()

    this function will not work under liquid unless penetrate_media is true

  .has_map_open (read-only) 20220115

    whether player has overhead map open

  .head_below_media (read-only)

    whether player is completely below liquid

  .head_direction 20200830

    direction in which player is looking

    while glancing, this differs from .direction

  .hotkey 20210408

    pressed hotkey, from 1-12, or 0 for no hotkey

    only valid when read/written in idle()

    hotkeys aren’t latched, and can only be transmitted every 3 ticks

    to check for a continously pressed hotkey, or to implement your own latch, count down from 2 before checking it again

    hotkeys override cycle weapon backward/forward; these flags will be false for 3 ticks after a hotkey is pressed

  .hotkey_bindings[n] 20210408 (local player)

    keys or buttons the player has bound to hotkeys 1-12

    .joystick (read-only)

      joystick button binding

    .key (read-only)

      key binding

    .mouse (read-only)

      mouse button binding

  .infravision_duration

    infravision time remaining

  .internal_velocity
    .forward (read-only)

      player’s forward velocity

    .perpendicular (read-only)

      player’s perpendicular (sidestep) velocity

  .invincibility_duration

    invincibility time remaining

  .invisibility_duration

    invisibility time remaining

    player will become subtly invisible if this is set higher than the standard invisibility duration (70 seconds)

  .items[item_type]

    how many of item the player is carrying

  .local_ (read-only)

    true if this player is the local player

    normally, you shouldn’t need this--you’ll just make the game go out of sync

  .kills[slain_player]

    kill count against slain_player

  .monster (read-only)

    monster that corresponds to player

  .motion_sensor_active (local player)

    whether player can view his motion sensor

    currently, this also controls compass visibility

  .name (read-only)

    player’s name

  .oxygen

    amount of oxygen player has (max is 10800)

  .overlays[n]

    there are 6 overlays, numbered 0 through 5

    :clear()

      turns off overlay

    .color (write-only)

      text color

    :fill_icon(color)

      fills icon with solid color

    .icon (write-only)

      icon

    .text (write-only)

      text

  :play_sound(sound, pitch)

    plays sound that only player can hear

    if you want all players to hear the sound as if it is coming from this player, use .monster:play_sound() instead

  .points

    how many points player has

  .polygon (read-only)

    polygon the player is standing on

    if this gives you trouble, try .monster.polygon

  :position(x, y, z, polygon)

    set player position

  :print(message)

    prints message to player’s screen

  :revive() 20210408

    revives player

    player must be totally dead

  .team

    player’s team (pants color)

  :teleport(polygon)

    teleports player to polygon

  :teleport_to_level(level)

    teleports player to level (of course, all the other players will also go to that level)

  .teleporting (read-only) 20220115

    whether player is teleporting

  .texture_palette

    displays a texture palette instead of the classic HUD

    .highlight (local player)

      number of slot to highlight

      can be nil

    .size (local player)

      how many slots the palette has

      there is a maximum of 256 slots

      the texture palette is visible whenever the size is greater than 0

      rows/columns may change in the future based on the user’s screen layout prefs

    .slots[n]
      :clear()

        makes this slot empty

      .collection (local player)

        collection of this slot

      .texture_index (local player)

        texture index of this slot

      .type (local player) 20090909

        texture type of this slot such as wall or sprite; see "Texture Types"

  .totally_dead (read-only) 20210408

    the player is dead and the death animation has finished

  :view_player(player) 20080707

    switch to another player’s view

  .viewed_player (read-only) (local player) 20200830

    the player currently being viewed by the local player

  .weapons
    .active 20080707

      when a player’s weapons are not active, he does not see weapons in hand, and can not fire

    .current (read-only)

      weapon the player is currently wielding

      can be nil

    .desired (read-only) 20090909

      weapon the player wants to switch to

      can be nil

  .weapons[weapon_type]
    .primary
    .secondary
      .rounds (read-only)

        how many rounds are currently loaded into the weapon

    :select()

      attempts to force player to ready weapon

    .type (read-only)

      type of this weapon

  .x (read-only)

  .y (read-only)

  .z (read-only)

  .zoom_active (local player)

    whether player’s sniper zoom is active

### Polygons

  number of polygons in the level

Polygons()

  iterates through all polygons in the level

Polygons[index]
  .adjacent_polygons[n]

    returns adjacent polygon n (across from line n), if one exists, or nil

  :adjacent_polygons()

    iterates through all polygons directly adjacent to this polygon

  .area (read-only)

    the area of this polygon

  .ceiling
  .floor
    .collection

      texture collection

    .height
    .z

      height

    .light

      texture light

    .texture_index

      texture bitmap index

    .texture_x

      texture x offset

    .texture_y

      texture y offset

    .transfer_mode

      texture transfer mode

  :change_height(floor, ceiling) 20210408

    changes polygon floor and ceiling heights, if possible

    won’t squish monsters; returns false instead

    this is much less optimized than moving a platform

    you may need to create sides if you are raising/lowering what used to be a flat floor/ceiling

  :check_collision(x0, y0, z0, owner, x1, y1, z1 [, include_objects] [, include_media]) 20210408

    returns t, x, y, z, polygon, where t is nil (if there was no collision), or the side, polygon_floor, polygon_ceiling, monster, scenery, or polygon (if the collision is with the surface of a liquid) where the line segment collided with the map (or object or media); and x, y, z, polygon is the location of the collision, or the end point if there was no collision

    the owner is a monster or player to ignore, or nil

    you can check the type of t with is_side(), is_polygon_floor(), is_polygon_ceiling(), is_monster(), is_scenery(), and is_polygon()

    in order of descending speed: find_polygon(), check_collision() without objects, check_collision() including objects

  :contains(x, y [, z])

    whether the point is in this polygon

  .endpoints[n]

    returns endpoint n

  :endpoints()

    iterates through all of this polygon’s endpoints

  :find_polygon(x1, y1, x2, y2) 20210408

    traverses map from (x1, y1) and returns polygon containing (x2, y2)

    can be nil if there is no direct route between the two points, or the destination point is not in any polygon

    ignores floor/ceiling height

  :find_line_crossed_leaving(x1, y1, x2, y2) 20080707

    returns the polygon line crossed by line segment (x1, y1) (x2, y2)

    can be nil if the line segment doesn’t intersect a polygon line

  .lines[n]

    returns polygon line n

  :lines()

    iterates through all of this polygon’s lines

  .media

    polygon media (liquid)

  :monsters()

    iterates through all monsters in this polygon (including player monsters)

  .permutation

    raw permutation index of this polygon

  :play_sound(sound)

    plays sound in center of polygon on floor

  :play_sound(x, y, z, sound [, pitch])

    plays sound at location

    if you want to play a sound at an object location, use that object’s play_sound function instead

  .sides[n]

    returns polygon side n if it exists

  :sides()

    iterates through all of this polygon’s sides

  .type

    polygon type

  .visible_on_automap 20150619

    whether polygon is revealed on local player’s automap

  .x (read-only)

    center of polygon

  .y (read-only)

    center of polygon

  .z (read-only)

    shortcut for .floor.height

### Projectiles

  maximum number of projectiles

Projectiles()

  iterates through all valid projectiles

Projectiles.new(x, y, z, polygon, type)

  returns a new projectile

  remember to set the projectile’s elevation, facing and owner immediately after you’ve created it

Projectiles[index]
  :delete() 20111201

    removes projectile from the map

  .damage_scale

    amount to scale projectile’s normal damage by upon detonating

  .dz

    instantaneous downward velocity

  .elevation
  .pitch

    vertical angle

  .facing
  .yaw

    direction

  :play_sound(sound)

    plays sound coming from this projectile

  :position(x, y, z, polygon)

    sets projectile position

  .owner

    monster that fired projectile, or nil

  .polygon (read-only)

    polygon the projectile is in

  .target

    target of guided projectile, or nil

  .type (read-only)

    type of projectile

  .x (read-only)

  .y (read-only)

  .z (read-only)

### Scenery

  maximum number of map objects

Scenery()

  iterates through all valid scenery

Scenery.new(x, y, height, polygon, type)

  returns a new scenery

Scenery[index]
  :damage()

    damages scenery

  .damaged (read-only)

    whether this scenery has been damaged

  :delete()

    removes scenery from the map

  .facing

    direction scenery is facing

  :play_sound(sound)

    play sound coming from this scenery

  .polygon (read-only)

    polygon the scenery is in

  :position(x, y, z, polygon) 20090909

    sets position of scenery

  .solid

    whether this scenery is solid

  :teleport_in() 20240712

    teleports scenery in

    can fail silently if there are not enough effects slots

  :teleport_out() 20240712

    teleports scenery out

    can fail silently if there are not enough effects slots

  .type (read-only)

    type of scenery

  .visible 20240712

    whether this scenery is visible

  .x (read-only)

  .y (read-only)

  .z (read-only)

### Sides

  number of sides on the level

Sides()

  iterates through all sides on the level

Sides.new(polygon, line) 20080707

  creates a new side

  side must not already exist

Sides[index]
  .ambient_delta 20210408

    constant offset from calculated light intensity

  .control_panel

    nil if the side is not a control panel

    set to true or false to create/destroy a control panel 20080707

    .can_be_destroyed 20080707

      whether projectiles destroy this switch

    .light_dependent 20080707

      switch can only be activated if light > 75%

    .only_toggled_by_weapons 20080707

      switch can only be toggled by weapons

    .permutation

      permutation of control panel

    .repair 20080707

      switch is a repair switch

    .status 20080707

      switch is active

    .type 20080707

      type of control panel

    .uses_item (read-only) 20111201

      i.e. chip insertion

  .primary
  .secondary
  .transparent
    .collection

      texture collection

    .empty

      whether side is empty

      transparent sides only in earlier versions Git

      setting empty to false is a no-op; set collection and texture_index instead

    .light

      texture light

    .texture_index

      texture bitmap index

    .texture_x

      texture x offset

    .texture_y

      texture y offset

    .transfer_mode

      texture transfer mode

  :play_sound(sound [, pitch])

    play sound coming from this side

  .line (read-only)

    line this side is attached to

  .polygon (read-only)

    polygon this side is attached to

  :recalculate_type() 20081213

    correct the side type (Forge can generate incorrect side types)

  .type (read-only) 20080707

    type of side

### SoundObjects

  number of map objects in the level

SoundObjects()

  iterates through all sound objects in the level

SoundObjects[index]
  .from_ceiling (read-only) 20111201

    whether sound object location z is from ceiling

  .light (read-only) 20111201

    if sound object uses a light for volume, the light it uses

    can be nil if sound object doesn’t use light for volume

  .on_platform (read-only) 20111201

    whether sound object is a platform sound

  .polygon (read-only) 20111201

    sound object polygon

  .type (read-only) 20111201

    type of sound object

  .volume (read-only) 20111201

    volume of sound object from 0.0 to 1.0

    can be nil if sound object uses light for volume

  .x (read-only) 20111201

  .y (read-only) 20111201

  .z (read-only) 20111201

    from floor or ceiling

### Tags

Tags[index]
  .active

    tag is active

### Terminals

  number of terminal texts in the level

Terminals()

  iterates through all terminal texts on the level

Terminals[index]

# Types and Mnemonics

The string mnemonics listed below can be used for assignment and as arguments to functions. Additionally, Aleph One’s Lua interpreter has been modified so that equality comparisons between userdata types and strings are possible.

For example, this script would move all players on the blue team to the red team: for p in Players() do if p.team == "blue" then p.team = "red" end end And this one would damage all major compilers with 10 points of fusion damage: for m in Monsters() do if m.type == "major compiler" then m:damage(10, "fusion") end end Each type has a read-only .index field, which represents the game’s internal index: > =ItemTypes["pistol"].index 1 Each type also has a .mnemonic field, which is handy for finding the mnemonic of a given type: > =MonsterTypes["major compiler"].class.mnemonic compiler You can even use the mnemonic field to customize the mnemonics for your scenario. Note that you can only have one string mnemonic per type index: > WeaponTypes["fist"].mnemonic = "puncher" > =WeaponTypes["puncher"].index 0 > =WeaponTypes["fist"] nil If you do this, you should customize them all at the beginning of the script. Changing mnemonics mid-game will confuse anyone who tries to read your script, and probably yourself as well!

### Ambient Sounds

# AmbientSounds
AmbientSounds()

#### Mnemonics

- "water"
- "sewage"
- "lava"
- "goo"
- "underwater"
- "wind"
- "waterfall"
- "siren"
- "fan"
- "spht door"

- "spht platform"
- "heavy spht door"
- "heavy spht platform"
- "light machinery"
- "heavy machinery"
- "transformer"
- "sparking transformer"
- "machine binder"
- "machine bookpress"
- "machine puncher"

- "electric hum"
- "alarm"
- "night wind"
- "pfhor door"
- "pfhor platform"
- "alien noise 1"
- "alien noise 2"
- "alien harmonics"

### Collections

Collections()
Collections[collection]
  .bitmap_count

    number of bitmaps in collection

#### Mnemonics

- "interface"
- "weapons in hand"
- "juggernaut"
- "tick"
- "explosions"
- "hunter"
- "player"
- "items"
- "trooper"
- "fighter"
- "defender"

- "yeti"
- "bob"
- "vacbob"
- "enforcer"
- "drone"
- "compiler"
- "water"
- "lava"
- "sewage"
- "jjaro"
- "pfhor"

- "water scenery"
- "lava scenery"
- "sewage scenery"
- "jjaro scenery"
- "pfhor scenery"
- "day"
- "night"
- "moon"
- "space"
- "cyborg"

### Completion States

# CompletionStates
CompletionStates()

#### Mnemonics

- "unfinished"
- "finished"
- "failed"

### Control Panel Classes

# ControlPanelClasses
ControlPanelClasses()

#### Mnemonics

- "oxygen recharger"
- "single shield recharger"
- "double shield recharger"

- "triple shield recharger"
- "light switch"
- "platform switch"

- "tag switch"
- "pattern buffer"
- "terminal"

### Control Panel Types

# ControlPanelTypes
ControlPanelTypes()
ControlPanelTypes[control_panel_type]
  .active_texture_index (read-only) 20080707

    bitmap index when control panel is active

  .class (read-only)

    class of this control panel type

  .collection (read-only) 20080707

    collection this control panel belongs to

  .inactive_texture_index (read-only) 20080707

    bitmap index when control panel is inactive/destroyed

### Damage

# DamageTypes
DamageTypes()

#### Mnemonics

- "explosion"
- "staff"
- "projectile"
- "absorbed"
- "flame"
- "claws"
- "alien weapon"
- "hulk slap"

- "compiler"
- "fusion"
- "hunter"
- "fists"
- "teleporter"
- "defender"
- "yeti claws"
- "yeti projectile"

- "crushing"
- "lava"
- "suffocation"
- "goo"
- "energy drain"
- "oxygen drain"
- "drone"
- "shotgun"

### Difficulty

# DifficultyTypes
DifficultyTypes()

#### Mnemonics

- "kindergarten"
- "easy"
- "normal"
- "major damage"
- "total carnage"

### Effects

# EffectTypes
EffectTypes()

#### Mnemonics

- "rocket explosion"
- "rocket contrail"
- "grenade explosion"
- "grenade contrail"
- "bullet ricochet"
- "alien weapon ricochet"
- "flamethrower burst"
- "fighter blood splash"
- "player blood splash"
- "civilian blood splash"
- "assimilated civilian blood splash"
- "enforcer blood splash"
- "compiler bolt minor detonation"
- "compiler bolt major detonation"
- "compiler bolt major contrail"
- "fighter projectile detonation"
- "fighter melee detonation"
- "hunter projectile detonation"
- "hunter spark"
- "minor fusion detonation"
- "major fusion detonation"
- "major fusion contrail"
- "fist detonation"
- "minor defender detonation"
- "major defender detonation"

- "defender spark"
- "trooper blood splash"
- "water lamp breaking"
- "lava lamp breaking"
- "sewage lamp breaking"
- "alien lamp breaking"
- "metallic clang"
- "teleport object in"
- "teleport object out"
- "small water splash"
- "medium water splash"
- "large water splash"
- "large water emergence"
- "small lava splash"
- "medium lava splash"
- "large lava splash"
- "large lava emergence"
- "small sewage splash"
- "medium sewage splash"
- "large sewage splash"
- "large sewage emergence"
- "small goo splash"
- "medium goo splash"
- "large goo splash"
- "large goo emergence"

- "minor hummer projectile detonation"
- "major hummer projectile detonation"
- "durandal hummer projectile detonation"
- "hummer spark"
- "cyborg projectile detonation"
- "cyborg blood splash"
- "minor fusion dispersal"
- "major fusion dispersal"
- "overloaded fusion dispersal"
- "sewage yeti blood splash"
- "sewage yeti projectile detonation"
- "water yeti blood splash"
- "lava yeti blood splash"
- "lava yeti projectile detonation"
- "yeti melee detonation"
- "juggernaut spark"
- "juggernaut missile contrail"
- "small jjaro splash"
- "medium jjaro splash"
- "large jjaro splash"
- "large jjaro emergence"
- "civilian fusion blood splash"
- "assimilated civilian fusion blood splash"

### Ephemera Quality

# EphemeraQualities
EphemeraQualities()

#### Mnemonics

- "off"
- "low"
- "medium"
- "high"
- "ultra"

### Faders

# FadeTypes
FadeTypes()

#### Mnemonics

- "start cinematic fade in"
- "cinematic fade in"
- "long cinematic fade in"
- "cinematic fade out"
- "end cinematic fade out"
- "red"
- "big red"
- "bonus"
- "bright"
- "long bright"
- "yellow"

- "big yellow"
- "purple"
- "cyan"
- "white"
- "big white"
- "orange"
- "long orange"
- "green"
- "long green"
- "static"
- "negative"

- "big negative"
- "flicker negative"
- "dodge purple"
- "burn cyan"
- "dodge yellow"
- "burn green"
- "tint green"
- "tint blue"
- "tint orange"
- "tint gross"
- "tint jjaro"

### Fog Modes

# FogModes
FogModes()

#### Mnemonics

- "linear"
- "exp"
- "exp2"

### Game Types

# GameTypes
GameTypes()

#### Mnemonics

- "kill monsters"
- "cooperative play"
- "capture the flag"

- "king of the hill"
- "kill the man with the ball"
- "defense"

- "rugby"
- "tag"
- "netscript"

### Item Kinds

# ItemKinds
ItemKinds()

#### Mnemonics

- "weapon"
- "ammunition"
- "powerup"
- "item"
- "weapon powerup"
- "ball"

### Item Types

# ItemTypes
ItemTypes()
ItemTypes[item_type]
  .initial_count 20111201

    how many items of this type are placed in the level during initial placement

  .kind (read-only) 20210408

    kind of item this is

  .maximum_count 20111201

    maximum number of this type of item in the level and in player inventories

  .maximum_inventory 20210408

    maximum number of this type of item players can carry

  .minimum_count 20111201

    minimum number of this type of item in the level and in player inventories

  .random_chance 20111201

    chance from 0 to 1.0 this item will appear in a respawn period

  .random_location 20111201

    whether items of this type spawn in random locations

  .total_available 20111201

    total number of items of this type that can be spawned in this level

    -1 means infinite items are available

    setting this to anything but -1 will only be effective if changed immediately when the script runs, before item placement is done

#### Mnemonics

- "knife"
- "pistol"
- "pistol ammo"
- "fusion pistol"
- "fusion pistol ammo"
- "assault rifle"
- "assault rifle ammo"
- "assault rifle grenades"
- "missile launcher"
- "missile launcher ammo"
- "invisibility"
- "invincibility"

- "infravision"
- "alien weapon"
- "alien weapon ammo"
- "flamethrower"
- "flamethrower ammo"
- "extravision"
- "oxygen"
- "single health"
- "double health"
- "triple health"
- "shotgun"
- "shotgun ammo"

- "key"
- "uplink chip"
- "light blue ball"
- "ball"
- "violet ball"
- "yellow ball"
- "brown ball"
- "orange ball"
- "blue ball"
- "green ball"
- "smg"
- "smg ammo"

### Light Functions

# LightFunctions
LightFunctions()

#### Mnemonics

- "constant"
- "linear"
- "smooth"
- "flicker"

### Light Presets

# LightPresets
LightPresets()

#### Mnemonics

- "normal"
- "strobe"
- "media"

### Light States

# LightStates
LightStates()

#### Mnemonics

- "becoming active"
- "primary active"
- "secondary active"
- "becoming inactive"
- "primary inactive"
- "secondary inactive"

### Media

# MediaTypes
MediaTypes()

#### Mnemonics

- "water"
- "lava"
- "goo"
- "sewage"
- "jjaro"

### Monster Actions

# MonsterActions
MonsterActions()

#### Mnemonics

- "stationary"
- "waiting to attack again"
- "moving"
- "attacking close"

- "attacking far"
- "being hit"
- "dying hard"
- "dying soft"

- "dying flaming"
- "teleporting"
- "teleporting in"
- "teleporting out"

### Monster Classes

# MonsterClasses
MonsterClasses()

#### Mnemonics

- "player"
- "bob"
- "madd"
- "possessed drone"
- "defender"
- "fighter"

- "trooper"
- "hunter"
- "enforcer"
- "juggernaut"
- "drone"
- "compiler"

- "cyborg"
- "explodabob"
- "tick"
- "yeti"

### Monster Modes

# MonsterModes
MonsterModes()

#### Mnemonics

- "locked"
- "losing lock"
- "lost lock"
- "unlocked"
- "running"

### Monsters

# MonsterTypes
MonsterTypes()
MonsterTypes[monster_type]
  .alien 20220115

    moves slower on slower levels, etc.

  .attacks_immediately 20120128

    monster will try an attack immediately

  .berserker 20220115

    below 1/4 vitality, this monster goes berserk

  .can_die_in_flames 20220115

    uses humanoid dying shape

  .can_teleport_under_media 20220115

  .cannot_attack 20220115

    monster has no weapons and cannot attack (runs constantly to safety)

  .cannot_be_dropped 20120128

    monster cannot be skipped during placement

  .cannot_fire_backward 20220115

    monster can’t turn more than 135 degrees

  .chooses_weapons_randomly 20220115

  .class

    class of monster type

  .collection (read-only) 20210408

    collection of monster type

  .clut_index (read-only) 20210408

    color table of monster type

  .enemies[monster_class]

    whether monster class is an enemy

  .enlarged 20220115

    monster is 1.25 times normal height

  .fires_symmetrically 20220115

    fires at +/- dy, simultaneously

  .flies 20220115

  .floats 20220115

    exclusive from flies; forces the monster to take delta-h gradually

  .friends[monster_class]

    whether monster class is a friend

  .has_delayed_hard_death 20220115

    always dies soft, then switches to hard

  .has_nuclear_hard_death 20220115

    player’s screen whites out and slowly recovers

  .impact_effect (read-only)

    type of effect generated when monster gets hit by a bleeding projectile

  .height (read-only)

    height of monster

  .immunities[damage_type]

    whether monster type is immune to damage type

  .impact_effect (read-only)

  .initial_count 20111201

    how many monsters of this type are placed in the level during initial placement

  .invisible 20220115

    this monster uses _xfer_invisibility

  .item

    type of item the monster drops when it dies

  .kamikaze 20220115

    monster does shrapnel damage and will suicide if close enough to target

  .major 20120128

    monster is major

  .maximum_count 20111201

    maximum number of this type of monster in the level

  .melee_impact_effect (read-only)

    type of effect generated when monster gets hit by a melee projectile

  .minimum_count 20111201

    minimum number of this type of monster in the level

  .minor 20120128

    monster is minor

  .not_afraid_of_goo 20220115

  .not_afraid_of_lava 20220115

  .not_afraid_of_sewage 20220115

  .not_afraid_of_water 20220115

  .omniscient 20220115

    ignores line-of-sight during find_closest_appropriate_target()

  .radius (read-only)

    radius of monster

  .random_chance 20111201

    chance from 0 to 1.0 this monster will appear in a respawn period

  .random_location 20111201

    whether monsters of this type spawn in random locations

  .subtly_invisible 20220115

    this monster uses _xfer_subtle_invisibility

  .tiny 20220115

    0.25-size normal height

  .total_available 20111201

    total number of monsters of this type that can be spawned in this level

    -1 means infinite monsters are available

    setting this to anything but -1 will only be effective if changed immediately when the script runs, before monster placement is done

  .uses_sniper_ledges 20220115

    sit on ledges and hurl shit at the player (ranged attack monsters only

  .vitality (read-only) 20220115

    monster’s initial vitality

  .weaknesses[damage type]

    whether monster type has a weakness to damage type

  .waits_with_clear_shot 20120128

    monster will sit and fire if he has a clear shot

#### Mnemonics

- "player"
- "minor tick"
- "major tick"
- "kamikaze tick"
- "minor compiler"
- "major compiler"
- "minor invisible compiler"
- "major invisible compiler"
- "minor fighter"
- "major fighter"
- "minor projectile fighter"
- "major projectile fighter"
- "green bob"
- "blue bob"
- "security bob"
- "explodabob"

- "minor drone"
- "major drone"
- "big minor drone"
- "big major drone"
- "possessed drone"
- "minor cyborg"
- "major cyborg"
- "minor flame cyborg"
- "major flame cyborg"
- "minor enforcer"
- "major enforcer"
- "minor hunter"
- "major hunter"
- "minor trooper"
- "major trooper"
- "mother of all cyborgs"

- "mother of all hunters"
- "sewage yeti"
- "water yeti"
- "lava yeti"
- "minor defender"
- "major defender"
- "minor juggernaut"
- "major juggernaut"
- "tiny pfhor"
- "tiny bob"
- "tiny yeti"
- "green vacbob"
- "blue vacbob"
- "security vacbob"
- "explodavacbob"

### Overlay Colors

# OverlayColors
OverlayColors()

#### Mnemonics

- "green"
- "white"
- "red"
- "dark green"
- "cyan"
- "yellow"
- "dark red"
- "blue"

### Platform Types

# PlatformTypes
PlatformTypes()

#### Mnemonics

- "spht door"
- "spht split door"
- "locked spht door"

- "spht platform"
- "noisy spht platform"
- "heavy spht door"

- "pfhor door"
- "heavy spht platform"
- "pfhor platform"

### Player and Team Colors

# PlayerColors
PlayerColors()

#### Mnemonics

- "slate"
- "red"
- "violet"
- "yellow"
- "white"
- "orange"
- "blue"
- "green"

### Polygons

# PolygonTypes
PolygonTypes()

#### Mnemonics

- "normal"
- "item impassable"
- "monster impassable"
- "hill"
- "base"
- "platform"
- "light on trigger"
- "platform on trigger"

- "light off trigger"
- "platform off trigger"
- "teleporter"
- "zone border"
- "goal"
- "visible monster trigger"
- "invisible monster trigger"
- "dual monster trigger"

- "item trigger"
- "must be explored"
- "automatic exit"
- "minor ouch"
- "major ouch"
- "glue"
- "glue trigger"
- "superglue"

### Projectiles

# ProjectileTypes
ProjectileTypes()

#### Mnemonics

- "missile"
- "grenade"
- "pistol bullet"
- "rifle bullet"
- "shotgun bullet"
- "staff"
- "staff bolt"
- "flamethrower burst"
- "compiler bolt minor"
- "compiler bolt major"
- "alien weapon"
- "fusion bolt minor"
- "fusion bolt major"

- "hunter"
- "fist"
- "armageddon sphere"
- "armageddon electricity"
- "juggernaut rocket"
- "trooper bullet"
- "trooper grenade"
- "minor defender"
- "major defender"
- "juggernaut missile"
- "minor energy drain"
- "major energy drain"
- "oxygen drain"

- "minor hummer"
- "major hummer"
- "durandal hummer"
- "minor cyborg ball"
- "major cyborg ball"
- "ball"
- "minor fusion dispersal"
- "major fusion dispersal"
- "overloaded fusion dispersal"
- "yeti"
- "sewage yeti"
- "lava yeti"
- "smg bullet"

### Scenery

# SceneryTypes
SceneryTypes()

#### Mnemonics

- "light dirt"
- "dark dirt"
- "lava bones"
- "lava bone"
- "ribs"
- "skull"
- "hanging light 1"
- "hanging light 2"
- "small cylinder"
- "large cylinder"
- "block 1"
- "block 2"
- "block 3"
- "pistol clip"
- "water short light"
- "water long light"
- "siren"
- "rocks"
- "blood drops"
- "water thing"
- "gun"

- "bob remains"
- "puddles"
- "big puddles"
- "security monitor"
- "water alien supply can"
- "machine"
- "staff"
- "sewage short light"
- "sewage long light"
- "junk"
- "antenna"
- "big antenna"
- "sewage alien supply can"
- "sewage bones"
- "sewage big bones"
- "pfhor pieces"
- "bob pieces"
- "bob blood"
- "alien short light"
- "alien long light"
- "alien ceiling rod light"

- "bulbous yellow alien object"
- "square gray organic object"
- "pfhor skeleton"
- "pfhor mask"
- "green stuff"
- "hunter shield"
- "alien bones"
- "alien sludge"
- "jjaro short light"
- "jjaro long light"
- "weird rod"
- "pfhor ship"
- "sun"
- "large glass container"
- "nub 1"
- "nub 2"
- "lh'owon"
- "floor whip antenna"
- "ceiling whip antenna"

### Scoring Modes

# ScoringModes
ScoringModes()

#### Mnemonics

- "most points"
- "most time"
- "least points"
- "least time"

### Side Types

# SideTypes
SideTypes()

#### Mnemonics

- "full"
- "high"
- "low"
- "split"

### Sounds

Sounds()

#### Mnemonics

- "startup"
- "teleport in"
- "teleport out"
- "crushed"
- "nuclear hard death"
- "absorbed"
- "breathing"
- "oxygen warning"
- "suffocation"
- "energy refuel"
- "oxygen refuel"
- "cant toggle switch"
- "switch on"
- "switch off"
- "puzzle switch"
- "chip insertion"
- "pattern buffer"
- "destroy control panel"
- "adjust volume"
- "got powerup"
- "get item"
- "bullet ricochet"
- "metallic ricochet"
- "empty gun"
- "spht door opening"
- "spht door closing"
- "spht door obstructed"
- "spht platform starting"
- "spht platform stopping"
- "loon"
- "smg firing"
- "smg reloading"
- "heavy spht platform starting"
- "heavy spht platform stopping"
- "fist hitting"
- "pistol firing"
- "pistol reloading"
- "assault rifle firing"
- "grenade launcher firing"
- "grenade expolding"
- "grenade flyby"
- "fusion firing"
- "fusion exploding"
- "fusion flyby"
- "fusion charging"
- "rocket exploding"
- "rocket flyby"
- "rocket firing"
- "flamethrower"
- "body falling"
- "body exploding"
- "bullet hit flesh"
- "fighter activate"
- "fighter wail"
- "fighter scream"
- "fighter chatter"
- "fighter attack"
- "fighter projectile hit"
- "fighter projectile flyby"
- "spht attack"
- "spht death"
- "spht hit"
- "spht projectile flyby"
- "spht projectile hit"
- "cyborg moving"
- "cyborg attack"
- "cyborg hit"
- "cyborg death"
- "cyborg projectile bounce"
- "cyborg projectile hit"
- "cyborg projectile flyby"
- "drone activate"

- "drone start attack"
- "drone attack"
- "drone dying"
- "drone death"
- "drone projectile hit"
- "drone projectile flyby"
- "bob wail"
- "bob scream"
- "bob hit"
- "bob chatter"
- "assimilated bob chatter"
- "bob trash talk"
- "bob apology"
- "bob activation"
- "bob clear"
- "bob angry"
- "bob secure"
- "bob kill the player"
- "water"
- "sewage"
- "lava"
- "goo"
- "underwater"
- "wind"
- "waterfall"
- "siren"
- "fan"
- "spht door"
- "spht platform"
- "alien harmonics"
- "heavy spht platform"
- "light machinery"
- "heavy machinery"
- "transformer"
- "sparking transformer"
- "water drip"
- "walking in water"
- "exiting water"
- "entering water"
- "small water splash"
- "medium water splash"
- "large water splash"
- "walking in lava"
- "entering lava"
- "exiting lava"
- "small lava splash"
- "medium lava splash"
- "large lava splash"
- "walking in sewage"
- "exiting sewage"
- "entering sewage"
- "small sewage splash"
- "medium sewage splash"
- "large sewage splash"
- "walking in goo"
- "exiting goo"
- "entering goo"
- "small goo splash"
- "medium goo splash"
- "large goo splash"
- "major fusion firing"
- "major fusion charged"
- "assault rifle reloading"
- "assault rifle shell casings"
- "shotgun firing"
- "shotgun reloading"
- "ball bounce"
- "you are it"
- "got ball"
- "computer login"
- "computer logout"
- "computer page"

- "heavy spht door"
- "heavy spht door opening"
- "heavy spht door closing"
- "heavy spht door open"
- "heavy spht door closed"
- "heavy spht door obstructed"
- "hunter activate"
- "hunter attack"
- "hunter dying"
- "hunter landing"
- "hunter exploding"
- "hunter projectile hit"
- "hunter projectile flyby"
- "enforcer activate"
- "enforcer attack"
- "enforcer projectile hit"
- "enforcer projectile flyby"
- "flickta melee attack"
- "flickta melee hit"
- "flickta projectile attack"
- "flickta projectile sewage hit"
- "flickta projectile sewage flyby"
- "flickta projectile lava hit"
- "flickta projectile lava flyby"
- "flickta dying"
- "machine binder"
- "machine bookpress"
- "machine puncher"
- "electric hum"
- "alarm"
- "night wind"
- "surface explosion"
- "underground explosion"
- "sphtkr attack"
- "sphtkr projectile hit"
- "sphtkr projectile flyby"
- "sphtkr hit"
- "sphtkr exploding"
- "tick chatter"
- "tick falling"
- "tick flapping"
- "tick exploding"
- "ceiling lamp exploding"
- "pfhor platform starting"
- "pfhor platform stopping"
- "pfhor platform"
- "pfhor door opening"
- "pfhor door closing"
- "pfhor door obstructed"
- "pfhor door"
- "pfhor switch off"
- "pfhor switch on"
- "juggernaut firing"
- "juggernaut warning"
- "juggernaut exploding"
- "juggernaut start attack"
- "enforcer exploding"
- "alien noise 1"
- "alien noise 2"
- "vacbob wail"
- "vacbob scream"
- "vacbob hit"
- "vacbob chatter"
- "assimilated vacbob chatter"
- "vacbob trash talk"
- "vacbob apology"
- "vacbob activation"
- "vacbob clear"
- "vacbob angry"
- "vacbob secure"
- "vacbob kill the player"

### Texture Types

# TextureTypes
TextureTypes()

#### Mnemonics

- "wall"
- "landscape"
- "sprite"
- "weapon in hand"
- "interface"

### Transfer Modes

# TransferModes
TransferModes()

#### Mnemonics

- "normal"
- "pulsate"
- "wobble"
- "fast wobble"
- "static"
- "landscape"

- "horizontal slide"
- "fast horizontal slide"
- "vertical slide"
- "fast vertical slide"
- "wander"
- "fast wander"

- "reverse horizontal slide" 20231125
- "reverse fast horizontal slide" 20231125
- "reverse vertical slide" 20231125
- "reverse fast vertical slide" 20231125
- "2x" 20231125
- "4x" 20231125

### Weapons

# WeaponTypes
WeaponTypes()

#### Mnemonics

- "fist"
- "pistol"
- "fusion pistol"
- "assault rifle"

- "missile launcher"
- "flamethrower"
- "alien weapon"
- "shotgun"

- "ball"
- "smg"

# Example Icon

    --[[
    This is  an example  of an  icon  in  the format  used by  Aleph One’s  overlay
    functions.
    The first characters  are a digit string  describing the number of  colors. (in
    this example, it’s 7.
    The first character that  is not a digit is ignored,  as are all the characters
    following it  that are the same  character. (i.e. I  could use a q instead of a
    newline here.
    Then,  for  every color,  it reads  a character,  followed by  a six-digit  hex
    string,  which is the  HTML-style color corresponding  to that character in the
    image.  After reading this string,  it ignores the next character,  whatever it
    is.
    Once it has  read every color,  it reads all the following characters,  and for
    every character it reads for which a color has defined, it puts that color into
    the icon as the next pixel. Other characters are ignored. (see below.)
    Icons are always 16x16.
    ]]

    [[
    7
     0000FF
    #000000
    .FFFFFF
    $7FAE20
    %EBD52A
    ,45983C
    *5B4714
    *************# The fact
    *************# that it
    *$$$#*********# ignores
    $$$$$#********# characters
    $$$$$#$$******# that
    $$##$##$$*****# are
    $$$$##.#$$#**# not colors
    $%%$$#.,#$#**# can be
    %%%%%%##,#$$# exploited to interesting
    %%%%%%%##$$# effect by a sufficiently
    #%%%%%%%$$$$# resourceful and obnoxious
    *##%%%%%%$$$$###
    #**#%%#%%%###**#
    *#*##%%#%%$$$$# person
    **#  #%%##%$$# such as
    **#   #%%%#%$# myself :)
    Additionally, once it has read 256 valid characters, it ignores the rest of the
    string.
    ]]