Server Global Functions
Global functions available in every server-side Lua script, and how locations are passed between Lua and the engine.
These functions are available as globals in every server-side Lua script — mob hooks, item hooks, interactable hooks, weather hooks, block hooks, chat commands, and NPC dialogue.
Function Reference
log_info(message)
Writes message (string) to the server log at INFO level. The standard way to debug server-side scripts.
log_info("boss fight started")
broadcast_server_message(message)
Sends a chat message to every connected player. For a private message to one player, use entity:send_message(text) instead (see lua-server-entity.md).
broadcast_server_message("A meteor is falling!")
broadcast_localized_message(key, args)
As broadcast_server_message, but key is looked up in the game’s string table, so each player reads the line in their own language. args is an optional table of { name = value } placeholders (strings or numbers) for the text’s {name} holes. A key the table does not have is shown as written. For one player, use entity:send_localized_message(key, args).
broadcast_localized_message("chat.joined", { name = "Alice" })
get_player_location_from_name(player_name)
Returns the named player’s current location (see below), or nil if no player with that exact name is online. The match is case-sensitive and uses the player’s login name, not their display name.
local loc = get_player_location_from_name("Alice")
if loc ~= nil then
log_info("Alice is at " .. loc.x .. ", " .. loc.y .. " in " .. loc.world)
end
spawn_mob_at(mob_name, location, initial_lua_data)
Spawns a mob at the given location and announces it to all clients. Returns the spawned entity object (see lua-server-entity.md) on success, or nil on failure (unknown mob name, or no loaded world matches location.world). Failures are logged to the server log.
mob_namemust be the fully qualified name,"ModName:mob_name"— e.g."Creation:glorbo". There is no automatic mod-name prefixing.locationis a table withx,y(block coordinates) andworld(world name string). All three are required.initial_lua_datais optional: a table whose key/value pairs are copied into the new mob’slua_databefore it joins the world.- The mob’s
scripts.server-on-createhook runs as part of the spawn. - No overlap check is performed — the mob spawns even inside other entities.
The returned object lets you keep scripting against the spawned mob — set its display name, path it, damage/heal it, store an id, etc. This is the standard way to spawn boss adds or segments and then drive them.
local mob = spawn_mob_at("Creation:glorbo", { x = 120.0, y = 46.0, world = "world" })
if mob == nil then
log_info("spawn failed")
else
mob:set_display_name("Summoned Glorbo")
end
Pass data the new mob needs on its first tick as initial_lua_data, not by assigning lua_data afterwards. The spawned mob starts updating the moment this call adds it to the world, and its server-update script can run before the spawning script resumes — so a field assigned on the returned object may arrive a tick late. That is invisible until the new mob’s own script reads the field on its first tick, which is common: a summon that removes itself when it cannot find its summoner will sometimes vanish instantly.
-- The add knows its boss on its very first tick.
local add = spawn_mob_at("Creation:torvastus_minion",
{ x = loc.x, y = loc.y, world = loc.world },
{ boss_id = entity:get_id() })
Assigning mob.lua_data.field = value after the call is still fine for anything the mob does not read immediately.
spawn_mount(mount_name, location)
Spawns a mount at the given location and announces it to all clients. Returns the spawned entity object (see lua-server-entity.md) on success, or nil on failure (unknown mount name, or no world matches location.world). Failures are logged to the server log.
mount_name is fully qualified ("ModName:mount_name"); location is the same {x, y, world} table as spawn_mob_at.
local boat = spawn_mount("Creation:rowboat", { x = 80.0, y = 30.0, world = "world" })
if boat ~= nil then
boat:set_display_name("S.S. Scripted")
end
spawn_static_object_at(object_name, location)
Spawns a tree or plant (Decoration) static object into the live world at the given location and announces it to all clients. Returns the spawned static object (see lua-server-static-object.md) on success, or nil on failure (unknown object name, an interactable — which needs per-instance setup and is not supported — or no world matches location.world). Failures are logged to the server log.
object_name is fully qualified ("ModName:object_name", e.g. "Creation:tall_grass"); location is the same {x, y, world} table as spawn_mob_at. The first variation is used. Trees and plants normally place at world generation; this hook is for scripting and testing (e.g. dropping a patch of flora on demand).
local loc = player:get_location()
for dx = -3, 3 do
spawn_static_object_at("Creation:tall_grass", { x = loc.x + dx, y = loc.y, world = loc.world })
end
set_weather_at(weather_name, duration_seconds, location)
Forces the weather in the region containing location to the named weather, overriding the biome’s normal selection (so you can set snow in a desert), and broadcasts the change to all clients. Returns true on success, or false (logged) if the world or weather name is unknown, or no weather region is loaded there yet.
weather_nameis fully qualified ("ModName:weather", e.g."Creation:snowy").duration_seconds— a positive value reverts to the normal biome weather cycle after it elapses;0(or negative) holds the weather until it is set again.locationis the same{x, y, world}table asspawn_mob_at, and comes last in the argument list.
local loc = player:get_location()
set_weather_at("Creation:snowy", 60.0, { x = loc.x, y = loc.y, world = loc.world }) -- snow here for 60s
set_block_in_world(block_name, location)
Places a block by name at a {x, y, world} location — the block-placement counterpart to spawn_mob_at, for contexts that have no world object in scope (chat commands, NPC dialogue). Returns true on success, or false (logged) if the world or block name is unknown, or the target cell is in an unloaded chunk.
block_nameis fully qualified ("ModName:block_name", e.g."Creation:stone").locationis the same{x, y, world}table asspawn_mob_at; coordinates are world coordinates (1.0= one block). The block is placed on its own configured layer.- Placing a falling block (
falls-when-unsupported) unsupported starts it falling, exactly as an in-world placement does. (In a block hook you already haveworld— useworld:set_block_at_from_namethere; see lua-server-world.md.)
local loc = executor:get_location()
set_block_in_world("Creation:stone", { x = loc.x, y = loc.y - 1, world = loc.world })
get_block_variation(base_block_id, variation_name)
Returns the block ID (number) of the named variation of a base block, or nil if that variation does not exist. Takes the base block’s numeric ID — get one from a block table’s id field (see lua-server-world.md).
get_difficulty()
Returns the save’s current difficulty as a lowercase string: "dormant", "awakened", "forsaken", or "condemned". Read it each time you need it rather than caching it at load: the host can step a world between dormant, awakened and forsaken mid-session, so the value can change while your script is running. (condemned is locked in both directions — a Condemned world never becomes anything else, and nothing becomes Condemned.)
if get_difficulty() == "condemned" then
spawn_mob_at("MyMod:elite_glorbo", { x = loc.x, y = loc.y, world = loc.world })
end
get_difficulty_floor()
Returns the lowest difficulty the save has ever been played at, in the same lowercase spelling as get_difficulty(). It only ever moves downwards: stepping a world down to dormant lowers it for good, and stepping back up leaves it where it fell.
Use it — not get_difficulty() — for anything you award: a reward, an unlock, a title, a record of having cleared something at a given difficulty. Keying a reward on the current tier lets a player drop to an easier tier for the hard part and step back up to collect, which the floor is there to prevent.
-- a hard-mode-only reward: honest for a player who has never dropped below forsaken
local floor = get_difficulty_floor()
if floor == "forsaken" or floor == "condemned" then
player:grant_milestone_event("MyMod:cleared_the_deep_the_hard_way")
end
world_set_flag(key)
Sets a persistent, world-scoped story flag and returns true if it was newly set (false if it was already set). Flags are the shared, save-level record of one-time world events — a boss’s first defeat, an unlocked gate, a story beat. They persist across sessions and, in co-op, are shared by the whole world (unlike per-player capabilities). A key is any string you choose; namespace it to avoid clashes with other mods (e.g. "MyMod:boss.genesis.defeated").
The return value lets you detect a first occurrence atomically — the idiomatic way to run first-kill logic exactly once:
-- in a boss's server-side on_death script
if world_set_flag("Creation:boss.genesis.defeated") then
-- first defeat only: advance the world, open the route onward
broadcast_server_message("The Genesis warden falls. A path opens.")
end
-- re-fighting the boss later sets nothing new (returns false) and pays loot only
world_has_flag(key)
Returns true if the given world flag is currently set. Use it to gate spawns, structures, or routes on prior progress:
if world_has_flag("Creation:boss.genesis.defeated") then
spawn_mob_at("Creation:harder_add", { x = loc.x, y = loc.y, world = loc.world })
end
world_clear_flag(key)
Unsets a world flag, returning true if it was present (false if it wasn’t). The mirror of
world_set_flag, for undoing a one-time flag — resetting state in a test harness, or re-arming a
story beat that can happen again.
world_clear_flag("Creation:met_survivor") -- next visit greets them as a stranger again
survivor_lose(mob_name)
Records that a survivor is gone for this save, for the scripted losses the design allows — a rescue
reached too late, a holdout who will not leave, a personal thread that ends badly. Returns true if it
changed anything; false when that survivor is not out in the world (already lost, already recruited,
or safe at home — none of which can be undone this way).
It marks state only. What the scene shows — the body, the empty room, the line of dialogue — belongs to the script that calls it.
if world_has_flag("Creation:ashen_collapse_triggered") then
survivor_lose("Creation:the_holdout") -- they would not leave, and the roof came down
end
survivor_reset(mob_name)
Development only. Forgets a survivor entirely — their state and every mirrored flag — so they can be placed and recruited again. It exists because a survivor is placed once per save, which otherwise makes a recruitment test a one-shot; the shipped game never calls it.
survivor_reset("Creation:reference_survivor") -- then spawn_mob_at(...) works a second time
Locations
Several APIs pass positions around as a location — a position plus a world name. Coordinates are in block units.
Receiving a location (from get_location(), get_player_location_from_name, weather region sampling): you get a read-only object with three fields:
local loc = entity:get_location()
loc.x -- number
loc.y -- number
loc.world -- string (world name)
Passing a location (to spawn_mob_at, spawn_mount): build a plain table with the same three keys — all required:
{ x = 100.0, y = 42.0, world = "world" }
A received location object can be passed straight back into these functions, but you cannot modify it — to move a position, build a new table:
local loc = player:get_location()
spawn_mob_at("Creation:glorbo", { x = loc.x + 10, y = loc.y, world = loc.world })
See Also
- lua-server-entity.md — methods on entity objects
- lua-server-world.md — reading and placing blocks
- lua-modding-overview.md — hook declaration and
require
Last updated