Since patch 1.50.7 there is a limited scripting support. The language used for scripts is a modified version of Lua 5.3. This is an experimental feature, it may be a bit rough to use. For example currently there is no way to interrupt a script, so if you forgot to break from an endless loop you’ll have to crash and restart the game.

This feature is present only in 1.50 fan patch, there is no scripting in the original game!

Scripts are used:

  • As a convenience for players, e.g. comparing one’s tech level to other empires.

  • As a modding tool e.g. a mod can specify a map pre-processing script in order to ensure certain map properties.

  • As a testing and debugging tool.

Changes in Lua

Due to limitation of the DOS runtime the following changes has been introduced:

  • All numbers are integer, not floating-point. Division by zero will throw an error.

  • Operator ^ does not work.

  • Some standard library functions are not included. This may change in the future. Notable examples are: require, loadfile, and the whole math library.

  • Some standard functions (e.g. tostring, print) behave a bit differently.

Contexts

Each script is run in a certain context. This determines the set of available API functions as well as details of their workings.

  • player — Scripts run in Main screen by a player (unless Lua cheat is enabled). Get functions return only objects observable by the current player. Only owned objects are modifiable, e.g. can scrap or rename ships.

  • universal

    • Scripts specified by newgame_postprocessor_script parameter that are run right after a new game is generated. All game objects are available and modifiable.

    • Scripts run in Main screen when Lua cheat is enabled. Used for testing.

  • pregame — Scripts specified by pregame_script parameter that are run before race selection. Only config and game settings are available, no galaxy or players exist yet. Can be used to randomize tech tree or race picks.

  • combat — Scripts run in combat by a player. Combat ships and the rest of the game objects observable by a player are available.

Running a Script

A player can run a script in the Main screen by pressing 0, …, 9 to run MAIN0.LUA, …, MAIN9.LUA. Those scripts are run in player context unless Lua cheat is enabled.

The game will automatically run a script from a file given by config parameters newgame_postprocessor_script and pregame_script. Both parameters allow specifying multiple files separated by a semicolon. They are also accumulative, meaning that specifying them multiple times results in joining values. E.g this:

newgame_postprocessor_script = CORE.LUA;
newgame_postprocessor_script = MAP.LUA;

is equivalent to:

newgame_postprocessor_script = "CORE.LUA;MAP.LUA";

This is needed so that different mods don’t overwrite each other’s scripts.

Game API

Note, that the tables returned by most APIs start with index 0, not 1, and may have gaps in indices depending on context. They are not Lua arrays, and cannot be used with array utility functions such as ipairs or the # operator.

If function’s context is unspecified then it’s available in any context.

Utility Functions

Several Lua library functions are available and work as described in Lua documentation. Aside from that several other convenience functions has been added:

Name Description

to_string(…)

Returns stringified version of its args concatenated. Also used internally by print() and msgbox()

print(…)

Outputs a line to ORION2.LOG.

msgbox(…)

Brings up a message box, useful for debugging.

get_conf(…)

Returns the currently active configuration settings (see Modding with Config). Passing a string parameter will only return the corresponding subsection of the config, which requires a lot less memory.

get_game()

Returns general information about the game, such as number of players and other starting settings.

get_coordinate_distance_between_stars( <star_id>, <star_id>)

Returns the euclidean distance between two stars. A distance of 30 equals 1 parsec.

get_milliseconds()

Returns currently elapsed milliseconds from DOS-perspective. Subtract from an earlier call to measure runtime for a given block of Lua code.

get_memory_used()

Returns the number of bytes currently allocated as memory for Lua, useful to find peaks.

collectgarbage()

Trigger Lua garbage collection.

Note: the memory available for running Lua scripts is limited. Exceeding the limit will at best fail the script with an error popping up as a message box, at worst it can crash your multiplayer game. Unused memory is generally not cleaned up during script execution by default, this so-called garbage collection can be triggered with this call. Here are some best practices on how to avoid memory issues:

  • Clean up variables when they are not needed anymore; this is especially important for bigger tables. To do this, set the value of the variable to nil and trigger the garbage collection.

  • Avoid calling get_conf() without a parameter as it will return a huge amount of data. Instead, call it only for the needed scope, e.g. get_conf("weapons").

  • Local memory inside a loop is generally not cleaned up after an iteration, this can sometimes make it necessary to trigger the garbage collection in every iteration.

  • When developing a script, call get_memory_used() in different places to determine areas with high memory consumption as well as the global peak.

Manipulating Players

Player table - is a Lua table with player info indexed by player id, e.g.:

{ [0] = {name = "Human", … }, [1] = {name = "Alkari", … } … }

Tech table - is a Lua table with the state of each tech for a player indexed by tech id. States are:

  • 0 — unacquirable (other Advanced Governments)

  • 1 — acquireable

  • 3 — researched

Tech field table - is a Lua table with the state of each research field of a playerd indexed by the name of the field. States are:

  • 0 — unavailable for research

  • 1 — available later in the tech tree

  • 2 — researchable right now

  • 3 — researched

Name Context Description

get_players()

universal
player

In universal context returns a player table with all players, including traits, spies and 152 population in transit. In player context returns only those in contact with the current players and only info visible by the opponent.

get_current_player_id()

player

Returns the id of the player calling the script.

get_player_techs(<player_id>)

universal
player

Returns a tech field table. In player context will return nil if you have no contact with that player or /noreport config option is enabled.

get_player_fields(<player_id>)

universal
player

Returns a tech field table. In player context will return nil if you have no contact with that player or /noreport config option is enabled.

get_player_hyper_advanced_progress(<player_id>)

universal
player

Returns the amount of completed Hyper-advanced stages for every tech branch. If run in player context or if no player id is provided it will refer to the player calling the script.

set_player_techs(<player_id>, <tech_table>)

universal

Sets player’s techs, useful for fixing uncreative races after map generation.

set_player_fileds(<player_id>, <tech_field_table>)

universal

Sets player’s tech fields.

Manipulating Stars

Star table - is a Lua table with star info indexed by star id, e.g.:

{ [0] = {name = "Orion", … }, [1] = {name = "Sol", … } … }

Star id array - is a Lua array of star ids, e.g.:

{ [1] = 7, [2] = 11 }
Name Context Description

get_stars()

universal

Returns a star table for all stars in the galaxy except Antares.

set_stars(<star_table>)

universal

Accepts star table, sets star attributes.

del_stars(<star_id_array>)

universal

Removes listed stars.

add_stars(<N>)

universal

Adds N empty stars. Returns star id array of created stars.

Manipulating Planets

Planet table - is a Lua table with planet info indexed by planet id, e.g.:

{ [0] = {star = 12, orbit = 0, … }, [1] = {star = 12, orbit = 4, … } … }

Planet id array - is a Lua array of planet ids, e.g.:

{ [1] = 7, [2] = 11 }
Name Context Description

get_planets()

universal
player

Returns a planet table of all known planets.

set_planets(<planet_table>)

universal

Modify planets.

del_planets(<planet_id_array>)

universal

Delete planets.

add_planets(<planet_table>)

universal

Create planets.

Manipulating Colonies

Colony table — is a Lua table with colony info indexed by colony id, e.g.:

{ [4] = {planet = 63, … }, [12] = {planet = 75, … } … }

Population table — is a Lua table in which an array of individual population units of a colony is returned, as well as growth gains and per mille units for every race, e.g.:

{ pop = { [0] = {job = 1, … }, [1] = {job = 1, … } … },
  race2growth = { [0] = 73, [1] = 0,  …},
  race2extra = { [0] = 146, [1] = 0, … } }
Name Context Description

get_colonies()

universal
player

Returns a colony table for all colonies. In player context only owned colonies are shown.

get_pop_info_of_colony(<colony_id>)

universal
player

Returns a population table. In player context, only an id of an owned colony is accepted.

get_buildings_of_colony(<colony_id>)

universal
player

Returns table with all building names as keys and status of existence as values. In player context, only an id of an owned colony is accepted.

get_build_queue_of_colony(<colony_id>)

universal
player

Returns the build queue of that colony as an array with the value "nothing" representing an empty queue slot. In player context, only an id of an owned colony is accepted.

Manipulating Ships

Ship table - is a Lua table with ship info indexed by ship id, e.g.:

{ [0] = {design = { name = "Scout", …}, x = 56, … }, [1] = { … } … }
Name Context Description

get_ships()

universal
player

Returns a ship table for all active ships (not including those currently being built or refitted). In player context only ships you can see or own are returned.

get_queued_ships()

universal
player

Returns a ship table for all ships that are being built or refitted. In player context only your own ships are returned.

del_ships(<ship_id_array>)

universal
player

Accepts ship id array, deletes these ships. Does not accept ships that are currently being built or refitted. In player context only ships you own may be deleted.

Retrieving Combat Information

These functions are only available during tactical ship combat. To check if your script is executed during the combat use get_active_combat_ship ~= nil.

Note & in combat & universal context. This means that such functions are only available in combat when universal context is also enabled. This can only happen if Lua cheat mode is on, since universal context is otherwise enabled only on mapgen stage.

Name Context Description

get_combat_info()

combat

Returns general information about the current battle, such as turn count and involved players.

get_active_combat_ship()

combat

Returns detailed information about the ship that is currently acting, including information about weapons, specials, systems and any damage they sustained.

get_combat_ships()

combat & universal

Returns combat-relevant information about all ships involved in the current battle, including satellites and planets. overmap_ship is a reference to the given ship as it would be return by get_ships(). combat_ship_id is usually different from the id of the overmap ship, it is used to retrieve further information.

get_combat_ship_weapons(<combat_ship_id>)

combat & universal

Returns information about all weapon slots of the given ship. Use the combat_ship_id of the given ship as a parameter, not the overmap_ship.

get_combat_ship_specials(<combat_ship_id>)

combat & universal

Returns information about all specials of the given ship. Use the combat_ship_id of the given ship as a parameter, not the overmap_ship.

Experimental API

A number of "raw" APIs were introduced in 1.50.18. These are experimental, so no in-depth description is provided. See MIRROR.LUA and RANDTECH.LUA for usage examples. Currently all such functions work only in the universal and pregame contexts.

Accessed Objects Get Set Del Add

Overmap ships

rget_ships

rset_ships

rdel_ships

radd_ships

Leaders

rget_leaders

rset_leaders

Nebulas

rget_nebulas

rset_nebulas

rdel_nebulas

radd_nebulas

Players

rget_players

rset_players

Tech tree (tech config table)

rget_techs

rset_techs

Tech tree (tech_field config table)

rget_fields

rset_fields

Tech tree (starting_techfield config table)

rget_starting_fields

rset_starting_fields

Race picks (race_pick config table)

rget_picks

rset_picks