Modding guide

LUA

Only declare functions.

Comments about functions should be placed inside the functions.

They should be declared with their namespace before them.
Example: a move function in user://mods/mymod/features/player/movement.lua should look like function player.movement.move()

You can hot-reload lua scripts using the dev tools (ESC > Settings > Game Settings > Dev Mode, then ESC > Dev Tools > Reload Lua Scripts) to work faster.

BEWARE! The user folder is usually erased when a new game is launched or the mod list is changed, this will erase your changes if you don’t back them up.

Data

The following fields will not be saved:

  • resource_local_to_scene
  • resource_path
  • resource_name
  • resource_scene_unique_id
  • script
  • comment

If you don’t fill title and description for objects with string ids, they’ll be filled with KEY_[id]_TITLE and KEY_[id]_DESC respectively.

For cells that contain arrays, make sure they’re surrounded by double-quoted brackets (ex: "[1, 2, 3]").
If they contain strings, you can surround them by single quotes or dashed double quotes (ex: "['string']" or "[\"string\"]").

Also, if said arrays contain strings that contain numbers with decimals, ensure the separator is a dot, not a comma (ex: "['1.0', '2.0', '3.0']" and not "['1,0', '2,0', '3,0']").

Init

Your mod can have an init function, which will be called when the mod is loaded. It should be declared in [User Game Folder]/data/features/game_manager/mods/init.lua.

Just call your function game_manager.mods.init.[mod_name] and it will be run after the initial game setup, but before the game starts (so the map isn’t generated yet for example).

Signals

Signals are used to communicate asynchronously between different parts of the game. You can register functions to be called when a signal is emitted with the following syntax:

register_signal_listener("name_of_the_signal", "path.to.your.function")

To know the different signal names and parameters passed with each signal, you can check the signals.lua files in the game’s data folder. There is one function for each emitted signal, with specific details explaining how they work.

Avoid editing those example signal functions if you want to maximize compatibility with other mods.

Mod.ini Format

Each mod must include a mod.ini file inside its folder, which defines its metadata, dependencies, and localization.
The file follows an INI-style format with different sections:

Example mod.ini

[Mod]
name = "alpha"
author = "Luc Toupense"
version = "0.0.2"
path = "res://mods/alpha"

[Dependencies]
core = "*"
other_mod = "^1.2.0"

[LocalizedTitle]
en = "Alpha"
fr = "Alpha"

[LocalizedDescription]
en = "Alpha version of Uncharted Sectors. Contains..."
fr = "Version alpha d'Uncharted Sectors. Contient..."

Sections:

  • [Mod]: General mod metadata.
    • name: The unique identifier for the mod.
    • author: The mod’s creator.
    • version: The mod’s version.
    • path: The mod’s folder path. If using Steam Workshop, you should omit this field, the path will be automatically provided.
  • [Dependencies]: List of required mods and their versions.
    • Versions must follow npm-like formatting (e.g., *, ^1.0.0, >2.0.0, >=1.2.3, <3.4.5, ~1.0.0).
    • If an invalid version format is detected, it defaults to *.
  • [LocalizedTitle]: The mod’s title in different languages.
    • Each entry follows language_code = title format.
  • [LocalizedDescription]: A brief description of the mod in different languages.
    • Each entry follows language_code = description format.

Version Formatting Rules:

  • * → Accepts any version.
  • ^1.0.0 → Accepts 1.x.x but not 2.0.0.
  • ~1.0.0 → Accepts 1.0.x but not 1.1.0.
  • >=1.2.3 → Accepts any version 1.2.3 or higher.
  • <3.4.5 → Accepts versions below 3.4.5.

When defining dependencies, ensure they follow this format to avoid compatibility issues.