User Tools

Site Tools


scripting

Server-side Lua scripting

This page documents the game-server Lua scripting system and how to bind scripts through ScriptComponent.

Related pages:

Where scripts live

  • Script resources are loaded from server/game-server/res/scripts.
  • A script resource name is its path relative to res/scripts without the .lua extension.
    • Example: res/scripts/player-init.lua is referenced as player-init.lua in component data and resolved to resource name player-init internally.
  • Files under res/scripts/include/ are preloaded as Lua modules and can be used with require(“…”).
    • Example: res/scripts/include/common.lua can be loaded as require(“common”).

Script execution model

The ScriptSystem runs once per server tick and drains queued ScriptEvent values.

Main execution paths:

  • ScriptComponent.on_init on entity spawn.
  • ScriptComponent.on_hit on OnEntityAttackedEvent for the target entity.
  • Interaction, dialog, item, and other systems can also queue script execution with a ScriptContext.

The global Context userdata is set before each script run. The concrete fields depend on which ScriptContext variant triggered execution.

Using ScriptComponent

Add a [script] table to an entity resource (res/ents/*.toml):

[script]
on_init = "player-init.lua"
on_hit = "tutorial/training-dummy-tutorial-hit.lua"

on_init

  • Runs when the entity is spawned.
  • Context type: DefaultScriptContextData
    • Context:ent_id()
    • Context:target_ent_id() (typically nil here)

on_hit

  • Runs when the entity is attacked.
  • Context type: OnEntityAttackedScriptContextData
    • Context:src_ent_id()
    • Context:tgt_ent_id()
    • Context:damage_amount()
    • Context:damage_type() (bitflags; see include/damage_type.lua)

Inline vs resource scripts

Both on_init and on_hit support two forms:

  1. Resource reference (string ending in .lua):
    1. The server looks up the resource and executes it.
  2. Inline Lua source (any other string):
    1. The string itself is executed as Lua code.

For maintainability, prefer resource scripts over inline Lua.

Script module (include/) usage

Modules under res/scripts/include are preloaded and added to Lua package.preload at startup and script reload.

Example:

local common = require("common")
local tutorial = require("tutorial")
local DamageType = require("damage_type")

Useful built-in modules currently in the repo:

  • common (helper wrappers, e.g. common.open_modal)
  • damage_type (damage bit constants)
  • stat (stat IDs)
  • tutorial (tutorial constants/content)

Resource validation

On resource load/reload, the server validates script references in entity and item resources.

For ScriptComponent, only values ending in .lua are validated as resource names. Missing resources are logged as validation errors.

Reload and iteration workflow

Recommended flow while developing scripts:

  1. Edit files in res/scripts or entity resources in res/ents.
  2. Use /reload_resources script (dev command) to reload ScriptDb.
  3. Scripts under include/ are reloaded and re-preloaded.
  4. Trigger the entity behavior in-game.

For quick one-off evaluation, developers can use /lua [code] which queues ad-hoc script execution with default context.

scripting.txt · Last modified: by dooskington