Skip to content

Authoring Mods: Events and API Reference

This page lists the Lua API version 1 behavior implemented by version 2.00. Unknown event, rule, and service names fail during package activation. Event payloads and rule contexts are immutable even when the current lifecycle permits mutation through ordinary game objects.

Registration and ordering

Register behavior only from main.lua or a module loaded by it:

events.on("planet.generated", function(event)
    local planet = game.planets:get(event.planet_id)
    -- Validated planet operations are available in this lifecycle.
end)

Packages set up from lowest to highest package priority. Callbacks dispatch in that package setup order, followed by source registration order within each package. Later callbacks observe successful writes made by earlier callbacks.

Events

Event Immutable payload Mutation and execution
game.initialized Empty May initialize storage and use permitted live game operations. Runs once after new-game setup.
game.loaded Empty Read-only. Rebuild transient Lua caches; do not change game state, storage, prototypes, registrations, services, or exports.
game.configuration_changed reason, changes, changed_groups Storage migration/configuration lifecycle. See persistence.
new_game.technology_setup setup_sequence May change supported global technology source state before player technology assignment. Not run when loading a save.
new_game.player_setup player_id May change supported initial player technology state. Runs once per player. Not run on load.
new_game.home_system_generated player_id, system_id May change supported staged home-system planet state. Not run on load.
planet.generated planet_id May change supported staged planet fields. Runs once per generated planet and is not rerun on load.
ship.destroyed destroyed_ship, optional killer, phase, sequence May use supported mutable game operations. Current network games reject this event.

destroyed_ship is an immutable historical record with id, owner, cost, cause, and name. killer, when present, is a live ship proxy. The record remains usable even though the destroyed entity no longer exists.

For game.configuration_changed, reason is package_version_changed or configuration_reloaded. changes is an ordered sequence whose records contain package_id, old_package_version, new_package_version, and, for Lua packages, old_storage_version and new_storage_version. changed_groups lists changed configuration groups for a reload.

Rules

Rule modifiers receive an immutable context and the current value, and must return a replacement integer:

rules.modify("population.growth", function(context, growth)
    if context.climate == defines.climate.gaia then
        return growth * 120 // 100
    end
    return growth
end)

Rules compose as:

native base -> package A -> package B -> validated final value

Rule callbacks cannot mutate game state or storage.

population.growth

Context fields are:

colony_id
planet_id
owner_id
race_id
race_population
total_population
population_limit
climate
housing
population_boom
plague

The result must fit a signed 16-bit integer. In multiplayer, this rule runs only during the elected gameplay host's authoritative strategic turn; clients receive the resulting state.

combat.beam_damage

Context fields are:

attacker_player_id
target_player_id
weapon_id
beam_ordinal
beam_count

The result must be an integer from 0 through 32767. It modifies successful strategic beam damage after native weapon and attacker bonuses and before target defenses. Current network games reject this rule.

Exclusive service

API version 1 supports one exclusive service:

services.register("galaxy_generator", 1, function()
    -- Inspect or transform the generated candidate through game objects.
end)

The callback takes no arguments. It runs after native new-game construction and can use the topology operations listed below. Only one active package may register the service. The engine validates and atomically installs the completed candidate; callback or topology validation failure discards it, although completed RNG draws remain consumed. The service is not invoked when loading a save.

In multiplayer, the host runs the provider and clients install the authoritative result.

game collections and objects

Most collections provide get(id) and all(). all() is a deterministic one-based sequence. Mutating properties and methods remain subject to lifecycle permissions even when listed here.

Players

game.players:get(id) and game.players:all() return player proxies with:

Member Meaning
kind, id, valid Stable identity and validity.
is_human, government Read-only player properties.
home_planet, home_system Stable related objects, or nil when absent.
technologies Player technology interface.
has_trait(id) Test a built-in or custom trait.
add_research(amount) Add research when the current mutable lifecycle permits it.
set_home_planet(planet) Galaxy-generator operation requiring an owned colony.

player.technologies provides:

status(application_id)
is_available(application_id)
is_researched(application_id)
field_of(application_id)
alternatives(field_id)
set_available(application_id, available)
set_status(application_id, status)
replace_available(removed_id, first_id, second_id, choose_first)
set_field_application(field_id, application_id)

Mutation requires a compatible mutable lifecycle. replace_available is restricted to new_game.player_setup. Canonical string IDs and defines.technology_status replace raw status bytes and table positions.

Ships

game.ships:get(id) and game.ships:all() return proxies with kind, id, valid, owner, owner_id, status, system, x, and y. set_system(system) and delete() are structural galaxy-generator operations. game.ships:copy(source, system) creates a candidate generated ship during that service.

Planets

game.planets:get(id) and game.planets:all() return proxies with:

kind, id, valid
system, orbit, planet_type
size, gravity, climate, minerals, special

Validated assignment to size, gravity, climate, and minerals is available in planet-mutable generation lifecycles. Use set_special(value) for specials. set_orbit(system, orbit) and delete() are structural galaxy-generator operations. game.planets:copy(source, system, orbit) creates an uncolonized candidate planet during that service.

Systems

game.systems:get(id) and game.systems:all() return proxies with:

kind, id, valid
x, y, spectral_class, special, size, picture, visited
wormhole, planets

system.planets:all() returns planets in orbit order. During galaxy_generator, validated assignment is supported for x, y, spectral_class, special, and visited; use set_wormhole(system_or_nil) for reciprocal links and delete() for an eligible non-home system. game.systems:copy(source) creates a candidate system.

game.map_width and game.map_height are read-only map bounds.

Global technology

game.technology contains applications, fields, and starting_fields collections. Application and field collections provide get(id) and all(); starting_fields:all() returns its ordered source list.

Applications expose id and field. Fields expose id, cost, previous, next, and ordered applications. During new_game.technology_setup, assign application.field, field.previous, or field.next to change the source graph. The engine validates membership, capacity, reciprocal links, branch coverage, cycles, and required starting fields after all callbacks.

Leaders and nebulas

game.leaders:get(id) and game.leaders:all() return leader proxies with kind, id, valid, name, status, and system where applicable. game.leaders:copy(source, unused_target, system) places a copied marooned leader during galaxy_generator.

game.nebulas:get(id) and game.nebulas:all() return proxies with kind, id, valid, x, y, and type. During galaxy_generator, x, y, and type are writable, delete() removes a candidate nebula, and game.nebulas:create(x, y, type) creates one.

Capability and lifetime rules

  • Event payloads and rule contexts reject assignment.
  • A mutable event permits only operations implemented for its current native owner.
  • Rule callbacks are read-only regardless of the ordinary object's wider API.
  • Topology creation, deletion, movement, and link changes are restricted to galaxy_generator.
  • Setup technology mutations are restricted to new_game.technology_setup.
  • Handles from a disposable galaxy candidate expire when that candidate is installed or discarded.
  • Stored player references remain stable; stored ship references use a slot and generation so reuse expires old references.
  • Unknown properties and operations fail rather than exposing native data accidentally.