==== 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.