Files
horizon-airdef/docs/api/mods-reference.md
T
Ludovic Marie c5bb51bb05 Mod API 0.3: typed server commands, in players' command trees
A server mod's registration now lists each command's arguments: a name, a
kind (word, text, integer with bounds, number, boolean, player, block-pos)
and whether it is optional. The server adds them to the command tree every
player receives, after vanilla's commands, so a player's chat box completes
and colours them as vanilla's. When a player sends one, the server parses
the line as vanilla's parsers do (horizon-mods' commands.rs: ~ coordinates
from the player, @s/@p, integer bounds) and calls the mod's command hook
with the values by name, or answers with vanilla's error without calling
the mod.

The hub keeps the server mods' commands as a root in the commands report's
format and resends players' trees when they change (CommandTree::
packet_with); the game sets it when its mods start, stop or reload, or a
hub opens. In-frame, the window's own chat box lists them by name.

SDK: Registration::command_with(name, [Argument::...]), Argument builders,
Args (text(), integer(), player(), block_pos() ...); command(name) is free
text, an optional text argument. Examples: welcome's /mined [player],
beacons' /beacon [height] and /ground [pos], with scripts for values and
errors.

Docs: docs/mods.md (typed commands, kinds table), docs/api/mods.md and
the regenerated reference.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 19:35:09 +01:00

12 KiB

Mod API reference

The contract between Horizon and its mods: the WIT package horizon:mods@0.1.0, every interface, type, function and hook in it, and the capabilities a manifest may list. The guide is mods.md; stability and versions: stability.md. Manifest api lines this game serves: 0.1, 0.2, 0.3.

Capabilities

In capabilities Grants The player reads "May …"
game-read game see your position, health and the time
chat chat show you chat messages
hud hud draw text on your screen
storage storage save its own settings to disk
registries data files (assets/, data/), no interface add blocks and items to your worlds
players players see who is on the server and message them
world world read and change the world's blocks

World horizon-mod

A client mod: runs in the player's game.

  • Imports (what the game offers): log, game, chat, hud, storage
  • Exports (what the mod provides): events

World horizon-server-mod

A server mod (manifest side = "server", api = "0.3", experimental): runs where the world is simulated, on the dedicated server, a LAN host and single player's own server.

  • Imports (what the game offers): log, storage, players, world
  • Exports (what the mod provides): server-events

log

Access: always granted.

The mod's log, in the game's log under the mod's id. Always granted.

enum level

Case
debug
info
warn
error
Function Signature What it does
write func(level: level, message: string) One line in the game's log as [mod <id>] message, at that level.

game

Access: capability game-read.

Capability game-read: the local player and the world clock.

record player

Field Type
x f64 Feet position, in blocks.
y f64
z f64
yaw f32 Degrees, as F3 shows them.
pitch f32 Degrees: -90 looks straight up, 90 straight down.
health f32 Hit points as vanilla counts them: 20 is full health without effects.
food u32 0 to 20, as the hunger bar.
dimension string minecraft:overworld, minecraft:the_nether, ...

record clock

Field Type
game-time u64 Ticks since the world was created.
day-time u64 24000 ticks per day; 0 is 6:00 on the first day.
Function Signature What it does
get-player func() -> option<player> None on the title screen.
get-clock func() -> option<clock> None on the title screen.

chat

Access: capability chat.

Capability chat: messages only the local player sees.

Function Signature What it does
show func(text: string) Shown in chat after the mod's name, like a system message.

hud

Access: capability hud.

Capability hud: one panel of text lines per mod, drawn by the game every frame until the mod changes or clears it (no call per frame).

enum corner

Case
top-left
top-right
bottom-left
bottom-right

record line

Field Type
text string Plain text, up to 256 characters.
color u32 0xRRGGBB.
Function Signature What it does
set-panel func(corner: corner, lines: list<line>) Replaces the mod's panel: up to 16 lines in that corner of the screen.
clear func() Removes the mod's panel.

storage

Access: capability storage.

Capability storage: a per-mod folder of small key/value files, quota'd (docs/mods.md). Keys are [a-z0-9_.-]{1,64}, one path segment.

Function Signature What it does
get func(key: string) -> option<list<u8>> None if key has never been set, or the key is not well-formed.
set func(key: string, value: list<u8>) -> result<_, string> Errs on a malformed key or over quota (bytes for the whole mod).
delete func(key: string) No error if key was already absent.

events

Access: exported by the mod: the game calls it.

What the game calls. Only the hooks init asks for are ever called.

record registration

Field Type
commands list<string> Chat commands, without the slash. A name vanilla already uses is refused (vanilla's command runs).
tick bool Call tick every game tick (20 per second while playing).
frame bool Call frame every rendered frame. Budget: 0.1 ms.
chat bool Call chat for each chat line the player receives.
Function Signature What it does
init func() -> result<registration, string> Once, after loading. An error keeps the mod off and is shown.
tick func(tick: u64) Each game tick while in a world, with the game's tick counter.
frame func(seconds: f32) Each rendered frame, with the seconds since the last one.
command func(name: string, args: string) -> result<option<string>, string> /name args: ok(some(text)) is shown as feedback, err(text) in red.
chat func(text: string) Each chat line the player receives, as plain text.

players

Access: capability players.

Capability players, server mods only (manifest api = "0.3", experimental): the players on the server, and messages to them.

enum game-mode

Case
survival
creative
adventure
spectator

record player

Field Type
id string The player's UUID, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
name string
x f64 Feet position, in blocks.
y f64
z f64
dimension string minecraft:overworld, minecraft:the_nether, ...
game-mode game-mode
health f32 Hit points as vanilla counts them: 20 is full health without effects.
Function Signature What it does
online func() -> list<player> The players online, in the order they joined.
tell func(player: string, text: string) -> bool A system message to one player, after the mod's name; false when no player with that id is online. Up to 8 messages per call.
broadcast func(text: string) A system message to every player and the server's log, after the mod's name. Counts toward the same 8 per call.

world

Access: capability world.

Capability world, server mods only (manifest api = "0.3", experimental): the blocks of the server's loaded chunks, and changes to them through the server's own block updates.

record block-change

Field Type
x s32
y s32
z s32
state string minecraft:oak_log[axis=y]; properties left out take the block's defaults, minecraft:stone alone is the default state.
Function Signature What it does
get-block func(dimension: string, x: s32, y: s32, z: s32) -> option<string> The block state at a position in a dimension (minecraft:overworld, ...), as minecraft:oak_log[axis=y], as of this call: none where the server has no chunk loaded there.
get-biome func(dimension: string, x: s32, y: s32, z: s32) -> option<string> The biome at a position (minecraft:plains, ...), as the server stores it (one per 4 x 4 x 4 cell): none where no chunk is loaded.
set-blocks func(dimension: string, blocks: list<block-change>) -> result<_, string> Sets blocks as /setblock does: the old block entity removed, neighbours and shapes updated, light, and every player told. Every state is checked now (an error queues nothing); the changes are made in order after this call returns, before that dimension's next tick; one in a chunk not loaded then is skipped. At most 4096 per call.

server-events

Access: exported by the mod: the game calls it.

What the server calls in a server mod (manifest api = "0.3", experimental). Only the hooks init asks for are ever called. The player in each event is as the server saw them when it happened.

type player

type player = player

record block-pos

Field Type
x s32
y s32
z s32

variant argument-kind

What an argument of a command takes. The server sends each command and its arguments to players' games, whose chat box completes and colours them as vanilla's; the server parses them before the mod's command hook gets their values.

Case Payload
word One word: letters, digits and _ - . +.
text The rest of the line, spaces included: only last.
integer tuple<option<s32>, option<s32>> A whole number, within the bounds given.
number A number with or without decimals.
boolean true or false.
player One online player: a name, or @s or @p (whoever typed it, as vanilla picks for a player).
block-pos A block position: three whole numbers, each one also ~ or ~n, relative to whoever typed it.

record argument

Field Type
name string Shown in the chat box's hint (<height>) and the key of its value.
kind argument-kind
optional bool Optional arguments come after every required one.

record server-command

Field Type
name string Without the slash. A name vanilla already uses is refused (vanilla's command runs).
arguments list<argument> In order; none: the command takes nothing after its name. Free text is one optional text argument.

variant argument-value

An argument's value, parsed as its kind says.

Case Payload
word string
text string
integer s32
number f64
boolean bool
player player
block-pos block-pos

record registration

Field Type
commands list<server-command> Commands players may type.
tick bool Call tick every server tick (20 per second).
joins bool Call player-joined and player-left.
chat bool Call chat for each chat message a player sends.
blocks bool Call block-broken and block-placed.
Function Signature What it does
init func() -> result<registration, string> Once, after loading. An error keeps the mod off and is logged.
tick func(tick: u64) Each server tick, with the server's tick counter.
player-joined func(player: player) A player joined the server; they are in players.online already.
player-left func(player: player) A player left the server; they are no longer in players.online.
chat func(player: player, text: string) A chat message a player sent, as plain text.
command func(player: player, name: string, args: string, values: list<tuple<string, argument-value>>) -> result<option<string>, string> /name args typed by player: ok(some(text)) is their feedback, err(text) their error in red. values holds each argument given, by name, in order (an optional one left out isn't there); a line that doesn't parse never reaches the mod: the player gets vanilla's error.
block-broken func(player: player, pos: block-pos, state: string) A player broke the block at pos in their dimension: state is what was there, as minecraft:oak_log[axis=y].
block-placed func(player: player, pos: block-pos, state: string) A player placed state at pos in their dimension.