Files
horizon-airdef/docs/api/mods-reference.md
T
Ludovic Marie c9f554d1c4 Mod API 0.3 (experimental): server mods' contract, runtime and SDK
A server mod runs where the world is simulated. Its manifest says side =
"server" and api = "0.3" (only a server mod may), and its component targets
the new WIT world horizon-server-mod:

- imports log and storage as client mods do, and the new capability players:
  online() (id, name, position, dimension, game mode, health), tell(id, text),
  broadcast(text), 8 lines per call shared with chat;
- exports server-events: init, tick, player-joined, player-left, chat, command
  (with the player who typed it; its feedback goes back to that player),
  block-broken and block-placed (with the block state as text).

horizon-mods: a second bindgen world sharing log and storage with the first;
a running mod holds either kind of hooks; Mods::load_for(Runs) starts only the
mods a game runs (the window client mods, the world's server server mods,
in-frame single player both) and marks the others Elsewhere. Client and server
commands are owned separately. The game passes Runs::Client for now, so
nothing changes in game until its server code calls these hooks.

The SDK gains horizon_mod_sdk::server (ServerMod, Registration,
export_server_mod!), the example server mod welcome (greets, announces
newcomers kept in storage, /online, /mined), and cargo horizon-mod check's
trial run plays a server mod with a player joining, chatting, typing its
commands and leaving. The manifest refuses client capabilities on a server
mod and players on a client mod. The generated reference, the guide, the
portal and the stability table describe it.

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

8.8 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 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
  • 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.

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 registration

Field Type
commands list<string> Commands players may type, without the slash. A name vanilla already uses is refused (vanilla's command runs).
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.

record block-pos

Field Type
x s32
y s32
z s32
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) -> result<option<string>, string> /name args typed by player: ok(some(text)) is their feedback, err(text) their error in red.
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.