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
  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. Game Types
    12. Item Kinds
    13. Item Types
    14. Light Functions
    15. Light Presets
    16. Light States
    17. Media
    18. Monster Actions
    19. Monster Classes
    20. Monster Modes
    21. Monsters
    22. Overlay Colors
    23. Platform Types
    24. Player and Team Colors
    25. Polygons
    26. Projectiles
    27. Scenery
    28. Scoring Modes
    29. Side Types
    30. Sounds
    31. Texture Types
    32. Transfer Modes
    33. 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:

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
.init(restoring_game)

at beginning of level

  • restoring_game: true if restoring from a saved game
.cleanup()

at end of the level

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

.idle()

at each tick, before physics and such

.postidle()

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

.start_refuel(class, player, side)

whenever a player starts to use a refuel panel

.end_refuel(class, player, side)

whenever a player stops using 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

.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

.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

.projectile_switch(projectile, side) 20111201

whenever a projectile toggles a switch

  • projectile: projectile that toggled the switch
  • side: side containing switch being toggled
.terminal_enter(terminal, player)

whenever a player starts using a terminal

.terminal_exit(terminal, player)

whenever a player stops using a terminal

.pattern_buffer(side, player)

whenever a player uses a pattern buffer

.got_item(type, player)

whenever a player picks up an item

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

.light_activated(light)

whenever a light is activated or deactivated

.platform_activated(polygon)

whenever a platform is activated or deactivated

.player_revived(player)

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

.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_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)
.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_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()

.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.

.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

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

# 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

# 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

# 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

# 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
.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

.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

.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.

.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.

.time_remaining (read-only)

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

.scoring_mode

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

.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.)

.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)

.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)

.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

.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

.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

# 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

ItemStarts

# 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

Items

# 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

.type (read-only)

type of item

.visible (read-only) 20220115

.x (read-only)

.y (read-only)

.z (read-only)

Level

Level
.calculate_completion_state() 20081213

returns whether level is finished, unfinished, or failed

.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

.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

# 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

# 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

# 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

# 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

Monsters

# 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

Music
.clear()

clears the level playlist

.fade(duration)

fades out the currently playing track and clears the playlist

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

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

.stop()

stops level music and clears the playlist

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

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

Platforms

# 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

.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

# 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

Players

# 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

.cycle_weapons_backward

switches to previous weapon

latched

.cycle_weapons_forward

switches to next weapon

latched

.left_trigger

fires primary trigger

.microphone_button

activates the net mic

can not be set to true; can be set to false

.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

.weapons.current (read-only)

weapon the player is currently wielding

can be nil

.x (read-only)

.y (read-only)

.z (read-only)

.zoom_active (local player)

whether player’s sniper zoom is active

Polygons

# 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

# 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

# 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

.type (read-only)

type of scenery

.x (read-only)

.y (read-only)

.z (read-only)

Sides

# 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 transparent side is empty

transparent side only

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

# 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

Tags

Tags[index]
.active

tag is active

Terminals

# 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

Collections

# Collections
Collections()
Collections[collection]
.bitmap_count

number of bitmaps in collection

Mnemonics

Completion States

# CompletionStates
CompletionStates()

Mnemonics

Control Panel Classes

# ControlPanelClasses
ControlPanelClasses()

Mnemonics

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

Difficulty

# DifficultyTypes
DifficultyTypes()

Mnemonics

Effects

# EffectTypes
EffectTypes()

Mnemonics

Ephemera Quality

# EphemeraQualities
EphemeraQualities()

Mnemonics

Faders

# FadeTypes
FadeTypes()

Mnemonics

Game Types

# GameTypes
GameTypes()

Mnemonics

Item Kinds

# ItemKinds
ItemKinds()

Mnemonics

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

Light Functions

# LightFunctions
LightFunctions()

Mnemonics

Light Presets

# LightPresets
LightPresets()

Mnemonics

Light States

# LightStates
LightStates()

Mnemonics

Media

# MediaTypes
MediaTypes()

Mnemonics

Monster Actions

# MonsterActions
MonsterActions()

Mnemonics

Monster Classes

# MonsterClasses
MonsterClasses()

Mnemonics

Monster Modes

# MonsterModes
MonsterModes()

Mnemonics

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

Overlay Colors

# OverlayColors
OverlayColors()

Mnemonics

Platform Types

# PlatformTypes
PlatformTypes()

Mnemonics

Player and Team Colors

# PlayerColors
PlayerColors()

Mnemonics

Polygons

# PolygonTypes
PolygonTypes()

Mnemonics

Projectiles

# ProjectileTypes
ProjectileTypes()

Mnemonics

Scenery

# SceneryTypes
SceneryTypes()

Mnemonics

Scoring Modes

# ScoringModes
ScoringModes()

Mnemonics

Side Types

# SideTypes
SideTypes()

Mnemonics

Sounds

# Sounds
Sounds()

Mnemonics

Texture Types

# TextureTypes
TextureTypes()

Mnemonics

Transfer Modes

# TransferModes
TransferModes()

Mnemonics

Weapons

# WeaponTypes
WeaponTypes()

Mnemonics

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.
]]