# 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](../mods.md); stability and versions: [stability.md](stability.md). Manifest `api` lines this game serves: `0.1`, `0.2`. ## Capabilities | In `capabilities` | Grants | The player reads "May …" | | --- | --- | --- | | `game-read` | [`game`](#game) | see your position, health and the time | | `chat` | [`chat`](#chat) | show you chat messages | | `hud` | [`hud`](#hud) | draw text on your screen | | `storage` | [`storage`](#storage) | save its own settings to disk | | `command` | [`command`](#command) | run commands as you, with your permissions | | `registries` | data files (`assets/`, `data/`), no interface | add blocks and items to your worlds | | `ui` | [`ui`](#ui) | show its own screens and a settings page | ## World `horizon-mod` - Imports (what the game offers): `log`, `game`, `chat`, `hud`, `storage`, `command` - 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`, `command` - 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 ] 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` | None on the title screen. | | `get-clock` | `func() -> option` | 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)` | 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>` | None if `key` has never been `set`, or the key is not well-formed. | | `set` | `func(key: string, value: list) -> 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. | ## `command` Access: capability `command`. Capability `command`: vanilla commands run as the player, with the player's permissions, after the hook call returns (8 per call). A mod's own commands are not run this way. | Function | Signature | What it does | | --- | --- | --- | | `run` | `func(line: string)` | `line` without its slash; its feedback goes to the chat as if typed. | ## `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`, `:`; 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` | The rows' texts, at most 512, each up to 256 characters. | | `selected` | `option` | 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` | 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)` | 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` | 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` | 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, 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. |