Skip to content
Basalt Server

Server control from Lua

The tick rate, server settings, server links, datapacks, advancements, loot tables and maps.

Tick#

tick is the machinery behind /tick.

Call Does
tick.rate(), tick.set_rate(rate) Reads or sets the tick rate
tick.frozen(frozen?) With no argument reads whether ticking is frozen; with a boolean sets it
tick.step(n) Runs n ticks while frozen. Returns whether it started
tick.sprint(n) Runs n ticks as fast as possible; tick.stop_sprint() ends it. Both return a boolean
tick.pace() A list of four numbers: the ticks per second over the last 1, 5 and 15 minutes, and the mean tick time in milliseconds
tick.times() The last hundred tick durations in nanoseconds, not sorted by age
tick.paused() Whether the server is ticking nothing because nobody has been online for pause_when_empty_seconds

With nobody online for pause-when-empty-seconds (server.toml, 60 as in vanilla) the tick loop only serves connections. It logs "Server empty for N seconds, pausing" and "Server resumed". A plugin that needs a heartbeat with nobody online sets settings.set("pause_when_empty_seconds", "0") or settings.set("pause_allowed", "false"), see Settings.

Settings#

settings reads and changes a few settings of the running server. Values travel as text, and booleans are "true" or "false".

Call Does
settings.keys() The list of keys
settings.get(key) The value as text, or nil for an unknown key
settings.set(key, value) Changes a writable key until the server stops, and returns whether the value was accepted
Key Writable Meaning
motd yes What the server list shows. Overrides the configured entry
max_players yes The number the server list shows. It is not enforced at login
gamemode yes The default game mode of every world: survival, creative, adventure or spectator
idle_timeout yes Minutes before an idle player is kicked, 0 for never
pause_when_empty_seconds yes Seconds with nobody online before the tick loop pauses; 0 never pauses (pause-when-empty-seconds in server.toml)
pause_allowed yes false forbids the pause altogether
spawn_protection yes The block radius around the overworld spawn that only operators may change (spawn-protection in server.toml)
respawn_world yes The name of a loaded world where a player without a spawn point comes back; the default world unless set
autosave yes The switch behind /save-on and /save-off
port, bind, online_mode, enforce_secure_profile, whitelist, view_distance, simulation_distance, bedrock_port, hide_online_players, level_type, initial_enabled_packs, initial_disabled_packs, allow_nether, allow_end, rcon_enabled, rcon_port, api_enabled, api_port no What the server started with

The links in the client's pause menu. Clients read the list when they log in.

lua
server_links.set({
  { kind = "website", url = "https://example.org" },
  { label = '{"text":"Rules"}', url = "https://example.org/rules" },
})

server_links.list() returns { { kind, label, url }, ... }. A kind is bug_report, community_guidelines, support, status, feedback, community, website, forums, news or announcements; a link without a kind carries a JSON label.

Datapacks#

datapacks.list() returns { id, enabled, required, compatibility, source } for each pack and datapacks.refresh() rescans the folder. Enabling and disabling go through the /datapack command.

Advancements#

Call Returns
advancements.ids() Every advancement id
advancements.info(id) { id, parent, root, criteria, children, frame, icon }
advancements.grant(player, id, criterion) Grants a criterion (required) and returns whether it changed anything, with the toast, announcement and rewards of /advancement grant
advancements.revoke(player, id, criterion) Takes it back and returns whether it changed anything
advancements.progress(player, id) { [criterion] = obtained_ms }

Loot#

loot.tables() lists the loot table ids. loot.roll(table, context) rolls one and returns { { item, count, components }, ... }, with components as SNBT.

lua
local drops = loot.roll("minecraft:chests/simple_dungeon", { world = "world", x = 0, y = 64, z = 0, luck = 1 })

The context takes world, x, y, z, luck, seed (0 rolls without a fixed seed) and looter (a uuid).

loot.enchant{...} returns { item, count, components }, or nil, for a stack with enchantments rolled as the enchant_with_levels loot function does. It takes item, count (1), components (SNBT), levels, options (an enchantment id, or a tag with a leading #, #minecraft:in_enchanting_table by default), seed and world.

lua
local made = loot.enchant{ item = "minecraft:diamond_sword", levels = 30, world = "world" }

Containers refill their loot only when the world turns on loot-refill (see the worlds configuration); rolling with loot.roll is unaffected.

Maps#

maps.create(world, center_x, center_z, [scale]) makes a map and returns its id; scale is 0 by default. maps.info(id) returns { dimension, scale, center_x, center_z, locked }.

maps.explorer makes a map that points at the nearest structure; see Structures and templates.

Edit this page