horizon-native-mod
Skill1 starsChanged 17 days agoMITView on GitHub
Create, build, test, and package native mods for Horizon using horizon-mixins. Use when developing native Rust mods that hook into Horizon or horizon-mixins bundles.
The file
Show its rules and text
We split this skill into the rules it gives an agent
16 rules. About 0 are common, 5 are distinctive, and 11 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
11
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 29
No Heavy Builds in CI/Development: Never run full game compiles during normal iteration.
- Distinctive: line 30
License Integrity: Never fabricate copyright notices.
- Very specific: line 44
Must pin an exact 40-character commit from a permanent nightly-source/<date>-<short> tag.
- Distinctive: line 45
All native mods installed together in one game instance must pin the exact same commit.
- Distinctive: line 53
Start from the official horizon-native-mod-template:
- Very specific: line 55
Update Cargo.toml with your package name, version, and set [lib] path = "mixins/<mod_id>/runtime.rs".
- Very specific: line 64
Add "hooks": <N> only for a hook-point-only mod (see horizon-mods/native/zoom/compatibility.json).
- Very specific: line 71
Prefer Stable Hook Points: Check crates/horizon-client/src/game/native_hooks.rs for relevant hooks (native_frame, native_key, native_hud, …
- Very specific: line 84
Follow the runtime.rs standalone library pattern:
- Very specific: line 85
Gameplay Logic in
runtime.rs: Put all math, data structures, state machines, and unit tests in mixins/<mod_id>/runtime.rs. - Very specific: line 94
Thin Adapter Helpers: Keep injection helper files (.rs) minimal.
- Very specific: line 95
State & Settings Caching: Never call game.native_setting() every frame.
- Distinctive: line 123
When requested by the human user:
- Very specific: line 128
Verify: mod listing in Options > Mods, settings persistence, key rebinds, vanilla behavior invariance when disabled, and logs at …
- Distinctive: line 142
If porting an existing mod, confirm upstream license permits ports.
- Very specific: line 144
If adapting Horizon code, include Horizon contributors notice in LICENSE.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Developing Horizon Native Mods
Native mods for Horizon are source-level mixin bundles processed by horizon-mixins and compiled into the game.
This skill guides AI coding agents and human developers through designing, writing, testing, and packaging native mods.
Technical References
Detailed specifications and verified procedures:
- Stable Native Hook Points & Helpers:
native_hooks.rsAPI, lifecycle hooks, and compatibility strategies. - Manifest & Injection Reference:
horizon-mixin.tomlschema, AST injection kinds, and theruntime.rspattern. - Build, Test, and Resource Management: Staged testing pipelines, resource safety, and launcher build steps.
- Publishing to the Registry: Packaging
.hnmod, registry policies, minisign signing, and revocation. - Proven Pitfalls and Lessons Learned: Proven gotchas from real mod builds and hardware tests.
Critical Safety & Execution Rules
- Unsandboxed Native Code: Native mods compile directly into Horizon and execute with the player's full user permissions.
- Agent Build Prohibition: Coding agents must never execute
horizon-launcher native-build --trust-native-codeautonomously. Full game builds and native code trust require explicit human approval. - No Heavy Builds in CI/Development: Never run full game compiles during normal iteration. Use fast unit tests and
cargo checkon staged AST trees. - License Integrity: Never fabricate copyright notices. Always copy upstream licenses byte-for-byte and credit upstream authors.
Step-by-Step Modding Workflow
Step 1: Choose Your Compatibility Strategy
Decide whether your mod requires arbitrary source modification or can rely exclusively on stable hook points:
- Hook-Point Mod (
hooks = <N>):- Targets only methods in
crates/horizon-client/src/game/native_hooks.rs. - Portable across Horizon nightly releases. Built on any Horizon where
NATIVE_HOOKS_API >= mod.hooks. - Examples: Zoom, Keystrokes, Minimap, FPS Overlay.
- Targets only methods in
- Arbitrary Injection Mod (
horizon_revision = "<commit40>"):- Modifies arbitrary Horizon functions (e.g.
Game::pick,Game::camera_view). - Must pin an exact 40-character commit from a permanent
nightly-source/<date>-<short>tag. - All native mods installed together in one game instance must pin the exact same commit.
- Example: Shoulder Surfing (
6f8c7a0e5d531d3834c4d0be4659a1db8e7e5c2a).
- Modifies arbitrary Horizon functions (e.g.
Read references/hook-points.md for full details on compatibility.
Step 2: Initialize from the Template
Start from the official horizon-native-mod-template:
- Rename the bundle directory from
mixins/example-modtomixins/<mod_id>(follow the template README's rename steps). - Update
Cargo.tomlwith your package name, version, and set[lib] path = "mixins/<mod_id>/runtime.rs". - Configure
compatibility.jsonwith the exact revisions you build and test on (values below last verified 2026-10-29):
Add{ "game": "26.3", "horizon_revision": "6f8c7a0e5d531d3834c4d0be4659a1db8e7e5c2a", "horizon_mixins_revision": "0500ff24aa5933fca95a877ef41125353c4b4fe3" }"hooks": <N>only for a hook-point-only mod (seehorizon-mods/native/zoom/compatibility.json); a mod with arbitrary injection targets relies on the pinnedhorizon_revisioninstead. - Configure
mixins/<mod_id>/horizon-mixin.tomlmatching your mod ID and target revisions.
Step 3: Identify Integration Points & Injection Kinds
Inspect Horizon client source (crates/horizon-client/src/):
- Prefer Stable Hook Points: Check
crates/horizon-client/src/game/native_hooks.rsfor relevant hooks (native_frame,native_key,native_hud,native_wheel,native_mods). - Choose Least Invasive Injection Kind:
HEAD: Clean insertion at start of method. Use non-cancellable for events; usecancellable = truereturningcore::ops::ControlFlowonly when early return is required.RETURN: Inspect or post-process return values.BEFORE_CALL/AFTER_CALL: Target specific inner call operations.WRAP_OPERATION: Intercept and conditionally wrap inner calls.- Avoid
OVERWRITE: Overwriting entire function bodies conflicts with all other mixins.
Read references/mixins.md for AST injection syntax and bindings.
Step 4: Implement Runtime Logic & Thin Helpers
Follow the runtime.rs standalone library pattern:
- Gameplay Logic in
runtime.rs: Put all math, data structures, state machines, and unit tests inmixins/<mod_id>/runtime.rs. - Mount as Module: Expose the runtime inside Horizon via
[[module]]inhorizon-mixin.toml:[[module]] id = "runtime" file = "crates/horizon-client/src/game.rs" name = "<mod_id>_runtime" source = "runtime.rs" - Thin Adapter Helpers: Keep injection helper files (
.rs) minimal. Bind necessary variables from target scope and delegate immediately to runtime methods. - State & Settings Caching: Never call
game.native_setting()every frame. Store configuration inthread_local!or runtime state, loading once at start and updating on click events.
Read references/pitfalls.md to avoid common runtime traps.
Step 5: Verification Pipeline
Execute verification in stages without triggering full game compilation:
- Unit Testing:
cargo test --workspace -j 2 - AST Planning:
horizon-mixins plan --workspace <path/to/horizon> --mods <path/to/mod>/mixins --out target/plan.json - Source Staging:
horizon-mixins apply --workspace <path/to/horizon> --mods <path/to/mod>/mixins --out target/staged - Staged Cargo Check:
(Limit jobs tocd target/staged cargo check -j 2 -p horizon-client --features horizon-client/mods-j 2or-j 4to prevent system freezes). - In-Game Validation (User Supervised):
When requested by the human user:
For test iterations, tell the user to sethorizon-launcher native-build <path/to/bundle> --trust-native-codeCARGO_PROFILE_RELEASE_LTO=false,CARGO_PROFILE_RELEASE_CODEGEN_UNITS=16andCARGO_PROFILE_RELEASE_INCREMENTAL=truefirst (Horizon's own[profile.fast]values). The default release profile makes every rebuild slow. See references/build-and-test.md. Verify: mod listing in Options > Mods, settings persistence, key rebinds, vanilla behavior invariance when disabled, and logs at%APPDATA%/horizon/logs/latest.log.
Read references/build-and-test.md for hardware benchmarks and staging details.
Step 6: Package and Publish
- Package Deterministic
.hnmodArchive: The registry's packagerpython3 native/tools/native.py package <name>only packages Horizon's own mods kept underhorizon-mods/native/<name>/. For a mod in its own repository, produce a zip withhorizon-native.jsonplusmixins/<mod_id>/*.rs|*.tomlmatching the schema in references/publishing.md, then validate it (next step). - Validate with
cargo-horizon-mod:cargo horizon-mod check target/<mod_id>-<version>.hnmod - Audit License & Attribution:
- If porting an existing mod, confirm upstream license permits ports.
- Include upstream copyright and license notices verbatim in
LICENSE. - If adapting Horizon code, include Horizon contributors notice in
LICENSE.
- Submit Pull Request:
As of 2026-10-29 the web form at playhorizon.dev/mods/submit lists only
.hmod,.hpackand resource pack.zipfiles. The only community native mod in the registry (Veinminer, horizon-rust/horizon-mods PR #20) was added by a hand-made pull request withkind = "native-mod"inmods/<mod_id>.toml. Read that PR before opening yours. Sign releases with Minisign (minisign -Sm ...) if a key is registered.
Read references/publishing.md for registry guidelines and manifest schemas.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

