Files
horizon-airdef/docs/api/mods-reference.md
T
socksprox af7a685b5c Mod API: capability ui — mod-owned screens and settings pages
New WIT interface `ui` (text, item and list widgets; open-screen,
close-screen, set-settings) plus a `ui-events` export (select, closed,
settings-opened), in a second world `horizon-ui-mod` so mods built before
it keep loading. The game lays out and draws the widgets with its own
menus' code: a screen the mod owns (Esc/Done to leave) and a Settings
button on the mod's Options > Mods row that opens its page.

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-25 17:09:25 +01:00

9.0 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.

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
ui ui show its own screens and a settings page

World horizon-mod

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

World horizon-ui-mod

A mod with widgets (capability ui): the SDK builds every mod against this world. Mods built for horizon-mod alone (no ui-events export) still load and simply hear nothing of their widgets.

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

World ui-host

The game's side of horizon-ui-mod beyond horizon-mod.

  • Imports (what the game offers): ui
  • Exports (what the mod provides): ui-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.

ui

Access: capability ui.

Capability ui: widgets the game draws with its own menus' widgets, for a screen the mod owns and a settings page in Options > Mods. Layout and drawing are the game's: a mod says what its widgets hold, never where they sit or how they look, and the game clips everything it is handed.

record text-widget

A line of text.

Field Type
id u32 The mod's own name for the widget; ui-events calls echo it.
text string Up to 256 characters.
color u32 0xRRGGBB; 0 is the menus' white.

record item-widget

An item's icon and a name beside it, as recipe viewers show them.

Field Type
id u32 The mod's own name for the widget.
item string minecraft:diamond, <mod>:<path>; an unknown id draws a "?".
name string The name shown beside the icon (empty: the item's own).

record list-widget

Rows the player picks one of, as an options page lists choices: a pick is ui-events::select, selected is the row to mark now.

Field Type
id u32 The mod's own name for the widget; ui-events::select echoes it.
rows list<string> The rows' texts, at most 512, each up to 256 characters.
selected option<u32> The row to mark as the current choice, if any.

variant widget

A thing on a mod's screen or settings page.

Case Payload
text text-widget Text the player reads.
item item-widget An item's icon and name.
list list-widget Rows the player picks from.

record screen

A screen the mod owns: a title over widgets stacked down the middle, the Done button the game adds, and Esc to leave it.

Field Type
title string Its title, up to 256 characters.
widgets list<widget> Its widgets, in order, at most 64.
Function Signature What it does
open-screen func(screen: screen) Show screen over the game; a second call while it is open replaces it. Only the last call of one hook counts.
close-screen func() Close the mod's screen when it is open (the mod hears no closed for this: it was its own doing).
set-settings func(widgets: list<widget>) The mod's page in Options > Mods, reached from a settings button on its row: the widgets it shows, an empty list for no page. The player opening the page is ui-events::settings-opened: push fresh widgets then; later calls update the page while it shows.

ui-events

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

What the game calls on a mod that shows widgets (capability ui): what the player did with them.

Function Signature What it does
select func(id: u32, row: u32) A row of one of the mod's list widgets was picked: the widget's id and the row, on the screen or the settings page that showed it.
closed func() The player left the mod's screen (Esc or Done); not for a screen the mod closed itself or one that went away with the mod.
settings-opened func() The player opened the mod's settings page in Options > Mods: call ui::set-settings now to fill it with fresh widgets.

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.