Skip to content

Writing Lua scripts

Put scripts under <root>/scripts. The default bootstrap is init.lua, selected by [scripting].bootstrap_file in server configuration. The host uses Lua 5.2 through LuaCSharp; execution and resumes occur on the game loop. No separate Lua installation is required.

This guide assumes basic Lua: variables, functions and tables. No Lua installation is needed. All paths below are relative to your server root.

Append this line to the existing scripts/init.lua; keep the shipped bootstrap and its registrations:

log.info("Hello from my shard")

Start the server, or enter script reload init.lua in the server console. The console log should contain Hello from my shard. If it does not, check the configured bootstrap path and script errors before continuing.

Create scripts/common/greeting.lua:

local greeting = {}
function greeting.for_name(name)
return "Welcome, " .. name
end
return greeting

Append to scripts/init.lua:

local greeting = require("common.greeting")
log.info("{Message}", greeting.for_name("Moongate"))

Reload init.lua from the console again. Look for Welcome, Moongate. require maps dotted module names to relative .lua paths: common.greeting loads common/greeting.lua. It caches the module result. Resolution stays inside the scripts directory, including checks against symbolic links escaping that root. A missing bootstrap logs a warning and starts an empty engine. A bootstrap that exists but fails compilation/execution aborts server startup.

Append this example to scripts/init.lua and reload it:

local pulse = timer.every(30, function()
log.info("Pulse")
wait(2)
log.info("Pulse resumed")
end)
timer.after(95, function()
log.info("Pulse cancelled: {Cancelled}", timer.cancel(pulse))
end)

All three delays are seconds: Pulse appears every 30 seconds, followed by Pulse resumed about 2 seconds later; after 95 seconds the repeating timer is cancelled. wait belongs inside the callback, not at the top level of the file. See Events and timers for cancellation and overlap rules.

The Lua API reference has a page for each module, with every function’s signature, parameters and return type; it is generated from the server’s code.

The default host registers log; the engine supplies engine, timer, events and wait. The Ultima plugin registers dice, cliloc, localization, npc, item, mobile, world, target, prompt, gump, bank, vendor, trainer, effect, moongates, locations, jail, board, commands, mount, stable, pet, hue_picker, skill, combat, npcguild, guild, schedule, help, book, harvest, craft and carve in game and standalone modes. Log levels still follow the host’s logging policy, so a log.debug call need not appear in the default console output. Use templates rather than concatenating changing values into messages.

The npc, item, mobile, effect, world, target, prompt, bank and gump modules serve the mobile and item scripts. A script reads and writes a mobile’s numbers and skills, and tries a mobile at a skill with skill.check, which may raise it (see Skills). To expose application behavior, bind a C# module using Writing a Lua module.

Some modules have a page that says more:

Module Read
events, timer Events and timers
npc Mobile scripts, with walking a path
item Item scripts
effect Effects
gump Gumps, with gumps built in Lua, and Your first gump
bank Bank
vendor Vendors
trainer Trainers
dice The forms of DiceSpec
localization Read a message from Lua
cliloc Constants for the client texts many scripts say, such as cliloc.TOO_FAR: Shipped scripts
locations Locations and the go command
moongates Moongates
jail Jail and the jail command
board Bulletin boards
commands Commands: commands.execute runs one as the console, commands.execute_as as a player
skill Skills: skill.check(mobile, skill, min, max) tries a mobile at a skill, which may rise
combat attack, stop, target, range, armor_rating, weapon, swing, spend_ammo: starts and ends melee fights and tells whom a mobile fights; see Combat
mount ride_ethereal(player, statuette): puts a player on the mount of a statuette; toggle_stone(player, stone): puts a player on the mount of a stone in its backpack, or gets it off; see Mounts
stable attend, pets, stable, claim, max_pets, fee: leaves a player’s pets in the stable and takes them back
pet info, lore, corpse, followers, max_followers, tame, hire, hire_period, attend, release, loyalty, control_chance, obey, feed: the creatures a player has tamed or hired, and taming a wild one; see Animal taming and Hirelings
hue_picker open(player, graphic, callback): shows the client’s hue picker and runs the function with the hue picked
npcguild of, member, quote, is_join_payment, join, resign: the guild of a trade, as a guildmaster takes members
guild of, get, is_member, member, leader, roster, wars, allies, declared_war, declared_alliance, create, recruit, resign, eject, set_title, set_charter, set_website, set_hue, set_fealty, declare_war, make_peace, declare_alliance, break_alliance: the player guilds of their stones; see Guilds
schedule is_active, active, events, set_event, next: the calendar of data/schedule.toml
help The help gump’s needs: the wait of the I am stuck button, the nearest starting city, and the queue of requests for the game masters (create_page, pages, take, answer, close…)
book give, write, open: creates and reads personalized scrolls and books from templates/books
harvest has, amount, vein, take: what is gathered from the world and runs out by area, such as fish
craft get, resource: the crafts of data/crafts, their groups and recipes, and the resource lists they use
carve corpse: carves a corpse with the tables of templates/carves; see Carving
  • Lua in Moongate: the Lua version, the libraries a script has, and where it differs from the manual.
  • Events and timers: server events, wait and repeating timers.
  • Mobile scripts: the functions an NPC’s script may define, and walking a path.
  • Item scripts: the functions an item’s script may define, and how one refuses a move.
  • Script hooks: the single list of every function the server calls on an NPC or an item script, with its arguments, when it runs and what its answer means.
  • Shipped scripts: what each script of the distribution does: monsters, doors, lights, food, teleporters, moongates, clocks and the containers that fill up.
  • Effects: the options of the effect module.
  • Reload, budgets and editor: reloading a script, the instruction budgets, and completion in an editor.
  • Lua API reference: every function, with its signature and, for many, an example.

Made with ❤️ by Tom

Buy me a coffee