Compare commits

...
Author SHA1 Message Date
Ludovic MarieandCateDesu 889d793849 Add pixelmon 0.1.0
Submitted by @CateDesu through the form.

Co-authored-by: CateDesu <[email protected]>
2026-10-30 04:50:22 +01:00
levzzz 678eb2d1af Merge pull request #40 from SU4G3/classic-zoom-native
classic_zoom 2.0.0: a native mod
2026-10-29 23:59:32 +05:00
levzzz 55e203b1cd Merge pull request #31 from d3grando/lookat-native
LookAt 0.2.1: turn native
2026-10-29 23:59:24 +05:00
levzzz e9f14ea77f Merge pull request #41 from d3grando/mod-icons
Icons for TreeFall, SmartF3, Item New, BiomeCompass, Enchantment Hints, Mouse Tricks and Carry Block
2026-10-29 23:45:09 +05:00
d3grandoandClaude Opus 5.5 190d8f9a60 Icons for d3grando's native mods, served from this repository
The entries pointed at raw.githubusercontent.com, which playhorizon.dev's
img-src and the launcher don't load. The same 256x256 PNGs now live in
icons/, as coords_hud's does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-30 00:51:23 +07:00
SU4G3andClaude Opus 5.5 bbe01b52ad classic_zoom 2.0.0: a native mod
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 18:04:39 +03:00
Ludovic Marie 0d8411b352 Merge pull request #39 from horizon-rust/native-coords-hud
Coordinates HUD turns native (2.0.0), on the hook points
2026-10-29 14:32:02 +01:00
Ludovic MarieandClaude Opus 5.5 890d330600 Coordinates HUD: drop a stray Python cache file
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 14:08:25 +01:00
Ludovic MarieandClaude Opus 5.5 7fd746624a Coordinates HUD turns native (2.0.0), on the hook points
The WebAssembly SDK's example mod, ported to a horizon-mixins bundle in
native/coords-hud: the position and facing box in the top left, /where and
/coords, and a Shown setting that /coords now keeps. The time of day line is
gone: the hook points don't give the game's clock yet. Tested on Nightly
4baa571, alone and with the five other native mods; the proof drives the
built game.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 14:08:17 +01:00
Ludovic MarieandClaude Opus 5.5 7ce014f8a9 Recipes turns native (2.0.0), on hook points version 2 (#38)
Pinned to Nightly 4baa571, the first with horizon#3435's hook points v2.

Co-authored-by: Claude Opus 5.5 <[email protected]>
2026-10-29 13:26:55 +01:00
d3grandoandClaude Opus 5.5 f6dade0df2 LookAt 0.2.1: turn native
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-29 13:18:27 +07:00
37 changed files with 501 additions and 34 deletions

No files matched your search

+1 -1
View File
@@ -65,7 +65,7 @@ why.
| `.github/workflows/publish.yml` | On merge: releases, then `index.json` on Pages |
| `.github/workflows/cleanup.yml` | Weekly: staging files nobody needs any more |
| `.github/workflows/native.yml` | Horizon's native mods: each changed one's tests, `.hnmod` and game check, all of them together, and weekly on the newest Nightly |
| `native/<name>/` | Horizon's own native mods (Zoom, FPS Counter, Keystrokes, Minimap, Recipes): the source of their `.hnmod` files |
| `native/<name>/` | Horizon's own native mods (Zoom, FPS Counter, Keystrokes, Minimap, Recipes, Coordinates HUD): the source of their `.hnmod` files |
| `native/tools/` | Shared by them: apply on Horizon, check, build, package, prove (`native/tools/native.py`) |
| `scripts/` | What the workflows share |
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 975 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+1 -1
View File
@@ -16,7 +16,7 @@ authors = ["d3grando"]
owners = ["d3grando"]
license = "MIT"
source = "https://github.com/d3grando/biomecompass"
icon = "https://raw.githubusercontent.com/d3grando/biomecompass/main/icon.png"
icon = "icons/biomecompass.png"
[[versions]]
version = "0.2.2"
+1 -1
View File
@@ -17,7 +17,7 @@ authors = ["d3grando"]
owners = ["d3grando"]
license = "MIT"
source = "https://github.com/d3grando/carryblock"
icon = "https://raw.githubusercontent.com/d3grando/carryblock/main/icon.png"
icon = "icons/carryblock.png"
[[versions]]
version = "0.1.2"
+17 -2
View File
@@ -1,5 +1,5 @@
id = "classic_zoom"
kind = "mod"
kind = "native-mod"
name = "Classic Zoom"
summary = "Hold V to zoom 3x, scroll for more, release to snap back. Instant, no settings, inspired by WI Zoom."
description = """
@@ -32,14 +32,29 @@ Both can be installed at once: they use different keys.
- Written from scratch for Horizon's mod API. Not affiliated with Wurst-Imperium.
- Some servers forbid zoom mods: check the rules before you join.
**Now a native mod (2.0.0)**: the launcher builds it into the game (Settings → Game → Native mods (experimental), then Build). Native mods are not sandboxed and run with your account's permissions, so read the source before you build it: it is one small bundle on Horizon's native hook points (key, wheel, zoom, mods list). Tested against Horizon `6f8c7a0e5d531d3834c4d0be4659a1db8e7e5c2a` with Horizon Mixins `0d6b103c70633d8fd9443d8d0acd3aadaacedb06`. A key set in 1.0.0 carries over. 1.0.0 is the WebAssembly version.
Source and issues: [github.com/SU4G3/classic-zoom](https://github.com/SU4G3/classic-zoom)"""
authors = ["Surge"]
owners = ["SU4G3"]
license = "GPL-3.0-or-later"
source = "https://github.com/SU4G3/classic-zoom"
icon = "https://github.com/SU4G3/classic-zoom/blob/main/.github/icon.png?raw=true"
icon = "icons/classic_zoom.png"
key = "RWTOxMcIG6MtC0QQnhWEMC+nLKJ6+u4trV/rF+4juSRuow8W4b5P+CPS"
[[versions]]
version = "2.0.0"
published = "2026-10-29"
game = "26.3"
file = "classic_zoom-2.0.0.hnmod"
sha256 = "a8bdeba615ed31b9bd10280fcf8ba04a31935bc65fff429fc0e83d1c8090dac9"
signature = """
untrusted comment: signature from minisign secret key
RUTOxMcIG6MtCyXVhFrgrbWwg3pEBeR8iQ6g3w8MlWbzunH02kAF3swud3hq59EQvuoNpQxj7eTNRy6IJ4l+++7H1EazgGLV3AY=
trusted comment: timestamp:1793286240\tfile:classic_zoom-2.0.0.hnmod\thashed
bbYFmm0wap7Mgnt+wxSMkC/FqklbuAZage02x4Kt5Mi2mzknFbhWij/6sOx5ojRAquDT1XLRpRd2UrrAy4x4Bg=="""
changelog = "Now a native mod (WebAssembly code mods are going away). Same zoom: V by default, 3x, x1.1 per wheel step within 1x-10x, instant, slower turning while zoomed; a key set in 1.0.0 carries over. Pinned to Horizon 6f8c7a0 and Horizon Mixins 0d6b103."
[[versions]]
version = "1.0.0"
published = "2026-10-29"
+20 -7
View File
@@ -1,22 +1,35 @@
id = "coords_hud"
kind = "mod"
kind = "native-mod"
name = "Coordinates HUD"
summary = "Your coordinates, facing and the time of day in a corner of the screen."
summary = "Your coordinates and facing in a corner of the screen."
description = """
The SDK's example mod. It draws your block position, the direction you face and the time of day
in the top-left corner, every frame.
Your block position and the direction you face in the top-left corner of the screen.
- `/where` puts your coordinates and dimension in chat.
- `/coords` hides or shows the panel.
- `/coords` hides or shows the box, and the game keeps your choice (also Options > Mods > Coordinates HUD > Settings).
It reads the game (position, health, time), draws on the HUD and writes to chat: nothing else.
It reads the player's position, draws on the HUD and writes to chat: nothing else.
Now a native mod (2.0.0): built into the game by the launcher, on the Horizon you play, like any native mod
(Settings → Game → Native mods (experimental), then Build). It was the WebAssembly SDK's example mod; the time of
day line is gone, since Horizon's hook points don't give the game's clock yet. Turn it off in Options > Mods: it
rests at once, and the next build leaves it out. Its source is
[horizon-mods/native/coords-hud](https://github.com/horizon-rust/horizon-mods/tree/main/native/coords-hud).
"""
authors = ["Horizon"]
owners = ["ludovic111"]
license = "MIT"
source = "https://github.com/horizon-rust/horizon/tree/main/crates/horizon-mod-sdk/examples/coords-hud"
source = "https://github.com/horizon-rust/horizon-mods/tree/main/native/coords-hud"
icon = "icons/coords_hud.png"
[[versions]]
version = "2.0.0"
published = "2026-10-29"
game = "26.3"
file = "coords_hud-2.0.0.hnmod"
sha256 = "432376fad3062b3517e274d3b8c0d0b52fc5d6de2aee20a0b340c8cab5a8cf08"
changelog = "Native: built into the game by the launcher on Horizon's native hook points; /coords is kept; turn it off in Options > Mods. The time of day line is gone for now."
[[versions]]
version = "0.1.0"
published = "2026-10-24"
+1 -1
View File
@@ -15,7 +15,7 @@ authors = ["d3grando"]
owners = ["d3grando"]
license = "MIT"
source = "https://github.com/d3grando/enchantmenthints"
icon = "https://raw.githubusercontent.com/d3grando/enchantmenthints/main/icon.png"
icon = "icons/enchantmenthints.png"
[[versions]]
version = "0.1.0"
+1 -1
View File
@@ -15,7 +15,7 @@ authors = ["d3grando"]
owners = ["d3grando"]
license = "MIT"
source = "https://github.com/d3grando/itemnew"
icon = "https://raw.githubusercontent.com/d3grando/itemnew/main/icon.png"
icon = "icons/itemnew.png"
[[versions]]
version = "0.1.1"
+17 -13
View File
@@ -1,26 +1,30 @@
id = "lookat"
kind = "mod"
kind = "native-mod"
name = "LookAt"
summary = "The block under your crosshair as a vanilla tooltip: its icon, its name in your language and where it comes from. Reach up to 1024 blocks"
summary = "The block or mob under your crosshair as a vanilla tooltip: icon, name in your language, health, the tool it needs and where it comes from"
description = """
The block under your crosshair at the top of the screen, drawn as a vanilla tooltip: its item's icon, its name in your language and the namespace it comes from.
The block or entity under your crosshair at the top of the screen, drawn as a vanilla tooltip: its item's icon, its name in your language and the namespace it comes from.
**Settings** (Options → Mods → LookAt):
- **Blocks**: up to 1024 blocks away, across distant terrain.
- **Mobs and players**: name and health as hearts or numbers; boats, minecarts, armor stands, paintings and item frames (with what they hold).
- **Harvest tool**: ✔ or ✘ with the tool a block needs.
- **Range**: Reach (5 blocks), 16, 64 or 1024 blocks, across distant terrain
- **Position**: Top, Top left, Top right
- **Background opacity**: 100%, 75%, 50%, 25%
- **Item icon**, **Where it comes from**: on or off
- **Position and distance**: the block's coordinates and how far it is
**Settings** (Options → Mods → LookAt): range, position (top, top left, top right), size, background opacity, item icon, where it comes from, position and distance, entities, health, harvest tool. Boxes keep clear of F3, boss bars, the minimap and effect icons.
To make the box bigger, raise the game's GUI Scale.
**Blocks only for now**: the mod API can't see entities yet, so mobs show nothing."""
**Now a native mod (0.2.1)**: the launcher builds it into the game (Settings → Game → Native mods (experimental), then Build). Native mods are not sandboxed and run with your account's permissions, so read the source before you build it. Tested against Horizon `142388e1c136e622652ec7505af15d8ad195e041` with Horizon Mixins `0d6b103c70633d8fd9443d8d0acd3aadaacedb06`; the launcher builds these exact pinned revisions. Settings from 0.1.0 carry over. 0.1.0 is the WebAssembly version."""
authors = ["d3grando"]
owners = ["d3grando"]
license = "MIT"
source = "https://github.com/d3grando/lookat"
icon = "https://raw.githubusercontent.com/d3grando/lookat/main/icon.png"
icon = "icons/lookat.png"
[[versions]]
version = "0.2.1"
published = "2026-10-29"
game = "26.3"
file = "lookat-0.2.1.hnmod"
sha256 = "6c15726116825b5955984223d0e1bccd5d18375005af243a061b2ba2b9139f33"
changelog = "Now a native mod (WebAssembly code mods are going away). New: mobs, players and other entities under the crosshair with their health, the harvest tool a block needs, a size setting, and boxes that keep clear of F3, boss bars, the minimap and effect icons. Pinned to Horizon 142388e and Horizon Mixins 0d6b103."
[[versions]]
version = "0.1.0"
+1 -1
View File
@@ -15,7 +15,7 @@ authors = ["d3grando"]
owners = ["d3grando"]
license = "MIT"
source = "https://github.com/d3grando/mousetricks"
icon = "https://raw.githubusercontent.com/d3grando/mousetricks/main/icon.png"
icon = "icons/mousetricks.png"
[[versions]]
version = "0.2.0"
+28
View File
@@ -0,0 +1,28 @@
id = "pixelmon"
kind = "native-mod"
name = "Pixelmon"
summary = "An early Pixelmon 9.4.2 port for Horizon with command-based catching, battles, party and PC storage."
description = """
A rough, experimental Pixelmon 9.4.2 port for Horizon, targeting Minecraft 26.3.
This early version includes:
- Starter selection, manual wild spawning, catching and battles
- Party and PC storage
- Virtual supplies and world save/reload
Controls currently use `/pokemon` commands in integrated worlds. Models are rough and currently limited to Bulbasaur, Charmander, Squirtle and Pikachu.
Menus, natural spawning, physical item interactions and dedicated multiplayer remain unfinished. This is an early playable prototype with bugs and missing features. I’ll continue working on it."""
authors = ["CateDesu"]
owners = ["CateDesu"]
license = "All Rights Reserved"
source = "https://github.com/CateDesu/pixelmon-horizon-port"
[[versions]]
version = "0.1.0"
published = "2026-10-30"
game = "26.3"
file = "pixelmon-0.1.0.hnmod"
sha256 = "95d3df997632990f0ecce3b4f58c7b1523ec67fae6e2b2922b9bc587c7ac68f0"
changelog = "Initial commit"
+16 -2
View File
@@ -1,5 +1,5 @@
id = "recipes"
kind = "mod"
kind = "native-mod"
name = "Recipes"
summary = "Every item beside your inventory, with its recipes and uses."
description = """
@@ -13,11 +13,25 @@ Horizon's own recipe viewer.
- On servers that are not Horizon, it shows this game's own 26.3 recipes. Which recipes you know, and what + can fill, follow the server's recipe book.
It reads the game's items and recipes, hears its own keys and your clicks on the panel, and places recipes or gives items only when you ask: nothing else.
Now a native mod (2.0.0): built into the game by the launcher, on the Horizon you play, like any native mod
(Settings → Game → Native mods (experimental), then Build). It needs Horizon's native hook points version 2, in the
Nightlies from 4baa571 on. Your settings and keys carry over from 1.0.0. Turn it off in Options > Mods: it rests at
once, and the next build leaves it out. Its source is
[horizon-mods/native/recipes](https://github.com/horizon-rust/horizon-mods/tree/main/native/recipes).
"""
authors = ["Horizon"]
owners = ["ludovic111"]
license = "MIT"
source = "https://github.com/horizon-rust/horizon/tree/main/mods/official/recipes"
source = "https://github.com/horizon-rust/horizon-mods/tree/main/native/recipes"
[[versions]]
version = "2.0.0"
published = "2026-10-29"
game = "26.3"
file = "recipes-2.0.0.hnmod"
sha256 = "51fddf300709404170061355afdf0b407f28eb928bcc0a9133c241cd63f4a0ed"
changelog = "Native: built into the game by the launcher on Horizon's native hook points (version 2); settings and keys carry over; turn it off in Options > Mods."
[[versions]]
version = "1.0.0"
+1 -1
View File
@@ -16,7 +16,7 @@ authors = ["d3grando"]
owners = ["d3grando"]
license = "MIT"
source = "https://github.com/d3grando/smartf3"
icon = "https://raw.githubusercontent.com/d3grando/smartf3/main/icon.png"
icon = "icons/smartf3.png"
[[versions]]
version = "0.1.0"
+1 -1
View File
@@ -16,7 +16,7 @@ authors = ["d3grando"]
owners = ["d3grando"]
license = "MIT"
source = "https://github.com/d3grando/treefall"
icon = "https://raw.githubusercontent.com/d3grando/treefall/main/icon.png"
icon = "icons/treefall.png"
[[versions]]
version = "0.3.0"
+7
View File
@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "horizon-mod-coords-hud"
version = "2.0.0"
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "horizon-mod-coords-hud"
version = "2.0.0"
edition = "2024"
license = "MIT"
publish = false
description = "Horizon's Coordinates HUD, a native mod: your position and facing in a corner of the screen."
# The mod's logic and its tests: the same file the bundle adds to the game.
[lib]
path = "mixins/coords_hud/runtime.rs"
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Ludovic Marie and the Horizon contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+46
View File
@@ -0,0 +1,46 @@
# Coordinates HUD (Horizon native mod)
Your block position and the direction you face in a box in the top-left corner of the screen.
- `/where` puts your coordinates and dimension in chat.
- `/coords` hides or shows the box, and the game keeps your choice (also Options > Mods > Coordinates HUD > Settings).
It is a [horizon-mixins](https://github.com/horizon-rust/horizon-mixins) bundle (`mixins/coords_hud/`) that the Horizon
launcher builds into the game. It replaces the WebAssembly Coordinates HUD 0.1.0, the WebAssembly SDK's example mod.
The time of day line is gone: Horizon's hook points don't give the game's clock yet.
## Install
In the Horizon launcher: Mods → Coordinates HUD → Install, then Settings → Game → Native mods (experimental) → Build. The
launcher downloads its own Rust and builds the game with your native mods; see Horizon's
[native mods](https://github.com/horizon-rust/horizon/blob/main/docs/native-mods.md).
## Made on the hook points
The bundle hooks only Horizon's native hook points (`crates/horizon-client/src/game/native_hooks.rs`), which keep
their names and signatures across releases. `compatibility.json` names the version it needs (`"hooks": 1`), so the
launcher builds it on any Horizon with that version or a later one, together with any other mod. `horizon_revision` is
only the commit it was last tested on.
| File | What it is |
|---|---|
| `mixins/coords_hud/horizon-mixin.toml` | The bundle: one module and the HEAD hooks |
| `mixins/coords_hud/runtime.rs` | The mod's logic and state, added to the game as `game::official_coords_hud`; also this crate's library, for its tests |
| `mixins/coords_hud/*.rs` | One small helper per hook |
| `proof.py` (with `../tools/game.py`) | The proof: the built game driven with `horizon-ctl --offscreen` on fresh, temporary data |
## Build and prove
```sh
(cd native/coords-hud && cargo test) # the logic
python3 native/tools/native.py check coords-hud # apply on the tested Horizon and cargo check the game
python3 native/tools/native.py check all # with the other native mods, as a player's set
python3 native/tools/native.py package coords-hud # native/target/coords_hud-<version>.hnmod for the registry
python3 native/tools/native.py proof coords-hud --resources /path/to/.local/horizon-client/26.3
```
The proof needs resources prepared from your own Minecraft 26.3 (`horizon-prepare`); none are in this repository.
It checks the row and the settings page in Options > Mods, that the box shows in the top left, that `/coords` hides it
and writes `horizon-mods/.horizon-mod-data/coords_hud/shown`, and takes a screenshot of `/where`'s line in chat.
License: MIT.
+8
View File
@@ -0,0 +1,8 @@
{
"game": "26.3",
"hooks": 1,
"horizon_repository": "https://github.com/horizon-rust/horizon",
"horizon_revision": "4baa571566e39bfd6594988d3bb2bc85440c30e7",
"horizon_mixins_repository": "https://github.com/horizon-rust/horizon-mixins",
"horizon_mixins_revision": "0d6b103c70633d8fd9443d8d0acd3aadaacedb06"
}
@@ -0,0 +1,10 @@
// A click on the mod's settings page: show or hide the box, and keep it.
fn official_coords_hud_click(game: &mut crate::game::Game<'_>, mod_id: &str, button: usize) {
use crate::game::official_coords_hud as m;
if mod_id != m::ID || button != 0 {
return;
}
let shown = !m::shown(|| game.native_setting(m::ID, "shown"));
m::set_shown(shown);
game.native_set_setting(m::ID, "shown", if shown { "true" } else { "false" });
}
@@ -0,0 +1,20 @@
// /where puts the position in chat; /coords hides or shows the box.
fn coords_hud_command(game: &mut crate::game::Game<'_>, command: &str, ran: &mut bool) {
use crate::game::official_coords_hud as m;
let name = command.split(' ').next().unwrap_or("");
if !game.native_on(m::ID) || !matches!(name, "where" | "coords") {
return;
}
*ran = true;
if name == "coords" {
let shown = !m::shown(|| game.native_setting(m::ID, "shown"));
m::set_shown(shown);
game.native_set_setting(m::ID, "shown", if shown { "true" } else { "false" });
game.native_chat(if shown { "Coordinates panel shown" } else { "Coordinates panel hidden" });
return;
}
match game.native_player() {
Some(p) => game.native_chat(&m::where_line(p.x, p.y, p.z, p.dimension)),
None => game.native_chat("Not in a world"),
}
}
@@ -0,0 +1,68 @@
[mod]
id = "coords_hud"
version = "2.0.0"
priority = 100
# The commit it was tested on. It uses only the native hook points (hooks 1 in
# compatibility.json): the launcher builds it on any Horizon that has them.
[compatibility]
horizon_revision = "4baa571566e39bfd6594988d3bb2bc85440c30e7"
[[module]]
id = "runtime"
file = "crates/horizon-client/src/game.rs"
name = "official_coords_hud"
source = "runtime.rs"
[[injection]]
id = "hud"
kind = "HEAD"
target = "horizon_client::game::native_hooks::Game<'_>::native_hud"
helper = "hud.rs"
bindings = [
{ name = "game", ty = "&mut crate::game::Game<'_>", value = "&mut *self" },
{ name = "batch", ty = "&mut horizon_client::hud::HudBatch", value = "&mut *batch" },
{ name = "corners", ty = "&mut horizon_client::extras_hud::Corners", value = "&mut *corners" },
]
[[injection]]
id = "command"
kind = "HEAD"
target = "horizon_client::game::native_hooks::Game<'_>::native_command"
helper = "command.rs"
bindings = [
{ name = "game", ty = "&mut crate::game::Game<'_>", value = "&mut *self" },
{ name = "command", ty = "&str", value = "command" },
{ name = "ran", ty = "&mut bool", value = "&mut *ran" },
]
[[injection]]
id = "list"
kind = "HEAD"
target = "horizon_client::game::native_hooks::Game<'_>::native_mods"
helper = "list.rs"
bindings = [
{ name = "mods", ty = "&mut Vec<crate::game::native_hooks::NativeMod>", value = "&mut *mods" },
]
[[injection]]
id = "settings"
kind = "HEAD"
target = "horizon_client::game::native_hooks::Game<'_>::native_settings"
helper = "settings.rs"
bindings = [
{ name = "game", ty = "&mut crate::game::Game<'_>", value = "&mut *self" },
{ name = "mod_id", ty = "&str", value = "mod_id" },
{ name = "buttons", ty = "&mut Vec<String>", value = "&mut *buttons" },
]
[[injection]]
id = "click"
kind = "HEAD"
target = "horizon_client::game::native_hooks::Game<'_>::native_settings_click"
helper = "click.rs"
bindings = [
{ name = "game", ty = "&mut crate::game::Game<'_>", value = "&mut *self" },
{ name = "mod_id", ty = "&str", value = "mod_id" },
{ name = "button", ty = "usize", value = "button" },
]
@@ -0,0 +1,28 @@
// The box in the top-left corner, drawn as the WebAssembly mods' panels were;
// the debug screen takes that corner.
fn coords_hud(
game: &mut crate::game::Game<'_>,
batch: &mut horizon_client::hud::HudBatch,
corners: &mut horizon_client::extras_hud::Corners,
) {
use crate::game::official_coords_hud as m;
use horizon_client::extras::Corner;
// Turned off in Options > Mods: nothing until the next build leaves it out.
if !game.native_on(m::ID) || !game.native_corner_shown(Corner::TopLeft) {
return;
}
if !m::shown(|| game.native_setting(m::ID, "shown")) {
return;
}
let Some(p) = game.native_player() else {
return;
};
let lines = m::lines(p.x, p.y, p.z, p.yaw);
let w = lines.iter().map(|l| game.native_text_width(l)).fold(0.0, f32::max) + 4.0;
let h = 10.0 * lines.len() as f32 + 2.0;
let (x, y) = corners.place(Corner::TopLeft, w, h);
game.native_fill(batch, [x, y, w, h], m::BACKGROUND);
for (i, line) in lines.iter().enumerate() {
game.native_text(batch, line, [x + 2.0, y + 2.0 + 10.0 * i as f32], m::INK, true);
}
}
@@ -0,0 +1,10 @@
// The mod's row in Options > Mods.
fn official_coords_hud_listed(mods: &mut Vec<crate::game::native_hooks::NativeMod>) {
use crate::game::official_coords_hud as m;
mods.push(crate::game::native_hooks::NativeMod {
id: m::ID.into(),
title: format!("{} {}", m::NAME, m::VERSION),
description: m::DESCRIPTION.into(),
keys: Vec::new(),
});
}
@@ -0,0 +1,100 @@
// Horizon's Coordinates HUD, formerly the WebAssembly SDK's example mod: the
// block position and the direction the player faces in a box in the top-left
// corner, `/where` to put the position in chat and `/coords` to hide or show
// the box. This file is both the mod's Cargo library (its tests) and the
// module the bundle adds to the game.
/// The mod's id (its settings folder), name and version.
pub const ID: &str = "coords_hud";
pub const NAME: &str = "Coordinates HUD";
pub const VERSION: &str = "2.0.0";
pub const DESCRIPTION: &str = "Your coordinates and facing in a corner of the screen. /where puts them in chat, /coords hides or shows the box.";
/// The WebAssembly mods' panel: translucent black, white text with a shadow.
pub const BACKGROUND: u32 = 0x7800_0000;
pub const INK: u32 = 0xFF_FFFF;
/// Direction.fromYRot: yaw 0 faces south, 90 west.
pub fn facing(yaw: f32) -> &'static str {
let i = (yaw / 90.0 + 0.5).floor() as i32 & 3;
["South (+Z)", "West (-X)", "North (-Z)", "East (+X)"][i as usize]
}
/// The box's lines, as the WebAssembly mod wrote them.
pub fn lines(x: f64, y: f64, z: f64, yaw: f32) -> [String; 2] {
[
format!("XYZ {x:.1} / {y:.1} / {z:.1}"),
format!("Facing {}", facing(yaw)),
]
}
/// `/where`'s line: `12, 70, -4 in minecraft:the_nether`.
pub fn where_line(x: f64, y: f64, z: f64, dimension: &str) -> String {
format!(
"{:.0}, {:.0}, {:.0} in {dimension}",
x.floor(),
y.floor(),
z.floor()
)
}
/// The stored `shown` value: shown unless it says `false`.
pub fn read_shown(stored: Option<String>) -> bool {
stored.is_none_or(|v| v.trim() != "false")
}
pub fn shown_label(shown: bool) -> String {
format!("Shown: {}", if shown { "ON" } else { "OFF" })
}
thread_local! {
/// Whether the box shows, read once from its file, then kept.
static SHOWN: std::cell::Cell<Option<bool>> = const { std::cell::Cell::new(None) };
}
/// Whether the box shows, read once through `get` (the `shown` file).
pub fn shown(get: impl FnOnce() -> Option<String>) -> bool {
SHOWN.with(|s| {
let found = s.get().unwrap_or_else(|| read_shown(get()));
s.set(Some(found));
found
})
}
/// Replaces it (`/coords` or the settings page changed it).
pub fn set_shown(shown: bool) {
SHOWN.with(|s| s.set(Some(shown)));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn facing_follows_vanilla_yaw() {
assert_eq!(facing(0.0), "South (+Z)");
assert_eq!(facing(90.0), "West (-X)");
assert_eq!(facing(-180.0), "North (-Z)");
assert_eq!(facing(-90.0), "East (+X)");
assert_eq!(facing(314.0), "East (+X)");
}
#[test]
fn lines_read_as_the_webassembly_mods() {
assert_eq!(
lines(12.5, 64.0, -3.25, 180.0),
["XYZ 12.5 / 64.0 / -3.2", "Facing North (-Z)"]
);
assert_eq!(
where_line(12.5, 70.2, -3.25, "minecraft:the_nether"),
"12, 70, -4 in minecraft:the_nether"
);
}
#[test]
fn shown_unless_stored_false() {
assert!(read_shown(None));
assert!(read_shown(Some("true".into())));
assert!(!read_shown(Some("false\n".into())));
assert_eq!(shown_label(false), "Shown: OFF");
}
}
@@ -0,0 +1,8 @@
// The mod's settings page: one button, the box shown or hidden.
fn official_coords_hud_page(game: &mut crate::game::Game<'_>, mod_id: &str, buttons: &mut Vec<String>) {
use crate::game::official_coords_hud as m;
if mod_id != m::ID {
return;
}
buttons.push(m::shown_label(m::shown(|| game.native_setting(m::ID, "shown"))));
}
+56
View File
@@ -0,0 +1,56 @@
"""Coordinates HUD in a running modded game: its row and settings page in Options > Mods, the box in the top
left, /coords hiding and showing it (and keeping that), and /where's line in chat (screenshots)."""
import json
import time
from game import Game, difference
DATA = "horizon-mods/.horizon-mod-data/coords_hud"
TOP_LEFT, CHAT = (0.0, 0.0, 0.25, 0.1), (0.0, 0.7, 0.5, 0.95)
def typed(g, line):
"""As the player types it: T opens the chat box, then the line and Enter."""
g.run("key", "t", "tap")
time.sleep(0.5)
g.run("type", line)
g.run("key", "enter", "tap")
time.sleep(1)
def run(ctl, resources, out):
with Game(ctl, resources, out) as g:
g.run("options", "mods")
assert "Coordinates HUD 2.0.0: ON" in g.labels(), g.labels()
g.run("click", g.ids()["Settings"])
page = g.labels()
assert "Shown: ON" in page, page
g.run("click", g.ids()["Shown: ON"])
clicked = (g.home / DATA / "shown").read_text()
g.run("click", g.ids()["Shown: OFF"])
g.play()
g.run("command", "tp @s ~ ~ ~ 0 10")
time.sleep(2)
shown = g.shot("1-shown")
typed(g, "/coords")
hidden_file = (g.home / DATA / "shown").read_text()
time.sleep(4)
hidden = g.shot("2-hidden")
typed(g, "/coords")
typed(g, "/where")
where = g.shot("3-where")
results = {
"page": page,
"shown_file_after_click": clicked,
"shown_file_after_coords": hidden_file,
"shown_file_at_end": (g.home / DATA / "shown").read_text(),
"diff_top_left_hidden": round(difference(shown, hidden, TOP_LEFT), 1),
"diff_top_left_shown_again": round(difference(shown, where, TOP_LEFT), 1),
"diff_chat_where": round(difference(hidden, where, CHAT), 1),
}
print(json.dumps(results, indent=2))
assert clicked == "false" and hidden_file == "false", results
assert results["shown_file_at_end"] == "true", results
assert results["diff_top_left_hidden"] > 4, results
assert results["diff_top_left_shown_again"] < results["diff_top_left_hidden"], results
# native_chat lines are the client's; chat-log reads the server's chat here: see 3-where.png.
print(json.dumps({"proof": "coords_hud", "ok": True, **results}, indent=2))
+1 -1
View File
@@ -2,7 +2,7 @@
"game": "26.3",
"hooks": 2,
"horizon_repository": "https://github.com/horizon-rust/horizon",
"horizon_revision": "8f91683323ac1165e7d76b3037e18f30fe647205",
"horizon_revision": "4baa571566e39bfd6594988d3bb2bc85440c30e7",
"horizon_mixins_repository": "https://github.com/horizon-rust/horizon-mixins",
"horizon_mixins_revision": "0d6b103c70633d8fd9443d8d0acd3aadaacedb06"
}
@@ -6,7 +6,7 @@ priority = 100
# The commit it was tested on. It uses only the native hook points (hooks 2 in
# compatibility.json): the launcher builds it on any Horizon that has them.
[compatibility]
horizon_revision = "8f91683323ac1165e7d76b3037e18f30fe647205"
horizon_revision = "4baa571566e39bfd6594988d3bb2bc85440c30e7"
[[module]]
id = "runtime"