==== Server-side Lua scripting ====
This page documents the game-server Lua scripting system and how to bind scripts through ''ScriptComponent''.
Related pages:
* [[scripting/lua|Lua API reference]]
==== 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:
- Resource reference (string ending in ''.lua''):
- The server looks up the resource and executes it.
- Inline Lua source (any other string):
- 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:
- Edit files in ''res/scripts'' or entity resources in ''res/ents''.
- Use ''/reload_resources script'' (dev command) to reload ''ScriptDb''.
- Scripts under ''include/'' are reloaded and re-preloaded.
- 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.