With the switch, the game draws 0.2 packs ([frame] blend = "linear" is still refused). A renderer made with a 0.2 pack picked draws a float frame where the device can, else the 8-bit one; a pack picked or dropped later runs on the frame there is, logged once. The renderer's material, sky, weather, vertex and shadow entries decode a 0.2 stage's colours and encode its results; scene_color, opaque_color and the water mirror are decoded copies, shadow_color is float, and Frame's sky and fog colours are decoded. The post chain ends in a window-size picture, and the pack's [tonemap] (or Horizon's clip) draws it onto the frame, encoded at alpha 1. With HDR on, HDR output lifts nothing of a 0.2 pack's world. Co-Authored-By: Claude Opus 5.5 <[email protected]>
7.3 KiB
API stability and versioning
The rules every Horizon API follows (the APIs): how each one is versioned, what the stability levels promise, how something is deprecated and removed, and the tests that keep old mods, scripts and tools working.
Versions
- Each API has its own version, separate from the game's release (
v0.2.14, versioning.md) and from Minecraft's. A game release says which API versions it serves. - Semantic versioning,
MAJOR.MINOR.PATCH. A line is what stays compatible:0.1,0.2, … before 1.0, then1,2, ….- Before 1.0: an addition makes the next patch (
0.1.0→0.1.1); a breaking change starts the next line (0.2.0). - From 1.0: an addition makes the next minor (
1.0→1.1); a breaking change starts the next major (2.0).
- Before 1.0: an addition makes the next patch (
- Where the version lives:
| API | The version | A user names the line they need |
|---|---|---|
| Content mods | the manifest's api line |
api = "0.2" in horizon-mod.toml |
| Native mods | the Horizon and horizon-mixins revisions the bundle pins | horizon_revision in horizon-mixin.toml |
| Agent control | the control protocol's version (hello replies it; MCP serverInfo carries the release) |
horizon-ctl --api 0.1 |
| Server control API | the path (/api/v1/) |
the path |
server.toml |
the file's keys; a key is never renamed in place | nothing: old files keep loading |
| Launcher commands | the command names and their --json output |
nothing |
| Data formats | a version or schema field in the file |
the reader rejects versions newer than it knows |
What counts as a breaking change
Breaking: removing or renaming anything; changing a type, a default, a unit or a meaning; making something optional required; refusing input that was accepted; a JSON field that changes type.
Not breaking: a new function, interface, capability, command, endpoint, tool or server.toml key; a new optional
argument or JSON field (readers must ignore fields they don't know); faster, or fixing behaviour to what the reference already says.
Stability levels
Every part of an API has one level, shown in its reference and its surface page.
| Experimental | Preview | Stable | |
|---|---|---|---|
| Who may use it | opt-in only (a flag or a manifest field naming it); never in a release default | anyone; marked "preview" where players see it (a mod's row on the Mods page) | anyone |
| May change | in any release, without notice | only at a new line, after a deprecation | only at a new major, after a deprecation |
| Deprecation window | none | at least 30 days, with one release line serving old and new | at least 180 days, with the old major served beside the new one |
| Needs | a design note | a generated reference, a guide section, an example, compatibility tests | the same, plus one line of real use without a break |
- Promotion. Experimental → preview when it has what the table asks. Preview → stable when real users (a published mod, a host's script, an agent's tool) used it for a whole line and nothing broke. The maintainers' orchestrator proposes the promotion with the evidence (the compatibility tests, the complete docs, that line of use) and Ludovic approves it.
- Horizon-only by design. An API is stable only for what Horizon itself does; a vanilla concept it exposes (a block
id, a command, a
server.propertieskey) changes when vanilla changes it, with a version port (version-ports.md), and the changelog says so.
Deprecation and removal
- The pull request that deprecates marks it where it is defined (a
/// Deprecated: use X; goes in 0.3.doc comment, adeprecatedfield in a tool's schema) and adds the replacement in the same release. - The reference shows it as deprecated, and the surface page's changelog says what replaces it and when it goes.
- Using it logs one warning per mod, session or client, naming the replacement; it keeps working.
- It is removed only after the window, and only at the next line (preview) or major (stable).
- A line or major that is no longer served is refused with a clear message (
needs API 0.1; this Horizon serves 0.3 and 0.4), never loaded half-way.
Compatibility tests
Every preview and stable API has tests that run old users against the current code, in CI:
| API | The test |
|---|---|
| Content mods | the content template builds and checks with cargo horizon-mod, and mod_content's tests load content mods; a line is served as long as they pass |
| Native mods | hook points are only ever added, and tests keep each one hookable (tests::hook_points_stay_hookable and tests::loot_table_load_stays_hookable, game/native_hooks.rs) |
| Agent control | a transcript per protocol version: commands and the reply keys each must have |
| Server | api::ROUTES against route() (generated reference); a server.toml from each release line parses to the same settings; golden replies per endpoint |
| Launcher | the generated reference; golden --json output per command |
| Launch | the generated reference, which holds --launch-api's reply; every listed option is accepted; horizon-prepare's --progress json lines (progress_json_lines_keep_their_shape), its --launch-api reply and options (launch_api::tests, launch_api_options_are_in_the_help) |
| Data formats | a sample file of every version a reader accepts, read by today's reader |
The generated references are the API's own diff: a pull request that changes an API changes its reference, and the reviewer applies the rules above to that diff.
Changelog
Each surface page ends with a changelog: one line per change, newest first, with the API version and the pull request. Deprecations and breaking changes are in bold. The release notes of the game release that ships a change link it.
Today
| Part | Level | Version |
|---|---|---|
Content mods (registries: data-driven blocks, items, mob effects, thrown entity types and menu types) |
preview | manifest api = "0.2" |
| Native mods (horizon-mixins bundles, native-mods.md) | experimental | the pinned revisions |
cargo horizon-mod (new, build, run, check) |
preview | none yet (unversioned) |
| Shader API | experimental | 0.1 |
| Shader API 0.2 (linear light, hdr-linear-light.md) | experimental, behind a switch: horizon-shader checks it, the game draws it only with HORIZON_HDR_FRAME=float set, and the registry doesn't list it |
0.2 |
horizon-ctl commands and MCP tools |
preview | none yet (unversioned) |
The game's own control-socket commands outside horizon-ctl's table (test hooks) |
experimental | |
horizon-server commands, server.toml |
stable | horizon-server --version |
| Server control API | stable | /api/v1 |
horizon-launcher commands and MCP tools |
preview | none yet (unversioned) |
Launch API: horizon-client's launch options, session JSON, exit codes; horizon-prepare's output and progress |
experimental | 0.1.0, horizon-client --launch-api and horizon-prepare --launch-api |
| Benchmark report | stable | "version": 1 |
| Telemetry batch and consent | stable | "schema": 1, consent 2 |
horizon-graphics.txt, horizon-extras.txt, horizon-mods.txt |
preview | none |
SHA256SUMS and SHA256SUMS.sig |
stable |