agentleFS
DarkTamaDarkTama/horizon-mod-skills/skills/horizon-native-mod/SKILL.md

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
  1. Very specific:

    No Heavy Builds in CI/Development: Never run full game compiles during normal iteration.

    line 29
  2. Distinctive:

    License Integrity: Never fabricate copyright notices.

    line 30
  3. Very specific:

    Must pin an exact 40-character commit from a permanent nightly-source/<date>-<short> tag.

    line 44
  4. Distinctive:

    All native mods installed together in one game instance must pin the exact same commit.

    line 45
  5. Distinctive:

    Start from the official horizon-native-mod-template:

    line 53
  6. Very specific:

    Update Cargo.toml with your package name, version, and set [lib] path = "mixins/<mod_id>/runtime.rs".

    line 55
  7. Very specific:

    Add "hooks": <N> only for a hook-point-only mod (see horizon-mods/native/zoom/compatibility.json).

    line 64
  8. Very specific:

    Prefer Stable Hook Points: Check crates/horizon-client/src/game/native_hooks.rs for relevant hooks (native_frame, native_key, native_hud, …

    line 71
  9. Very specific:

    Follow the runtime.rs standalone library pattern:

    line 84
  10. Very specific:

    Gameplay Logic in runtime.rs: Put all math, data structures, state machines, and unit tests in mixins/<mod_id>/runtime.rs.

    line 85
  11. Very specific:

    Thin Adapter Helpers: Keep injection helper files (.rs) minimal.

    line 94
  12. Very specific:

    State & Settings Caching: Never call game.native_setting() every frame.

    line 95
  13. Distinctive:

    When requested by the human user:

    line 123
  14. Very specific:

    Verify: mod listing in Options > Mods, settings persistence, key rebinds, vanilla behavior invariance when disabled, and logs at …

    line 128
  15. Distinctive:

    If porting an existing mod, confirm upstream license permits ports.

    line 142
  16. Very specific:

    If adapting Horizon code, include Horizon contributors notice in LICENSE.

    line 144

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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.rs API, lifecycle hooks, and compatibility strategies.
  • Manifest & Injection Reference: horizon-mixin.toml schema, AST injection kinds, and the runtime.rs pattern.
  • 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

  1. Unsandboxed Native Code: Native mods compile directly into Horizon and execute with the player's full user permissions.
  2. Agent Build Prohibition: Coding agents must never execute horizon-launcher native-build --trust-native-code autonomously. Full game builds and native code trust require explicit human approval.
  3. No Heavy Builds in CI/Development: Never run full game compiles during normal iteration. Use fast unit tests and cargo check on staged AST trees.
  4. 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.
  • 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).

Read references/hook-points.md for full details on compatibility.


Step 2: Initialize from the Template

Start from the official horizon-native-mod-template:

  1. Rename the bundle directory from mixins/example-mod to mixins/<mod_id> (follow the template README's rename steps).
  2. Update Cargo.toml with your package name, version, and set [lib] path = "mixins/<mod_id>/runtime.rs".
  3. Configure compatibility.json with the exact revisions you build and test on (values below last verified 2026-10-29):
    {
      "game": "26.3",
      "horizon_revision": "6f8c7a0e5d531d3834c4d0be4659a1db8e7e5c2a",
      "horizon_mixins_revision": "0500ff24aa5933fca95a877ef41125353c4b4fe3"
    }
    Add "hooks": <N> only for a hook-point-only mod (see horizon-mods/native/zoom/compatibility.json); a mod with arbitrary injection targets relies on the pinned horizon_revision instead.
  4. Configure mixins/<mod_id>/horizon-mixin.toml matching your mod ID and target revisions.

Step 3: Identify Integration Points & Injection Kinds

Inspect Horizon client source (crates/horizon-client/src/):

  1. Prefer Stable Hook Points: Check crates/horizon-client/src/game/native_hooks.rs for relevant hooks (native_frame, native_key, native_hud, native_wheel, native_mods).
  2. Choose Least Invasive Injection Kind:
    • HEAD: Clean insertion at start of method. Use non-cancellable for events; use cancellable = true returning core::ops::ControlFlow only 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:

  1. Gameplay Logic in runtime.rs: Put all math, data structures, state machines, and unit tests in mixins/<mod_id>/runtime.rs.
  2. Mount as Module: Expose the runtime inside Horizon via [[module]] in horizon-mixin.toml:
    [[module]]
    id = "runtime"
    file = "crates/horizon-client/src/game.rs"
    name = "<mod_id>_runtime"
    source = "runtime.rs"
  3. Thin Adapter Helpers: Keep injection helper files (.rs) minimal. Bind necessary variables from target scope and delegate immediately to runtime methods.
  4. State & Settings Caching: Never call game.native_setting() every frame. Store configuration in thread_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:

  1. Unit Testing:
    cargo test --workspace -j 2
  2. AST Planning:
    horizon-mixins plan --workspace <path/to/horizon> --mods <path/to/mod>/mixins --out target/plan.json
  3. Source Staging:
    horizon-mixins apply --workspace <path/to/horizon> --mods <path/to/mod>/mixins --out target/staged
  4. Staged Cargo Check:
    cd target/staged
    cargo check -j 2 -p horizon-client --features horizon-client/mods
    (Limit jobs to -j 2 or -j 4 to prevent system freezes).
  5. In-Game Validation (User Supervised): When requested by the human user:
    horizon-launcher native-build <path/to/bundle> --trust-native-code
    For test iterations, tell the user to set CARGO_PROFILE_RELEASE_LTO=false, CARGO_PROFILE_RELEASE_CODEGEN_UNITS=16 and CARGO_PROFILE_RELEASE_INCREMENTAL=true first (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

  1. Package Deterministic .hnmod Archive: The registry's packager python3 native/tools/native.py package <name> only packages Horizon's own mods kept under horizon-mods/native/<name>/. For a mod in its own repository, produce a zip with horizon-native.json plus mixins/<mod_id>/*.rs|*.toml matching the schema in references/publishing.md, then validate it (next step).
  2. Validate with cargo-horizon-mod:
    cargo horizon-mod check target/<mod_id>-<version>.hnmod
  3. 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.
  4. Submit Pull Request: As of 2026-10-29 the web form at playhorizon.dev/mods/submit lists only .hmod, .hpack and resource pack .zip files. The only community native mod in the registry (Veinminer, horizon-rust/horizon-mods PR #20) was added by a hand-made pull request with kind = "native-mod" in mods/<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.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.