c28bea8e96
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
404 lines
16 KiB
Markdown
404 lines
16 KiB
Markdown
<!-- Generated from crates/horizon-mod-sdk/wit/horizon.wit and the manifest's capabilities by crates/horizon-mods/tests/api_reference.rs; a test fails when this file is out of date. Update it with: HORIZON_WRITE_DOCS=1 cargo test -p horizon-mods --features pack --test api_reference -->
|
||
# 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 |
|
||
| `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 |
|
||
| `render` | [`render`](#render) | draw on your screen and shake the camera |
|
||
| `input` | [`input`](#input) | see the keys you hold and your clicks, take over the use button on its own items, and add keys |
|
||
|
||
## 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`, `render`, `input`, `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`
|
||
|
||
## World `render-host`
|
||
|
||
The game's side of capability `render` (imports only).
|
||
|
||
- Imports (what the game offers): `render`, `input`
|
||
- Exports (what the mod provides):
|
||
|
||
## `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. |
|
||
|
||
### record `button-widget`
|
||
|
||
A thing on a mod's screen or settings page. A button as the options pages have them (200 × 20): a click is `ui-events::select(id, 0)`. Mods cycle its label for a choice ("Corner: Top Left").
|
||
|
||
| Field | Type | |
|
||
| --- | --- | --- |
|
||
| `id` | `u32` | The mod's own name for the widget. |
|
||
| `label` | `string` | Up to 256 characters. |
|
||
|
||
### variant `widget`
|
||
|
||
| Case | Payload | |
|
||
| --- | --- | --- |
|
||
| `text` | `text-widget` | Text the player reads. |
|
||
| `button` | `button-widget` | A button. |
|
||
| `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. |
|
||
|
||
## `input`
|
||
|
||
Access: capability `input`.
|
||
|
||
Capability `input` (experimental: the manifest needs `experimental = ["input"]`): the use button on items the mod claims, and the mod's own keys. Events wait for `poll`, at most 256.
|
||
|
||
### record `held-item`
|
||
|
||
The main hand's stack.
|
||
|
||
| Field | Type | |
|
||
| --- | --- | --- |
|
||
| `id` | `string` | `minecraft:spyglass`, `<mod>:<path>`. |
|
||
| `count` | `u32` | |
|
||
| `slot` | `u32` | The hotbar slot, 0 to 8. |
|
||
|
||
### record `item-use`
|
||
|
||
| Field | Type | |
|
||
| --- | --- | --- |
|
||
| `item` | `held-item` | |
|
||
| `ticks` | `u32` | Game ticks the button was held (0 on `use-start`). |
|
||
|
||
### variant `event`
|
||
|
||
| Case | Payload | |
|
||
| --- | --- | --- |
|
||
| `use-start` | `item-use` | The use button went down with a claimed item in the main hand. The game does nothing else with the click: no placing, no eating, no swing. |
|
||
| `use-stop` | `item-use` | It came up again, or the item left the hand, or a screen opened. |
|
||
| `key-down` | `string` | A key `register-key` named went down or up while playing (no screen open). The game's own mapping on that key still runs. |
|
||
| `key-up` | `string` | |
|
||
|
||
### record `mapping-state`
|
||
|
||
A mapping as the player has bound it.
|
||
|
||
| Field | Type | |
|
||
| --- | --- | --- |
|
||
| `label` | `string` | The bound key's name as Controls shows it: `W`, `Space`, `LMB`. |
|
||
| `down` | `bool` | Held down now (as of this frame for a mod with a `frame` hook, else this tick). |
|
||
|
||
| Function | Signature | What it does |
|
||
| --- | --- | --- |
|
||
| `claim-items` | `func(ids: list<string>)` | The items whose use the mod handles instead of the game, by id (at most 64). Replaces the previous list. |
|
||
| `register-key` | `func(name: string, label: string, key: string) -> result<_, string>` | A key of the mod's: `name` comes back in `key-down` and `key-up`, `label` says what it does, `key` is the key as options.txt writes it (`key.keyboard.r`). At most 16; an unknown key is an error. |
|
||
| `held` | `func() -> option<held-item>` | The main hand's stack, as of this tick; none when it is empty. |
|
||
| `poll` | `func() -> list<event>` | The events since the last call, oldest first. |
|
||
| `mapping` | `func(name: string) -> option<mapping-state>` | A movement or click mapping as the player has bound it: `key.forward`, `key.left`, `key.back`, `key.right`, `key.jump`, `key.sneak`, `key.sprint`, `key.attack` or `key.use`. None for another name. |
|
||
| `clicks-per-second` | `func() -> tuple<u32, u32>` | Clicks of the attack and use buttons in the last second. |
|
||
|
||
## `render`
|
||
|
||
Access: capability `render`.
|
||
|
||
Capability `render` (experimental: the manifest needs `experimental = ["render"]`): shapes the game draws for the mod with its own renderer, kept until the mod replaces them (no call per frame). A mod never supplies shader code.
|
||
|
||
### enum `corner`
|
||
|
||
A corner of the screen, as `hud`'s panels use them.
|
||
|
||
| Case | |
|
||
| --- | --- |
|
||
| `top-left` | |
|
||
| `top-right` | |
|
||
| `bottom-left` | |
|
||
| `bottom-right` | |
|
||
|
||
### record `rect`
|
||
|
||
A rectangle in GUI pixels: the top left corner and the size.
|
||
|
||
| Field | Type | |
|
||
| --- | --- | --- |
|
||
| `x` | `f32` | |
|
||
| `y` | `f32` | |
|
||
| `w` | `f32` | |
|
||
| `h` | `f32` | |
|
||
|
||
### record `point`
|
||
|
||
A point in GUI pixels from the screen's top left.
|
||
|
||
| Field | Type | |
|
||
| --- | --- | --- |
|
||
| `x` | `f32` | |
|
||
| `y` | `f32` | |
|
||
|
||
### record `fill-shape`
|
||
|
||
| Field | Type | |
|
||
| --- | --- | --- |
|
||
| `rect` | `rect` | |
|
||
| `color` | `u32` | 0xAARRGGBB. |
|
||
|
||
### record `quad-shape`
|
||
|
||
Any four-cornered shape (a wheel's segment, an arrow): the corners in order round it.
|
||
|
||
| Field | Type | |
|
||
| --- | --- | --- |
|
||
| `corners` | `tuple<point, point, point, point>` | |
|
||
| `color` | `u32` | 0xAARRGGBB. |
|
||
|
||
### record `sprite-shape`
|
||
|
||
| Field | Type | |
|
||
| --- | --- | --- |
|
||
| `sprite` | `string` | One of the game's GUI sprites, as `gui/sprites/` names them (`hud/heart/full`, `widget/button`), the resource packs' versions included. An unknown one draws nothing. |
|
||
| `rect` | `rect` | |
|
||
| `color` | `u32` | A tint, 0xAARRGGBB: 0xFFFFFFFF draws it as it is. |
|
||
|
||
### record `item-shape`
|
||
|
||
| Field | Type | |
|
||
| --- | --- | --- |
|
||
| `item` | `string` | `minecraft:diamond`, `<mod>:<path>`; an unknown one draws nothing. |
|
||
| `at` | `point` | The icon's top left. |
|
||
| `scale` | `f32` | 1.0 is the hotbar's 16 × 16. |
|
||
|
||
### record `text-shape`
|
||
|
||
| Field | Type | |
|
||
| --- | --- | --- |
|
||
| `text` | `string` | Up to 256 characters, one line. |
|
||
| `at` | `point` | |
|
||
| `color` | `u32` | 0xRRGGBB, as `hud`'s lines. |
|
||
| `centered` | `bool` | Centred on `at.x` instead of starting there. |
|
||
| `shadow` | `bool` | |
|
||
|
||
### variant `shape`
|
||
|
||
| Case | Payload | |
|
||
| --- | --- | --- |
|
||
| `fill` | `fill-shape` | |
|
||
| `quad` | `quad-shape` | |
|
||
| `sprite` | `sprite-shape` | |
|
||
| `item` | `item-shape` | |
|
||
| `text` | `text-shape` | |
|
||
|
||
### record `frame-rate`
|
||
|
||
| Field | Type | |
|
||
| --- | --- | --- |
|
||
| `fps` | `u32` | Frames drawn in the last second. |
|
||
| `min` | `u32` | The slowest frame's rate, and the 1% low (the 99th percentile frame time's rate), over the last 5 seconds. |
|
||
| `low` | `u32` | |
|
||
|
||
| Function | Signature | What it does |
|
||
| --- | --- | --- |
|
||
| `set-hud` | `func(shapes: list<shape>)` | Replaces the mod's HUD shapes: up to 1024, drawn every frame in order over the HUD (after the hotbar, under chat and screens), hidden with the HUD (F1). An empty list removes them. |
|
||
| `gui-size` | `func() -> tuple<f32, f32>` | The screen's size in GUI pixels (width, height), as of this tick. |
|
||
| `shake` | `func(strength: f32, seconds: f32)` | Shakes the camera: a jolt of `strength` (0 to 1, 1 the hardest) that fades out over `seconds` (at most 10). Jolts add up to 1. The view turns, the player doesn't, and the player's Distortion Effects option scales it (0 turns it off). |
|
||
| `set-corner` | `func(corner: corner, width: f32, height: f32, shapes: list<shape>)` | Replaces the mod's corner panel: shapes in GUI pixels from the top left of a `width` × `height` box that the game places in `corner`, stacked with the game's overlays and the other mods' panels (under the status effects at the top right), as `hud`'s panels are. |
|
||
| `clear-corner` | `func()` | Removes the mod's corner panel. |
|
||
| `text-width` | `func(text: string) -> f32` | The width of one line of text in GUI pixels, in the HUD's font: exact for Latin letters (U+0000 to U+024F), 6 per other character. |
|
||
| `frame-stats` | `func() -> frame-rate` | The game's frame counter, recomputed twice a second. |
|
||
|
||
## `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. |
|