This is an old revision of the document!
# Server-side Lua scripting
This page documents the game-server Lua scripting system and how to bind scripts through `ScriptComponent`.
Related pages: - Lua API reference - [Lua API reference (Markdown)](./SCRIPTING_API.md)
## 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`s.
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`):
```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`):
- The server looks up the resource and executes it.
2. 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:
```lua 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, devs can use `/lua [code]` which queues an ad-hoc script execution with default context.
