Compare commits

...
30 Commits
Author SHA1 Message Date
Ludovic MarieandClaude Opus 5.5 d9351ec054 Menus: Horizon-style options screen, pause polish, screenshots
Options open as the launcher's Settings page: a sidebar with the sliding
selection (Video, Audio, Controls, Accessibility, Language, Chat, Interface)
and rows with a switch, slider or value button per option
(options_horizon.rs; new sections or rows slot into SECTIONS). Key binds,
the language list and resource packs open vanilla's pages. Interface holds
Menu style (Horizon / Classic). The pause menu hides the in-game HUD over the
blurred world. Scripted and frame-limited runs default to Classic, so the
harnesses see vanilla's screens.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 15:33:15 +02:00
Ludovic MarieandClaude Opus 5.5 eb18bb42af Menus: Horizon style for the title, worlds, create, multiplayer and pause screens
One theme for the launcher and the game: crates/horizon-theme holds the
palette, type scale, spacing, radii, control sizes, motion and the bundled
fonts; launcher/src/theme.rs and the game's ui_theme both read it. ui_theme
ports the launcher's components (button with hover layer and press state,
sidebar list with the sliding selection, segmented control, switch, rows)
and draws Geist and Instrument Serif through the HUD atlas.

The title is laid out like the launcher (sidebar, page header, rows) over a
live backdrop: Horizon generates an ice-spikes landscape for a fixed seed,
orbits a camera over it with falling snow, then blurs and cold-grades the
frame (post.rs). The launcher's opening (wordmark, then the interface) plays
once per session and a click or key skips it. Menu style Horizon / Classic
lives in horizon.txt, never options.txt; Classic keeps vanilla's drawing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 15:19:14 +02:00
Ludovic MarieandClaude Opus 5.5 27a32cc30d README: parity is what the harnesses check, until the final audit
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 14:17:34 +02:00
Ludovic MarieandClaude Opus 5.5 8cdec2c8d9 Tidy the repository now that parity is reached: launcher-first README, docs index, research leftovers removed
Removed (each unreferenced by code, workflows, tests or living docs; no harness
dependency record names any of them, and parity.py --list still finds all 281):
- 22 one-off write-ups of the Java-pack experiments in docs/: adaptive-terrain,
  client-graphics-smoke, compact-headers, core-performance, culling-empty,
  culling-rays, debounce-queue, dispatch-retry, foreground-first,
  graphics-api-comparison, heap-budget, mac-first-test, optimization-plan,
  playable-validation, quad-reuse, server-graphics-context, shader-world-smoke,
  terrain-measurements, terrain-position, terrain-read-wait, tick-membership,
  worker-pacing. Their findings are folded into one paragraph of java-packs.md.
- 24 benchmarks/ observation dumps only those write-ups linked (client graphics,
  culling, queues, heap, Mac Vulkan, shader worlds, software identity, and the
  unlinked rust-core, rust-worldgen-2026-10-05, rust-native-client and
  rust-cuboid-model-decoding runs), plus 12 unlinked files inside kept
  report folders. The scoped-parity reports the living docs cite stay.
- debug/: one server log from a chunk investigation.
- The manual macos-shader-research and macos-vulkan-research workflows.
- tools/logs/latest.log, an empty log committed by accident (now ignored).

Kept: research-lock.json (parity.py, packaging, the launcher and datafix read
it), the Java-pack how-tos (vulkan, collectors, profiling, process-memory,
tick-state) and tools/test_client_graphics.py (ci.yml runs it).

README: leads with what Horizon is and "Download the launcher" (the
launcher-v* releases; the launcher updates itself), then build from source
for developers. Direct game downloads and PLAY.txt steps for players are gone;
the launcher has its own section with two screenshots. The roadmap merges the
known differences, the final checks and the plans after parity, under the
"Roadmap" heading the launcher's What's next page reads. The parity table and
its 100%-of-what-the-harnesses-compare note are unchanged.

docs/README.md indexes what remains: build and run, parity (status and
workflow), world generation, world data and simulation, the old Java track.
Links to the removed pages and README anchors are fixed.

packaging/PLAY.txt now speaks to players who came through the launcher and
points anyone with a bare archive to it, keeping the manual steps short.

The launcher's README link points at main instead of the launcher branch.
.gitignore: tools/logs/ and .DS_Store. No code behaviour changes; the compiler
and clippy flag no unused code and the tree has no stale TODOs.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 14:16:55 +02:00
Ludovic MarieandClaude Opus 5.5 2e4c4d1861 Launcher: run the game from the saves folder, never a version folder
The client ran in the version's own folder, so saves and options.txt would have
landed there and been deleted with the version, and the saves in
~/.local/share/horizon (where the release folders' horizon.sh keeps them) were
not seen. It now runs in HORIZON_HOME, else horizon in the platform's data
folder, with --resources pointing at the version.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 14:12:16 +02:00
Ludovic MarieandClaude Opus 5.5 ed05c1970f Launcher: release workflow for launcher-v tags (Linux, macOS, Windows, draft), README for updates, CLI and MCP; quieter CLI progress
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 13:28:57 +02:00
Ludovic MarieandClaude Opus 5.5 6c51322171 Launcher: opening screen over the prismal background, violet accent from it, opening setting, docs frames and clip
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 13:27:30 +02:00
Ludovic MarieandClaude Opus 5.5 86e4a05c01 Launcher: CLI subcommands and an MCP server over stdio, both on the shared core
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 13:20:39 +02:00
Ludovic MarieandClaude Opus 5.5 53583b28d8 Launcher design pass: aurora background, eased page, pill, hover and bar motion, Play hero, Settings page with update state; Geist, Instrument Serif and Geist Mono
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 13:18:17 +02:00
Ludovic MarieandClaude Opus 5.5 55ecf5a59e Launcher core: update checks for Horizon and the launcher, self-update, install by tag, notes as plain text, tests
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 13:13:57 +02:00
Ludovic MarieandClaude Opus 5.5 e5e27c24d4 Launcher: backend as a shared library; game and launcher tags kept apart, numeric version order, HORIZON_LAUNCHER_HOME
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 13:11:00 +02:00
Ludovic MarieandClaude Opus 5.5 5a2602406b Launcher: preview screenshot
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 13:01:46 +02:00
Ludovic MarieandClaude Opus 5.5 a2fe7286c1 Launcher: README and screenshots
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 12:51:46 +02:00
Ludovic MarieandClaude Opus 5.5 d7bcc04064 Launcher workflow: also run on pushes to the launcher branch
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 12:50:59 +02:00
Ludovic MarieandClaude Opus 5.5 7ff1b97f80 Launcher: tables in notes, the README roadmap, the server's EULA, and a macOS/Windows build workflow
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 12:50:49 +02:00
Ludovic MarieandClaude Opus 5.5 57257ae231 Launcher: a GPUI app that installs, prepares and starts Horizon builds
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 12:45:05 +02:00
Ludovic MarieandClaude Opus 5.5 b279705c8d README: every subsystem matches vanilla in its harnesses (100%), audit and launch checks next
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 07:18:24 +02:00
Ludovic Marie 7d4304a840 Merge branch 'parity/leftovers' into parity-base 2026-10-13 07:07:54 +02:00
Ludovic Marie b7ced27dd1 Merge branch 'parity/server-leftovers' into parity-base 2026-10-13 06:52:25 +02:00
Ludovic Marie c6d0184353 Merge branch 'parity/screens' into parity-base 2026-10-13 06:47:44 +02:00
Ludovic MarieandClaude Opus 5.5 98ec7bc509 Edit word moves with Cmd on macOS, as InputQuirks does
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 06:38:47 +02:00
Ludovic Marie 2aa3cd5afa Merge branch 'parity-base' into parity/screens 2026-10-13 06:29:00 +02:00
Ludovic Marie b0e5fe5591 docs: pack screen session count 2026-10-13 06:28:59 +02:00
Ludovic MarieandClaude Opus 5.5 8a13322143 README: the resource pack screen and the chat input match vanilla
Assets and Menus score 1; Java parity is 93%.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 06:28:53 +02:00
Ludovic MarieandClaude Opus 5.5 436d71eba2 Compare the chat screen's input and command suggestions with vanilla
horizon_client::chat::ChatScreen is now a port of vanilla's ChatScreen,
EditBox and CommandSuggestions: the input's scrolling, cursor, selection,
word moves and select all, history up and down, argument colouring, usage
lines and parse errors, the suggestion list (sorting, hover, Tab and
Shift+Tab cycling, clicks, wheel) and its tooltips, drawn as GUI calls the
game paints. tools/test_chat_screen_parity.py drives a real ChatScreen on
vanilla's client command tree (custom suggestions answered by the server
dispatcher): 3000/3000 cases match.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 06:27:55 +02:00
Ludovic MarieandClaude Opus 5.5 639237afcc Show the ported pack screen in the game
The options' Packs page is horizon_client::pack_screen: vanilla's layout,
lists, focus and selection, search box typing, the mouse wheel per list and
the confirmation of an incompatible pack (Escape answers no). Packs carry
their raw description, compatibility (too old, too new, unknown) and icon.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 06:10:23 +02:00
Ludovic MarieandClaude Opus 5.5 a7606c4ad4 Compare the resource pack screen's drawing with vanilla
horizon_client::pack_screen ports PackSelectionScreen, its two
TransferableSelectionLists and the ConfirmScreen of an incompatible pack as
vanilla's state machine (clicks, wheel, search typing, focus, selection,
scroll) and gives its GUI calls; screen_draw holds the widgets (StringWidget,
MultiLineTextWidget, Button, a font-aware EditBox port) and StringSplitter's
line splitting with legacy codes. Pack components keep their legacy codes and
style fields. tools/test_pack_screen_parity.py runs a real
PackSelectionScreen through the same actions: 1500/1500 cases match.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 06:07:04 +02:00
Ludovic MarieandClaude Opus 5.5 7c8afc8a34 Merge branch 'parity-base' into parity/server-leftovers
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 05:44:19 +02:00
Ludovic MarieandClaude Opus 5.5 0a2601c33a Send recipes, advancements and command replies to players as vanilla does
- ClientboundUpdateRecipesPacket at join: the recipe property sets and the
  stonecutter's recipes, from the data pack (lan/recipes.rs).
- On a player's first tick the minecraft:tick criteria are met: the recipes
  their advancements grant go out in ClientboundRecipeBookAddPacket, then
  ClientboundUpdateAdvancementsPacket with what the player may see
  (lan/advancements.rs).
- Command replies reach remote players as the components vanilla sends:
  Text keeps the Component it was built from (literal, translatable,
  siblings, style), sendFailure wraps the message as vanilla does, and the
  NBT wraps the elements of mixed lists.

The dedicated-server harness drops its known gaps: it compares these
packets (sorted where vanilla's hash maps order them per run) and the
replies to three failing commands, keeps only the first set_time among the
joining packets and turns random ticks off in the generated world.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 05:43:51 +02:00
Ludovic MarieandClaude Opus 5.5 e70c38e578 Send the command tree in vanilla's registration order
The LAN and dedicated servers built the tree from the data generator's
commands report, which sorts each node's children. lan/command_order.rs,
generated from vanilla's Commands(CommandSelection.ALL) by
tools/generate_lan_command_order.py, gives the registration order, and the
dedicated-server harness now compares the tree in order (the game rules,
registered in an identity-hashed order, aside).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 04:59:34 +02:00
175 changed files with 20865 additions and 17025 deletions

No files matched your search

+86
View File
@@ -0,0 +1,86 @@
name: launcher
# Builds the launcher on Linux, macOS and Windows. A pushed `launcher-vX.Y.Z` tag also puts the
# three archives on a draft GitHub release of that tag, to publish by hand. Horizon's own
# releases are tagged `vYYYY.MM.DD`; the launcher reads only `launcher-v*` releases for itself.
on:
workflow_dispatch:
push:
branches: [launcher]
tags: ['launcher-v*']
permissions:
contents: read
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
asset: horizon-launcher-linux-x86_64.tar.gz
binary: horizon-launcher
- os: macos-latest
asset: horizon-launcher-macos-arm64.zip
binary: horizon-launcher
- os: windows-latest
asset: horizon-launcher-windows-x64.zip
binary: horizon-launcher.exe
runs-on: ${{ matrix.os }}
defaults:
run:
working-directory: launcher
shell: bash
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: launcher
- name: Linux libraries GPUI links to
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y libxkbcommon-x11-dev libwayland-dev libx11-xcb-dev libfontconfig-dev libvulkan-dev libasound2-dev
- name: The tag matches Cargo.toml
if: startsWith(github.ref, 'refs/tags/launcher-v')
run: grep -qx "version = \"${GITHUB_REF_NAME#launcher-v}\"" Cargo.toml
- run: cargo test --release --locked --lib
- run: cargo build --release --locked
- name: Package
run: |
mkdir -p dist
cp target/release/${{ matrix.binary }} dist/
cd dist
if [[ "${{ matrix.asset }}" == *.tar.gz ]]; then
tar czf ../${{ matrix.asset }} ${{ matrix.binary }}
elif [[ "$RUNNER_OS" == "Windows" ]]; then
7z a ../${{ matrix.asset }} ${{ matrix.binary }}
else
zip ../${{ matrix.asset }} ${{ matrix.binary }}
fi
- uses: actions/upload-artifact@v4
with:
name: ${{ matrix.asset }}
path: launcher/${{ matrix.asset }}
release:
if: startsWith(github.ref, 'refs/tags/launcher-v')
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
# A draft, and never marked latest: Horizon's own releases stay the repository's latest.
- uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: Horizon launcher ${{ github.ref_name }}
draft: true
make_latest: false
files: dist/*
@@ -1,46 +0,0 @@
name: macOS shader research
on:
workflow_dispatch:
permissions:
contents: read
jobs:
shader-worlds:
runs-on: macos-26
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '25'
- name: Build original mod and private probe dependencies
run: python tools/build_mod.py
- name: Verify required cinematic shaders in OpenGL and Vulkan worlds
run: |
python - <<'PY'
import json, subprocess, sys
from pathlib import Path
observations = []
for backend in ['opengl', 'vulkan']:
case = ['--profile', 'cinematic', '--backend', backend, '--world', '--shaders']
result = subprocess.run([sys.executable, 'tools/test_client_graphics.py', '--native-display', *case], capture_output=True, text=True)
print(result.stdout, end='', flush=True)
print(result.stderr, end='', flush=True)
observation = {'case': case, 'exit_code': result.returncode}
if result.returncode:
marker = 'HORIZON_FIXTURE_FAILURE '
observation['failure'] = [json.loads(line.split(marker, 1)[1]) for line in result.stdout.splitlines() if marker in line]
else:
observation['report'] = json.loads(Path('dist/client-graphics-smoke.json').read_text())
observations.append(observation)
Path('dist/client-graphics-shader-research.json').write_text(json.dumps(observations, indent=2) + '\n')
sys.exit(int(any(item['exit_code'] for item in observations)))
PY
- name: Retain selected observations including failed cases
if: always()
uses: actions/upload-artifact@v4
with:
name: macos-shader-observations
path: dist/client-graphics-shader-research.json
@@ -1,59 +0,0 @@
name: macOS Vulkan research
on:
workflow_dispatch:
inputs:
world:
description: Create or open disposable demo worlds instead of title probes
type: boolean
default: false
permissions:
contents: read
jobs:
native-probes:
runs-on: macos-26
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '25'
- name: Build original mod and private probe dependencies
run: python tools/build_mod.py
- name: Probe vanilla, core and distant-terrain Vulkan cases
env:
HORIZON_GRAPHICS_WORLD: ${{ inputs.world }}
run: |
python - <<'PY'
import json, os, subprocess, sys
from pathlib import Path
cases = [
['--profile', 'baseline', '--backend', 'vulkan'],
['--profile', 'core-performance', '--backend', 'vulkan'],
['--profile', 'vulkan'],
]
if os.environ.get('HORIZON_GRAPHICS_WORLD') == 'true':
cases = [case + ['--world'] for case in cases]
observations = []
for case in cases:
result = subprocess.run([sys.executable, 'tools/test_client_graphics.py', '--native-display', *case], capture_output=True, text=True)
print(result.stdout, end='', flush=True)
print(result.stderr, end='', flush=True)
observation = {'case': case, 'exit_code': result.returncode}
if result.returncode:
marker = 'HORIZON_FIXTURE_FAILURE '
observation['failure'] = [json.loads(line.split(marker, 1)[1]) for line in result.stdout.splitlines() if marker in line]
else:
observation['report'] = json.loads(Path('dist/client-graphics-smoke.json').read_text())
observations.append(observation)
Path('dist/client-graphics-vulkan-research.json').write_text(json.dumps(observations, indent=2) + '\n')
sys.exit(int(any(item['exit_code'] for item in observations)))
PY
- name: Retain selected observations including failed cases
if: always()
uses: actions/upload-artifact@v4
with:
name: macos-vulkan-observations
path: dist/client-graphics-vulkan-research.json
+2
View File
@@ -16,3 +16,5 @@
/dist/
/mods/horizon/build/
/saves/
/tools/logs/
.DS_Store
Generated
+6
View File
@@ -681,12 +681,14 @@ dependencies = [
name = "horizon-client"
version = "0.1.0"
dependencies = [
"ab_glyph",
"bytemuck",
"cpal",
"glam",
"horizon-assets",
"horizon-core",
"horizon-protocol",
"horizon-theme",
"horizon-world",
"miniz_oxide 0.8.9",
"png",
@@ -713,6 +715,10 @@ dependencies = [
"serde_json",
]
[[package]]
name = "horizon-theme"
version = "0.1.0"
[[package]]
name = "horizon-world"
version = "0.1.0"
+2 -1
View File
@@ -1,5 +1,6 @@
[workspace]
members = ["crates/horizon-core", "crates/horizon-world", "crates/voxel-kernels", "crates/horizon-client", "crates/horizon-assets", "crates/horizon-protocol"]
exclude = ["launcher"]
members = ["crates/horizon-core", "crates/horizon-world", "crates/voxel-kernels", "crates/horizon-client", "crates/horizon-assets", "crates/horizon-protocol", "crates/horizon-theme"]
resolver = "2"
[workspace.package]
+40 -58
View File
@@ -6,26 +6,43 @@
<a href="https://github.com/ludovic111/horizon/actions/workflows/ci.yml"><img src="https://github.com/ludovic111/horizon/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI"></a>
<img src="https://img.shields.io/badge/Minecraft-Java%2026.3-5D9C3F" alt="Minecraft Java 26.3">
<img src="https://img.shields.io/badge/Rust-stable-B7410E?logo=rust&logoColor=white" alt="Rust">
<img src="https://img.shields.io/badge/vanilla%20parity-89%25-F0795A" alt="Vanilla parity 89%">
<img src="https://img.shields.io/badge/vanilla%20parity-100%25-F0795A" alt="Vanilla parity 100%">
<img src="https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20Windows-2A2470" alt="Linux, macOS and Windows">
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-3B2F7E" alt="MIT license"></a>
</p>
<p align="center">
<a href="#getting-it"><b>Get started</b></a> ·
<a href="#download"><b>Download</b></a> ·
<a href="#screenshots"><b>Screenshots</b></a> ·
<a href="#project-status"><b>Parity status</b></a> ·
<a href="docs/native-client.md"><b>Native client guide</b></a>
<a href="docs/README.md"><b>Documentation</b></a>
</p>
# Horizon
A Rust rewrite of Minecraft: Java Edition 26.3 that aims for one-to-one vanilla parity, checked against the game itself with differential tests.
A Rust rewrite of Minecraft: Java Edition 26.3 built for one-to-one vanilla parity, checked against the game itself with differential tests.
**Status:** in development. The native client is playable on Linux, macOS (Apple Silicon) and Windows; Java parity is 89% (see [Project status](#project-status)).
Every subsystem matches vanilla in all 281 parity harnesses, on Linux and macOS: 100% of what the harnesses compare (see [Project status](#project-status)). The native client is playable on Linux, macOS (Apple Silicon) and Windows.
> Not an official Minecraft product. Not approved by or associated with Mojang or Microsoft. Horizon contains no Minecraft code, assets or data: you need your own legally obtained copy of Minecraft: Java Edition 26.3.
## Download
**[Download the Horizon launcher](https://github.com/ludovic111/horizon/releases?q=launcher-v&expanded=true)** for Linux x86-64, macOS Apple Silicon or Windows x64: take the newest `launcher-v*` release (currently [launcher-v0.1.1](https://github.com/ludovic111/horizon/releases/tag/launcher-v0.1.1)); the launcher then updates itself. The launcher is the way to get Horizon: it installs and updates the game, prepares its resources from your own copy of Minecraft, and starts the client or a dedicated server.
**You need** Minecraft: Java Edition installed with the official launcher, with 26.3 played once; Python 3.10 or newer and Java 25 (a JDK, e.g. Eclipse Temurin 25) for the one-time resource preparation; and a GPU with Vulkan on Linux and Windows, or any Apple Silicon Mac.
### The launcher
<table>
<tr>
<td width="50%"><img src="launcher/docs/play.png" alt="The launcher's Play page"></td>
<td width="50%"><img src="launcher/docs/versions.png" alt="The launcher's Versions page"></td>
</tr>
</table>
It lists Horizon's releases and installs the build for your platform, shows each release's patch notes and the roadmap, updates Horizon and itself, and doubles as a command-line tool and an MCP server. See [the launcher's README](launcher/README.md).
## Screenshots
Captured in the Rust client itself, with vanilla assets and no mods or shaders.
@@ -69,22 +86,14 @@ The [native client](docs/native-client.md) opens on a vanilla-style title screen
- shields, maps, books, fireworks, beacons, advancements and statistics;
- Anvil saves, joining vanilla servers, and opening a world to LAN.
## Getting it
## Build from source
Builds for **Linux x86-64**, **macOS Apple Silicon** and **Windows x64** are attached to the [releases](https://github.com/ludovic111/horizon/releases). Each folder holds the game, the resource preparation tool and a `PLAY.txt`; the first start prepares the resources from your own copy of the game, as below. You can also build from source.
**Platform.** A GPU with Vulkan on Linux and Windows, or any Apple Silicon Mac. Development and the vanilla harnesses run on Linux.
**Requirements.** Python 3.10 or newer and JDK 25 (for resource preparation). To build from source: Rust 1.90 or newer, and on Linux the ALSA development headers (`libasound2-dev` on Debian and Ubuntu).
### Bring your own copy
For developers. Requirements: Rust 1.90 or newer, Python 3.10 or newer, JDK 25, and on Linux the ALSA development headers (`libasound2-dev` on Debian and Ubuntu). Development and the vanilla harnesses run on Linux.
Horizon contains no game files and never downloads them. It builds its resources from **your own copy** of Minecraft: Java Edition 26.3, verified against the checksums in `research-lock.json`:
1. **Client:** install Java Edition with the official launcher and play 26.3 once. Horizon reads `versions/26.3/`, `libraries/` and `assets/` from the launcher's game directory (`~/.minecraft` on Linux). If yours lives elsewhere, pass `--minecraft-dir` or set `HORIZON_MINECRAFT_DIR`.
2. **Server jar:** download the 26.3 server jar yourself, from [minecraft.net/download/server](https://www.minecraft.net/en-us/download/server) while 26.3 is the current release, or otherwise from the `downloads.server.url` in your launcher's `versions/26.3/26.3.json`. Pass it with `--server-jar` or set `HORIZON_SERVER_JAR`. It is only needed the first time.
### Build and run
2. **Server jar:** the 26.3 server jar, from the `downloads.server.url` in your launcher's `versions/26.3/26.3.json` (or [minecraft.net/download/server](https://www.minecraft.net/en-us/download/server) while 26.3 is the current release). Pass it with `--server-jar` or set `HORIZON_SERVER_JAR`. It is only needed the first time.
```sh
git clone https://github.com/ludovic111/horizon.git
@@ -96,73 +105,46 @@ cargo run --release -p horizon-client
Everything prepared lands in the gitignored `.local/`. It is derived from the game: never commit it or share it.
## Usage
The client starts on the title screen. Command-line options (`--world`, `--seed`, `--creative`, `--render-distance`), controls, scripting through `horizon-ctl`, and packaging for another of your own Linux machines are described in [the native client guide](docs/native-client.md).
## Documentation
- [Native client](docs/native-client.md): running, options, controls, scripting and architecture.
- [Rust rewrite status](docs/rust-parity.md): completion criteria and per-area scope.
- Parity notes: [block behaviours and ticking](docs/parity/blocks.md), [section meshing](docs/parity/meshing.md).
- [Decompilation and Rust research lab](docs/research-lab.md): the local game inspection workspace and the first research crates.
- [Decompilation status](docs/decompilation-status.md).
- [Java performance packs](docs/java-packs.md): the earlier, no longer developed Java track.
The client starts on the title screen. Command-line options (`--world`, `--seed`, `--creative`, `--render-distance`, `--dedicated`), controls, scripting through `horizon-ctl`, and the architecture are described in [the native client guide](docs/native-client.md). The rest of the documentation is indexed in [docs/README.md](docs/README.md), including [the parity workflow](docs/parity-workflow.md).
## Project status
Parity is **not** complete. The table below is the project's own audit of each subsystem. Still missing: the warden's brain and the sculk shrieker summoning it, villager breeding and gossip, the resource pack screen, a dedicated server mode, and worlds older than 1.17.
The table below is the project's own audit of each subsystem. Every subsystem now matches vanilla in every harness that compares it. 100% means 100% of what the harnesses compare, not proof that nothing else differs. The remaining known differences and the final checks are listed in the roadmap.
### Java parity: 89%
### Java parity: 100%
Each subsystem scores 0 (absent), 0.25 (started, not playable), 0.5 (playable,
major vanilla features missing), 0.75 (playable, mostly complete) or 1 (complete
and verified against vanilla by differential tests). The percentage is the
average; `tests/test_parity.py` keeps it in sync with this table. Last audited
2026-10-12 against the harness results: 270 harnesses pass. Two still differ
from vanilla in places: `mob_ai` (83 of 84 scenarios; a tempted ghastling) and
`sculk` (427 of 435; shrieker warnings and warden summoning).
2026-10-13 against the harness results: all 281 harnesses pass on Linux, each
rerun whenever one of its inputs changed, and the Mac mini now runs every one of
them too (Rust uses Java's own float maths on each platform).
| Subsystem | Score | Main gaps |
| --- | ---: | --- |
| Window, input and game loop | 1 | None: the game loop, options, camera, auto-jump, toggle sprint/sneak, local input and the frame limiter match vanilla |
| Assets and resources | 0.75 | Item models match vanilla over 196,290 stacks and the client draws every item through them; no resource pack screen |
| Network protocol and multiplayer | 0.75 | Joins vanilla servers and opens worlds to LAN; server.properties, eula.txt and the user lists match vanilla, but there is no dedicated server mode and LAN hosting is not tested against a vanilla client |
| Assets and resources | 1 | None: item models match vanilla over 196,290 stacks and the client draws every item through them; the resource pack screen matches vanilla's drawing over 3,000 sessions of clicks, scrolling and searching, its incompatibility confirmation included |
| Network protocol and multiplayer | 1 | None: joins vanilla servers; the dedicated server (`--dedicated`) matches vanilla's files, status ping, login, configuration, play, chunks, chat, recipes, advancements and command tree, a client built from vanilla's packet code joins it, Horizon joins a vanilla server, and LAN discovery matches over 462 cases (offline mode only) |
| Chunk storage and palettes | 1 | None: client and saves share paletted containers, identical to vanilla over 266 scenarios |
| Section meshing | 1 | None: 112 scenes and over a million quads identical to vanilla |
| Rendering | 1 | None: entity models, block entity renderers (407 cases, End portals, gateways and the loom's banner preview included) and their animations (296 cases, End gateway beams included), the HUD overlays (2,200 states), the recipe book (600 states), the player list, subtitles and the world border match vanilla |
| Lighting | 1 | None: saved and relit light matches vanilla, slabs and stairs included |
| World generation | 1 | None: 2,352 whole chunks over 225 structure sites, in all three dimensions, identical to vanilla |
| Region files and saves | 0.75 | Saves round-trip with vanilla, and worlds from 1.17 to 26.2 upgrade as vanilla's DataFixers do; worlds older than 1.17 are not upgraded |
| Entities and physics | 0.75 | Attributes, dimensions, death loot, spawn rules, natural spawning (15,500 cases), raids and patrols (1,900 cases), spawned mobs' gear, enchantments and state (`finalizeSpawn`, 24,000 cases) and mob AI (83 of 84 scenarios, villager and copper golem brains included) match; the warden's brain and villager breeding and gossip are missing |
| Region files and saves | 1 | None: saves round-trip with vanilla, and worlds from 1.8 to 26.2 upgrade as vanilla's DataFixers do, superflat worlds included; old options.txt and hotbar.nbt files are upgraded too |
| Entities and physics | 1 | None: attributes, dimensions, death loot, spawn rules, natural spawning (15,500 cases), raids and patrols (1,900 cases), spawned mobs' gear, enchantments and state (`finalizeSpawn`, 24,000 cases) and mob AI (92 scenarios: villager breeding and gossip, the warden, ghastlings and copper golems included) match vanilla |
| Interaction and inventory | 1 | None: menu clicks match over 8,000 click sequences, the loom and the crafter included; recipe book placement (6,000 cases), its buttons (1,200), the saved book (1,500) and the loom and crafter screens (1,600) match vanilla |
| Menus, HUD and chat | 0.75 | Every command runs as vanilla (758 commands over 39,685 parsed inputs), scoreboards and teams match (81,000 operations), the player list matches over 872,000 draw calls with heads drawn from players' skins (authlib's textures, SkinManager's lookup, legacy skin conversion), and the chat matches focused and scrolled; the resource pack screen's selection (moving packs between the lists, ordering, required and fixed packs) matches over 4,000 cases; the pack screen's drawing, its incompatibility confirmation, and the chat input box and command suggestions are not compared |
| Menus, HUD and chat | 1 | None: every command runs as vanilla (758 commands over 39,685 parsed inputs), scoreboards and teams match (81,000 operations), the player list matches over 872,000 draw calls with heads drawn from players' skins (authlib's textures, SkinManager's lookup, legacy skin conversion), and the chat matches focused and scrolled; the resource pack screen (selection over 4,000 cases, drawing and its incompatibility confirmation over 3,000 sessions) and the chat input with its command suggestions, usage lines, Tab completion and history (3,000 sessions on vanilla's client command tree) match vanilla |
| Audio | 1 | None: the sound engine, sound events, music, situational music, ambience and subtitles match vanilla |
| Block behaviours and ticking | 0.75 | Block updates, random ticks, redstone, dispensers (6,000 cases), crafters (4,000 crafts) and block entity removal (containers spill, 4,000 cases) match vanilla; copper golems sort chests as vanilla's brain does (7 scenarios, tick for tick); 8 of 435 sculk scenarios differ (shrieker warnings and warden summoning) |
### What's new since the previous version
- **Mob AI matches vanilla**, compared tick by tick in 72 scenarios, with villagers on a port of vanilla's brain (memories, sensors, schedules and behaviours).
- **New mobs:** the breeze and wind charges, the creaking and the creaking heart, the sniffer, the happy ghast and ghastlings, llamas and trader llamas, and the copper golem; the warden's model, animations and emissive layers.
- **Raids and pillager patrols**, with the Raid Omen, the waves and the Hero of the Village effect.
- **Dispensers, crafters, the loom and the recipe book**, and containers spill their items when their block is replaced.
- **Every command runs as vanilla**, including /item modify, /spectate, /waypoint, /dialog and /place.
- **Scoreboards and teams** in gameplay (criteria, friendly fire, collision, name tags), the **player list**, **subtitles**, every **HUD overlay**, **block entity animations** (chests, shulker boxes, bells, conduits, heads, the enchanting table's book) and **End portals and gateways** drawn with vanilla's shader.
- **Worlds from 1.17 onwards** open and are upgraded as vanilla does; server.properties, eula.txt and the server user lists are read and written as vanilla does.
- **Builds for Linux, macOS (Apple Silicon) and Windows.**
| Block behaviours and ticking | 1 | None: block updates, random ticks, redstone, dispensers (6,000 cases), crafters (4,000 crafts), block entity removal (containers spill, 4,000 cases), copper golem chest sorting and the sculk family (435 scenarios: shrieker warnings and warden summoning included) match vanilla |
### Roadmap
1. Finish the warden's brain and the sculk shrieker summoning it, and the tempted ghastling.
2. A dedicated server mode, and LAN hosting tested with a vanilla client.
3. Save upgrades from before 1.17, and the resource pack screen.
4. Platform-independent float math, so every harness also gives vanilla's results on macOS.
**Known differences.** Online-mode servers (Mojang's session servers) are not supported; skins served over https show the default skin unless already cached; pack icons show the unknown-pack texture in game; the creative hotbar keys (C/X) aren't wired to the hotbar loader; item tooltips lack attribute lines.
The rewrite is complete when it reaches one-to-one parity and packaged native builds pass the launch checks in [Rust rewrite status](docs/rust-parity.md#completion-criteria-and-playable-builds).
**Final checks.** A from-scratch audit (`tools/parity.py --all`) on Linux and on macOS, and the launch checks on the packaged Linux, macOS and Windows builds listed in [Rust rewrite status](docs/rust-parity.md#completion-criteria-and-playable-builds).
### After the rewrite
Once Horizon matches vanilla, the plan is to build on that exact base:
**Next.** With vanilla parity as the base:
- **Performance:** optimize the client and the server as far as they can go (rendering, chunk generation and meshing, memory, multithreaded ticking) while the differential harnesses keep gameplay identical to vanilla.
- **Modding support:** a stable API for writing mods against Horizon.
@@ -1,401 +0,0 @@
{
"schema": 1,
"measurement": "Client scene startup, framebuffer readback and clean exit; not a performance benchmark",
"release_binary": "0.20.0",
"production_mod_sha256": "e651ef49bc97486e8dacfd4b640465c442525cd645e2dba71ddea9fb64347dd8",
"macos_required_ci": {
"run": 37192178667,
"source_commit": "a5000edf11094e00ebef0fc362aa4adc322f2df6",
"all_jobs_passed": true,
"reports": {
"title": {
"schema": 1,
"platform": "macOS-26.6.2-arm64-arm-64bit",
"architecture": "arm64",
"minecraft": "26.3",
"original_mod_sha256": "e651ef49bc97486e8dacfd4b640465c442525cd645e2dba71ddea9fb64347dd8",
"results": [
{
"observed_mode": "title",
"title_screen_observed": true,
"world_loaded": false,
"ready_client_ticks": 53,
"window_active": true,
"framebuffer_width": 1280,
"framebuffer_height": 646,
"sampled_pixels": 4160,
"distinct_sampled_rgb": 1525,
"gpu": "Apple Software Renderer",
"graphics_backend": "OpenGL",
"graphics_driver": "4.1 APPLE-23.1.1",
"private_png_sha256": "ed503082baca3a8646e7e864bf363e6e2a705a2b4aade2ec4bae6d3a108b07ab",
"profile": "core-performance",
"preferred_backend": "opengl",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "OpenGL",
"operation": "load_library",
"result": "success"
},
{
"backend": "OpenGL",
"operation": "create_device",
"result": "success"
}
]
},
{
"observed_mode": "title",
"title_screen_observed": true,
"world_loaded": false,
"ready_client_ticks": 55,
"window_active": true,
"framebuffer_width": 1280,
"framebuffer_height": 646,
"sampled_pixels": 4160,
"distinct_sampled_rgb": 1855,
"gpu": "Apple Software Renderer",
"graphics_backend": "OpenGL",
"graphics_driver": "4.1 APPLE-23.1.1",
"private_png_sha256": "959fe6afbe1897cd9711c083e88ccc617ee9d8669983987abda84e0f5979e82d",
"profile": "m2-balanced",
"preferred_backend": "opengl",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "OpenGL",
"operation": "load_library",
"result": "success"
},
{
"backend": "OpenGL",
"operation": "create_device",
"result": "success"
}
]
}
],
"limits": [
"Short scene startup and nonuniform framebuffer readback only.",
"World mode uses the ordinary limited demo; world files remain private.",
"No exhaustive gameplay, visual-correctness, FPS or M2 Pro performance claim.",
"Vulkan preference can fall back; inspect the observed backend.",
"PNG images, assets and full logs remain in the private runtime directory."
]
},
"world": {
"schema": 1,
"platform": "macOS-26.6.2-arm64-arm-64bit",
"architecture": "arm64",
"minecraft": "26.3",
"original_mod_sha256": "e651ef49bc97486e8dacfd4b640465c442525cd645e2dba71ddea9fb64347dd8",
"results": [
{
"observed_mode": "world",
"title_screen_observed": false,
"world_loaded": true,
"ready_client_ticks": 40,
"window_active": true,
"framebuffer_width": 1280,
"framebuffer_height": 646,
"sampled_pixels": 4160,
"distinct_sampled_rgb": 1537,
"gpu": "Apple Software Renderer",
"graphics_backend": "OpenGL",
"graphics_driver": "4.1 APPLE-23.1.1",
"private_png_sha256": "31be5cc8188b3494d76232cba79cf320a64523b4906ab720a38997a125eb37fa",
"profile": "core-performance",
"preferred_backend": "opengl",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "OpenGL",
"operation": "load_library",
"result": "success"
},
{
"backend": "OpenGL",
"operation": "create_device",
"result": "success"
}
]
},
{
"observed_mode": "world",
"title_screen_observed": false,
"world_loaded": true,
"ready_client_ticks": 40,
"window_active": true,
"framebuffer_width": 1280,
"framebuffer_height": 646,
"sampled_pixels": 4160,
"distinct_sampled_rgb": 2074,
"gpu": "Apple Software Renderer",
"graphics_backend": "OpenGL",
"graphics_driver": "4.1 APPLE-23.1.1",
"private_png_sha256": "0929c865d723fe0eea8f37bcc45e9636c6f342d04fe507f9bd592dfd30d73f42",
"profile": "m2-balanced",
"preferred_backend": "opengl",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "OpenGL",
"operation": "load_library",
"result": "success"
},
{
"backend": "OpenGL",
"operation": "create_device",
"result": "success"
}
]
}
],
"limits": [
"Short scene startup and nonuniform framebuffer readback only.",
"World mode uses the ordinary limited demo; world files remain private.",
"No exhaustive gameplay, visual-correctness, FPS or M2 Pro performance claim.",
"Vulkan preference can fall back; inspect the observed backend.",
"PNG images, assets and full logs remain in the private runtime directory."
]
}
}
},
"earlier_vulkan_research": {
"run": 37191171799,
"source_commit": "3858ab38b51f434ebe892b564e013c7c8bcaba45",
"outcomes": [
{
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"profile": "baseline",
"preferred_backend": "vulkan",
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"vulkan_error_codes": [
"VK_ERROR_FEATURE_NOT_PRESENT"
],
"fatal_jvm_error": false,
"expected_demo_authentication_errors_observed": true
},
{
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"profile": "core-performance",
"preferred_backend": "vulkan",
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"vulkan_error_codes": [
"VK_ERROR_FEATURE_NOT_PRESENT"
],
"fatal_jvm_error": false,
"expected_demo_authentication_errors_observed": true
},
{
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"profile": "vulkan",
"preferred_backend": "vulkan",
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"vulkan_error_codes": [
"VK_ERROR_FEATURE_NOT_PRESENT"
],
"fatal_jvm_error": false,
"expected_demo_authentication_errors_observed": true
}
],
"full_private_logs_uploaded": false,
"readback_request_stage_not_yet_captured": true
},
"selected_local_software_checks": {
"linux-opengl": {
"title_screen_observed": true,
"title_client_ticks": 56,
"framebuffer_width": 1280,
"framebuffer_height": 800,
"sampled_pixels": 4288,
"distinct_sampled_rgb": 1762,
"gpu": "llvmpipe (LLVM 21.1.8, 256 bits)",
"graphics_backend": "OpenGL",
"graphics_driver": "4.5 (Core Profile) Mesa 26.0.8-1ubuntu0.3",
"private_png_sha256": "cf4eaa7d576ec8f608205258774fbd2384bf5382da86b60628d590f959145fd3",
"profile": "core-performance",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "OpenGL",
"operation": "load_library",
"result": "success"
},
{
"backend": "OpenGL",
"operation": "create_device",
"result": "success"
}
]
},
"linux-vulkan": {
"title_screen_observed": true,
"title_client_ticks": 56,
"framebuffer_width": 1280,
"framebuffer_height": 800,
"sampled_pixels": 4288,
"distinct_sampled_rgb": 1743,
"gpu": "llvmpipe (LLVM 21.1.8, 256 bits)",
"graphics_backend": "Vulkan",
"graphics_driver": "1.4.335 llvmpipe Mesa 26.0.8-1ubuntu0.3 (LLVM 21.1.8)",
"private_png_sha256": "edfc9b8431505c9c009da7bb8be0ed5676effb90757cd4ae4bda525e4db5da8c",
"profile": "vulkan",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
]
},
"linux-world-core": {
"observed_mode": "world",
"title_screen_observed": false,
"world_loaded": true,
"ready_client_ticks": 51,
"window_active": true,
"framebuffer_width": 1280,
"framebuffer_height": 800,
"sampled_pixels": 4288,
"distinct_sampled_rgb": 1297,
"gpu": "llvmpipe (LLVM 21.1.8, 256 bits)",
"graphics_backend": "OpenGL",
"graphics_driver": "4.5 (Core Profile) Mesa 26.0.8-1ubuntu0.3",
"private_png_sha256": "1a8ba681681f5e37986e1b411e5ebc80d47279c54368f43f935707092b70ffd0",
"profile": "core-performance",
"preferred_backend": "opengl",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "OpenGL",
"operation": "load_library",
"result": "success"
},
{
"backend": "OpenGL",
"operation": "create_device",
"result": "success"
}
]
},
"linux-world-balanced": {
"observed_mode": "world",
"title_screen_observed": false,
"world_loaded": true,
"ready_client_ticks": 40,
"window_active": true,
"framebuffer_width": 1280,
"framebuffer_height": 800,
"sampled_pixels": 4288,
"distinct_sampled_rgb": 1551,
"gpu": "llvmpipe (LLVM 21.1.8, 256 bits)",
"graphics_backend": "OpenGL",
"graphics_driver": "4.5 (Core Profile) Mesa 26.0.8-1ubuntu0.3",
"private_png_sha256": "82ced9bcf7178a35063e6a7fa9049fe7cfcf26dcb92aace59de6bb022609833a",
"profile": "m2-balanced",
"preferred_backend": "opengl",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "OpenGL",
"operation": "load_library",
"result": "success"
},
{
"backend": "OpenGL",
"operation": "create_device",
"result": "success"
}
]
}
},
"limits": [
"macOS OpenGL uses Apple Software Renderer; Vulkan exposes Apple Paravirtual device. No physical M2 GPU performance test.",
"World-mode checks ordinary limited-demo world startup and saved data, not exhaustive gameplay or completed LOD generation.",
"A nonuniform framebuffer does not prove pixel-correct rendering.",
"Three exploratory Vulkan cases fail with VK_ERROR_FEATURE_NOT_PRESENT after successful device creation; later stage remains to be isolated.",
"The probe uses 3 GiB; balanced can warn about low memory. The 16 GB Mac starter suggests 6 GiB.",
"No FPS, CPU/RAM reduction, statistical speedup or universal hardware-compatibility claim.",
"Raw PNGs, assets, world files and full logs remain private. Production JAR matches the published binary and excludes probe classes."
]
}
@@ -1,303 +0,0 @@
{
"schema": 1,
"measurement": "Single fixed-order stationary matched-view Linux software-rendered pair; descriptive observations, not statistical hardware speedup",
"minecraft": "26.3",
"java_vendor": "Ubuntu",
"java_runtime_version": "25.0.4.1+1-1-26.04.4-Ubuntu",
"graphics": "llvmpipe LLVM21.1.8 OpenGL,1280x800",
"captured_settings_match": true,
"settings": {
"full_detail_chunks": 12,
"simulation_chunks": 12,
"distant_terrain": "not installed",
"iris_shaders": "not installed",
"heap_max": "3G",
"collector": "G1",
"compact_headers": true,
"world_difficulty": "PEACEFUL",
"fov": 70,
"graphics_preset": "CUSTOM",
"frame_limit": "uncapped",
"all_original_controllers": false
},
"runs": [
{
"profile": "baseline",
"elapsed_seconds": 120.175428046,
"frame_samples": 651,
"tick_samples": 2401,
"tick_elapsed_seconds": 120.028670836,
"recorded_tick_samples_per_elapsed_second": 20.003554011529317,
"excluded_frames": 0,
"dropped_samples": 0,
"visual_settings_changed": [],
"frame_stats": {
"count": 651,
"meanMs": 183.95013769585256,
"p50Ms": 181.43732,
"p95Ms": 194.888166,
"p99Ms": 242.713818,
"maxMs": 300.17755,
"meanRate": 5.436255783909352,
"lowOnePercentRate": 3.864724477942431,
"over16Ms": 651,
"over33Ms": 651,
"over50Ms": 651,
"over100Ms": 651
},
"tick_execution_stats": {
"count": 2401,
"meanMs": 8.97966414119117,
"p50Ms": 7.166902,
"p95Ms": 16.131444,
"p99Ms": 19.670957,
"maxMs": 38.194457,
"meanRate": 111.36273966114595,
"lowOnePercentRate": 43.536701509030834,
"over16Ms": 106,
"over33Ms": 2,
"over50Ms": 0,
"over100Ms": 0
},
"process_cpu_seconds": 337.86,
"process_rss_peak_sampled_bytes": 2842439680,
"mods": [
"[email protected]+38c7a2d55d",
"[email protected]+fcdff87f5d",
"[email protected]+3434d6d95d",
"[email protected]+26.3",
"[email protected]+74ed1ea55d",
"[email protected]+0ae6f9115d",
"[email protected]+3434d6d95d",
"[email protected]+fcdff87f5d",
"[email protected]+74ed1ea55d",
"[email protected]+6b5b47fd5d",
"[email protected]+fcdff87f5d",
"[email protected]+fcdff87f5d",
"[email protected]+3434d6d95d",
"[email protected]+427eab975d",
"[email protected]+3434d6d95d",
"[email protected]+47f74c985d",
"[email protected]+3434d6d95d",
"[email protected]+3434d6d95d",
"[email protected]+3434d6d95d",
"[email protected]+cf6bc2db5d",
"[email protected]+3434d6d95d",
"[email protected]+ffef5f675d",
"[email protected]+4068fd645d",
"[email protected]+ed66f0a35d",
"[email protected]+3434d6d95d",
"[email protected]+fcdff87f5d",
"[email protected]+fcdff87f5d",
"[email protected]+3434d6d95d",
"[email protected]+3434d6d95d",
"[email protected]+fcdff87f5d",
"[email protected]+fcdff87f5d",
"[email protected]+fcdff87f5d",
"[email protected]+79385d0b5d",
"[email protected]+b9d63e335d",
"[email protected]+3434d6d95d",
"[email protected]+901a437c5d",
"[email protected]+3434d6d95d",
"[email protected]+4fc5413f5d",
"[email protected]+fcdff87f5d",
"[email protected]+48607d035d",
"[email protected]+74ed1ea55d",
"[email protected]+3434d6d95d",
"[email protected]+fcdff87f5d",
"[email protected]+fcdff87f5d",
"[email protected]+52268a0e5d",
"[email protected]",
"[email protected]",
"java@25",
"[email protected]",
"[email protected]"
],
"preceding_jfr_server_render_allocation_counters": [
{
"thread_id": 59,
"thread": "Server thread",
"counter_observations": 2,
"observed_seconds": 64.375293599,
"observed_allocated_bytes": 1096511648,
"observed_bytes_per_second": 17033112.96458356
},
{
"thread_id": 3,
"thread": "Render thread",
"counter_observations": 2,
"observed_seconds": 64.375293599,
"observed_allocated_bytes": 203851256,
"observed_bytes_per_second": 3166607.0102889067
}
],
"preceding_jfr_gc_pause_total_ms": 30.391511,
"preceding_jfr_gc_pause_longest_ms": 18.705464,
"exit_code": 0
},
{
"profile": "core-performance",
"elapsed_seconds": 120.10416213,
"frame_samples": 785,
"tick_samples": 2402,
"tick_elapsed_seconds": 120.041892203,
"recorded_tick_samples_per_elapsed_second": 20.0096812530915,
"excluded_frames": 0,
"dropped_samples": 0,
"visual_settings_changed": [],
"frame_stats": {
"count": 785,
"meanMs": 152.43891740636943,
"p50Ms": 150.474848,
"p95Ms": 163.179892,
"p99Ms": 198.41,
"maxMs": 228.508471,
"meanRate": 6.560004603904492,
"lowOnePercentRate": 4.756900949481116,
"over16Ms": 785,
"over33Ms": 785,
"over50Ms": 785,
"over100Ms": 785
},
"tick_execution_stats": {
"count": 2402,
"meanMs": 6.370044777268943,
"p50Ms": 5.805562,
"p95Ms": 10.732708,
"p99Ms": 13.377683,
"maxMs": 23.875155,
"meanRate": 156.98476776308226,
"lowOnePercentRate": 63.74793922036882,
"over16Ms": 5,
"over33Ms": 0,
"over50Ms": 0,
"over100Ms": 0
},
"process_cpu_seconds": 345.46,
"process_rss_peak_sampled_bytes": 2211401728,
"mods": [
"[email protected]",
"[email protected]+38c7a2d55d",
"[email protected]+fcdff87f5d",
"[email protected]+3434d6d95d",
"[email protected]+26.3",
"[email protected]+74ed1ea55d",
"[email protected]+0ae6f9115d",
"[email protected]+3434d6d95d",
"[email protected]+fcdff87f5d",
"[email protected]+74ed1ea55d",
"[email protected]+6b5b47fd5d",
"[email protected]+fcdff87f5d",
"[email protected]+fcdff87f5d",
"[email protected]+3434d6d95d",
"[email protected]+427eab975d",
"[email protected]+3434d6d95d",
"[email protected]+47f74c985d",
"[email protected]+3434d6d95d",
"[email protected]+3434d6d95d",
"[email protected]+3434d6d95d",
"[email protected]+cf6bc2db5d",
"[email protected]+3434d6d95d",
"[email protected]+ffef5f675d",
"[email protected]+4068fd645d",
"[email protected]+ed66f0a35d",
"[email protected]+3434d6d95d",
"[email protected]+fcdff87f5d",
"[email protected]+fcdff87f5d",
"[email protected]+3434d6d95d",
"[email protected]+3434d6d95d",
"[email protected]+fcdff87f5d",
"[email protected]+fcdff87f5d",
"[email protected]+fcdff87f5d",
"[email protected]+79385d0b5d",
"[email protected]+b9d63e335d",
"[email protected]+3434d6d95d",
"[email protected]+901a437c5d",
"[email protected]+3434d6d95d",
"[email protected]+4fc5413f5d",
"[email protected]+fcdff87f5d",
"[email protected]+48607d035d",
"[email protected]+74ed1ea55d",
"[email protected]+3434d6d95d",
"[email protected]+fcdff87f5d",
"[email protected]+fcdff87f5d",
"[email protected]+52268a0e5d",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]+26.3",
"java@25",
"[email protected]+mc26.3",
"[email protected]",
"[email protected]",
"[email protected]+mc26.3",
"[email protected]",
"[email protected]"
],
"preceding_jfr_server_render_allocation_counters": [
{
"thread_id": 55,
"thread": "Server thread",
"counter_observations": 2,
"observed_seconds": 64.387372441,
"observed_allocated_bytes": 691148360,
"observed_bytes_per_second": 10734222.158752
},
{
"thread_id": 3,
"thread": "Render thread",
"counter_observations": 2,
"observed_seconds": 64.387372441,
"observed_allocated_bytes": 107888768,
"observed_bytes_per_second": 1675619.9843200867
}
],
"preceding_jfr_gc_pause_total_ms": 54.65954,
"preceding_jfr_gc_pause_longest_ms": 25.746574,
"exit_code": 0
}
],
"provenance": {
"production_mod_source_commit": "2a268fefbf0ab3d478ca7755e609f7146d6f5145",
"workflow_run": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37179596850",
"runtime_mod_matches_linux_ci": true,
"original_mod_sha256": "df0bab0a6d87a1c609a051c190939010506f8cdd81897e82aa48caad032ef4e0",
"initial_player_snapshot_sha256": "b4d11dbd6443625415a1e32aa242d0e2d09cd77ddb1becfde5d35cb6ab8d278a",
"saved_first_cameras_match": true,
"saved_camera": {
"position": [
-56.5,
69.0,
55.5
],
"rotation": [
141.5,
16.950002670288086
]
},
"private_world_timing_protocol": {
"world_copy": "private only",
"advance_time": false,
"advance_weather": false,
"overworld_clock_ticks": 6000,
"modified_file_sha256": {
"game_rules": "47abf5e1fe82d54057ad7b095df3b9e29a8e4e9db7484988e09f3caaeedc12eb",
"world_clocks": "575d4a7663b154077a5be4c596790f3af178a00ab5a1e9cd58f37c1afa2c03b5"
},
"level_and_player_files_unchanged": true,
"pack_default_rules_unchanged": true
},
"clock_and_rules_verified_after_both_saves": true,
"candidate_save_reload_second_save_exit_zero": true
},
"notes": [
"Separate private copies, baseline then core. JFR begins about 121 seconds after demo dismissal; a separate 120-second frame capture begins about 307 seconds after dismissal.",
"Both captures have zero menu/pause/focus exclusions and no drops. Actual CSV counts and means match; viewer charts, 390-pixel layout and explicit software-change warnings pass.",
"Core records about 20.7% higher average FPS and 22.2% lower sampled peak RSS in this pair; whole-process CPU is slightly higher while rendering more frames.",
"No mod is isolated by this group comparison. Rendering-work completion, entity activity, cache/JIT and thermal state remain variables. Matching captured configuration is not pixel equivalence or exhaustive vanilla gameplay proof.",
"Tick execution inverse meanRate is capacity, not actual TPS. Record counts/elapsed seconds are exposed separately and include any pauses. Both captures have about 20 tick samples per elapsed second.",
"Preceding JFR server/render allocation counters are lower with core, but total and longest measured GC pauses are higher. Those profiles precede the frame captures and are not simultaneous with them.",
"No hardware GPU or M2/Apple Silicon result; RSS is not complete unified/GPU memory. Repeat alternating trials on real hardware.",
"No private worlds, full game logs, JFR recordings, game binaries or fixture agents are included."
]
}
File diff suppressed because it is too large. Load diff
@@ -1,47 +0,0 @@
{
"schema": 1,
"platform": "Linux-6.17.0-1022-azure-x86_64-with-glibc2.39",
"architecture": "x86_64",
"minecraft": "26.3",
"entity_culling": "1.11.2",
"results": [
{
"enabled": false,
"empty_iterator_calls": 1,
"live_registration_checked": true,
"block_callback_order_checked": true,
"type_guard_checked": true,
"allocated_bytes": 128001272,
"cpu_ns": 29632156,
"wall_ns": 49712014,
"measured_calls": 4000000,
"result": false
},
{
"enabled": true,
"empty_iterator_calls": 0,
"live_registration_checked": true,
"block_callback_order_checked": true,
"type_guard_checked": true,
"allocated_bytes": 208,
"cpu_ns": 809881,
"wall_ns": 801517,
"measured_calls": 4000000,
"result": false
}
],
"notes": [
"Actual publisher whitelist methods inside Fabric; live registration and block-entity callbacks checked.",
"Nonempty iteration, callback order, short circuit, null/wrong-type inputs and clearing retain upstream behavior.",
"Empty-state iterator counts use a private instrumented set; allocation loop uses normal empty HashSets.",
"Entity callbacks with a valid game entity are not exercised by this menu-only fixture.",
"JIT escape analysis can remove allocations in an isolated loop; real culling-thread profiles are needed.",
"Not a game FPS, whole-game RAM, visual equivalence or Mac GPU benchmark.",
"Much of an empty warmed loop may be folded by the JIT; CPU timings are not per-check costs or game speed estimates."
],
"provenance": {
"source_commit": "35dd69e9a6279fa89d762a0d24e49b0dbdb11b51",
"ci_run": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37164002916",
"artifact": "horizon-ubuntu-latest"
}
}
@@ -1,57 +0,0 @@
{
"schema": 1,
"platform": "Linux-6.17.0-1022-azure-x86_64-with-glibc2.39",
"architecture": "x86_64",
"minecraft": "26.3",
"entity_culling": "1.11.2",
"original_mod_sha256": "7351b417fc83460def5947636444413874ee812e949342f091ef03674e0c0e58",
"results": [
{
"enabled": false,
"public_boxes": 12800,
"provider_reads": 105239,
"edge_rays": 2197,
"visibility_digest": "da7286327283ce854dca2ab798d97c3b1cde55ac67112bd231c48df6d9388e00",
"query_digest": "124074ad764ab680b93896d47fa347a15f0b17ef41d2f8af5bd8e75f75208e12",
"intersection_digest": "f311c0b608b44b9eab2bb1e6347c3e18b003d05c939a8fbea9ba81fb16c8e8ae",
"allocated_bytes": 1040,
"cpu_ns": 101807697,
"wall_ns": 162651689,
"measured_checks": 2000000,
"checksum": 0,
"input_unchanged": true,
"scratch_ownership_checked": true
},
{
"enabled": true,
"public_boxes": 12800,
"provider_reads": 105239,
"edge_rays": 2197,
"visibility_digest": "da7286327283ce854dca2ab798d97c3b1cde55ac67112bd231c48df6d9388e00",
"query_digest": "124074ad764ab680b93896d47fa347a15f0b17ef41d2f8af5bd8e75f75208e12",
"intersection_digest": "f311c0b608b44b9eab2bb1e6347c3e18b003d05c939a8fbea9ba81fb16c8e8ae",
"allocated_bytes": 920,
"cpu_ns": 118540489,
"wall_ns": 235470173,
"measured_checks": 2000000,
"checksum": 0,
"input_unchanged": true,
"scratch_ownership_checked": true
}
],
"notes": [
"Actual upstream culling methods inside Fabric; private fixture invokers do not enter production packs.",
"Two interleaved instances and several occluder patterns; matching boolean and query digests.",
"Signed zero, tiny/large values, infinities and NaN are exercised directly in ray intersection.",
"Unchanged input vectors, independent instance scratch and upstream arithmetic values are checked.",
"Allocation and CPU are single warmed caller-loop observations; JIT folding can vary.",
"Not a game FPS, visual-equivalence proof, whole-game RAM or Mac GPU benchmark."
],
"provenance": {
"source_commit": "7cbe37b60594fb1631bc308f126d7925c4264a18",
"command": "python tools/test_culling_rays.py",
"workflow_run": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37168352974",
"job": "portable-mod (ubuntu-latest)",
"artifact": "horizon-ubuntu-latest"
}
}
@@ -1,71 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"entity_culling": "1.11.2",
"original_mod_sha256": "7351b417fc83460def5947636444413874ee812e949342f091ef03674e0c0e58",
"platform": "Linux x86_64",
"graphics": "llvmpipe software OpenGL",
"settings": {
"heap_bytes": 3221225472,
"gc": "G1",
"compact_headers": true,
"render_distance": 12,
"simulation_distance": 12,
"lod_radius_chunks": 128,
"lod_quality": "MEDIUM/MEDIUM/BLOCK",
"terrain_workers": 2,
"runtime_ratio": 0.5,
"world_difficulty": "PEACEFUL",
"empty_culling_whitelist": false
},
"results": [
{
"profile": "m2-balanced",
"ray_enabled": false,
"elapsed_seconds": 120.02619604,
"frame_samples": 599,
"tick_samples": 2400,
"excluded_frames": 0,
"dropped_samples": 0,
"visual_settings_changed": [],
"culling_allocation_counter": {
"thread_id": 49,
"thread": "CullThread",
"counter_observations": 2,
"observed_seconds": 64.509265987,
"observed_allocated_bytes": 1817768,
"observed_bytes_per_second": 28178.40153949851
}
},
{
"profile": "culling-rays",
"ray_enabled": true,
"elapsed_seconds": 120.099980458,
"frame_samples": 584,
"tick_samples": 2401,
"excluded_frames": 0,
"dropped_samples": 0,
"visual_settings_changed": [],
"culling_allocation_counter": {
"thread_id": 49,
"thread": "CullThread",
"counter_observations": 2,
"observed_seconds": 64.321034235,
"observed_allocated_bytes": 1798336,
"observed_bytes_per_second": 27958.754416629756
}
}
],
"notes": [
"Fixed-order single pair using separate copies of the same private saved world and stationary view, with approximately three-minute warm-up before clean frame recordings.",
"One earlier candidate frame capture contained pause exclusions and was discarded; its separate preceding allocation recording had already completed.",
"Allocation counters have their own roughly 64-second observation spans; recordings started approximately 36-42 seconds after joining. Profiling overhead and JIT/cache effects are not eliminated.",
"Both worlds saved and exited with no crash report or remaining game process. The outer foreground control launcher returned 143; it did not expose the game exit status.",
"No useful allocation reduction or whole-game speedup is established. Not a Mac, retained-memory or GPU performance benchmark."
],
"provenance": {
"source_commit": "349724b3b612351daa1616daa79beca8897839ab",
"runtime_mod_matches_linux_ci": true,
"workflow_run": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37168818519"
}
}
@@ -1,54 +0,0 @@
{
"schema": 1,
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"architecture": "x86_64",
"minecraft": "26.3",
"entity_culling": "1.11.2",
"original_mod_sha256": "7351b417fc83460def5947636444413874ee812e949342f091ef03674e0c0e58",
"results": [
{
"enabled": false,
"public_boxes": 12800,
"provider_reads": 105239,
"edge_rays": 2197,
"visibility_digest": "da7286327283ce854dca2ab798d97c3b1cde55ac67112bd231c48df6d9388e00",
"query_digest": "124074ad764ab680b93896d47fa347a15f0b17ef41d2f8af5bd8e75f75208e12",
"intersection_digest": "f311c0b608b44b9eab2bb1e6347c3e18b003d05c939a8fbea9ba81fb16c8e8ae",
"allocated_bytes": 24318096,
"cpu_ns": 166989515,
"wall_ns": 239648128,
"measured_checks": 2000000,
"checksum": 0,
"input_unchanged": true,
"scratch_ownership_checked": true
},
{
"enabled": true,
"public_boxes": 12800,
"provider_reads": 105239,
"edge_rays": 2197,
"visibility_digest": "da7286327283ce854dca2ab798d97c3b1cde55ac67112bd231c48df6d9388e00",
"query_digest": "124074ad764ab680b93896d47fa347a15f0b17ef41d2f8af5bd8e75f75208e12",
"intersection_digest": "f311c0b608b44b9eab2bb1e6347c3e18b003d05c939a8fbea9ba81fb16c8e8ae",
"allocated_bytes": 920,
"cpu_ns": 149367051,
"wall_ns": 165549458,
"measured_checks": 2000000,
"checksum": 0,
"input_unchanged": true,
"scratch_ownership_checked": true
}
],
"notes": [
"Actual upstream culling methods inside Fabric; private fixture invokers do not enter production packs.",
"Two interleaved instances and several occluder patterns; matching boolean and query digests.",
"Signed zero, tiny/large values, infinities and NaN are exercised directly in ray intersection.",
"Unchanged input vectors, independent instance scratch and upstream arithmetic values are checked.",
"Allocation and CPU are single warmed caller-loop observations; JIT folding can vary.",
"Not a game FPS, visual-equivalence proof, whole-game RAM or Mac GPU benchmark."
],
"provenance": {
"source_commit": "7cbe37b60594fb1631bc308f126d7925c4264a18",
"command": "python tools/test_culling_rays.py"
}
}
@@ -1,14 +0,0 @@
Java openjdk 25.0.4.1 2026-08-18 LTS
Platform Darwin 25.6.0 arm64; logical CPUs 3
mode=upstream size=1 polls=2050320 worker_cpu_ms=218.517 wall_ms=250.000 worker_allocated_bytes=65610240
mode=wait size=1 polls=24 worker_cpu_ms=1.116 wall_ms=250.103 worker_allocated_bytes=768
mode=upstream size=1 polls=2641880 worker_cpu_ms=247.157 wall_ms=250.000 worker_allocated_bytes=84540160
mode=wait size=1 polls=26 worker_cpu_ms=0.873 wall_ms=258.012 worker_allocated_bytes=832
mode=upstream size=1 polls=2502067 worker_cpu_ms=248.481 wall_ms=250.000 worker_allocated_bytes=80066144
mode=wait size=1 polls=22 worker_cpu_ms=0.693 wall_ms=252.426 worker_allocated_bytes=704
mode=upstream size=64 polls=1073260 worker_cpu_ms=249.930 wall_ms=250.000 worker_allocated_bytes=34344320
mode=wait size=64 polls=21 worker_cpu_ms=0.624 wall_ms=251.431 worker_allocated_bytes=672
mode=upstream size=64 polls=1117775 worker_cpu_ms=248.519 wall_ms=250.000 worker_allocated_bytes=35768800
mode=wait size=64 polls=66 worker_cpu_ms=1.172 wall_ms=252.401 worker_allocated_bytes=2112
mode=upstream size=64 polls=1017233 worker_cpu_ms=248.550 wall_ms=250.000 worker_allocated_bytes=32551456
mode=wait size=64 polls=74 worker_cpu_ms=1.154 wall_ms=250.207 worker_allocated_bytes=2368
@@ -1,14 +0,0 @@
Java openjdk 25.0.4.1 2026-08-18 LTS
Platform Linux 6.17.0-1022-azure x86_64; logical CPUs 4
mode=upstream size=1 polls=3147912 worker_cpu_ms=248.446 wall_ms=250.000 worker_allocated_bytes=100733184
mode=wait size=1 polls=234 worker_cpu_ms=3.085 wall_ms=250.068 worker_allocated_bytes=7488
mode=upstream size=1 polls=3108002 worker_cpu_ms=249.985 wall_ms=250.000 worker_allocated_bytes=99456064
mode=wait size=1 polls=235 worker_cpu_ms=2.960 wall_ms=250.088 worker_allocated_bytes=7520
mode=upstream size=1 polls=3073051 worker_cpu_ms=248.404 wall_ms=250.000 worker_allocated_bytes=98337632
mode=wait size=1 polls=235 worker_cpu_ms=2.904 wall_ms=250.067 worker_allocated_bytes=7520
mode=upstream size=64 polls=999765 worker_cpu_ms=248.680 wall_ms=250.000 worker_allocated_bytes=31992480
mode=wait size=64 polls=235 worker_cpu_ms=2.887 wall_ms=250.067 worker_allocated_bytes=7520
mode=upstream size=64 polls=999096 worker_cpu_ms=250.000 wall_ms=250.000 worker_allocated_bytes=31971072
mode=wait size=64 polls=234 worker_cpu_ms=2.890 wall_ms=250.068 worker_allocated_bytes=7488
mode=upstream size=64 polls=992373 worker_cpu_ms=249.987 wall_ms=250.000 worker_allocated_bytes=31755936
mode=wait size=64 polls=234 worker_cpu_ms=2.891 wall_ms=250.068 worker_allocated_bytes=7488
@@ -1,14 +0,0 @@
Java openjdk 25.0.4.1 2026-08-18 LTS
Platform Windows 2025Server AMD64; logical CPUs 4
mode=upstream size=1 polls=3016566 worker_cpu_ms=234.375 wall_ms=250.000 worker_allocated_bytes=96530112
mode=wait size=1 polls=173 worker_cpu_ms=0.000 wall_ms=250.006 worker_allocated_bytes=5536
mode=upstream size=1 polls=2991508 worker_cpu_ms=250.000 wall_ms=250.000 worker_allocated_bytes=95728256
mode=wait size=1 polls=175 worker_cpu_ms=0.000 wall_ms=250.856 worker_allocated_bytes=5600
mode=upstream size=1 polls=2979343 worker_cpu_ms=250.000 wall_ms=250.000 worker_allocated_bytes=95338976
mode=wait size=1 polls=171 worker_cpu_ms=0.000 wall_ms=251.306 worker_allocated_bytes=5472
mode=upstream size=64 polls=1001664 worker_cpu_ms=250.000 wall_ms=250.000 worker_allocated_bytes=32053248
mode=wait size=64 polls=168 worker_cpu_ms=0.000 wall_ms=250.695 worker_allocated_bytes=5376
mode=upstream size=64 polls=1001600 worker_cpu_ms=250.000 wall_ms=250.000 worker_allocated_bytes=32051200
mode=wait size=64 polls=166 worker_cpu_ms=0.000 wall_ms=250.593 worker_allocated_bytes=5312
mode=upstream size=64 polls=988856 worker_cpu_ms=234.375 wall_ms=250.000 worker_allocated_bytes=31643392
mode=wait size=64 polls=171 worker_cpu_ms=0.000 wall_ms=250.557 worker_allocated_bytes=5472
@@ -1,196 +0,0 @@
{
"schema": 1,
"measurement": "Single fixed-order stationary Linux software-rendered pair; targeted allocation observation, not a statistical FPS/RAM comparison",
"minecraft": "26.3",
"distant_horizons": "3.3.4",
"java_vendor": "Ubuntu",
"java_runtime_version": "25.0.4.1+1-1-26.04.4-Ubuntu",
"graphics": "llvmpipe LLVM21.1.8 OpenGL, 1280x800",
"captured_settings_match": true,
"settings": {
"render_distance": 12,
"simulation_distance": 12,
"lod_radius": 128,
"lod_quality": "MEDIUM/MEDIUM BLOCK",
"terrain_workers": 2,
"runtime_ratio_start_and_end": 0.5,
"world_difficulty": "PEACEFUL",
"fov": 70,
"heap_max": "3G",
"collector": "G1",
"compact_headers": true,
"frame_limit": "uncapped",
"other_original_controllers": false,
"interruptible_terrain_read": true
},
"runs": [
{
"profile": "m2-balanced",
"elapsed_seconds": 120.305371929,
"frame_samples": 230,
"tick_samples": 2401,
"tick_elapsed_seconds": 120.040272048,
"excluded_frames": 0,
"dropped_samples": 0,
"frame_stats": {
"count": 230,
"meanMs": 519.2565329826086,
"p50Ms": 492.583608,
"p95Ms": 700.364095,
"p99Ms": 803.28719,
"maxMs": 955.16614,
"meanRate": 1.9258303679994195,
"lowOnePercentRate": 1.146414365311511,
"over16Ms": 230,
"over33Ms": 230,
"over50Ms": 230,
"over100Ms": 230
},
"tick_execution_stats": {
"count": 2401,
"meanMs": 9.248066071636819,
"p50Ms": 8.529226,
"p95Ms": 16.494711,
"p99Ms": 23.483163,
"maxMs": 65.248147,
"meanRate": 108.13071535755256,
"lowOnePercentRate": 29.893225023275733,
"over16Ms": 113,
"over33Ms": 9,
"over50Ms": 2,
"over100Ms": 0
},
"process_cpu_seconds": 432.81,
"process_rss_peak_sampled_bytes": 2898677760,
"queue_wait": false,
"wakeable_idle": false,
"queue_allocation_counters": [
{
"thread_id": 86,
"thread": "DH-Chunk Update Queue [minecraft:overworld] Thread[0]",
"counter_observations": 2,
"observed_seconds": 64.391610411,
"observed_allocated_bytes": 982644080,
"observed_bytes_per_second": 15260436.471893786
},
{
"thread_id": 93,
"thread": "DH-Chunk Update Queue [minecraft:the_end] Thread[0]",
"counter_observations": 2,
"observed_seconds": 64.391610411,
"observed_allocated_bytes": 66520,
"observed_bytes_per_second": 1033.0538338055978
},
{
"thread_id": 98,
"thread": "DH-Chunk Update Queue [minecraft:the_nether] Thread[0]",
"counter_observations": 2,
"observed_seconds": 64.391610411,
"observed_allocated_bytes": 66408,
"observed_bytes_per_second": 1031.3144767793467
}
],
"preceding_jfr_gc_pause_total_ms": 178.149902,
"preceding_jfr_gc_pause_longest_ms": 34.011115,
"world_save_and_exit_zero": true
},
{
"profile": "queue-wait",
"elapsed_seconds": 120.448597645,
"frame_samples": 225,
"tick_samples": 2401,
"tick_elapsed_seconds": 120.040563501,
"excluded_frames": 0,
"dropped_samples": 0,
"frame_stats": {
"count": 225,
"meanMs": 529.5368389244444,
"p50Ms": 502.825816,
"p95Ms": 717.088739,
"p99Ms": 798.871994,
"maxMs": 843.221511,
"meanRate": 1.8884427418328913,
"lowOnePercentRate": 1.2159699757233216,
"over16Ms": 225,
"over33Ms": 225,
"over50Ms": 225,
"over100Ms": 225
},
"tick_execution_stats": {
"count": 2401,
"meanMs": 9.375896729279466,
"p50Ms": 8.803401,
"p95Ms": 16.938218,
"p99Ms": 22.983944,
"maxMs": 63.421671,
"meanRate": 106.65646485601272,
"lowOnePercentRate": 31.02504677094056,
"over16Ms": 128,
"over33Ms": 7,
"over50Ms": 2,
"over100Ms": 0
},
"process_cpu_seconds": 430.67,
"process_rss_peak_sampled_bytes": 2989219840,
"queue_wait": true,
"wakeable_idle": true,
"queue_allocation_counters": [
{
"thread_id": 88,
"thread": "DH-Chunk Update Queue [minecraft:overworld] Thread[0]",
"counter_observations": 2,
"observed_seconds": 64.387296767,
"observed_allocated_bytes": 739640,
"observed_bytes_per_second": 11487.359108684974
},
{
"thread_id": 93,
"thread": "DH-Chunk Update Queue [minecraft:the_nether] Thread[0]",
"counter_observations": 2,
"observed_seconds": 64.387296767,
"observed_allocated_bytes": 0,
"observed_bytes_per_second": 0.0
},
{
"thread_id": 100,
"thread": "DH-Chunk Update Queue [minecraft:the_end] Thread[0]",
"counter_observations": 2,
"observed_seconds": 64.387296767,
"observed_allocated_bytes": 0,
"observed_bytes_per_second": 0.0
}
],
"preceding_jfr_gc_pause_total_ms": 151.522451,
"preceding_jfr_gc_pause_longest_ms": 47.79999,
"world_save_and_exit_zero": true
}
],
"provenance": {
"production_mod_source_commit": "24c65f512dece83b153b206e33cd4c4294b42de2",
"original_mod_sha256": "2196637c5b2180a33fa5b926ab51069ab480618c1186b8a02872c7e758be0a70",
"initial_player_snapshot_sha256": "b4d11dbd6443625415a1e32aa242d0e2d09cd77ddb1becfde5d35cb6ab8d278a",
"source_level_snapshot_sha256": "86a3c75ea993e50c4428da4dbadc5856688a9367f035c41b8bb49863a9aeb644",
"first_saved_cameras_match": true,
"saved_camera": {
"position": [
-56.5,
69.0,
55.5
],
"rotation": [
141.5,
16.950002670288086
]
}
},
"notes": [
"Separate copies of the same private world; candidate then control. JFR begins about121seconds after demo dismissal; frame capture begins about307seconds after dismissal.",
"JFR allocation counters span about64seconds; pause measurements are from the preceding JFR recordings, not the later frame capture.",
"Recorded overworld queue allocation counter rate is about15.3MB/s upstream versus11.5KB/s with waiting. Task-completion and generated geometry volumes are not controlled quantitatively.",
"Control has230frames versus225candidate; sampled peak RSS is lower in control, and later whole-process CPU differences are small. No game FPS, retained-memory or whole-process CPU improvement is established.",
"Daylight advances normally; lighting, entity activity and cache/JIT differences are not fully controlled. No Apple Silicon or hardware-GPU result.",
"Tick meanRate is inverse execution duration, not observed TPS. Both recordings contain2401tick execution samples over about120seconds.",
"Actual JSON/CSV viewer comparisons and390pxlayout pass. The real discarded capture with zero eligible frames and209exclusions is rejected by the viewer and excluded from performance comparisons.",
"No private worlds, full game logs or JFR recordings are published."
]
}
@@ -1,34 +0,0 @@
{
"schema": 1,
"platform": "Linux-6.17.0-1022-azure-x86_64-with-glibc2.39",
"architecture": "x86_64",
"minecraft": "26.3",
"distant_horizons": "3.3.4",
"results": [
{
"enabled": false,
"submission_allocated_bytes": 216987192,
"submission_cpu_ns": 372949442,
"submission_wall_ns": 401548875,
"rejections": 63790,
"tasks_completed": 2,
"occupied_slots": 0
},
{
"enabled": true,
"submission_allocated_bytes": 103384,
"submission_cpu_ns": 941367,
"submission_wall_ns": 959453,
"rejections": 6,
"tasks_completed": 2,
"occupied_slots": 0
}
],
"notes": [
"Synthetic full physical worker queue; both modes use the actual publisher dispatcher inside Fabric.",
"Allocation and CPU measure the submission caller only; retry scheduler activity is excluded.",
"Upstream keeps the caller blocked for the requested 200 ms observation window; patched returns earlier.",
"Both modes verify exact task counts, recovered occupied slots and fixture worker shutdown.",
"Not a game FPS, terrain completion, whole-game RAM, or hardware compatibility benchmark."
]
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,42 +0,0 @@
Java openjdk 25.0.4.1 2026-08-18 LTS
Platform Darwin 25.6.0 arm64; logical CPUs 3
mode=upstream trial=0 incoming_after_idle_ms=26.655 publication_to_pop_ms=27.930
mode=wakeable trial=0 incoming_after_idle_ms=23.086 publication_to_pop_ms=0.098
mode=upstream trial=1 incoming_after_idle_ms=25.029 publication_to_pop_ms=94.707
mode=wakeable trial=1 incoming_after_idle_ms=19.340 publication_to_pop_ms=16.096
mode=upstream trial=2 incoming_after_idle_ms=16.530 publication_to_pop_ms=98.696
mode=wakeable trial=2 incoming_after_idle_ms=12.085 publication_to_pop_ms=0.080
mode=upstream trial=3 incoming_after_idle_ms=20.350 publication_to_pop_ms=50.086
mode=wakeable trial=3 incoming_after_idle_ms=15.681 publication_to_pop_ms=0.051
mode=upstream trial=4 incoming_after_idle_ms=26.474 publication_to_pop_ms=90.380
mode=wakeable trial=4 incoming_after_idle_ms=21.794 publication_to_pop_ms=0.054
mode=upstream trial=5 incoming_after_idle_ms=20.069 publication_to_pop_ms=91.508
mode=wakeable trial=5 incoming_after_idle_ms=14.527 publication_to_pop_ms=0.069
mode=upstream trial=6 incoming_after_idle_ms=25.051 publication_to_pop_ms=58.889
mode=wakeable trial=6 incoming_after_idle_ms=20.193 publication_to_pop_ms=0.081
mode=upstream trial=7 incoming_after_idle_ms=12.084 publication_to_pop_ms=41.323
mode=wakeable trial=7 incoming_after_idle_ms=5.867 publication_to_pop_ms=0.057
mode=upstream trial=8 incoming_after_idle_ms=19.023 publication_to_pop_ms=99.615
mode=wakeable trial=8 incoming_after_idle_ms=18.833 publication_to_pop_ms=0.063
mode=upstream trial=9 incoming_after_idle_ms=13.648 publication_to_pop_ms=103.446
mode=wakeable trial=9 incoming_after_idle_ms=28.375 publication_to_pop_ms=0.056
mode=upstream trial=10 incoming_after_idle_ms=17.449 publication_to_pop_ms=98.829
mode=wakeable trial=10 incoming_after_idle_ms=24.812 publication_to_pop_ms=0.062
mode=upstream trial=11 incoming_after_idle_ms=26.751 publication_to_pop_ms=88.715
mode=wakeable trial=11 incoming_after_idle_ms=28.154 publication_to_pop_ms=0.067
mode=upstream trial=12 incoming_after_idle_ms=20.596 publication_to_pop_ms=73.247
mode=wakeable trial=12 incoming_after_idle_ms=16.397 publication_to_pop_ms=0.080
mode=upstream trial=13 incoming_after_idle_ms=19.685 publication_to_pop_ms=53.674
mode=wakeable trial=13 incoming_after_idle_ms=21.934 publication_to_pop_ms=0.050
mode=upstream trial=14 incoming_after_idle_ms=16.937 publication_to_pop_ms=37.755
mode=wakeable trial=14 incoming_after_idle_ms=18.296 publication_to_pop_ms=0.074
mode=upstream trial=15 incoming_after_idle_ms=17.572 publication_to_pop_ms=68.115
mode=wakeable trial=15 incoming_after_idle_ms=13.516 publication_to_pop_ms=0.072
mode=upstream trial=16 incoming_after_idle_ms=24.639 publication_to_pop_ms=100.433
mode=wakeable trial=16 incoming_after_idle_ms=22.918 publication_to_pop_ms=0.103
mode=upstream trial=17 incoming_after_idle_ms=30.593 publication_to_pop_ms=79.830
mode=wakeable trial=17 incoming_after_idle_ms=25.080 publication_to_pop_ms=0.053
mode=upstream trial=18 incoming_after_idle_ms=15.889 publication_to_pop_ms=108.892
mode=wakeable trial=18 incoming_after_idle_ms=27.297 publication_to_pop_ms=0.034
mode=upstream trial=19 incoming_after_idle_ms=10.808 publication_to_pop_ms=59.234
mode=wakeable trial=19 incoming_after_idle_ms=16.349 publication_to_pop_ms=0.083
@@ -1,42 +0,0 @@
Java openjdk 25.0.4.1 2026-08-18 LTS
Platform Linux 6.17.0-1022-azure x86_64; logical CPUs 4
mode=upstream trial=0 incoming_after_idle_ms=5.089 publication_to_pop_ms=45.143
mode=wakeable trial=0 incoming_after_idle_ms=5.100 publication_to_pop_ms=0.073
mode=upstream trial=1 incoming_after_idle_ms=5.125 publication_to_pop_ms=45.051
mode=wakeable trial=1 incoming_after_idle_ms=5.097 publication_to_pop_ms=0.055
mode=upstream trial=2 incoming_after_idle_ms=5.098 publication_to_pop_ms=45.135
mode=wakeable trial=2 incoming_after_idle_ms=5.088 publication_to_pop_ms=0.042
mode=upstream trial=3 incoming_after_idle_ms=5.091 publication_to_pop_ms=45.084
mode=wakeable trial=3 incoming_after_idle_ms=5.149 publication_to_pop_ms=0.049
mode=upstream trial=4 incoming_after_idle_ms=5.103 publication_to_pop_ms=45.060
mode=wakeable trial=4 incoming_after_idle_ms=5.141 publication_to_pop_ms=0.064
mode=upstream trial=5 incoming_after_idle_ms=5.127 publication_to_pop_ms=45.047
mode=wakeable trial=5 incoming_after_idle_ms=5.137 publication_to_pop_ms=0.053
mode=upstream trial=6 incoming_after_idle_ms=5.129 publication_to_pop_ms=45.177
mode=wakeable trial=6 incoming_after_idle_ms=5.134 publication_to_pop_ms=0.068
mode=upstream trial=7 incoming_after_idle_ms=5.107 publication_to_pop_ms=45.059
mode=wakeable trial=7 incoming_after_idle_ms=5.137 publication_to_pop_ms=0.061
mode=upstream trial=8 incoming_after_idle_ms=5.168 publication_to_pop_ms=45.005
mode=wakeable trial=8 incoming_after_idle_ms=5.134 publication_to_pop_ms=0.060
mode=upstream trial=9 incoming_after_idle_ms=5.105 publication_to_pop_ms=45.077
mode=wakeable trial=9 incoming_after_idle_ms=5.148 publication_to_pop_ms=0.070
mode=upstream trial=10 incoming_after_idle_ms=5.092 publication_to_pop_ms=45.197
mode=wakeable trial=10 incoming_after_idle_ms=5.136 publication_to_pop_ms=0.055
mode=upstream trial=11 incoming_after_idle_ms=5.113 publication_to_pop_ms=45.045
mode=wakeable trial=11 incoming_after_idle_ms=5.122 publication_to_pop_ms=0.044
mode=upstream trial=12 incoming_after_idle_ms=5.095 publication_to_pop_ms=45.070
mode=wakeable trial=12 incoming_after_idle_ms=5.147 publication_to_pop_ms=0.052
mode=upstream trial=13 incoming_after_idle_ms=5.118 publication_to_pop_ms=45.048
mode=wakeable trial=13 incoming_after_idle_ms=5.168 publication_to_pop_ms=0.047
mode=upstream trial=14 incoming_after_idle_ms=5.133 publication_to_pop_ms=45.129
mode=wakeable trial=14 incoming_after_idle_ms=5.155 publication_to_pop_ms=0.047
mode=upstream trial=15 incoming_after_idle_ms=5.098 publication_to_pop_ms=45.031
mode=wakeable trial=15 incoming_after_idle_ms=5.167 publication_to_pop_ms=0.044
mode=upstream trial=16 incoming_after_idle_ms=5.129 publication_to_pop_ms=45.051
mode=wakeable trial=16 incoming_after_idle_ms=5.135 publication_to_pop_ms=0.073
mode=upstream trial=17 incoming_after_idle_ms=5.148 publication_to_pop_ms=45.034
mode=wakeable trial=17 incoming_after_idle_ms=5.148 publication_to_pop_ms=0.044
mode=upstream trial=18 incoming_after_idle_ms=5.181 publication_to_pop_ms=45.103
mode=wakeable trial=18 incoming_after_idle_ms=5.127 publication_to_pop_ms=0.046
mode=upstream trial=19 incoming_after_idle_ms=5.094 publication_to_pop_ms=45.075
mode=wakeable trial=19 incoming_after_idle_ms=5.148 publication_to_pop_ms=0.051
@@ -1,42 +0,0 @@
Java openjdk 25.0.4.1 2026-08-18 LTS
Platform Windows 2025Server AMD64; logical CPUs 4
mode=upstream trial=0 incoming_after_idle_ms=5.487 publication_to_pop_ms=45.519
mode=wakeable trial=0 incoming_after_idle_ms=5.377 publication_to_pop_ms=0.127
mode=upstream trial=1 incoming_after_idle_ms=6.059 publication_to_pop_ms=44.593
mode=wakeable trial=1 incoming_after_idle_ms=5.539 publication_to_pop_ms=0.094
mode=upstream trial=2 incoming_after_idle_ms=5.096 publication_to_pop_ms=45.005
mode=wakeable trial=2 incoming_after_idle_ms=5.624 publication_to_pop_ms=0.079
mode=upstream trial=3 incoming_after_idle_ms=5.649 publication_to_pop_ms=44.691
mode=wakeable trial=3 incoming_after_idle_ms=4.731 publication_to_pop_ms=0.077
mode=upstream trial=4 incoming_after_idle_ms=5.312 publication_to_pop_ms=45.488
mode=wakeable trial=4 incoming_after_idle_ms=5.156 publication_to_pop_ms=0.108
mode=upstream trial=5 incoming_after_idle_ms=5.190 publication_to_pop_ms=45.580
mode=wakeable trial=5 incoming_after_idle_ms=5.457 publication_to_pop_ms=0.077
mode=upstream trial=6 incoming_after_idle_ms=5.141 publication_to_pop_ms=45.619
mode=wakeable trial=6 incoming_after_idle_ms=5.592 publication_to_pop_ms=0.074
mode=upstream trial=7 incoming_after_idle_ms=5.823 publication_to_pop_ms=44.487
mode=wakeable trial=7 incoming_after_idle_ms=5.355 publication_to_pop_ms=0.066
mode=upstream trial=8 incoming_after_idle_ms=5.675 publication_to_pop_ms=45.050
mode=wakeable trial=8 incoming_after_idle_ms=5.252 publication_to_pop_ms=0.075
mode=upstream trial=9 incoming_after_idle_ms=5.921 publication_to_pop_ms=44.505
mode=wakeable trial=9 incoming_after_idle_ms=6.002 publication_to_pop_ms=0.072
mode=upstream trial=10 incoming_after_idle_ms=5.797 publication_to_pop_ms=44.517
mode=wakeable trial=10 incoming_after_idle_ms=5.103 publication_to_pop_ms=0.070
mode=upstream trial=11 incoming_after_idle_ms=5.115 publication_to_pop_ms=45.066
mode=wakeable trial=11 incoming_after_idle_ms=5.638 publication_to_pop_ms=0.071
mode=upstream trial=12 incoming_after_idle_ms=5.239 publication_to_pop_ms=45.538
mode=wakeable trial=12 incoming_after_idle_ms=5.666 publication_to_pop_ms=0.083
mode=upstream trial=13 incoming_after_idle_ms=5.136 publication_to_pop_ms=45.251
mode=wakeable trial=13 incoming_after_idle_ms=4.163 publication_to_pop_ms=0.073
mode=upstream trial=14 incoming_after_idle_ms=5.256 publication_to_pop_ms=46.048
mode=wakeable trial=14 incoming_after_idle_ms=5.545 publication_to_pop_ms=0.074
mode=upstream trial=15 incoming_after_idle_ms=4.239 publication_to_pop_ms=47.028
mode=wakeable trial=15 incoming_after_idle_ms=5.292 publication_to_pop_ms=0.053
mode=upstream trial=16 incoming_after_idle_ms=5.959 publication_to_pop_ms=45.046
mode=wakeable trial=16 incoming_after_idle_ms=5.230 publication_to_pop_ms=0.182
mode=upstream trial=17 incoming_after_idle_ms=5.153 publication_to_pop_ms=45.005
mode=wakeable trial=17 incoming_after_idle_ms=5.220 publication_to_pop_ms=0.066
mode=upstream trial=18 incoming_after_idle_ms=5.358 publication_to_pop_ms=46.008
mode=wakeable trial=18 incoming_after_idle_ms=5.156 publication_to_pop_ms=0.062
mode=upstream trial=19 incoming_after_idle_ms=4.370 publication_to_pop_ms=47.015
mode=wakeable trial=19 incoming_after_idle_ms=5.162 publication_to_pop_ms=0.073
@@ -1,930 +0,0 @@
{
"schema": 1,
"measurement": "Failed hosted macOS Vulkan graphics probes, not performance measurements",
"source_commit": "8282a731ecc08691f798a3ec596c7cc1d4f1dad1",
"run_url": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37193558884",
"original_mod_sha256": "e651ef49bc97486e8dacfd4b640465c442525cd645e2dba71ddea9fb64347dd8",
"cases": [
{
"case": [
"--profile",
"baseline",
"--backend",
"vulkan"
],
"exit_code": 1,
"failure": [
{
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"readback_requested": true,
"vulkan_error_codes": [
"VK_ERROR_FEATURE_NOT_PRESENT"
],
"fatal_jvm_error": false,
"profile": "baseline",
"preferred_backend": "vulkan"
}
]
},
{
"case": [
"--profile",
"core-performance",
"--backend",
"vulkan"
],
"exit_code": 1,
"failure": [
{
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"readback_requested": true,
"vulkan_error_codes": [
"VK_ERROR_FEATURE_NOT_PRESENT"
],
"fatal_jvm_error": false,
"profile": "core-performance",
"preferred_backend": "vulkan"
}
]
},
{
"case": [
"--profile",
"vulkan"
],
"exit_code": 1,
"failure": [
{
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"readback_requested": true,
"vulkan_error_codes": [
"VK_ERROR_FEATURE_NOT_PRESENT"
],
"fatal_jvm_error": false,
"profile": "vulkan",
"preferred_backend": "vulkan"
}
]
}
],
"limits": [
"Apple Paravirtual device and MoltenVK on a hosted ARM Mac; not physical M2 Pro GPU testing.",
"Library/device creation and readback request were observed, but no completed nonuniform readback report was produced.",
"All failures retained; neither successful rendering nor a screenshot-specific root cause is established.",
"Baseline includes the same original measurement mod and private test fixture; no core optimization mods or distant terrain.",
"Full logs, screenshots, game binaries and assets remain private.",
"Later selected stack locations place the observed failures in the screenshot callback; the independently logged Vulkan identifier is not established as their cause.",
"Actual assertions rejected uniform callback images in all three cases. Overlay state was not recorded, and displayed-window correctness is not established.",
"After guarding overlays, core/distant-terrain title readbacks pass but vanilla remains uniform; the aggregate research run fails. No world-rendering or physical-M2 claim.",
"Later world probes pass all three Vulkan cases on the hosted Mac; failed title cases remain retained. These are short startup/readback/save probes, not physical-GPU performance tests."
],
"later_stack_run": {
"source_commit": "a77476b54e7bf4a1b3a96cb9d8108ed7c1c7b2b0",
"run_url": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37193954843",
"cases": [
{
"case": [
"--profile",
"baseline",
"--backend",
"vulkan"
],
"exit_code": 1,
"failure": [
{
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"readback_requested": true,
"vulkan_error_codes": [
"VK_ERROR_FEATURE_NOT_PRESENT"
],
"fatal_jvm_error": false,
"observed_graphics_stack_methods": [
"net.minecraft.client.Screenshot.lambda$takeScreenshot$1",
"com.mojang.renderpearl.backend.vulkan.DestructionQueue.rotate",
"com.mojang.renderpearl.backend.vulkan.VulkanCommandEncoder.submit",
"com.mojang.renderpearl.frontend.FrontendCommandEncoder.submit"
],
"profile": "baseline",
"preferred_backend": "vulkan"
}
]
},
{
"case": [
"--profile",
"core-performance",
"--backend",
"vulkan"
],
"exit_code": 1,
"failure": [
{
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"readback_requested": true,
"vulkan_error_codes": [
"VK_ERROR_FEATURE_NOT_PRESENT"
],
"fatal_jvm_error": false,
"observed_graphics_stack_methods": [
"net.minecraft.client.Screenshot.lambda$takeScreenshot$1",
"com.mojang.renderpearl.backend.vulkan.DestructionQueue.rotate",
"com.mojang.renderpearl.backend.vulkan.VulkanCommandEncoder.submit",
"com.mojang.renderpearl.frontend.FrontendCommandEncoder.submit"
],
"profile": "core-performance",
"preferred_backend": "vulkan"
}
]
},
{
"case": [
"--profile",
"vulkan"
],
"exit_code": 1,
"failure": [
{
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"readback_requested": true,
"vulkan_error_codes": [
"VK_ERROR_FEATURE_NOT_PRESENT"
],
"fatal_jvm_error": false,
"observed_graphics_stack_methods": [
"net.minecraft.client.Screenshot.lambda$takeScreenshot$1",
"com.mojang.renderpearl.backend.vulkan.DestructionQueue.rotate",
"com.mojang.renderpearl.backend.vulkan.VulkanCommandEncoder.submit",
"com.mojang.renderpearl.frontend.FrontendCommandEncoder.submit"
],
"profile": "vulkan",
"preferred_backend": "vulkan"
}
]
}
]
},
"later_pixel_run": {
"source_commit": "213498c77ed643617083dacf4aaa283a1cb4815a",
"run_url": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37194354615",
"cases": [
{
"case": [
"--profile",
"baseline",
"--backend",
"vulkan"
],
"exit_code": 1,
"failure": [
{
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"readback_requested": true,
"readback_callback_received": true,
"readback_inspections": [
{
"framebuffer_width": 1280,
"framebuffer_height": 646,
"sampled_pixels": 4160,
"distinct_sampled_rgb": 1
}
],
"probe_failure_categories": [
"uniform_readback"
],
"vulkan_error_codes": [
"VK_ERROR_FEATURE_NOT_PRESENT"
],
"fatal_jvm_error": false,
"observed_graphics_stack_methods": [
"net.minecraft.client.Screenshot.lambda$takeScreenshot$1",
"com.mojang.renderpearl.backend.vulkan.DestructionQueue.rotate",
"com.mojang.renderpearl.backend.vulkan.VulkanCommandEncoder.submit",
"com.mojang.renderpearl.frontend.FrontendCommandEncoder.submit"
],
"profile": "baseline",
"preferred_backend": "vulkan"
}
]
},
{
"case": [
"--profile",
"core-performance",
"--backend",
"vulkan"
],
"exit_code": 1,
"failure": [
{
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"readback_requested": true,
"readback_callback_received": true,
"readback_inspections": [
{
"framebuffer_width": 1280,
"framebuffer_height": 646,
"sampled_pixels": 4160,
"distinct_sampled_rgb": 1
}
],
"probe_failure_categories": [
"uniform_readback"
],
"vulkan_error_codes": [
"VK_ERROR_FEATURE_NOT_PRESENT"
],
"fatal_jvm_error": false,
"observed_graphics_stack_methods": [
"net.minecraft.client.Screenshot.lambda$takeScreenshot$1",
"com.mojang.renderpearl.backend.vulkan.DestructionQueue.rotate",
"com.mojang.renderpearl.backend.vulkan.VulkanCommandEncoder.submit",
"com.mojang.renderpearl.frontend.FrontendCommandEncoder.submit"
],
"profile": "core-performance",
"preferred_backend": "vulkan"
}
]
},
{
"case": [
"--profile",
"vulkan"
],
"exit_code": 1,
"failure": [
{
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"readback_requested": true,
"readback_callback_received": true,
"readback_inspections": [
{
"framebuffer_width": 1280,
"framebuffer_height": 646,
"sampled_pixels": 4160,
"distinct_sampled_rgb": 1
}
],
"probe_failure_categories": [
"uniform_readback"
],
"vulkan_error_codes": [
"VK_ERROR_FEATURE_NOT_PRESENT"
],
"fatal_jvm_error": false,
"observed_graphics_stack_methods": [
"net.minecraft.client.Screenshot.lambda$takeScreenshot$1",
"com.mojang.renderpearl.backend.vulkan.DestructionQueue.rotate",
"com.mojang.renderpearl.backend.vulkan.VulkanCommandEncoder.submit",
"com.mojang.renderpearl.frontend.FrontendCommandEncoder.submit"
],
"profile": "vulkan",
"preferred_backend": "vulkan"
}
]
}
]
},
"later_overlay_run": {
"source_commit": "a1d8c1b8246008ac4076cdcaf0f64c71eaf4c767",
"run_url": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37194690645",
"cases": [
{
"case": [
"--profile",
"baseline",
"--backend",
"vulkan"
],
"exit_code": 1,
"failure": [
{
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"readback_requested": true,
"readback_callback_received": true,
"readback_inspections": [
{
"framebuffer_width": 1280,
"framebuffer_height": 646,
"sampled_pixels": 4160,
"distinct_sampled_rgb": 1
}
],
"probe_failure_categories": [
"uniform_readback"
],
"vulkan_error_codes": [
"VK_ERROR_FEATURE_NOT_PRESENT"
],
"fatal_jvm_error": false,
"observed_graphics_stack_methods": [
"net.minecraft.client.Screenshot.lambda$takeScreenshot$1",
"com.mojang.renderpearl.backend.vulkan.DestructionQueue.rotate",
"com.mojang.renderpearl.backend.vulkan.VulkanCommandEncoder.submit",
"com.mojang.renderpearl.frontend.FrontendCommandEncoder.submit"
],
"profile": "baseline",
"preferred_backend": "vulkan"
}
]
},
{
"case": [
"--profile",
"core-performance",
"--backend",
"vulkan"
],
"exit_code": 0,
"report": {
"schema": 1,
"platform": "macOS-26.6.2-arm64-arm-64bit",
"architecture": "arm64",
"minecraft": "26.3",
"original_mod_sha256": "e651ef49bc97486e8dacfd4b640465c442525cd645e2dba71ddea9fb64347dd8",
"results": [
{
"observed_mode": "title",
"title_screen_observed": true,
"world_loaded": false,
"ready_client_ticks": 42,
"window_active": true,
"overlay_present": false,
"overlay_wait_ticks": 105,
"framebuffer_width": 1280,
"framebuffer_height": 646,
"sampled_pixels": 4160,
"distinct_sampled_rgb": 163,
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2",
"private_png_sha256": "3c802923766cf9e7f45020bc2d858c23de655cb8e35fa058a050e7b09a1d3708",
"profile": "core-performance",
"preferred_backend": "vulkan",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
]
}
],
"limits": [
"Short scene startup and nonuniform framebuffer readback only.",
"World mode uses the ordinary limited demo; world files remain private.",
"No exhaustive gameplay, visual-correctness, FPS or M2 Pro performance claim.",
"Vulkan preference can fall back; inspect the observed backend.",
"PNG images, assets and full logs remain in the private runtime directory."
]
}
},
{
"case": [
"--profile",
"vulkan"
],
"exit_code": 0,
"report": {
"schema": 1,
"platform": "macOS-26.6.2-arm64-arm-64bit",
"architecture": "arm64",
"minecraft": "26.3",
"original_mod_sha256": "e651ef49bc97486e8dacfd4b640465c442525cd645e2dba71ddea9fb64347dd8",
"results": [
{
"observed_mode": "title",
"title_screen_observed": true,
"world_loaded": false,
"ready_client_ticks": 42,
"window_active": true,
"overlay_present": false,
"overlay_wait_ticks": 122,
"framebuffer_width": 1280,
"framebuffer_height": 646,
"sampled_pixels": 4160,
"distinct_sampled_rgb": 163,
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2",
"private_png_sha256": "3c802923766cf9e7f45020bc2d858c23de655cb8e35fa058a050e7b09a1d3708",
"profile": "vulkan",
"preferred_backend": "vulkan",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
]
}
],
"limits": [
"Short scene startup and nonuniform framebuffer readback only.",
"World mode uses the ordinary limited demo; world files remain private.",
"No exhaustive gameplay, visual-correctness, FPS or M2 Pro performance claim.",
"Vulkan preference can fall back; inspect the observed backend.",
"PNG images, assets and full logs remain in the private runtime directory."
]
}
}
]
},
"later_world_run": {
"source_commit": "5f9f973295c5cc948a6999a849c2c843f5e831f6",
"run_url": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37195149166",
"cases": [
{
"case": [
"--profile",
"baseline",
"--backend",
"vulkan",
"--world"
],
"exit_code": 0,
"report": {
"schema": 1,
"platform": "macOS-26.6.2-arm64-arm-64bit",
"architecture": "arm64",
"minecraft": "26.3",
"original_mod_sha256": "e651ef49bc97486e8dacfd4b640465c442525cd645e2dba71ddea9fb64347dd8",
"results": [
{
"observed_mode": "world",
"title_screen_observed": false,
"world_loaded": true,
"ready_client_ticks": 42,
"window_active": true,
"overlay_present": false,
"overlay_wait_ticks": 323,
"framebuffer_width": 1280,
"framebuffer_height": 646,
"sampled_pixels": 4160,
"distinct_sampled_rgb": 1278,
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2",
"private_png_sha256": "9e9be2562390f24fe8c8e0442ef9cdfd47910febd95d8f0c0f5706191a53f1f6",
"profile": "baseline",
"preferred_backend": "vulkan",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
]
}
],
"limits": [
"Short scene startup and nonuniform framebuffer readback only.",
"World mode uses the ordinary limited demo; world files remain private.",
"No exhaustive gameplay, visual-correctness, FPS or M2 Pro performance claim.",
"Vulkan preference can fall back; inspect the observed backend.",
"PNG images, assets and full logs remain in the private runtime directory."
]
}
},
{
"case": [
"--profile",
"core-performance",
"--backend",
"vulkan",
"--world"
],
"exit_code": 0,
"report": {
"schema": 1,
"platform": "macOS-26.6.2-arm64-arm-64bit",
"architecture": "arm64",
"minecraft": "26.3",
"original_mod_sha256": "e651ef49bc97486e8dacfd4b640465c442525cd645e2dba71ddea9fb64347dd8",
"results": [
{
"observed_mode": "world",
"title_screen_observed": false,
"world_loaded": true,
"ready_client_ticks": 51,
"window_active": true,
"overlay_present": false,
"overlay_wait_ticks": 90,
"framebuffer_width": 1280,
"framebuffer_height": 646,
"sampled_pixels": 4160,
"distinct_sampled_rgb": 1024,
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2",
"private_png_sha256": "e0a6ad253ca0490b35217ce9ad799dc7d4c04e4ecf446eeacd1aa5196db317bb",
"profile": "core-performance",
"preferred_backend": "vulkan",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
]
}
],
"limits": [
"Short scene startup and nonuniform framebuffer readback only.",
"World mode uses the ordinary limited demo; world files remain private.",
"No exhaustive gameplay, visual-correctness, FPS or M2 Pro performance claim.",
"Vulkan preference can fall back; inspect the observed backend.",
"PNG images, assets and full logs remain in the private runtime directory."
]
}
},
{
"case": [
"--profile",
"vulkan",
"--world"
],
"exit_code": 0,
"report": {
"schema": 1,
"platform": "macOS-26.6.2-arm64-arm-64bit",
"architecture": "arm64",
"minecraft": "26.3",
"original_mod_sha256": "e651ef49bc97486e8dacfd4b640465c442525cd645e2dba71ddea9fb64347dd8",
"results": [
{
"observed_mode": "world",
"title_screen_observed": false,
"world_loaded": true,
"ready_client_ticks": 53,
"window_active": true,
"overlay_present": false,
"overlay_wait_ticks": 88,
"framebuffer_width": 1280,
"framebuffer_height": 646,
"sampled_pixels": 4160,
"distinct_sampled_rgb": 1287,
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2",
"private_png_sha256": "a17d1740e34cc9f49b67a4c56f51d0843f756e9d2eb3d19d6a926ad5f8f0ed36",
"profile": "vulkan",
"preferred_backend": "vulkan",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
]
}
],
"limits": [
"Short scene startup and nonuniform framebuffer readback only.",
"World mode uses the ordinary limited demo; world files remain private.",
"No exhaustive gameplay, visual-correctness, FPS or M2 Pro performance claim.",
"Vulkan preference can fall back; inspect the observed backend.",
"PNG images, assets and full logs remain in the private runtime directory."
]
}
}
]
},
"local_linux_core_vulkan_world": {
"schema": 1,
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"architecture": "x86_64",
"minecraft": "26.3",
"original_mod_sha256": "e651ef49bc97486e8dacfd4b640465c442525cd645e2dba71ddea9fb64347dd8",
"results": [
{
"observed_mode": "world",
"title_screen_observed": false,
"world_loaded": true,
"ready_client_ticks": 47,
"window_active": true,
"overlay_present": false,
"overlay_wait_ticks": 111,
"framebuffer_width": 1280,
"framebuffer_height": 800,
"sampled_pixels": 4288,
"distinct_sampled_rgb": 1895,
"gpu": "llvmpipe (LLVM 21.1.8, 256 bits)",
"graphics_backend": "Vulkan",
"graphics_driver": "1.4.335 llvmpipe Mesa 26.0.8-1ubuntu0.3 (LLVM 21.1.8)",
"private_png_sha256": "52b26102b3037cab4ab6b7011a6c1255eebaa808d1d3dd5e77ff23fcde092acb",
"profile": "core-performance",
"preferred_backend": "vulkan",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
]
}
],
"limits": [
"Short scene startup and nonuniform framebuffer readback only.",
"World mode uses the ordinary limited demo; world files remain private.",
"No exhaustive gameplay, visual-correctness, FPS or M2 Pro performance claim.",
"Vulkan preference can fall back; inspect the observed backend.",
"PNG images, assets and full logs remain in the private runtime directory."
]
}
}
@@ -1,104 +0,0 @@
Java openjdk 25.0.4.1 2026-08-18 LTS
Platform Darwin 25.6.0 arm64; logical CPUs 3
fork=0 requested_compact_headers=False
compact_object_headers=false
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
fork=0 requested_compact_headers=True
compact_object_headers=true
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
fork=1 requested_compact_headers=False
compact_object_headers=false
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
fork=1 requested_compact_headers=True
compact_object_headers=true
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
fork=2 requested_compact_headers=False
compact_object_headers=false
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
fork=2 requested_compact_headers=True
compact_object_headers=true
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
@@ -1,104 +0,0 @@
Java openjdk 25.0.4.1 2026-08-18 LTS
Platform Linux 6.17.0-1022-azure x86_64; logical CPUs 4
fork=0 requested_compact_headers=False
compact_object_headers=false
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
fork=0 requested_compact_headers=True
compact_object_headers=true
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
fork=1 requested_compact_headers=False
compact_object_headers=false
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
fork=1 requested_compact_headers=True
compact_object_headers=true
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
fork=2 requested_compact_headers=False
compact_object_headers=false
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
fork=2 requested_compact_headers=True
compact_object_headers=true
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
@@ -1,104 +0,0 @@
Java openjdk 25.0.4.1 2026-08-18 LTS
Platform Windows 2025Server AMD64; logical CPUs 4
fork=0 requested_compact_headers=False
compact_object_headers=false
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
fork=0 requested_compact_headers=True
compact_object_headers=true
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
fork=1 requested_compact_headers=False
compact_object_headers=false
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
fork=1 requested_compact_headers=True
compact_object_headers=true
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
fork=2 requested_compact_headers=False
compact_object_headers=false
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=AABB objects=100000 allocated_bytes=6400000 bytes_per_object=64.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=Vec3 objects=100000 allocated_bytes=4000000 bytes_per_object=40.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
fork=2 requested_compact_headers=True
compact_object_headers=true
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=AABB objects=100000 allocated_bytes=5600000 bytes_per_object=56.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=Vec3 objects=100000 allocated_bytes=3200000 bytes_per_object=32.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=DhChunkPos objects=100000 allocated_bytes=2400000 bytes_per_object=24.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Long objects=100000 allocated_bytes=1600000 bytes_per_object=16.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
type=Object objects=100000 allocated_bytes=800000 bytes_per_object=8.000
@@ -1,67 +0,0 @@
{
"schema": 1,
"purpose": "Earlier private quad-reuse explorations; CPU mixed and allocation reduction is not retained RAM/FPS",
"original_mod_sha256": "98f8db7ca8962a71625eef835f57d25c8afb802f2cf1b7c4c832fc070757e011",
"private_fixture_sources": "Uncommitted private prototype before the production-hook fixture; not the final reproducible protocol",
"observations": [
{
"private_probe": "latest-discarded-object",
"results": [
{
"enabled": false,
"applied_hook_checked": true,
"geometry_digest": "31509677879305c6a721677b38516fda0336f8c7b53dc3946839eb6fbf7fd0ee",
"geometry_quads": 108358,
"input_faces": 55296,
"measured_faces": 3072000,
"checksum": 60000,
"cpu_ns": 166481448,
"allocated_bytes": 144576000,
"observations": [
{
"cpu_ns": 54349387,
"allocated_bytes": 48192000
},
{
"cpu_ns": 84133914,
"allocated_bytes": 48192000
},
{
"cpu_ns": 27998147,
"allocated_bytes": 48192000
}
]
},
{
"enabled": true,
"applied_hook_checked": true,
"geometry_digest": "31509677879305c6a721677b38516fda0336f8c7b53dc3946839eb6fbf7fd0ee",
"geometry_quads": 108358,
"input_faces": 55296,
"measured_faces": 3072000,
"checksum": 60000,
"cpu_ns": 185505067,
"allocated_bytes": 2016000,
"observations": [
{
"cpu_ns": 59897923,
"allocated_bytes": 672000
},
{
"cpu_ns": 63778316,
"allocated_bytes": 672000
},
{
"cpu_ns": 61828828,
"allocated_bytes": 672000
}
]
}
]
},
{
"private_probe": "first-discarded-object",
"results": []
}
]
}
@@ -1,75 +0,0 @@
{
"schema": 1,
"platform": "Linux-6.17.0-1022-azure-x86_64-with-glibc2.39",
"architecture": "x86_64",
"minecraft": "26.3",
"distant_horizons": "3.3.4",
"original_mod_sha256": "2196637c5b2180a33fa5b926ab51069ab480618c1186b8a02872c7e758be0a70",
"results": [
{
"enabled": false,
"applied_hook_checked": true,
"geometry_digest": "8251175aa3e3cac30bb1366f8b40d0576c17978076ea7d244ff4d7cc361da7ee",
"thread_geometry_digest": "096a85be06031d248f12e536e19e5c0496bb00c80f3387f670a0fae29438a732",
"thread_workers": 4,
"geometry_quads": 108358,
"input_faces": 55296,
"measured_faces": 3072000,
"checksum": 60000,
"cpu_ns": 40437624,
"allocated_bytes": 144576000,
"observations": [
{
"cpu_ns": 13455029,
"allocated_bytes": 48192000
},
{
"cpu_ns": 13828075,
"allocated_bytes": 48192000
},
{
"cpu_ns": 13154520,
"allocated_bytes": 48192000
}
]
},
{
"enabled": true,
"applied_hook_checked": true,
"geometry_digest": "8251175aa3e3cac30bb1366f8b40d0576c17978076ea7d244ff4d7cc361da7ee",
"thread_geometry_digest": "096a85be06031d248f12e536e19e5c0496bb00c80f3387f670a0fae29438a732",
"thread_workers": 4,
"geometry_quads": 108358,
"input_faces": 55296,
"measured_faces": 3072000,
"checksum": 60000,
"cpu_ns": 44074799,
"allocated_bytes": 2016000,
"observations": [
{
"cpu_ns": 16004752,
"allocated_bytes": 672000
},
{
"cpu_ns": 14047833,
"allocated_bytes": 672000
},
{
"cpu_ns": 14022214,
"allocated_bytes": 672000
}
]
}
],
"notes": [
"Actual publisher quad builder inside Fabric with generated faces and lighting/material values.",
"Opaque/translucent geometry, pooled error flags and every retained quad field match before and after upstream merging.",
"Fresh allocations reuse at most one discarded successful-premerge quad; existing pool selection stays upstream.",
"Three sequential warmed caller-loop observations are not independent forks; compilation can vary.",
"Allocation reduction is not retained RAM, game FPS or a Mac GPU benchmark."
],
"provenance": {
"source_commit": "0a0cd667d5cfdee7c59f5fe2c7a2eb15bd19e66e",
"workflow_run": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37175709062"
}
}
@@ -1,166 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"distant_horizons": "3.3.4",
"original_mod_sha256": "2196637c5b2180a33fa5b926ab51069ab480618c1186b8a02872c7e758be0a70",
"platform": "Linux x86_64",
"graphics": "llvmpipe software OpenGL",
"settings": {
"heap_bytes": 3221225472,
"gc": "G1",
"compact_headers": true,
"render_distance": 12,
"simulation_distance": 12,
"lod_radius_chunks": 128,
"lod_quality": "MEDIUM/MEDIUM/BLOCK",
"terrain_workers": 2,
"runtime_ratio": 0.5,
"world_difficulty": "PEACEFUL"
},
"results": [
{
"profile": "m2-balanced",
"quad_reuse_enabled": false,
"elapsed_seconds": 120.415309971,
"frame_samples": 220,
"tick_samples": 2400,
"excluded_frames": 0,
"dropped_samples": 0,
"visual_settings_changed": [],
"frame_stats": {
"count": 220,
"meanMs": 542.3438610045455,
"p50Ms": 522.365908,
"p95Ms": 713.237831,
"p99Ms": 860.91664,
"maxMs": 885.115974,
"meanRate": 1.8438486574693962,
"lowOnePercentRate": 1.1446485854821962,
"over16Ms": 220,
"over33Ms": 220,
"over50Ms": 220,
"over100Ms": 220
},
"tick_stats": {
"count": 2400,
"meanMs": 9.639125558749999,
"p50Ms": 9.137695,
"p95Ms": 16.989389,
"p99Ms": 25.152306,
"maxMs": 52.879001,
"meanRate": 103.74385040479541,
"lowOnePercentRate": 30.37834831626593,
"over16Ms": 133,
"over33Ms": 8,
"over50Ms": 2,
"over100Ms": 0
},
"process_rss_peak_sampled_bytes": 3129790464,
"render_loader_allocation_counters": [
{
"thread_id": 124,
"thread": "DH-Render Loader Thread[1]",
"counter_observations": 2,
"observed_seconds": 64.375191422,
"observed_allocated_bytes": 97869576,
"observed_bytes_per_second": 1520299.5725237317
},
{
"thread_id": 123,
"thread": "DH-Render Loader Thread[0]",
"counter_observations": 2,
"observed_seconds": 64.375191422,
"observed_allocated_bytes": 91443128,
"observed_bytes_per_second": 1420471.5509203072
}
],
"preceding_jfr_gc_pause_total_ms": 263.975028,
"preceding_jfr_gc_pause_longest_ms": 45.0698
},
{
"profile": "quad-reuse",
"quad_reuse_enabled": true,
"elapsed_seconds": 120.476138714,
"frame_samples": 224,
"tick_samples": 2401,
"excluded_frames": 0,
"dropped_samples": 0,
"visual_settings_changed": [],
"frame_stats": {
"count": 224,
"meanMs": 532.6331643258928,
"p50Ms": 505.6209,
"p95Ms": 735.235244,
"p99Ms": 774.189261,
"maxMs": 926.006251,
"meanRate": 1.8774647674551252,
"lowOnePercentRate": 1.208934822852848,
"over16Ms": 224,
"over33Ms": 224,
"over50Ms": 224,
"over100Ms": 224
},
"tick_stats": {
"count": 2401,
"meanMs": 9.308558193669304,
"p50Ms": 8.82277,
"p95Ms": 16.529268,
"p99Ms": 22.206144,
"maxMs": 95.741877,
"meanRate": 107.42802259968617,
"lowOnePercentRate": 30.32324112917506,
"over16Ms": 114,
"over33Ms": 8,
"over50Ms": 3,
"over100Ms": 0
},
"process_rss_peak_sampled_bytes": 3100016640,
"render_loader_allocation_counters": [
{
"thread_id": 125,
"thread": "DH-Render Loader Thread[1]",
"counter_observations": 2,
"observed_seconds": 64.347664971,
"observed_allocated_bytes": 116155920,
"observed_bytes_per_second": 1805130.3035214841
},
{
"thread_id": 124,
"thread": "DH-Render Loader Thread[0]",
"counter_observations": 2,
"observed_seconds": 64.347664971,
"observed_allocated_bytes": 104401656,
"observed_bytes_per_second": 1622462.229935638
}
],
"preceding_jfr_gc_pause_total_ms": 166.770211,
"preceding_jfr_gc_pause_longest_ms": 46.786101
}
],
"provenance": {
"source_commit": "0a0cd667d5cfdee7c59f5fe2c7a2eb15bd19e66e",
"workflow_run": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37175709062",
"runtime_mod_matches_linux_ci": true,
"initial_player_snapshot_sha256": "b4d11dbd6443625415a1e32aa242d0e2d09cd77ddb1becfde5d35cb6ab8d278a",
"source_level_snapshot_sha256": "86a3c75ea993e50c4428da4dbadc5856688a9367f035c41b8bb49863a9aeb644",
"first_saved_player_position": [
-56.5,
69.0,
55.5
],
"first_saved_player_rotation": [
141.5,
16.950002670288086
],
"first_saved_cameras_matched": true
},
"notes": [
"Fixed-order candidate then control single pair from separate copies of the same private world. Both stationary captures start approximately 307 seconds after the demo popup is dismissed; first saved cameras match.",
"Both reports have zero menu/pause/focus exclusions, no dropped samples and matching captured settings apart from the isolated quad hook. CSV counts and actual offline viewer timelines pass.",
"The preceding 60-second JFR recordings begin approximately 121 seconds after dismissal. Allocation counters have their own approximately 64-second spans; GC pause data is from those recordings, not from the later frame captures.",
"Render-loader allocation counter rates are higher in this candidate observation. Task-completion/geometry volumes and cache/JIT effects are not controlled quantitatively. No useful live allocation improvement is established.",
"Frame count and sampled peak RSS differences in this single software-rendered pair do not establish a meaningful game speed or retained-memory gain. RSS is not complete GPU/unified RAM. Not an Apple Silicon benchmark.",
"Candidate saved, reloaded, saved again and exited with launcher code zero. Control saved, closed all terrain databases and exited with launcher code zero.",
"No private worlds, full game logs or JFR recordings are included in these selected observations."
]
}
@@ -1,75 +0,0 @@
{
"schema": 1,
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"architecture": "x86_64",
"minecraft": "26.3",
"distant_horizons": "3.3.4",
"original_mod_sha256": "2196637c5b2180a33fa5b926ab51069ab480618c1186b8a02872c7e758be0a70",
"results": [
{
"enabled": false,
"applied_hook_checked": true,
"geometry_digest": "8251175aa3e3cac30bb1366f8b40d0576c17978076ea7d244ff4d7cc361da7ee",
"thread_geometry_digest": "096a85be06031d248f12e536e19e5c0496bb00c80f3387f670a0fae29438a732",
"thread_workers": 4,
"geometry_quads": 108358,
"input_faces": 55296,
"measured_faces": 3072000,
"checksum": 60000,
"cpu_ns": 198847198,
"allocated_bytes": 144576000,
"observations": [
{
"cpu_ns": 82119774,
"allocated_bytes": 48192000
},
{
"cpu_ns": 60671068,
"allocated_bytes": 48192000
},
{
"cpu_ns": 56056356,
"allocated_bytes": 48192000
}
]
},
{
"enabled": true,
"applied_hook_checked": true,
"geometry_digest": "8251175aa3e3cac30bb1366f8b40d0576c17978076ea7d244ff4d7cc361da7ee",
"thread_geometry_digest": "096a85be06031d248f12e536e19e5c0496bb00c80f3387f670a0fae29438a732",
"thread_workers": 4,
"geometry_quads": 108358,
"input_faces": 55296,
"measured_faces": 3072000,
"checksum": 60000,
"cpu_ns": 178894413,
"allocated_bytes": 2016000,
"observations": [
{
"cpu_ns": 60070905,
"allocated_bytes": 672000
},
{
"cpu_ns": 60020252,
"allocated_bytes": 672000
},
{
"cpu_ns": 58803256,
"allocated_bytes": 672000
}
]
}
],
"notes": [
"Actual publisher quad builder inside Fabric with generated faces and lighting/material values.",
"Opaque/translucent geometry, pooled error flags and every retained quad field match before and after upstream merging.",
"Fresh allocations reuse at most one discarded successful-premerge quad; existing pool selection stays upstream.",
"Three sequential warmed caller-loop observations are not independent forks; compilation can vary.",
"Allocation reduction is not retained RAM, game FPS or a Mac GPU benchmark."
],
"provenance": {
"source_commit": "0a0cd667d5cfdee7c59f5fe2c7a2eb15bd19e66e",
"fixture_protocol": "55,296 generated faces plus four concurrent builders, geometry/list boundaries checked before and after upstream merge; warm 2,000 batches, then 500 warm batches and 2,000 measured batches per sequential observation, 512 faces/batch"
}
}
@@ -1,87 +0,0 @@
{
"schema": 1,
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"architecture": "x86_64",
"minecraft": "26.3",
"distant_horizons": "3.3.4",
"original_mod_sha256": "2196637c5b2180a33fa5b926ab51069ab480618c1186b8a02872c7e758be0a70",
"results": [
{
"enabled": false,
"compact_headers": false,
"builder_shallow_bytes": 48,
"quad_shallow_bytes": 56,
"pending_scratch_shallow_bytes": 0,
"geometry_quads": 1,
"java_vendor": "Ubuntu",
"java_runtime_version": "25.0.4.1+1-1-26.04.4-Ubuntu",
"object_alignment_bytes": 8,
"compressed_oops": true,
"compressed_class_pointers": true
},
{
"enabled": true,
"compact_headers": false,
"builder_shallow_bytes": 48,
"quad_shallow_bytes": 56,
"pending_scratch_shallow_bytes": 56,
"geometry_quads": 1,
"java_vendor": "Ubuntu",
"java_runtime_version": "25.0.4.1+1-1-26.04.4-Ubuntu",
"object_alignment_bytes": 8,
"compressed_oops": true,
"compressed_class_pointers": true
},
{
"enabled": false,
"compact_headers": true,
"builder_shallow_bytes": 40,
"quad_shallow_bytes": 48,
"pending_scratch_shallow_bytes": 0,
"geometry_quads": 1,
"java_vendor": "Ubuntu",
"java_runtime_version": "25.0.4.1+1-1-26.04.4-Ubuntu",
"object_alignment_bytes": 8,
"compressed_oops": true,
"compressed_class_pointers": true
},
{
"enabled": true,
"compact_headers": true,
"builder_shallow_bytes": 48,
"quad_shallow_bytes": 48,
"pending_scratch_shallow_bytes": 48,
"geometry_quads": 1,
"java_vendor": "Ubuntu",
"java_runtime_version": "25.0.4.1+1-1-26.04.4-Ubuntu",
"object_alignment_bytes": 8,
"compressed_oops": true,
"compressed_class_pointers": true
}
],
"differences": [
{
"compact_headers": false,
"additional_builder_shallow_bytes": 0,
"additional_builder_and_scratch_bytes": 56
},
{
"compact_headers": true,
"additional_builder_shallow_bytes": 8,
"additional_builder_and_scratch_bytes": 56
}
],
"notes": [
"Instrumentation.getObjectSize measures shallow object sizes inside real applied Fabric clients.",
"Four adjacent north-facing quads premerge to one retained geometry quad in each combination.",
"Builder plus pending scratch difference excludes referenced lists, existing pools and every other game object.",
"Object alignment/header/compressed-reference settings can differ on other JVMs or architectures.",
"Not deep heap, GC residency, whole-game RSS/unified RAM, FPS or Apple Silicon performance.",
"The agent and fixture are private test binaries excluded from playable packs."
],
"provenance": {
"source_commit": "1243e148d455cd83f18b66f70bcfe2b8a4b746c9",
"four_processes_exited_successfully": true,
"agent_path_with_spaces_verified_separately": true
}
}
@@ -1,69 +0,0 @@
{
"schema": 1,
"measurement": "Instrumentation.getObjectSize inside four private applied Fabric clients",
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"architecture": "x86_64",
"java_vendor": "Ubuntu",
"java_runtime_version": "25.0.4.1+1-1-26.04.4-Ubuntu",
"original_mod_sha256": "2196637c5b2180a33fa5b926ab51069ab480618c1186b8a02872c7e758be0a70",
"production_source_commit": "24c65f512dece83b153b206e33cd4c4294b42de2",
"results": [
{
"enabled": false,
"compact_headers": false,
"builder_shallow_bytes": 48,
"quad_shallow_bytes": 56,
"pending_scratch_shallow_bytes": 0,
"geometry_quads": 1
},
{
"enabled": true,
"compact_headers": false,
"builder_shallow_bytes": 48,
"quad_shallow_bytes": 56,
"pending_scratch_shallow_bytes": 56,
"geometry_quads": 1
},
{
"enabled": false,
"compact_headers": true,
"builder_shallow_bytes": 40,
"quad_shallow_bytes": 48,
"pending_scratch_shallow_bytes": 0,
"geometry_quads": 1
},
{
"enabled": true,
"compact_headers": true,
"builder_shallow_bytes": 48,
"quad_shallow_bytes": 48,
"pending_scratch_shallow_bytes": 48,
"geometry_quads": 1
}
],
"differences": [
{
"compact_headers": false,
"additional_builder_shallow_bytes": 0,
"additional_builder_and_scratch_bytes": 56
},
{
"compact_headers": true,
"additional_builder_shallow_bytes": 8,
"additional_builder_and_scratch_bytes": 56
}
],
"provenance": {
"protocol": "Initial private size agent and corrected system-loader reflection probe; metadata was later expanded in the reusable source.",
"agent_source_sha256": "4783850bf80e9eb0379570bb7794a610406b48bddd7fe36ff499222d01e789b1",
"fixture_source_sha256": "842514f97116a1e9cf5eb9a4b951657c90f7639effdfd526357831e2424282bf"
},
"notes": [
"Shallow object sizes only, not a heap walk or whole-game memory measurement.",
"Four north-facing adjacent quads produce one retained geometry quad in every process.",
"Header modes use separate upstream/patched JVMs.",
"Layouts can differ with JVM, architecture, compressed references and object alignment.",
"The hook remains optional; these sizes do not establish an FPS or RAM improvement.",
"No test agent binaries, game binaries, private worlds, full logs or JFR recordings are published."
]
}
@@ -1,54 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"manifest_sha1": "4fe1aa1ef8da1cb95c5bad1fb98890ca56dd8ca3",
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"java": "openjdk 25.0.4.1 2026-08-18",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"resource_models": 2883,
"graph_fixtures": 440,
"rejected_roots": 1039,
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaModelBakingOracle.java": "d05e04d25ed5e5aef260ce21cac627a79bdc5376326a5cb34ffb98462b79c79b",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCuboidModelOracle.java": "7526f20513c549483122ab0d5ad24b9e87f38dc2f6aae55addd701a91ac85e43",
"tools/test_model_baking_parity.py": "392ffec44918fb91740ca4a1316d684480d39f14bd34d46175f7f44946d15bd7",
"tools/test_cuboid_model_parity.py": "4a8b1cdcac335751c23413341ae939eea1c49c38d33d70d0708b8904ab8d0461",
"tools/test_model_resolution_parity.py": "d9595f2f1442f1f590b72d2a46600657e79ae103bec3d4c45db98242b964bde0",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "cb1e87d449114a63edd904c0559d631e8fa9feeb27efd6539aacdcfeae178876",
"crates/horizon-assets/Cargo.toml": "2f2cffacec0b4e22dd7cb032d594289bc51c94ae6cc4e985fee3e310f441d751",
"crates/horizon-assets/examples/blockstate_binding_fixture.rs": "e58fdb432f6bfc1e400729baa9b48d4f00955b3143b98b52506b47dd8b065cf8",
"crates/horizon-assets/examples/blockstate_model_fixture.rs": "8f063322e57abdf9361a5a3a3badce2a7e727ee6d5e3947071cb448dfb38e8fd",
"crates/horizon-assets/examples/cuboid_model_fixture.rs": "97609d90e3f6ce340f3590296db2dc778113bb2b33c7d1b54080a1d6f3023f40",
"crates/horizon-assets/examples/model_baking_fixture.rs": "a762a8b48f09b5ac5e9c48d4a578b18b700810807fe5d3fc50798365cce1c314",
"crates/horizon-assets/examples/model_choice_fixture.rs": "a4c8a46501d2b5ae7051f10f2307ade048e96c2d330af51cd2431bb44977a99a",
"crates/horizon-assets/examples/model_resolution_fixture.rs": "c071067140299e49345a6ebd94e15b3b6d853cb9ae11d8de46e3cbdfb8b01f0e",
"crates/horizon-assets/examples/sprite_animation_fixture.rs": "254314d52deda129ab461221d3d8b95323a60730d374e566c1cd599fba85f072",
"crates/horizon-assets/examples/support/mod.rs": "bcf5a6d8a54845982191e037911c24139237771d6afa4b01b1e83c011489c3f5",
"crates/horizon-assets/src/animation.rs": "ebbf7952146a0e66b41396174492f5702627170b03a57e6cd5a45c97a08c975e",
"crates/horizon-assets/src/bake/transform.rs": "a95e658fef85b21bcb2f9f7512f98f98d57022d62c1199885b7133beae35a09d",
"crates/horizon-assets/src/bake.rs": "f55dda6b6cee5ac6e65a8ee4837fdd2c6674437d59e59b4c45718f6324d4a4d5",
"crates/horizon-assets/src/blockstate/bind.rs": "6278962e55c9786bba8184bdf2939af9c6e3b9002b08c3022129964b49a60009",
"crates/horizon-assets/src/blockstate/choice.rs": "5a66c8b9833e2f19dd8b0773f3593d97ff5941d3c5b773896b98049efa1395ba",
"crates/horizon-assets/src/blockstate.rs": "a4299dfd7adaeb4173982ffaa8e9c9eda2925739ae579a714193c99da2e7ce56",
"crates/horizon-assets/src/json.rs": "99fe8af4fbf5d4eed408a92e829ac1a39597a0d92471a6bff73771fad9c830a8",
"crates/horizon-assets/src/lib.rs": "e39f21c59a2c3e1c53d977b29bd5e0638e5fc41d86ff0fcc1882a6d90fd961e4",
"crates/horizon-assets/src/model.rs": "57ddb3d65e88e7a8aa22c62bc298a2dae7f4e994326a873a31f06c0f36ed051b",
"crates/horizon-assets/src/resolve.rs": "3927ac926cdcbd7d334901cc32d0ecc1e498b1bec98f76a46bca6d4964c13541"
},
"fixtures_sha256": {
".local/rust-model-baking-parity/inputs.jsonl": "aba24d38f4fc1af060502f983923c2f279c016d0fd412d40f6d50093fac1d811"
},
"rust_output_sha256": "9216be3bbae9e59bb89b6ed780ccedc5608cd4583c8e7527e50b165a0d8d30da",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "9216be3bbae9e59bb89b6ed780ccedc5608cd4583c8e7527e50b165a0d8d30da",
"matched_output_lines": 7100
}
],
"scope": "Actual client FaceBakery geometry overload with a real unit-atlas sprite and default JOML math options. Identity blockstate transform, all bundled cuboid geometry and synthetic rotations, rescaling, default/explicit UVs, winding, degenerate and reversed bounds, inherited models and missing materials. Positions, UVs and element matrix coefficients compare by float bits. This does not cover blockstate transforms/UV lock, atlas packing, transparency classification, lighting, GPU rendering or gameplay."
}
@@ -1,44 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"java": "openjdk 25.0.4.1 2026-08-18",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"manifest_sha1": "4fe1aa1ef8da1cb95c5bad1fb98890ca56dd8ca3",
"commands": {
"position": 12375,
"legacy": 23,
"xoroshiro": 23,
"xoroshiro_state": 5,
"storage": 274
},
"inputs_sha256": "dbdebadd4b14ec57d198d22f15e196e0cc9a6b88bac6691db702348a769459c1",
"rust_output_sha256": "7801e3274307aab1852d96d996d7f29b1ca1567750d231c5f74c9e3263f84f87",
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCoreOracle.java": "649b8353fcc3c45a3baf8e2d78dc76cfedfd96de36030b0dddfb2305829cd844",
"tools/test_rust_parity.py": "d2d06842abb80d9c718a5bf0e71ab0c098ad4c519b8ef35711e30cf58af140d7",
"crates/horizon-core/src/bin/parity.rs": "7b455f2181862e1430e7387633c146877c2d317c2ea682c1e6fa64345dbc5885",
"crates/horizon-core/src/lib.rs": "deb2e339f78c9f5bd55a1c8a8428f3e37fae93a02268f9a2fc782dc3e27c2869",
"crates/horizon-core/src/position.rs": "8c2a54e912f8c31a774682b3377ca5f2138910350fbf605e760b24e2cbcacfba",
"crates/horizon-core/src/random.rs": "2f304dfb580a6bc1b5c51b048a2fa2a57f73c5f28f5eb2447f925bf138513389",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/Cargo.toml": "1928b71e389c24c506804f0d8e3104976da6feb27d9bfdbb3b55fb7af0c62664",
"Cargo.toml": "9ca59fba126895de9e58952eb5e9421bee0ffdfb5f6d2fcb03d7726e394e7c3f",
"Cargo.lock": "f2b104dbb3f64512b6c72e8d8732b7adda849212689e8c816f9a6abf564f4660"
},
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "7801e3274307aab1852d96d996d7f29b1ca1567750d231c5f74c9e3263f84f87",
"matched_output_lines": 1017920
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "7801e3274307aab1852d96d996d7f29b1ca1567750d231c5f74c9e3263f84f87",
"matched_output_lines": 1017920
}
],
"scope": "Selected integer position, seeded RNG and packed-storage operations only. No gameplay, rendering or performance claim."
}
@@ -1,40 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"manifest_sha1": "4fe1aa1ef8da1cb95c5bad1fb98890ca56dd8ca3",
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"java": "openjdk 25.0.4.1 2026-08-18",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"resource_models": 2883,
"synthetic_models": 2337,
"rejected_models": 1034,
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCuboidModelOracle.java": "7526f20513c549483122ab0d5ad24b9e87f38dc2f6aae55addd701a91ac85e43",
"tools/test_cuboid_model_parity.py": "3b7c018570b0f609aae43cef60ff3139c543d5d629be804a5aa257e3ab2dd67c",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "7b4ab0ffa35af7ea8b6e38525f18ff6c3e94768198915f5ffe560d84263423f8",
"crates/horizon-assets/Cargo.toml": "fadb78cf819e026500606c45d27138ed67fcbbc967ae8cee6c1e7c82c9046b36",
"crates/horizon-assets/examples/cuboid_model_fixture.rs": "97609d90e3f6ce340f3590296db2dc778113bb2b33c7d1b54080a1d6f3023f40",
"crates/horizon-assets/examples/model_resolution_fixture.rs": "c071067140299e49345a6ebd94e15b3b6d853cb9ae11d8de46e3cbdfb8b01f0e",
"crates/horizon-assets/examples/support/mod.rs": "bcf5a6d8a54845982191e037911c24139237771d6afa4b01b1e83c011489c3f5",
"crates/horizon-assets/src/json.rs": "e7b89bf4852f561a0e5bf1a984857c61e755961dfd86fcc326b6d55558615f39",
"crates/horizon-assets/src/lib.rs": "0d31dd0fa84d7b4467a78a1a2b8a8e179533ef5e64a7cbae88e5358e59160a40",
"crates/horizon-assets/src/model.rs": "57ddb3d65e88e7a8aa22c62bc298a2dae7f4e994326a873a31f06c0f36ed051b",
"crates/horizon-assets/src/resolve.rs": "3927ac926cdcbd7d334901cc32d0ecc1e498b1bec98f76a46bca6d4964c13541"
},
"fixtures_sha256": {
".local/rust-cuboid-model-parity/inputs.jsonl": "9c1822180e1d6869e65eea81a38cbcf3786b9286d4c839e31ba686501694d171"
},
"rust_output_sha256": "80c4b305084658ab968ed466fb1609bfa78d60738d09790c6243b4de27dfb8fc",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "80c4b305084658ab968ed466fb1609bfa78d60738d09790c6243b4de27dfb8fc",
"matched_output_lines": 5220
}
],
"scope": "Actual pinned CuboidModel.fromStream parser compared over every bundled block model and synthetic JSON/numeric/syntax cases. Decoded geometry, texture materials/references, nullable children, inheritance markers, face quadrants, light emission and display transforms; floats compare by IEEE-754 bits. Rejections normalize exception text. This client-only API is absent from the server. Does not yet validate parent resolution, rotation matrices, quad baking, blockstate dispatch, rendered pixels or gameplay."
}
@@ -1,373 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"java": "openjdk 25.0.4.1 2026-08-18",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"manifest_sha1": "4fe1aa1ef8da1cb95c5bad1fb98890ca56dd8ca3",
"exhaustive": false,
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaFloatLogOracle.java": "1794510183faa07892761e93094301b69665d4b6a5300ef7117b5482832165f2",
"tools/test_float_log_parity.py": "1ba733163133ea6232a9021fcee5b38255887d62ebab8d1b42e4ccad259b21f3",
"tools/test_rust_parity.py": "7efa699a38c5820424f5fc8992ee601dbfe26d6482da9d2dab2c17c41fe8f12a",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"crates/horizon-core/src/bin/density_parity.rs": "ca79feb1ff690557a54dcb3a504967453dd0190ac65d7322512c778048127c5e",
"crates/horizon-core/src/bin/float_log_parity.rs": "4a655fcf8822ee7668c4bd126bc84d0b118864a6fc7f5a6aeee667d8bf2590b1",
"crates/horizon-core/src/bin/geometry_parity.rs": "27f6c09fe5018ac3de8e70e0f0bbf78f9abb14f5e4783bcaf46e8ca87b9c6f8a",
"crates/horizon-core/src/bin/noise_parity.rs": "c135bfc708d853e7061e81487d2cfe10de64b2f65677d3b4837cbfe0b8341010",
"crates/horizon-core/src/bin/parity.rs": "f35d928c66f958de39fac5e7e836a657eed95f83599e84899f7ea7a5802ba481",
"crates/horizon-core/src/bin/tick_parity.rs": "a54c164fe4814034d369947a887f5273966f5a878ba849204b80d1c729526a8f",
"crates/horizon-core/src/density/arithmetic.rs": "e42a19893a8d75f8f62b564bd9e527131d87fb469c808422fb8d3b14eb9edac0",
"crates/horizon-core/src/density/cache.rs": "3ccc1268dca96259890279e9f91cb7a099c74b12e6ca2973880d4fa246f7a619",
"crates/horizon-core/src/density/end_islands.rs": "168b9384237bd2e41d0ae5a74e944da4dc74e493bdec31fb73184c9a49e3de55",
"crates/horizon-core/src/density/graph/compiler.rs": "ede1da60dec40f6df846e44a663bff03c21631c21f2b6e25a58c358115f122a1",
"crates/horizon-core/src/density/graph/mod.rs": "47f1716a8b5fffc1012b9e4654e223b0ff818f00f6a059818ab3dfe8c37e3056",
"crates/horizon-core/src/density/graph/seeded.rs": "6bcdcaa3dffcfa9df673bbbea35120057a16ba3d2b506c52709c36cf8976b74a",
"crates/horizon-core/src/density/graph/tests.rs": "3034eccba649851d7a95e276a48472efd70cdf747b54526b565fb0feb88ce43a",
"crates/horizon-core/src/density/interpolation.rs": "8c890f52b6467f38a94c654986a6a484b8e0b296ab98c398e60a6ce465b5b010",
"crates/horizon-core/src/density/interval.rs": "b42629163baa6b599a233afe8596d1c370cd81d015cc6fc36a9663aa47b98424",
"crates/horizon-core/src/density/mod.rs": "3e56cc0f6b51c6faa4bd8d9fc259bf01a0c3bf647f36be8be7640971cfe3b334",
"crates/horizon-core/src/density/power.rs": "b18a5b0d524de52a3d1e6028adcddd183424be2913f24d3f098ff56c5e1c6942",
"crates/horizon-core/src/density/rounding.rs": "71840c5206ff8d218ac29bf6f66915d5212764ba270c675711a866ba5b55a7a6",
"crates/horizon-core/src/density/selection.rs": "0dd26af2e85004ec5e053039ad11c384c17c56ace9ab45eb3f5cb3503c0b0330",
"crates/horizon-core/src/density/slice.rs": "5d77605573c0deda47778f1f78f7fa3fbf1944d8f5efbcc65cf589181cadf80b",
"crates/horizon-core/src/density/spline.rs": "6bb2e40f940fc6544d6fb09cb0b8cac722be03bc663dbdfb0f61faae207400bc",
"crates/horizon-core/src/density/surface.rs": "159e0e69cda74f870e80ea64fe523c4397e64af4ccb861bb9fd07b2c3cb91b00",
"crates/horizon-core/src/density/terrain_noise.rs": "8d0059d25eb5d248cb97a4c5a2e670d61528928ea151495c004f25adb723fe3e",
"crates/horizon-core/src/density/tests.rs": "7817796ee40d0ae241bfbebec6bca190e0a8e7d5a1caa8ddf858c3eaa58b8858",
"crates/horizon-core/src/geometry/mod.rs": "dc92f73885dd0a7760743bf74f1ab8afa839d61cef2dfef890f8a23b67b4742e",
"crates/horizon-core/src/geometry/movement.rs": "930e34abef6f6eeec1ee7a6c920b5ba01bfe37b90678884490f4be53241f6b96",
"crates/horizon-core/src/geometry/shape/create.rs": "189812b91d5e0e3ad963afcd1a6e2831b31b8188df91a904ef27061e644806ad",
"crates/horizon-core/src/geometry/shape/join.rs": "f1b51887b7bf9482557e3ffa99e136f2e5db07ceeb05fdb116adf45e87129075",
"crates/horizon-core/src/geometry/shape.rs": "de22acd7430df3f69ef3632d427c57dffe57f3bdb78950bc75eac7e179ccf9df",
"crates/horizon-core/src/geometry/sweep.rs": "abd6009c61555161ef2f18b431b2aa384b126c0871cae8b96a62358498a56a1d",
"crates/horizon-core/src/geometry/traversal.rs": "77a3da570a0b85582b669cf4d841cba4b06327006dda26d4a26df4e8ce05bae4",
"crates/horizon-core/src/geometry/trig.rs": "05cef9341a298a474221a0556a11ddf47650393ea7a97b4b2022a4da6628fe37",
"crates/horizon-core/src/lib.rs": "3968e2a337a6a23226c485057c79359e66df16683f00fb4ebc9fabb03910a015",
"crates/horizon-core/src/noise/mod.rs": "1dab5a713abf702402e69ace1bf9e476bba544b0ede5a61c3c3afc60af0a03f3",
"crates/horizon-core/src/noise/normal.rs": "e9e7a46472a54a02c98c46da819842090567153b32fe0c84249009ef19af7aad",
"crates/horizon-core/src/noise/perlin.rs": "e73815447432eab7542f67366cb3f1b368d164e33f6c9cdbd045ac8e4db0932a",
"crates/horizon-core/src/noise/simplex.rs": "6c0dbc15b2b7510195dd28fceca01dcaac1847ccc4a84d299c351589c642fe7a",
"crates/horizon-core/src/noise/stack.rs": "7f6ef0e7d920139ef1a6ad3ec5640f92765715f86dcc5ec29f1a149984f45fa3",
"crates/horizon-core/src/noise/volume.rs": "3f05d2b1780acfdfee60037677d309937a5033b45ef428fc2d540942d4b56b43",
"crates/horizon-core/src/position/iter.rs": "32d2d8e74821cc4e49e3354202d35d3120e4415bfdda9375a73f2137ef651129",
"crates/horizon-core/src/position.rs": "e10101088e6902386b9b6d27773d44312f1ff72bebb19e57967a54945dde9dcd",
"crates/horizon-core/src/random/hash.rs": "0f88a127a1ba2705d3d6c0ebd009324d6ba86ffa2d27edf2d2a84765e690e4a3",
"crates/horizon-core/src/random/positional.rs": "35494745e5d4cf89e282c3ae0ee245e9f2640ddbbc03bc0055df742006a9c862",
"crates/horizon-core/src/random.rs": "92135a94c79111cc810b4b071dbd76043ee47c2585fd431e7486ea381f19e5db",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/src/ticks/heap.rs": "bf28afab8af77c3d243aa96cd8a1fb8d934140a4dbd07dbfdbf4e7908bb4b845",
"crates/horizon-core/src/ticks/index.rs": "1f1a6a568c2a30eafecb020ca4d5f5fc414860de85b8b381fc419a2e3e65c24a",
"crates/horizon-core/src/ticks/mod.rs": "84852599dde78687d782f115a5b4b3ef6856c1f9cc92917255167e89c72ab01e",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"Cargo.toml": "dc370d5fdde37238c3e4820046f11c3201020406a4edfa1308257c13edbdcda4",
"Cargo.lock": "faae2edce8b573fd32fcb4bd1f898be7d700a5b38479439f5bec96df764688fd"
},
"comparisons": [
{
"start_bits": 0,
"count": 65536,
"rust_output_sha256": "1e684e3e6b93407fb3f37762a4de01f8706c047cf5294cf9d2a1ac173fc02075",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "1e684e3e6b93407fb3f37762a4de01f8706c047cf5294cf9d2a1ac173fc02075",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "1e684e3e6b93407fb3f37762a4de01f8706c047cf5294cf9d2a1ac173fc02075",
"matched_float_values": 65536
}
]
},
{
"start_bits": 8388608,
"count": 65536,
"rust_output_sha256": "4200cba9cf0053911e1d672fabbee94f5267d5b7aa109fbe57ddc5a4f7b70393",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "4200cba9cf0053911e1d672fabbee94f5267d5b7aa109fbe57ddc5a4f7b70393",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "4200cba9cf0053911e1d672fabbee94f5267d5b7aa109fbe57ddc5a4f7b70393",
"matched_float_values": 65536
}
]
},
{
"start_bits": 1056899072,
"count": 65536,
"rust_output_sha256": "cae10428767d3e776f5183caba1780897d2e1831913c05ae6dd8d843a6e25a76",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "cae10428767d3e776f5183caba1780897d2e1831913c05ae6dd8d843a6e25a76",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "cae10428767d3e776f5183caba1780897d2e1831913c05ae6dd8d843a6e25a76",
"matched_float_values": 65536
}
]
},
{
"start_bits": 1065287680,
"count": 65536,
"rust_output_sha256": "59024062288c0bc65906a38484eff0fb73aaba11cb8110aaebc6dde8891ed10c",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "59024062288c0bc65906a38484eff0fb73aaba11cb8110aaebc6dde8891ed10c",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "59024062288c0bc65906a38484eff0fb73aaba11cb8110aaebc6dde8891ed10c",
"matched_float_values": 65536
}
]
},
{
"start_bits": 1065353216,
"count": 65536,
"rust_output_sha256": "01849695d0e9a30ccd132270cb79ecaaf1065411d66b323a36f1b87f5d0e4596",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "01849695d0e9a30ccd132270cb79ecaaf1065411d66b323a36f1b87f5d0e4596",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "01849695d0e9a30ccd132270cb79ecaaf1065411d66b323a36f1b87f5d0e4596",
"matched_float_values": 65536
}
]
},
{
"start_bits": 1073741824,
"count": 65536,
"rust_output_sha256": "0df001f091df446399cccd24b0fa1e4114894c263d5cdc707b8c4a2ded269936",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "0df001f091df446399cccd24b0fa1e4114894c263d5cdc707b8c4a2ded269936",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "0df001f091df446399cccd24b0fa1e4114894c263d5cdc707b8c4a2ded269936",
"matched_float_values": 65536
}
]
},
{
"start_bits": 2139029504,
"count": 65536,
"rust_output_sha256": "c39faee80d047d450472ae5eb25f2811e4010b5aad1ccad80ff4d8f7638bd3d5",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "c39faee80d047d450472ae5eb25f2811e4010b5aad1ccad80ff4d8f7638bd3d5",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "c39faee80d047d450472ae5eb25f2811e4010b5aad1ccad80ff4d8f7638bd3d5",
"matched_float_values": 65536
}
]
},
{
"start_bits": 2139095040,
"count": 65536,
"rust_output_sha256": "1c60d380d4dc55a05bed3452e32f4d5c813c9beb4459ba890338c27f0b047345",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "1c60d380d4dc55a05bed3452e32f4d5c813c9beb4459ba890338c27f0b047345",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "1c60d380d4dc55a05bed3452e32f4d5c813c9beb4459ba890338c27f0b047345",
"matched_float_values": 65536
}
]
},
{
"start_bits": 2147418112,
"count": 65536,
"rust_output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
}
]
},
{
"start_bits": 2147483648,
"count": 65536,
"rust_output_sha256": "b365699b17956be9409c58c88b48da5f7edf7e4783fcca72efa00b0dae84455f",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "b365699b17956be9409c58c88b48da5f7edf7e4783fcca72efa00b0dae84455f",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "b365699b17956be9409c58c88b48da5f7edf7e4783fcca72efa00b0dae84455f",
"matched_float_values": 65536
}
]
},
{
"start_bits": 2155872256,
"count": 65536,
"rust_output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
}
]
},
{
"start_bits": 3212771328,
"count": 65536,
"rust_output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
}
]
},
{
"start_bits": 3212836864,
"count": 65536,
"rust_output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
}
]
},
{
"start_bits": 4286513152,
"count": 65536,
"rust_output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
}
]
},
{
"start_bits": 4286578688,
"count": 65536,
"rust_output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
}
]
},
{
"start_bits": 4294901760,
"count": 65536,
"rust_output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "f3b37b44be6c4c25b1d85b2bce7844c67cc9f3e5a3270d4a53101d99049b966e",
"matched_float_values": 65536
}
]
}
],
"scope": "Compiled scalar UnaryFunction.LogSampler compared by float result bits across the recorded input bit ranges, including signed zeros, subnormals, finite values, infinities and NaNs. NaN results are canonicalized as Float.floatToIntBits. Exhaustive mode checks all 2^32 float input bit patterns against both checksum-pinned JARs on this machine's JDK. Bulk composition, range propagation, compiler rewriting and other operations belong to the separate density suite. This does not establish double-precision Math.log parity, other-platform math parity, complete terrain, gameplay or performance."
}
@@ -1,202 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"manifest_sha1": "4fe1aa1ef8da1cb95c5bad1fb98890ca56dd8ca3",
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"java": "openjdk 25.0.4.1 2026-08-18",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"fixtures": 8338,
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCollisionContextOracle.java": "d2f5b022be1ee2111c38acf6710c21b59da09506e246fb22b8c7c8eeb253a7d9",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaFaceSupportOracle.java": "9ce939a435842867786fed648951bbe77f6ab843f6df09af15f3deb1948c4877",
"tools/test_collision_context_parity.py": "75d6f01e072867d2bd286d2e518e123fcfe055a11ac1705ec99ecec3975cb8d2",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "cb1e87d449114a63edd904c0559d631e8fa9feeb27efd6539aacdcfeae178876",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"crates/horizon-world/Cargo.toml": "977338bf3e654193685b015d383493b9f59ff6f5d6210bec212cef8ac4a50bed",
"crates/horizon-core/src/bin/density_parity.rs": "e5b1dd33b7d01306c73cf072629b4fb186e9ab87b672a00108999d1a72263fd0",
"crates/horizon-core/src/bin/float_log_parity.rs": "4a655fcf8822ee7668c4bd126bc84d0b118864a6fc7f5a6aeee667d8bf2590b1",
"crates/horizon-core/src/bin/geometry_parity.rs": "27f6c09fe5018ac3de8e70e0f0bbf78f9abb14f5e4783bcaf46e8ca87b9c6f8a",
"crates/horizon-core/src/bin/noise_parity.rs": "c135bfc708d853e7061e81487d2cfe10de64b2f65677d3b4837cbfe0b8341010",
"crates/horizon-core/src/bin/parity.rs": "f35d928c66f958de39fac5e7e836a657eed95f83599e84899f7ea7a5802ba481",
"crates/horizon-core/src/bin/tick_parity.rs": "a54c164fe4814034d369947a887f5273966f5a878ba849204b80d1c729526a8f",
"crates/horizon-core/src/biome/seed_hash.rs": "5afbb4921c750826b395a08bf06f382fc7f01b5759a93de02a2749c523e2a317",
"crates/horizon-core/src/biome.rs": "908efa8cd4aa0a7adf1cb5e1a222e3dfb640eed5e9172e0fe7f0d1287afae7e8",
"crates/horizon-core/src/carving/ellipsoid.rs": "09232a7588610e8a9176fd9c62d40afb1fb89f2ecab6d555536a1d847b142d86",
"crates/horizon-core/src/carving.rs": "0aa3093caa0437868a8c0ed52a6c6e1993bd51c03583c670a2837e749eae5426",
"crates/horizon-core/src/density/arithmetic.rs": "372faec96c923e2cf4aa6c66c1ac398e676853274557823850dbc8933dd15ab1",
"crates/horizon-core/src/density/beardifier.rs": "bb1052e27dae4a01954ca78d7d5babafef85f3b2c704ccaf1920cb85a098cb50",
"crates/horizon-core/src/density/cache.rs": "38d0b6c9dd04ffef979fdad3f29cfebf98d331c8c9d430be5f39aa34f6c30975",
"crates/horizon-core/src/density/end_islands.rs": "168b9384237bd2e41d0ae5a74e944da4dc74e493bdec31fb73184c9a49e3de55",
"crates/horizon-core/src/density/graph/compiler.rs": "ac67deeb16f16d0859aa20e5a165811a29aca0b910037ee6bf5098211f3a6ede",
"crates/horizon-core/src/density/graph/mod.rs": "b776e7da934cb03051a3053d56d461c71e9978e084922fe4194147aa580c07bf",
"crates/horizon-core/src/density/graph/seeded.rs": "6bcdcaa3dffcfa9df673bbbea35120057a16ba3d2b506c52709c36cf8976b74a",
"crates/horizon-core/src/density/graph/tests.rs": "6bfb8cbff462587dd147b0775ea01d370abbd97544b9bd596c792df1b5f7e634",
"crates/horizon-core/src/density/interpolation.rs": "8c890f52b6467f38a94c654986a6a484b8e0b296ab98c398e60a6ce465b5b010",
"crates/horizon-core/src/density/interval.rs": "b42629163baa6b599a233afe8596d1c370cd81d015cc6fc36a9663aa47b98424",
"crates/horizon-core/src/density/mod.rs": "ca0d77d3282e3746ddcbc92bee97dbf640b9a56214e6ac1537f51f9a5b63d6e7",
"crates/horizon-core/src/density/power.rs": "d5b7270a128d4264268cd772109ad16d71a8ec3ff2d3b63b84cb985296d54a91",
"crates/horizon-core/src/density/rounding.rs": "71840c5206ff8d218ac29bf6f66915d5212764ba270c675711a866ba5b55a7a6",
"crates/horizon-core/src/density/selection.rs": "0dd26af2e85004ec5e053039ad11c384c17c56ace9ab45eb3f5cb3503c0b0330",
"crates/horizon-core/src/density/slice.rs": "5d77605573c0deda47778f1f78f7fa3fbf1944d8f5efbcc65cf589181cadf80b",
"crates/horizon-core/src/density/spline.rs": "6bb2e40f940fc6544d6fb09cb0b8cac722be03bc663dbdfb0f61faae207400bc",
"crates/horizon-core/src/density/surface.rs": "159e0e69cda74f870e80ea64fe523c4397e64af4ccb861bb9fd07b2c3cb91b00",
"crates/horizon-core/src/density/terrain_noise.rs": "8d0059d25eb5d248cb97a4c5a2e670d61528928ea151495c004f25adb723fe3e",
"crates/horizon-core/src/density/tests.rs": "7817796ee40d0ae241bfbebec6bca190e0a8e7d5a1caa8ddf858c3eaa58b8858",
"crates/horizon-core/src/density/world_fields.rs": "c1ce305cb8046b384d90c564cafb24af7365d580389637910f3d8b0cc18eb583",
"crates/horizon-core/src/geometry/mod.rs": "dc92f73885dd0a7760743bf74f1ab8afa839d61cef2dfef890f8a23b67b4742e",
"crates/horizon-core/src/geometry/movement.rs": "930e34abef6f6eeec1ee7a6c920b5ba01bfe37b90678884490f4be53241f6b96",
"crates/horizon-core/src/geometry/shape/create.rs": "189812b91d5e0e3ad963afcd1a6e2831b31b8188df91a904ef27061e644806ad",
"crates/horizon-core/src/geometry/shape/face.rs": "f243bce81384040a95ce7984b02b5699206c596c537b2713097e86005b4d3a5c",
"crates/horizon-core/src/geometry/shape/join.rs": "f1b51887b7bf9482557e3ffa99e136f2e5db07ceeb05fdb116adf45e87129075",
"crates/horizon-core/src/geometry/shape.rs": "e8d88a763de1525f77a30b99591641e8a8b80946263acbde035a9bcc356df960",
"crates/horizon-core/src/geometry/sweep.rs": "abd6009c61555161ef2f18b431b2aa384b126c0871cae8b96a62358498a56a1d",
"crates/horizon-core/src/geometry/traversal.rs": "77a3da570a0b85582b669cf4d841cba4b06327006dda26d4a26df4e8ce05bae4",
"crates/horizon-core/src/geometry/trig.rs": "05cef9341a298a474221a0556a11ddf47650393ea7a97b4b2022a4da6628fe37",
"crates/horizon-core/src/lib.rs": "4255e16837fde42a52ba118f60581d197c571bb530b60d635e506184ebf4db0b",
"crates/horizon-core/src/noise/mod.rs": "1dab5a713abf702402e69ace1bf9e476bba544b0ede5a61c3c3afc60af0a03f3",
"crates/horizon-core/src/noise/normal.rs": "e9e7a46472a54a02c98c46da819842090567153b32fe0c84249009ef19af7aad",
"crates/horizon-core/src/noise/perlin.rs": "e73815447432eab7542f67366cb3f1b368d164e33f6c9cdbd045ac8e4db0932a",
"crates/horizon-core/src/noise/simplex.rs": "6c0dbc15b2b7510195dd28fceca01dcaac1847ccc4a84d299c351589c642fe7a",
"crates/horizon-core/src/noise/stack.rs": "7f6ef0e7d920139ef1a6ad3ec5640f92765715f86dcc5ec29f1a149984f45fa3",
"crates/horizon-core/src/noise/volume.rs": "3f05d2b1780acfdfee60037677d309937a5033b45ef428fc2d540942d4b56b43",
"crates/horizon-core/src/position/iter.rs": "32d2d8e74821cc4e49e3354202d35d3120e4415bfdda9375a73f2137ef651129",
"crates/horizon-core/src/position.rs": "e10101088e6902386b9b6d27773d44312f1ff72bebb19e57967a54945dde9dcd",
"crates/horizon-core/src/random/hash.rs": "0f88a127a1ba2705d3d6c0ebd009324d6ba86ffa2d27edf2d2a84765e690e4a3",
"crates/horizon-core/src/random/positional.rs": "35494745e5d4cf89e282c3ae0ee245e9f2640ddbbc03bc0055df742006a9c862",
"crates/horizon-core/src/random/worldgen.rs": "9f07ff33bcc038d34e27aa5465753bb21df18f2975e43cae201f709bc186945a",
"crates/horizon-core/src/random.rs": "ddb95d3a83e28ad605ff1f49f5df270cc543ca5ef1130e37d989dc74c8d861e6",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/src/text.rs": "e6553ddb5db5039e8dc4614b6a6dc9f35a26dc3d1673b68a04e72e7983b67abb",
"crates/horizon-core/src/ticks/generation.rs": "be1237e790693f633a61714ddae68c6506a777588a8a3ab5efbe53a35774dbd2",
"crates/horizon-core/src/ticks/heap.rs": "bf28afab8af77c3d243aa96cd8a1fb8d934140a4dbd07dbfdbf4e7908bb4b845",
"crates/horizon-core/src/ticks/index.rs": "1f1a6a568c2a30eafecb020ca4d5f5fc414860de85b8b381fc419a2e3e65c24a",
"crates/horizon-core/src/ticks/mod.rs": "01634630668172516b8b79d0907bad47f6e2c543a6d499c2fa4b201823b375cb",
"crates/horizon-world/src/bin/worldgen_parity.rs": "3143ceb9b56eecfd7667e5feb5f9f0cd13cfb8754b38d4ea338dbba97f2819da",
"crates/horizon-world/src/block_collision.rs": "a40c9d7a4e0a734c124dc856e31359fd4d8de3d1bfc79c86787afa8e8e05e480",
"crates/horizon-world/src/block_entities.rs": "a9deae92e6e5a1fcf4f0476c33ea4d170ddad6fd4b3303e1bb66d933973d5e06",
"crates/horizon-world/src/block_placement.rs": "524f4892d50bab77b7d89d19f7b048ffe746996f2ed7f376db2c6ab00ed75c24",
"crates/horizon-world/src/block_properties.rs": "b0bd8a983336c48e488a20caa77dd5c39b1a74bbd14ebc03b3b64556a1c864fc",
"crates/horizon-world/src/block_render.rs": "8df52ee11aef406a1571198a64048062a0ef6864e0058d9293a57f64b73c916a",
"crates/horizon-world/src/block_support.rs": "ade4fbd47284b450dabdd682dc86138b2ac05a0fd379525d7110648908245476",
"crates/horizon-world/src/block_survival.rs": "28ce64375e09819a4f13da9cfbe37c08b5ad0daf01b289c1c360b4567e50e811",
"crates/horizon-world/src/chunk.rs": "8843e6f48dbbc4245ce4e95564dfba3a4d7a051ba0b1577fb038c07adb0ff0f9",
"crates/horizon-world/src/chunk_status.rs": "dbb8583cfa775203c544d24d69e03720385428f15a267a561356c21f5025e9c7",
"crates/horizon-world/src/collision.rs": "05313e0c1f3089524fe029f9aac3e439cd47f1c9584c8c7e154c9adcfa88c335",
"crates/horizon-world/src/collision_context.rs": "2176c7034e07f547510a8327cdad9d3b63f26e4754032b76b7d5fe13166c333c",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/dynamic_support.rs": "5996bc1c436fb6215d8fc3d0bb4de5dd9b966d842d432580d624195771697fb8",
"crates/horizon-world/src/entity_obstruction.rs": "a4b28a19bf83b23611c59d94535c488db37e4aee24b22c973c545910894a809f",
"crates/horizon-world/src/fluid.rs": "a0a1f34ba94d8b59dc975becee8952960764d67ae08cf2d6a8bcd40a614b15c4",
"crates/horizon-world/src/heightmap.rs": "a5edef082b5af40d814421ea17e129b3b06d70abee6434ed263e4bba58571698",
"crates/horizon-world/src/lib.rs": "e321bed47d34ef1fdcdd99dad07cc537d34ed3cfbc07f10f10ec8b6848daf208",
"crates/horizon-world/src/liquid_collision.rs": "0f0a83b04e5a5bc9d98ed05fde4d6584ba69642e93522e726e4cfc325d6fcb1d",
"crates/horizon-world/src/main.rs": "fce57418b8c22a6a0a9044baa89ed3d9c243bc2e8413fea3ff0f32985daba021",
"crates/horizon-world/src/nbt.rs": "60262c3de8c8f68bc2da0370ccb17393d32b85f5f5022c6358599a7d32119ea6",
"crates/horizon-world/src/piston_shape.rs": "399c2337103b8e7e0eb5667227c5aa14f9549d6a467b7be7da3d0717f0263500",
"crates/horizon-world/src/region.rs": "72b642e87fed37ed17f54d4c30f96c3b64d26c14bc0589c31ef40ff1616188fc",
"crates/horizon-world/src/registry/json.rs": "7a683afcd1742c5307756927d7f0aa779c7d7992af87d8d371dd98108728e235",
"crates/horizon-world/src/registry.rs": "f2e58b2b4d944ac8fc6226bd3352cefc3d2052d8473e02ccf7dc402b176df435",
"crates/horizon-world/src/retrogen.rs": "6efd36a6293756688c1990a7965bd65609d7c5e2bf2a5f4f01d54932d2b9386b",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/worldgen/anchor.rs": "d156b8a0b147a274cdd143409b441f4f43edecde6e8ee14ef9cf0309f743143a",
"crates/horizon-world/src/worldgen/aquifer/config.rs": "fcd2cc3a520c1527c88f095a3b5d38487e7ebb1ccecc5f757f93d04a069add4f",
"crates/horizon-world/src/worldgen/aquifer/noise_based.rs": "74daaa389b5c3dfdc99214dfff256a9e172f83548d2326cbc941d9637cc53fb7",
"crates/horizon-world/src/worldgen/aquifer.rs": "cb4b66d87de3f9f79ae6ffe4badd6f0f44886cd42ad9de2771b8b56c4f1e28c7",
"crates/horizon-world/src/worldgen/bamboo.rs": "d9b47113c99be34256e58308bc6f40072ff25c579d6bf995182aa862c0006102",
"crates/horizon-world/src/worldgen/biome.rs": "3fe316b875aa32683759c337dc71f624910faf0812a2d6d83b8098d6d0bac7a0",
"crates/horizon-world/src/worldgen/biome_chunk.rs": "8fdfe6ebe3ffeca97611fd5991a5bc6b2783ea1c62f4d8ef3b2dd53c04a5dc1d",
"crates/horizon-world/src/worldgen/biome_predicate.rs": "bfc581bc40077cc74ffda43e990a55fe997adc04c7130f98e039c3305ca79aac",
"crates/horizon-world/src/worldgen/biome_source/codec.rs": "2b9e4f5d679eb444cb73174f511e3b9f32e9eb138248ab12cffc6cfd76adf3a8",
"crates/horizon-world/src/worldgen/biome_source/runtime.rs": "f0b02c1521178e4d0377c6ca62694604b6a773f1f234f070ff0cde4685911d45",
"crates/horizon-world/src/worldgen/biome_source.rs": "e181e1736f3e0b75f7091a24c88de3fd116e01b98424d02382aea7a503d1eb54",
"crates/horizon-world/src/worldgen/biome_temperature.rs": "cde4bbab5e260c4065b113376c423b8511ade93c5aa5fd976e245ee8a58b5ad1",
"crates/horizon-world/src/worldgen/biome_weather.rs": "96b1f9494559ed31d06257b83d604d00cc069ccc8c7b68094117e034b4a71bd7",
"crates/horizon-world/src/worldgen/block_blob.rs": "c608c57b3d77279646ecb89e50677dd8e452b0422ffd357ba755536c5589eb89",
"crates/horizon-world/src/worldgen/block_column.rs": "f72c21a9066ee0aa68c2fb79fba436d05afb14c6ef5a2cb012f1ed35fc17cd22",
"crates/horizon-world/src/worldgen/block_feature.rs": "36b4e46ee7f7f73bcb94d8bce8d99013e4b16234c9a03542eeb3186e88dd1c21",
"crates/horizon-world/src/worldgen/block_pile.rs": "623e369b77e0526ed2756485a6c0bb09683cd28ad8876dea907360ca6665b39d",
"crates/horizon-world/src/worldgen/block_predicate.rs": "074c692367e3f2191a1bb28d87b23402430a843c246bd30a4ea838ee3500280e",
"crates/horizon-world/src/worldgen/blue_ice.rs": "eedd77bdaff808330b864166d303378096daa5c7d235e925770b171c05109247",
"crates/horizon-world/src/worldgen/bonus_chest.rs": "05d0f63fbc7412f13ba1fa37a7238114b8f70bfff318beb2dece590482d49cc0",
"crates/horizon-world/src/worldgen/bulk_section.rs": "eecf61532d7793f853884c5a18a7f436a59835c7b13d3ec9075804511553c9ba",
"crates/horizon-world/src/worldgen/carver/canyon.rs": "509c4d5a9d689849e98e894ab14a9fbf82d10707d38e9cc688ded3c4778df3e2",
"crates/horizon-world/src/worldgen/carver/generation.rs": "a4498d0d1457536de3922a08e9c40ccce8d2ef9cc263801c15a412327513c098",
"crates/horizon-world/src/worldgen/carver.rs": "46b251e28225fe1250de38f49dec5dacda4e2c4ba1e556e21e6d1e14e2651fc3",
"crates/horizon-world/src/worldgen/carving.rs": "4e77d4e5c4a0ca55ca3563b9bdf6f379342e0bdf9d019d60f7bc57ce4afb5fbd",
"crates/horizon-world/src/worldgen/chorus_plant.rs": "29224c164ede919e280a65a68f155c873e2c8fd0aa7d7e244d8fa9e468760250",
"crates/horizon-world/src/worldgen/climate/codec.rs": "d567adeb5d837816fca69102db51d790f71aec1b51c09298230d24612e400a14",
"crates/horizon-world/src/worldgen/climate/index.rs": "c5ce61679a5f0e0f2f0af2a373424effa124d0cce8250609eff38b7034650756",
"crates/horizon-world/src/worldgen/climate.rs": "1b9ad44407f40aee4c1cd5357a5c9c443c1b105728f01cf5c644072f99f8357e",
"crates/horizon-world/src/worldgen/decoration.rs": "75a79b20b21e133816e729f16e758be6165d0db18a64bfbd5fd3618325a2adf3",
"crates/horizon-world/src/worldgen/delta.rs": "c2bf49ddf3231d28c109e68871429bc13d76a7bebe14eb33e84aa856bdd66145",
"crates/horizon-world/src/worldgen/density.rs": "65a98c156a290a6b374ef670d28cd5dfbe0aa93171824d1bbd96422536273f84",
"crates/horizon-world/src/worldgen/disk.rs": "6f8f9e059755af44c9bfa1b91eba54a7d13fad811dce31717c5502d7f6df33d7",
"crates/horizon-world/src/worldgen/end_gateway.rs": "f53fde77d6a36a525cd15d890003b2c129d0689a4cbfa2cf443a0c2e3acae040",
"crates/horizon-world/src/worldgen/end_podium.rs": "8f6d0d6d60ff0fde63de5781e867239db321f82cf12639f0537d410a3731ee1d",
"crates/horizon-world/src/worldgen/feature.rs": "40500af71ee6628dfb27518262d99f08d0383ae6c7b9397452feef0c213eadd9",
"crates/horizon-world/src/worldgen/feature_catalog.rs": "efc7b17b227e71622ef34108be9abd010f5675b68ea0409fcab82581d9aab88a",
"crates/horizon-world/src/worldgen/feature_graph.rs": "da132fca9fdafb0d89a917d5f4b68c60b70fb33cadf948a107da0e35d83dcd91",
"crates/horizon-world/src/worldgen/feature_region.rs": "df0ff142a461cafa9a3b42b949ad3376887f2be8d4ea5cc794a3ed2e977bb499",
"crates/horizon-world/src/worldgen/feature_sort.rs": "3488a093dfe1321aaa29d8a30cfb115d8e666a81bf195514e87b170de626835c",
"crates/horizon-world/src/worldgen/fluid_predicate.rs": "64197c9e63bebf1ce04bc280bfe980bb6c1b9aa887ca5cded904aeb0d9ae6c46",
"crates/horizon-world/src/worldgen/height_provider.rs": "368d4dc119854742a045c4a717679c921456da681fc5f71aa9b37102d6f33b47",
"crates/horizon-world/src/worldgen/material_condition/codec.rs": "09b909bc384472f76d163c8069ec6b507c7d5c6a028a36d5e0e3df20deff7b3b",
"crates/horizon-world/src/worldgen/material_condition/density.rs": "df9d0761e978e5010663ae8b44f2d6c1ecb4907331e333bdb6a2b487c1e107de",
"crates/horizon-world/src/worldgen/material_condition/library.rs": "a55534c5da97575a819af5a7dc0dbec9069993fa8b2619c6c9d5576946e683fa",
"crates/horizon-world/src/worldgen/material_condition/noise.rs": "ffb59cc6be2275d7a5621bf7d768527e74a8326ed7ad78618746711540921675",
"crates/horizon-world/src/worldgen/material_condition/rule.rs": "fed643352efbcb1f68f29b6241896617db889fc7c577a6247564e01922fec1fe",
"crates/horizon-world/src/worldgen/material_condition.rs": "d638dcb8cbcb5da20b3cb29602b0ae6a86c4fdf9d8c0fb725de8ec5fc108717e",
"crates/horizon-world/src/worldgen/material_extensions.rs": "ab806eb679d5116e1aebb64fca70e1499ae71f83c9507a8cb4c3201c2b1bf037",
"crates/horizon-world/src/worldgen/material_stage.rs": "698cbc786eff13c246e2bc2ea062401918cd4265899fbc3d53abc87e45a8e7a1",
"crates/horizon-world/src/worldgen/material_surface.rs": "5d37b90099df3d6da0845dab164e71469fb287019c2ee74bc6714f3b9d6d6d5b",
"crates/horizon-world/src/worldgen/ore_feature.rs": "83b89fd3be691c5412c0215b6abefdcaa44119a05aa41217e061970eb7e12ebd",
"crates/horizon-world/src/worldgen/placement/chain.rs": "9218399b4d3757f7bbc550d7729a7201f32a1c83a7030865e0c12aab8a80d116",
"crates/horizon-world/src/worldgen/placement/context.rs": "a278304795136677ad4b4933ea50c972b9729a1c671c03fa309c193e224b1fd6",
"crates/horizon-world/src/worldgen/placement/layer.rs": "a0f5ca776f33f9d4f72b8fdcd163426152e5e43cb4a7572fc1d4fc57bf965de1",
"crates/horizon-world/src/worldgen/placement.rs": "b0397e5818fae84358546193a95f84bcb0b5bffafce909e6fcb3386179ee8023",
"crates/horizon-world/src/worldgen/replace_blobs.rs": "bf3377d86d2570cd15288ba69dde64a2cf67c5bcbb9a31d0c23421964af74afa",
"crates/horizon-world/src/worldgen/router.rs": "2cee7cf15a0d2ada12be6b39d83e78177fd3033922e4f4cce87a64073cec2847",
"crates/horizon-world/src/worldgen/rule_test.rs": "d1662ec492489ebaa4b87e20f9a8c809dcf3a223a151211bd65ec241a63692fc",
"crates/horizon-world/src/worldgen/settings.rs": "a8fe87752e1982ef11cb67f8d80d8e3428b2c27db178044cb425ba803e689e59",
"crates/horizon-world/src/worldgen/simple_block.rs": "9ba1a88d5db4925f8c37366557887f776c805f9a6444781615b5dbaff52e92a4",
"crates/horizon-world/src/worldgen/snow_freeze.rs": "9040be3d5c7f8f0fd812d2df45e154bf8a9eeef038530b83fa4159d246eac35f",
"crates/horizon-world/src/worldgen/speleothem.rs": "c71651c1c97818a8a85863e14414d6139ea3bdeb897fa422043bcc1499d99aae",
"crates/horizon-world/src/worldgen/spike.rs": "eacf0d9d3d2bc3d4bcf62bc87555f90031138236a5bfef0eb5270204f7c2a4fc",
"crates/horizon-world/src/worldgen/spring.rs": "830849e9b89fcdf09e9b06fbefdcdebe3c8c3f82804f60b8bd5de04ba303cb62",
"crates/horizon-world/src/worldgen/state_provider/catalog.rs": "c8687e15a4887a9200c8d365857d801efaa8f90e669eee3e600a1db4905119eb",
"crates/horizon-world/src/worldgen/state_provider/noise.rs": "7ee369c2a032e5620cb9bdf9ee7adad1f70870fb0a27efb7b7c514d92f83491f",
"crates/horizon-world/src/worldgen/state_provider/properties.rs": "9909139aaca1dc4f743957257fadaa9d423d21fa401fa9abc050505f79365139",
"crates/horizon-world/src/worldgen/state_provider.rs": "be29ada818826a90afe01ab60916360fdfc4cbde5af15c9359cd56b1f1f7b156",
"crates/horizon-world/src/worldgen/tags.rs": "d35ded93fe6e95ea045cadcf4925e656dc34ef832b742179b9ad0cc49f902f31",
"crates/horizon-world/src/worldgen/terrain.rs": "fd1f2e0afc15daf66f484ea40a1f2b7013650bda0941b23c64c81ee9f79cb673",
"crates/horizon-world/src/worldgen/underwater_magma.rs": "7317e40af5ee5a9780f90ce358fa5d3e7f5b3d513b731df6ff97754d9c2a0154",
"crates/horizon-world/src/worldgen/value_provider.rs": "3358b563db8cb0bc8a9cfbbe2b8b3e70941cd2d37a0b519fbb6545f8d0dcbb69",
"crates/horizon-world/src/worldgen/vines.rs": "ee9b79b65012bd86a838241d2ef708680f7fe8eafc8aa656dae9cf2abf3c6418",
"crates/horizon-world/src/worldgen/weighted.rs": "839840aae25302933bbd97a81a2336330e2d03a0ad1684e1e16ac769ed408e6b",
"crates/horizon-world/src/worldgen/write_zone.rs": "8e17a179764d3f68c05882aef35f6810c28a0000f9a83e58bd6030660b76e64e",
"crates/horizon-world/src/worldgen.rs": "e8e9f099ee1fcec8eedce31805d676d3f89c18e84f494a147ffcbfee23d3d54f",
"crates/horizon-world/examples/collision_context_fixture.rs": "22701112922a2f806a1d6906f0e56bfbff309093bbbc7c140bf077d9686e854f"
},
"fixtures_sha256": {
".local/rust-collision-context-parity/inputs.txt": "60b49e91a7a4999cfb8eb6ac3fbc6ec0a931d68cd53f9737959a2bd2b42be7a5"
},
"rust_output_sha256": "7b23eb34c86c3db5a9e90bdd8ef772b79b2a06c8460542e032589f7962fd8f64",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "7b23eb34c86c3db5a9e90bdd8ef772b79b2a06c8460542e032589f7962fd8f64",
"matched_output_lines": 225126
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "7b23eb34c86c3db5a9e90bdd8ef772b79b2a06c8460542e032589f7962fd8f64",
"matched_output_lines": 225126
}
],
"scope": "Actual CollisionContext factories and EntityCollisionContext/Empty/PositionCollisionContext queries on controlled player and marker snapshots. Checks entity identity, captured descending and placement flags, fluid collision flags, empty-stack AIR identity, height thresholds including f32 epsilon, null factories, callback arguments/order/failures and all five fluid type pairs. Entity lifecycle, inventory mutations after capture, experimental minecart contexts, contextual block shape dispatch and live movement integration remain pending."
}
@@ -1,204 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"manifest_sha1": "4fe1aa1ef8da1cb95c5bad1fb98890ca56dd8ca3",
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"java": "openjdk 25.0.4.1 2026-08-18",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"fixtures": 56448,
"block_states": 32,
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCollisionContextOracle.java": "d2f5b022be1ee2111c38acf6710c21b59da09506e246fb22b8c7c8eeb253a7d9",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaFaceSupportOracle.java": "9ce939a435842867786fed648951bbe77f6ab843f6df09af15f3deb1948c4877",
"tools/test_collision_context_parity.py": "75d6f01e072867d2bd286d2e518e123fcfe055a11ac1705ec99ecec3975cb8d2",
"tools/test_scaffolding_collision_parity.py": "bab75e2cad68a3193035a87497eaa372466c405293cc547e39dbd7bd4450d69d",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "cb1e87d449114a63edd904c0559d631e8fa9feeb27efd6539aacdcfeae178876",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"crates/horizon-world/Cargo.toml": "977338bf3e654193685b015d383493b9f59ff6f5d6210bec212cef8ac4a50bed",
"crates/horizon-core/src/bin/density_parity.rs": "e5b1dd33b7d01306c73cf072629b4fb186e9ab87b672a00108999d1a72263fd0",
"crates/horizon-core/src/bin/float_log_parity.rs": "4a655fcf8822ee7668c4bd126bc84d0b118864a6fc7f5a6aeee667d8bf2590b1",
"crates/horizon-core/src/bin/geometry_parity.rs": "27f6c09fe5018ac3de8e70e0f0bbf78f9abb14f5e4783bcaf46e8ca87b9c6f8a",
"crates/horizon-core/src/bin/noise_parity.rs": "c135bfc708d853e7061e81487d2cfe10de64b2f65677d3b4837cbfe0b8341010",
"crates/horizon-core/src/bin/parity.rs": "f35d928c66f958de39fac5e7e836a657eed95f83599e84899f7ea7a5802ba481",
"crates/horizon-core/src/bin/tick_parity.rs": "a54c164fe4814034d369947a887f5273966f5a878ba849204b80d1c729526a8f",
"crates/horizon-core/src/biome/seed_hash.rs": "5afbb4921c750826b395a08bf06f382fc7f01b5759a93de02a2749c523e2a317",
"crates/horizon-core/src/biome.rs": "908efa8cd4aa0a7adf1cb5e1a222e3dfb640eed5e9172e0fe7f0d1287afae7e8",
"crates/horizon-core/src/carving/ellipsoid.rs": "09232a7588610e8a9176fd9c62d40afb1fb89f2ecab6d555536a1d847b142d86",
"crates/horizon-core/src/carving.rs": "0aa3093caa0437868a8c0ed52a6c6e1993bd51c03583c670a2837e749eae5426",
"crates/horizon-core/src/density/arithmetic.rs": "372faec96c923e2cf4aa6c66c1ac398e676853274557823850dbc8933dd15ab1",
"crates/horizon-core/src/density/beardifier.rs": "bb1052e27dae4a01954ca78d7d5babafef85f3b2c704ccaf1920cb85a098cb50",
"crates/horizon-core/src/density/cache.rs": "38d0b6c9dd04ffef979fdad3f29cfebf98d331c8c9d430be5f39aa34f6c30975",
"crates/horizon-core/src/density/end_islands.rs": "168b9384237bd2e41d0ae5a74e944da4dc74e493bdec31fb73184c9a49e3de55",
"crates/horizon-core/src/density/graph/compiler.rs": "ac67deeb16f16d0859aa20e5a165811a29aca0b910037ee6bf5098211f3a6ede",
"crates/horizon-core/src/density/graph/mod.rs": "b776e7da934cb03051a3053d56d461c71e9978e084922fe4194147aa580c07bf",
"crates/horizon-core/src/density/graph/seeded.rs": "6bcdcaa3dffcfa9df673bbbea35120057a16ba3d2b506c52709c36cf8976b74a",
"crates/horizon-core/src/density/graph/tests.rs": "6bfb8cbff462587dd147b0775ea01d370abbd97544b9bd596c792df1b5f7e634",
"crates/horizon-core/src/density/interpolation.rs": "8c890f52b6467f38a94c654986a6a484b8e0b296ab98c398e60a6ce465b5b010",
"crates/horizon-core/src/density/interval.rs": "b42629163baa6b599a233afe8596d1c370cd81d015cc6fc36a9663aa47b98424",
"crates/horizon-core/src/density/mod.rs": "ca0d77d3282e3746ddcbc92bee97dbf640b9a56214e6ac1537f51f9a5b63d6e7",
"crates/horizon-core/src/density/power.rs": "d5b7270a128d4264268cd772109ad16d71a8ec3ff2d3b63b84cb985296d54a91",
"crates/horizon-core/src/density/rounding.rs": "71840c5206ff8d218ac29bf6f66915d5212764ba270c675711a866ba5b55a7a6",
"crates/horizon-core/src/density/selection.rs": "0dd26af2e85004ec5e053039ad11c384c17c56ace9ab45eb3f5cb3503c0b0330",
"crates/horizon-core/src/density/slice.rs": "5d77605573c0deda47778f1f78f7fa3fbf1944d8f5efbcc65cf589181cadf80b",
"crates/horizon-core/src/density/spline.rs": "6bb2e40f940fc6544d6fb09cb0b8cac722be03bc663dbdfb0f61faae207400bc",
"crates/horizon-core/src/density/surface.rs": "159e0e69cda74f870e80ea64fe523c4397e64af4ccb861bb9fd07b2c3cb91b00",
"crates/horizon-core/src/density/terrain_noise.rs": "8d0059d25eb5d248cb97a4c5a2e670d61528928ea151495c004f25adb723fe3e",
"crates/horizon-core/src/density/tests.rs": "7817796ee40d0ae241bfbebec6bca190e0a8e7d5a1caa8ddf858c3eaa58b8858",
"crates/horizon-core/src/density/world_fields.rs": "c1ce305cb8046b384d90c564cafb24af7365d580389637910f3d8b0cc18eb583",
"crates/horizon-core/src/geometry/mod.rs": "dc92f73885dd0a7760743bf74f1ab8afa839d61cef2dfef890f8a23b67b4742e",
"crates/horizon-core/src/geometry/movement.rs": "930e34abef6f6eeec1ee7a6c920b5ba01bfe37b90678884490f4be53241f6b96",
"crates/horizon-core/src/geometry/shape/create.rs": "189812b91d5e0e3ad963afcd1a6e2831b31b8188df91a904ef27061e644806ad",
"crates/horizon-core/src/geometry/shape/face.rs": "f243bce81384040a95ce7984b02b5699206c596c537b2713097e86005b4d3a5c",
"crates/horizon-core/src/geometry/shape/join.rs": "f1b51887b7bf9482557e3ffa99e136f2e5db07ceeb05fdb116adf45e87129075",
"crates/horizon-core/src/geometry/shape.rs": "e8d88a763de1525f77a30b99591641e8a8b80946263acbde035a9bcc356df960",
"crates/horizon-core/src/geometry/sweep.rs": "abd6009c61555161ef2f18b431b2aa384b126c0871cae8b96a62358498a56a1d",
"crates/horizon-core/src/geometry/traversal.rs": "77a3da570a0b85582b669cf4d841cba4b06327006dda26d4a26df4e8ce05bae4",
"crates/horizon-core/src/geometry/trig.rs": "05cef9341a298a474221a0556a11ddf47650393ea7a97b4b2022a4da6628fe37",
"crates/horizon-core/src/lib.rs": "4255e16837fde42a52ba118f60581d197c571bb530b60d635e506184ebf4db0b",
"crates/horizon-core/src/noise/mod.rs": "1dab5a713abf702402e69ace1bf9e476bba544b0ede5a61c3c3afc60af0a03f3",
"crates/horizon-core/src/noise/normal.rs": "e9e7a46472a54a02c98c46da819842090567153b32fe0c84249009ef19af7aad",
"crates/horizon-core/src/noise/perlin.rs": "e73815447432eab7542f67366cb3f1b368d164e33f6c9cdbd045ac8e4db0932a",
"crates/horizon-core/src/noise/simplex.rs": "6c0dbc15b2b7510195dd28fceca01dcaac1847ccc4a84d299c351589c642fe7a",
"crates/horizon-core/src/noise/stack.rs": "7f6ef0e7d920139ef1a6ad3ec5640f92765715f86dcc5ec29f1a149984f45fa3",
"crates/horizon-core/src/noise/volume.rs": "3f05d2b1780acfdfee60037677d309937a5033b45ef428fc2d540942d4b56b43",
"crates/horizon-core/src/position/iter.rs": "32d2d8e74821cc4e49e3354202d35d3120e4415bfdda9375a73f2137ef651129",
"crates/horizon-core/src/position.rs": "e10101088e6902386b9b6d27773d44312f1ff72bebb19e57967a54945dde9dcd",
"crates/horizon-core/src/random/hash.rs": "0f88a127a1ba2705d3d6c0ebd009324d6ba86ffa2d27edf2d2a84765e690e4a3",
"crates/horizon-core/src/random/positional.rs": "35494745e5d4cf89e282c3ae0ee245e9f2640ddbbc03bc0055df742006a9c862",
"crates/horizon-core/src/random/worldgen.rs": "9f07ff33bcc038d34e27aa5465753bb21df18f2975e43cae201f709bc186945a",
"crates/horizon-core/src/random.rs": "ddb95d3a83e28ad605ff1f49f5df270cc543ca5ef1130e37d989dc74c8d861e6",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/src/text.rs": "e6553ddb5db5039e8dc4614b6a6dc9f35a26dc3d1673b68a04e72e7983b67abb",
"crates/horizon-core/src/ticks/generation.rs": "be1237e790693f633a61714ddae68c6506a777588a8a3ab5efbe53a35774dbd2",
"crates/horizon-core/src/ticks/heap.rs": "bf28afab8af77c3d243aa96cd8a1fb8d934140a4dbd07dbfdbf4e7908bb4b845",
"crates/horizon-core/src/ticks/index.rs": "1f1a6a568c2a30eafecb020ca4d5f5fc414860de85b8b381fc419a2e3e65c24a",
"crates/horizon-core/src/ticks/mod.rs": "01634630668172516b8b79d0907bad47f6e2c543a6d499c2fa4b201823b375cb",
"crates/horizon-world/src/bin/worldgen_parity.rs": "3143ceb9b56eecfd7667e5feb5f9f0cd13cfb8754b38d4ea338dbba97f2819da",
"crates/horizon-world/src/block_collision.rs": "a40c9d7a4e0a734c124dc856e31359fd4d8de3d1bfc79c86787afa8e8e05e480",
"crates/horizon-world/src/block_entities.rs": "a9deae92e6e5a1fcf4f0476c33ea4d170ddad6fd4b3303e1bb66d933973d5e06",
"crates/horizon-world/src/block_placement.rs": "524f4892d50bab77b7d89d19f7b048ffe746996f2ed7f376db2c6ab00ed75c24",
"crates/horizon-world/src/block_properties.rs": "b0bd8a983336c48e488a20caa77dd5c39b1a74bbd14ebc03b3b64556a1c864fc",
"crates/horizon-world/src/block_render.rs": "8df52ee11aef406a1571198a64048062a0ef6864e0058d9293a57f64b73c916a",
"crates/horizon-world/src/block_support.rs": "ade4fbd47284b450dabdd682dc86138b2ac05a0fd379525d7110648908245476",
"crates/horizon-world/src/block_survival.rs": "28ce64375e09819a4f13da9cfbe37c08b5ad0daf01b289c1c360b4567e50e811",
"crates/horizon-world/src/chunk.rs": "8843e6f48dbbc4245ce4e95564dfba3a4d7a051ba0b1577fb038c07adb0ff0f9",
"crates/horizon-world/src/chunk_status.rs": "dbb8583cfa775203c544d24d69e03720385428f15a267a561356c21f5025e9c7",
"crates/horizon-world/src/collision.rs": "05313e0c1f3089524fe029f9aac3e439cd47f1c9584c8c7e154c9adcfa88c335",
"crates/horizon-world/src/collision_context.rs": "2176c7034e07f547510a8327cdad9d3b63f26e4754032b76b7d5fe13166c333c",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/dynamic_support.rs": "5996bc1c436fb6215d8fc3d0bb4de5dd9b966d842d432580d624195771697fb8",
"crates/horizon-world/src/entity_obstruction.rs": "a4b28a19bf83b23611c59d94535c488db37e4aee24b22c973c545910894a809f",
"crates/horizon-world/src/fluid.rs": "a0a1f34ba94d8b59dc975becee8952960764d67ae08cf2d6a8bcd40a614b15c4",
"crates/horizon-world/src/heightmap.rs": "a5edef082b5af40d814421ea17e129b3b06d70abee6434ed263e4bba58571698",
"crates/horizon-world/src/lib.rs": "e321bed47d34ef1fdcdd99dad07cc537d34ed3cfbc07f10f10ec8b6848daf208",
"crates/horizon-world/src/liquid_collision.rs": "0f0a83b04e5a5bc9d98ed05fde4d6584ba69642e93522e726e4cfc325d6fcb1d",
"crates/horizon-world/src/main.rs": "fce57418b8c22a6a0a9044baa89ed3d9c243bc2e8413fea3ff0f32985daba021",
"crates/horizon-world/src/nbt.rs": "60262c3de8c8f68bc2da0370ccb17393d32b85f5f5022c6358599a7d32119ea6",
"crates/horizon-world/src/piston_shape.rs": "399c2337103b8e7e0eb5667227c5aa14f9549d6a467b7be7da3d0717f0263500",
"crates/horizon-world/src/region.rs": "72b642e87fed37ed17f54d4c30f96c3b64d26c14bc0589c31ef40ff1616188fc",
"crates/horizon-world/src/registry/json.rs": "7a683afcd1742c5307756927d7f0aa779c7d7992af87d8d371dd98108728e235",
"crates/horizon-world/src/registry.rs": "f2e58b2b4d944ac8fc6226bd3352cefc3d2052d8473e02ccf7dc402b176df435",
"crates/horizon-world/src/retrogen.rs": "6efd36a6293756688c1990a7965bd65609d7c5e2bf2a5f4f01d54932d2b9386b",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/worldgen/anchor.rs": "d156b8a0b147a274cdd143409b441f4f43edecde6e8ee14ef9cf0309f743143a",
"crates/horizon-world/src/worldgen/aquifer/config.rs": "fcd2cc3a520c1527c88f095a3b5d38487e7ebb1ccecc5f757f93d04a069add4f",
"crates/horizon-world/src/worldgen/aquifer/noise_based.rs": "74daaa389b5c3dfdc99214dfff256a9e172f83548d2326cbc941d9637cc53fb7",
"crates/horizon-world/src/worldgen/aquifer.rs": "cb4b66d87de3f9f79ae6ffe4badd6f0f44886cd42ad9de2771b8b56c4f1e28c7",
"crates/horizon-world/src/worldgen/bamboo.rs": "d9b47113c99be34256e58308bc6f40072ff25c579d6bf995182aa862c0006102",
"crates/horizon-world/src/worldgen/biome.rs": "3fe316b875aa32683759c337dc71f624910faf0812a2d6d83b8098d6d0bac7a0",
"crates/horizon-world/src/worldgen/biome_chunk.rs": "8fdfe6ebe3ffeca97611fd5991a5bc6b2783ea1c62f4d8ef3b2dd53c04a5dc1d",
"crates/horizon-world/src/worldgen/biome_predicate.rs": "bfc581bc40077cc74ffda43e990a55fe997adc04c7130f98e039c3305ca79aac",
"crates/horizon-world/src/worldgen/biome_source/codec.rs": "2b9e4f5d679eb444cb73174f511e3b9f32e9eb138248ab12cffc6cfd76adf3a8",
"crates/horizon-world/src/worldgen/biome_source/runtime.rs": "f0b02c1521178e4d0377c6ca62694604b6a773f1f234f070ff0cde4685911d45",
"crates/horizon-world/src/worldgen/biome_source.rs": "e181e1736f3e0b75f7091a24c88de3fd116e01b98424d02382aea7a503d1eb54",
"crates/horizon-world/src/worldgen/biome_temperature.rs": "cde4bbab5e260c4065b113376c423b8511ade93c5aa5fd976e245ee8a58b5ad1",
"crates/horizon-world/src/worldgen/biome_weather.rs": "96b1f9494559ed31d06257b83d604d00cc069ccc8c7b68094117e034b4a71bd7",
"crates/horizon-world/src/worldgen/block_blob.rs": "c608c57b3d77279646ecb89e50677dd8e452b0422ffd357ba755536c5589eb89",
"crates/horizon-world/src/worldgen/block_column.rs": "f72c21a9066ee0aa68c2fb79fba436d05afb14c6ef5a2cb012f1ed35fc17cd22",
"crates/horizon-world/src/worldgen/block_feature.rs": "36b4e46ee7f7f73bcb94d8bce8d99013e4b16234c9a03542eeb3186e88dd1c21",
"crates/horizon-world/src/worldgen/block_pile.rs": "623e369b77e0526ed2756485a6c0bb09683cd28ad8876dea907360ca6665b39d",
"crates/horizon-world/src/worldgen/block_predicate.rs": "074c692367e3f2191a1bb28d87b23402430a843c246bd30a4ea838ee3500280e",
"crates/horizon-world/src/worldgen/blue_ice.rs": "eedd77bdaff808330b864166d303378096daa5c7d235e925770b171c05109247",
"crates/horizon-world/src/worldgen/bonus_chest.rs": "05d0f63fbc7412f13ba1fa37a7238114b8f70bfff318beb2dece590482d49cc0",
"crates/horizon-world/src/worldgen/bulk_section.rs": "eecf61532d7793f853884c5a18a7f436a59835c7b13d3ec9075804511553c9ba",
"crates/horizon-world/src/worldgen/carver/canyon.rs": "509c4d5a9d689849e98e894ab14a9fbf82d10707d38e9cc688ded3c4778df3e2",
"crates/horizon-world/src/worldgen/carver/generation.rs": "a4498d0d1457536de3922a08e9c40ccce8d2ef9cc263801c15a412327513c098",
"crates/horizon-world/src/worldgen/carver.rs": "46b251e28225fe1250de38f49dec5dacda4e2c4ba1e556e21e6d1e14e2651fc3",
"crates/horizon-world/src/worldgen/carving.rs": "4e77d4e5c4a0ca55ca3563b9bdf6f379342e0bdf9d019d60f7bc57ce4afb5fbd",
"crates/horizon-world/src/worldgen/chorus_plant.rs": "29224c164ede919e280a65a68f155c873e2c8fd0aa7d7e244d8fa9e468760250",
"crates/horizon-world/src/worldgen/climate/codec.rs": "d567adeb5d837816fca69102db51d790f71aec1b51c09298230d24612e400a14",
"crates/horizon-world/src/worldgen/climate/index.rs": "c5ce61679a5f0e0f2f0af2a373424effa124d0cce8250609eff38b7034650756",
"crates/horizon-world/src/worldgen/climate.rs": "1b9ad44407f40aee4c1cd5357a5c9c443c1b105728f01cf5c644072f99f8357e",
"crates/horizon-world/src/worldgen/decoration.rs": "75a79b20b21e133816e729f16e758be6165d0db18a64bfbd5fd3618325a2adf3",
"crates/horizon-world/src/worldgen/delta.rs": "c2bf49ddf3231d28c109e68871429bc13d76a7bebe14eb33e84aa856bdd66145",
"crates/horizon-world/src/worldgen/density.rs": "65a98c156a290a6b374ef670d28cd5dfbe0aa93171824d1bbd96422536273f84",
"crates/horizon-world/src/worldgen/disk.rs": "6f8f9e059755af44c9bfa1b91eba54a7d13fad811dce31717c5502d7f6df33d7",
"crates/horizon-world/src/worldgen/end_gateway.rs": "f53fde77d6a36a525cd15d890003b2c129d0689a4cbfa2cf443a0c2e3acae040",
"crates/horizon-world/src/worldgen/end_podium.rs": "8f6d0d6d60ff0fde63de5781e867239db321f82cf12639f0537d410a3731ee1d",
"crates/horizon-world/src/worldgen/feature.rs": "40500af71ee6628dfb27518262d99f08d0383ae6c7b9397452feef0c213eadd9",
"crates/horizon-world/src/worldgen/feature_catalog.rs": "efc7b17b227e71622ef34108be9abd010f5675b68ea0409fcab82581d9aab88a",
"crates/horizon-world/src/worldgen/feature_graph.rs": "da132fca9fdafb0d89a917d5f4b68c60b70fb33cadf948a107da0e35d83dcd91",
"crates/horizon-world/src/worldgen/feature_region.rs": "df0ff142a461cafa9a3b42b949ad3376887f2be8d4ea5cc794a3ed2e977bb499",
"crates/horizon-world/src/worldgen/feature_sort.rs": "3488a093dfe1321aaa29d8a30cfb115d8e666a81bf195514e87b170de626835c",
"crates/horizon-world/src/worldgen/fluid_predicate.rs": "64197c9e63bebf1ce04bc280bfe980bb6c1b9aa887ca5cded904aeb0d9ae6c46",
"crates/horizon-world/src/worldgen/height_provider.rs": "368d4dc119854742a045c4a717679c921456da681fc5f71aa9b37102d6f33b47",
"crates/horizon-world/src/worldgen/material_condition/codec.rs": "09b909bc384472f76d163c8069ec6b507c7d5c6a028a36d5e0e3df20deff7b3b",
"crates/horizon-world/src/worldgen/material_condition/density.rs": "df9d0761e978e5010663ae8b44f2d6c1ecb4907331e333bdb6a2b487c1e107de",
"crates/horizon-world/src/worldgen/material_condition/library.rs": "a55534c5da97575a819af5a7dc0dbec9069993fa8b2619c6c9d5576946e683fa",
"crates/horizon-world/src/worldgen/material_condition/noise.rs": "ffb59cc6be2275d7a5621bf7d768527e74a8326ed7ad78618746711540921675",
"crates/horizon-world/src/worldgen/material_condition/rule.rs": "fed643352efbcb1f68f29b6241896617db889fc7c577a6247564e01922fec1fe",
"crates/horizon-world/src/worldgen/material_condition.rs": "d638dcb8cbcb5da20b3cb29602b0ae6a86c4fdf9d8c0fb725de8ec5fc108717e",
"crates/horizon-world/src/worldgen/material_extensions.rs": "ab806eb679d5116e1aebb64fca70e1499ae71f83c9507a8cb4c3201c2b1bf037",
"crates/horizon-world/src/worldgen/material_stage.rs": "698cbc786eff13c246e2bc2ea062401918cd4265899fbc3d53abc87e45a8e7a1",
"crates/horizon-world/src/worldgen/material_surface.rs": "5d37b90099df3d6da0845dab164e71469fb287019c2ee74bc6714f3b9d6d6d5b",
"crates/horizon-world/src/worldgen/ore_feature.rs": "83b89fd3be691c5412c0215b6abefdcaa44119a05aa41217e061970eb7e12ebd",
"crates/horizon-world/src/worldgen/placement/chain.rs": "9218399b4d3757f7bbc550d7729a7201f32a1c83a7030865e0c12aab8a80d116",
"crates/horizon-world/src/worldgen/placement/context.rs": "a278304795136677ad4b4933ea50c972b9729a1c671c03fa309c193e224b1fd6",
"crates/horizon-world/src/worldgen/placement/layer.rs": "a0f5ca776f33f9d4f72b8fdcd163426152e5e43cb4a7572fc1d4fc57bf965de1",
"crates/horizon-world/src/worldgen/placement.rs": "b0397e5818fae84358546193a95f84bcb0b5bffafce909e6fcb3386179ee8023",
"crates/horizon-world/src/worldgen/replace_blobs.rs": "bf3377d86d2570cd15288ba69dde64a2cf67c5bcbb9a31d0c23421964af74afa",
"crates/horizon-world/src/worldgen/router.rs": "2cee7cf15a0d2ada12be6b39d83e78177fd3033922e4f4cce87a64073cec2847",
"crates/horizon-world/src/worldgen/rule_test.rs": "d1662ec492489ebaa4b87e20f9a8c809dcf3a223a151211bd65ec241a63692fc",
"crates/horizon-world/src/worldgen/settings.rs": "a8fe87752e1982ef11cb67f8d80d8e3428b2c27db178044cb425ba803e689e59",
"crates/horizon-world/src/worldgen/simple_block.rs": "9ba1a88d5db4925f8c37366557887f776c805f9a6444781615b5dbaff52e92a4",
"crates/horizon-world/src/worldgen/snow_freeze.rs": "9040be3d5c7f8f0fd812d2df45e154bf8a9eeef038530b83fa4159d246eac35f",
"crates/horizon-world/src/worldgen/speleothem.rs": "c71651c1c97818a8a85863e14414d6139ea3bdeb897fa422043bcc1499d99aae",
"crates/horizon-world/src/worldgen/spike.rs": "eacf0d9d3d2bc3d4bcf62bc87555f90031138236a5bfef0eb5270204f7c2a4fc",
"crates/horizon-world/src/worldgen/spring.rs": "830849e9b89fcdf09e9b06fbefdcdebe3c8c3f82804f60b8bd5de04ba303cb62",
"crates/horizon-world/src/worldgen/state_provider/catalog.rs": "c8687e15a4887a9200c8d365857d801efaa8f90e669eee3e600a1db4905119eb",
"crates/horizon-world/src/worldgen/state_provider/noise.rs": "7ee369c2a032e5620cb9bdf9ee7adad1f70870fb0a27efb7b7c514d92f83491f",
"crates/horizon-world/src/worldgen/state_provider/properties.rs": "9909139aaca1dc4f743957257fadaa9d423d21fa401fa9abc050505f79365139",
"crates/horizon-world/src/worldgen/state_provider.rs": "be29ada818826a90afe01ab60916360fdfc4cbde5af15c9359cd56b1f1f7b156",
"crates/horizon-world/src/worldgen/tags.rs": "d35ded93fe6e95ea045cadcf4925e656dc34ef832b742179b9ad0cc49f902f31",
"crates/horizon-world/src/worldgen/terrain.rs": "fd1f2e0afc15daf66f484ea40a1f2b7013650bda0941b23c64c81ee9f79cb673",
"crates/horizon-world/src/worldgen/underwater_magma.rs": "7317e40af5ee5a9780f90ce358fa5d3e7f5b3d513b731df6ff97754d9c2a0154",
"crates/horizon-world/src/worldgen/value_provider.rs": "3358b563db8cb0bc8a9cfbbe2b8b3e70941cd2d37a0b519fbb6545f8d0dcbb69",
"crates/horizon-world/src/worldgen/vines.rs": "ee9b79b65012bd86a838241d2ef708680f7fe8eafc8aa656dae9cf2abf3c6418",
"crates/horizon-world/src/worldgen/weighted.rs": "839840aae25302933bbd97a81a2336330e2d03a0ad1684e1e16ac769ed408e6b",
"crates/horizon-world/src/worldgen/write_zone.rs": "8e17a179764d3f68c05882aef35f6810c28a0000f9a83e58bd6030660b76e64e",
"crates/horizon-world/src/worldgen.rs": "e8e9f099ee1fcec8eedce31805d676d3f89c18e84f494a147ffcbfee23d3d54f",
"crates/horizon-world/examples/collision_context_fixture.rs": "22701112922a2f806a1d6906f0e56bfbff309093bbbc7c140bf077d9686e854f"
},
"fixtures_sha256": {
".local/rust-scaffolding-collision-parity/inputs.txt": "5945054e86700237a7b6de6b362a37a98bdc8afaa67004e8aaa92da1421b552c"
},
"rust_output_sha256": "33a33cd612c999ab21f1acbbdee522f2ec2b3f877d62f922c665715e3012e207",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "33a33cd612c999ab21f1acbbdee522f2ec2b3f877d62f922c665715e3012e207",
"matched_output_lines": 524300
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "33a33cd612c999ab21f1acbbdee522f2ec2b3f877d62f922c665715e3012e207",
"matched_output_lines": 524300
}
],
"scope": "Actual CollisionContext.getCollisionShape dispatch and native scaffolding behavior for all 32 scaffolding states, nine context variants, descending flags, integer Y extremes, nonfinite positions and adjacent double values around the top/bottom float-epsilon thresholds. Full shape coordinates, extrema, box ordering and cube metadata match. A rejecting world proxy verifies selection performs no world reads. Scaffolding placement/update/falling behavior and live movement remain pending."
}
@@ -1,141 +0,0 @@
{
"adapter": {
"backend": "Vulkan",
"device": 0,
"device_type": "Cpu",
"name": "llvmpipe (LLVM 21.1.8, 256 bits)",
"vendor": 65541
},
"arch": "x86_64",
"camera_pitch": -0.3839724354387525,
"camera_position": [
25.0,
18.0,
25.0
],
"camera_yaw": -2.356194490192345,
"elapsed_seconds": 0.541997659,
"error": null,
"merged_quads": 166,
"os": "linux",
"presented_frames": 30,
"project": "Horizon",
"resident_chunks": 9,
"schema": 1,
"scope": "Native opaque-cube renderer and free inspection camera; no gameplay simulation",
"window_size": [
1280,
720
],
"executable_sha256": "4907a5678c323ab250934f3dfa32ba10e1554635f81d226ed2a88e7625737c5f",
"resource_manifest_sha256": "eda44ebee6904eab880c15458dbd1212dc2799d320a4419fc810e2ceb0e5d9d6",
"sources": {
"crates/horizon-client/src/assets.rs": "f35107193fc6d08be41891181da1803abf15bd373b62dd63758213809e2c5cbf",
"crates/horizon-client/src/camera.rs": "f9821c8a51a004dd4ad9c0952e746eb07926f6040cf8660bc26da5a0728ae572",
"crates/horizon-client/src/main.rs": "0cc250b695ba0d1e49107f581695edea1d24cdc2fb8ffa3a46368ef2c40430a7",
"crates/horizon-client/src/mesh.rs": "e2fa00435ec8239ba8a3c6539022bb50a10ff9c3850c6faab72f86aabea896ef",
"crates/horizon-client/src/render.rs": "4d58443465ea25769d73701d138db6a99c4f939a288e89e1f2b1ee3d017a2737",
"crates/horizon-client/src/world.rs": "901aa59c23ea084e926eec014589f4d511c41691a8dc1520534e039c28cfc76c",
"crates/horizon-client/src/world.wgsl": "dd7d579d0afb8a61da849171e444fa05a3e9d15bbfe6d019ff6653e8e0774c66",
"Cargo.toml": "4f803d21656a1420555bee6369617ddc825219a2cf05f842a209b3f8eaa583ec",
"Cargo.lock": "b1674833e1d5e66032589eea75643bf1c1eb2f2d6503e79ff7da8efa1b6d21dc",
"crates/horizon-client/Cargo.toml": "3047995858c9cd103ce358dfd991cb81e7d0688a149f4874cc73c36b859bbff7",
"tools/prepare_native_client.py": "b16f62acfc6242552af14ff405e2169ebba3adab12b991fc011e78edb4ffa982",
"tools/test_native_client.py": "adb9aa87cc28b0980d811ce47c1b09878d2d72cef2e083b278ec41183d231f1b"
},
"validation": {
"rust_workspace_tests": "passed",
"clippy_all_targets": "passed",
"python_tooling_tests": 149,
"mesh_tests": 2,
"manual_visual_checks": [
"textured scene with 81 chunks and 382 merged quads",
"window resize from 1600x1000 to 1280x720"
],
"input_checks": [
"physical W movement",
"physical Right rotation",
"captured relative mouse delta (150,-50) changed yaw by -0.3 and pitch by +0.1 radians",
"Escape and Ctrl+Q"
]
},
"environment": {
"os": "Ubuntu 26.04.1 LTS",
"kernel": "7.0.0-31-generic",
"cpu": "Intel Core i7-7500U",
"display": "headless Sway Wayland",
"renderer": "Vulkan llvmpipe software rasterizer"
},
"limits": [
"Controlled development scene only; no gameplay simulation or vanilla pixel-parity claim",
"No hardware FPS or render-distance improvement demonstrated",
"macOS and Windows runtime checks and final playable packages remain pending",
"Private game resources and screenshots excluded from this report"
],
"mouse_check": {
"adapter": {
"backend": "Vulkan",
"device": 0,
"device_type": "Cpu",
"name": "llvmpipe (LLVM 21.1.8, 256 bits)",
"vendor": 65541
},
"arch": "x86_64",
"camera_pitch": -0.2839724354387525,
"camera_position": [
25.0,
18.0,
25.0
],
"camera_yaw": -2.6561944901923447,
"elapsed_seconds": 8.654220098,
"error": null,
"merged_quads": 166,
"os": "linux",
"presented_frames": 532,
"project": "Horizon",
"resident_chunks": 9,
"schema": 1,
"scope": "Native opaque-cube renderer and free inspection camera; no gameplay simulation",
"window_size": [
1280,
720
]
},
"physical_keyboard_check": {
"adapter": {
"backend": "Vulkan",
"device": 0,
"device_type": "Cpu",
"name": "llvmpipe (LLVM 21.1.8, 256 bits)",
"vendor": 65541
},
"arch": "x86_64",
"camera_pitch": -0.3839724354387525,
"camera_position": [
18.943610750255,
18.0,
18.943610750255
],
"camera_yaw": -2.6478875051923443,
"elapsed_seconds": 17.488515374,
"error": null,
"merged_quads": 166,
"os": "linux",
"presented_frames": 1080,
"project": "Horizon",
"resident_chunks": 9,
"schema": 1,
"scope": "Native opaque-cube renderer and free inspection camera; no gameplay simulation",
"window_size": [
1280,
720
],
"source_note": "Same camera/input behavior; before subsequent diagnostic formatting and equivalent let-chain cleanup"
},
"private_capture_sha256": {
"first-launch.png": "7e53fa26d3d55f943db41828e1c8dd5b65279f9a130854fff288c75a394ee5aa",
"moved-resized.png": "be5a0473ab505740d18ba8eecf1512c15ba93d53d046f49b8dfa96357b25bf22",
"mouse-look.png": "7103678309f06938de40ac294f2f9ca1f56b253bc463e792b121ba607cd7b0a3"
}
}
@@ -1,800 +0,0 @@
{
"adapter": {
"backend": "Vulkan",
"device": 0,
"device_type": "Cpu",
"name": "llvmpipe (LLVM 21.1.8, 256 bits)",
"vendor": 65541
},
"animated_sprites": 1,
"animation_uploads": 1,
"arch": "x86_64",
"camera_pitch": -0.3839724354387525,
"camera_position": [
25.0,
18.0,
25.0
],
"camera_yaw": -2.356194490192345,
"collision_camera": false,
"culled_model_faces": 59636,
"elapsed_seconds": 0.547544857,
"error": null,
"fall_damage_requests": 0,
"last_requested_fall_damage": null,
"merged_quads": 3169,
"mesh_revision": 0,
"model_blocks": 10919,
"model_gallery": [
{
"block": "minecraft:oak_stairs",
"models": [
{
"model": "minecraft:block/oak_stairs_inner",
"rotations": [
2,
3,
0
],
"uv_lock": true
}
],
"position": [
-7,
4,
14
],
"properties": {
"facing": "north",
"half": "top",
"shape": "inner_left",
"waterlogged": "false"
},
"state_id": 5466
},
{
"block": "minecraft:stone_slab",
"models": [
{
"model": "minecraft:block/stone_slab_top",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
-3,
4,
14
],
"properties": {
"type": "top",
"waterlogged": "false"
},
"state_id": 15250
},
{
"block": "minecraft:anvil",
"models": [
{
"model": "minecraft:block/anvil",
"rotations": [
0,
3,
0
],
"uv_lock": false
}
],
"position": [
1,
4,
14
],
"properties": {
"facing": "east"
},
"state_id": 12965
},
{
"block": "minecraft:torch",
"models": [
{
"model": "minecraft:block/torch",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
14
],
"properties": {},
"state_id": 4926
},
{
"block": "minecraft:lantern",
"models": [
{
"model": "minecraft:block/lantern",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
-7,
4,
18
],
"properties": {
"hanging": "false",
"waterlogged": "false"
},
"state_id": 24197
},
{
"block": "minecraft:oak_fence",
"models": [
{
"model": "minecraft:block/oak_fence_post",
"rotations": [
0,
0,
0
],
"uv_lock": false
},
{
"model": "minecraft:block/oak_fence_side",
"rotations": [
0,
0,
0
],
"uv_lock": true
},
{
"model": "minecraft:block/oak_fence_side",
"rotations": [
0,
1,
0
],
"uv_lock": true
}
],
"position": [
-3,
4,
18
],
"properties": {
"east": "true",
"north": "true",
"south": "false",
"waterlogged": "false",
"west": "false"
},
"state_id": 8642
},
{
"block": "minecraft:oak_fence_gate",
"models": [
{
"model": "minecraft:block/oak_fence_gate_open",
"rotations": [
0,
1,
0
],
"uv_lock": true
}
],
"position": [
1,
4,
18
],
"properties": {
"facing": "west",
"in_wall": "false",
"open": "true",
"powered": "false"
},
"state_id": 10401
},
{
"block": "minecraft:iron_bars",
"models": [
{
"model": "minecraft:block/iron_bars_post_ends",
"rotations": [
0,
0,
0
],
"uv_lock": false
},
{
"model": "minecraft:block/iron_bars_side",
"rotations": [
0,
0,
0
],
"uv_lock": false
},
{
"model": "minecraft:block/iron_bars_side_alt",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
18
],
"properties": {
"east": "false",
"north": "true",
"south": "true",
"waterlogged": "false",
"west": "false"
},
"state_id": 9711
},
{
"block": "minecraft:cobweb",
"models": [
{
"model": "minecraft:block/cobweb",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
-7,
4,
22
],
"properties": {},
"state_id": 2362
},
{
"block": "minecraft:grindstone",
"models": [
{
"model": "minecraft:block/grindstone",
"rotations": [
1,
3,
0
],
"uv_lock": false
}
],
"position": [
-3,
4,
22
],
"properties": {
"face": "wall",
"facing": "west"
},
"state_id": 24135
},
{
"block": "minecraft:ladder",
"models": [
{
"model": "minecraft:block/ladder",
"rotations": [
0,
3,
0
],
"uv_lock": false
}
],
"position": [
1,
4,
22
],
"properties": {
"facing": "west",
"waterlogged": "false"
},
"state_id": 7312
},
{
"block": "minecraft:amethyst_cluster",
"models": [
{
"model": "minecraft:block/amethyst_cluster",
"rotations": [
1,
1,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
22
],
"properties": {
"facing": "east",
"waterlogged": "false"
},
"state_id": 26764
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone",
"rotations": [
0,
2,
0
],
"uv_lock": false
}
],
"position": [
-7,
4,
26
],
"properties": {},
"state_id": 1
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone_mirrored",
"rotations": [
0,
2,
0
],
"uv_lock": false
}
],
"position": [
-3,
4,
26
],
"properties": {},
"state_id": 1
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
1,
4,
26
],
"properties": {},
"state_id": 1
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone",
"rotations": [
0,
2,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
26
],
"properties": {},
"state_id": 1
}
],
"model_quads": 179,
"movement_ticks": 0,
"os": "linux",
"player_absorption": null,
"player_dead": null,
"player_exhaustion": null,
"player_fall_distance": null,
"player_food": null,
"player_food_timer": null,
"player_health": null,
"player_hurt_cooldown": null,
"player_on_ground": null,
"player_position": null,
"player_saturation": null,
"player_velocity": null,
"presented_frames": 30,
"project": "Horizon",
"resident_chunks": 9,
"schema": 1,
"scope": "Native resident-scene renderer with inspection camera and optional fixed-rate dry walking test; full gameplay remains unfinished",
"sprite_layers": 18,
"visible_model_faces": 5991,
"walking": false,
"window_size": [
1280,
720
],
"world_revision": 0,
"native_scene_culling": {
"blocks": 10919,
"culled_faces": 59636,
"visible_faces": 5991
},
"native_selection": {
"matched_placements": 16,
"selected_parts": 20,
"client_jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "a2ff1c890d6f3a5292c3a9402f02ca5404a993dc117853b25cbe64ac92b76d30",
"scope": "Actual native registry states, blockstate dispatch, tagged root baking and legacy collection using state.getSeed(position). All 16 featured placements match model names/transforms. An independently constructed native scene also matches total occupied blocks and visible/culled model faces using native parent resolution, rotated culling directions and Block.shouldRenderFace. No shader/pixel parity claim."
},
"resource_files": {
"files": 5590,
"sha256": "62f859d4d21b82158ab73e26cfa4973d58ab5926ab63d71c70c7a4d173502b7b"
},
"executable_sha256": "62fc8ff8bc750d2afeede7aaf830484de869655d7334c2a6405c9194e9a79cf9",
"resource_manifest_sha256": "92a51de578be0e7c37d21e94caa3f22503f7d88b73827a5fce109b1b889e5d18",
"sources": {
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "6884c7209f007ab9ee742b9c3c73828cfa1c6753d35b5fe25a87cab5955b33f8",
"tools/test_native_client.py": "6c615fed67fd7bcf09b3184216e08a82012049880a0d4da7c89f86553090cbda",
"crates/horizon-client/Cargo.toml": "d56524457d761c2613c0699b20e21ad6977d93e009d59ef150bbd9fc20d7a025",
"crates/horizon-assets/Cargo.toml": "2f2cffacec0b4e22dd7cb032d594289bc51c94ae6cc4e985fee3e310f441d751",
"crates/horizon-client/src/assets.rs": "e595afa610e0425d0b3ad694218794bf9e680e46ae80f3925c278ef1a823c914",
"crates/horizon-client/src/camera.rs": "d386a56ca8fb3b37ba2b2ed9d09342f61b409a575bb21590e934120b4ccebfa6",
"crates/horizon-client/src/clock.rs": "4851ada3e8e65d935eda8c0b57d3b51233b34f74aab4f040fd53db0e0d40b8df",
"crates/horizon-client/src/collisions.rs": "112286b07c4cd11b36da8b6799e0e069e69dfddf9a8a3f9ce36dcb282c791d67",
"crates/horizon-client/src/health.rs": "b5e2d3cde4bd58d906e6f6d47cd756ed23aa6706c71b10c3aedde30c11806403",
"crates/horizon-client/src/hunger.rs": "01d8a35f570f2a0991ac17a078f2066a5a83037a728158585765723d208b4611",
"crates/horizon-client/src/input.rs": "55b259ca6425c502270e7abc4d3ae1b3838633e2bd77d3817c6e00d9143a2beb",
"crates/horizon-client/src/landing.rs": "b9d0ecc5ec60a09d75ab9fe778e0a2e5bbb36fd8364a7ce996405f3dc9cb3b9f",
"crates/horizon-client/src/lib.rs": "bc1d0a7e42c11a9090abfebc4ed1f595415dd8b72a6a04b63c765b0deba29f6f",
"crates/horizon-client/src/main.rs": "aeb6b5220f8b89a1c9e85bf23fa2bbbafbc876108e59a222d383ad6e6fa238a6",
"crates/horizon-client/src/mesh.rs": "4ac8d85b30f599b37a98b92adcc016b16434816b93c401bd39b8215f591f9330",
"crates/horizon-client/src/models/catalog.rs": "620103719167fc9ab76e730d68eeacb50014e95b7ad209ae7adf2cbbe69f70f7",
"crates/horizon-client/src/models/cube.rs": "1067229f9dd9b276950bf7ec0c5f67061ce3d40a21932dca8034b9748e7439a4",
"crates/horizon-client/src/models.rs": "98dd3b969947c2b297862a934e6235067ddc1fc8cda5adcc6276d19014d4b048",
"crates/horizon-client/src/motion.rs": "673cc4bf6c4bc5523c104981e7c1cd640081a1b6ddca1e0ebe02181f04830347",
"crates/horizon-client/src/render.rs": "75cb40c257cf61e51009d292a06cd96532f59320b12ed7c3a509bbdbe1accdd4",
"crates/horizon-client/src/sprites.rs": "292f844a31f6e8884008df9630e2b8862db1acfbc4640cc07d526e25f21f0bc5",
"crates/horizon-client/src/world.rs": "0333ecf3e18ccc63117295feb2cf77661462ba13feb293eeec667c12811423b5",
"crates/horizon-client/src/world.wgsl": "972a58ccb34e9965515adbb30c47a93fceca5b742390db6d9f69cba1ec31f559",
"crates/horizon-assets/src/animation.rs": "ebbf7952146a0e66b41396174492f5702627170b03a57e6cd5a45c97a08c975e",
"crates/horizon-assets/src/bake/transform.rs": "a95e658fef85b21bcb2f9f7512f98f98d57022d62c1199885b7133beae35a09d",
"crates/horizon-assets/src/bake.rs": "f55dda6b6cee5ac6e65a8ee4837fdd2c6674437d59e59b4c45718f6324d4a4d5",
"crates/horizon-assets/src/blockstate/bind.rs": "6278962e55c9786bba8184bdf2939af9c6e3b9002b08c3022129964b49a60009",
"crates/horizon-assets/src/blockstate/choice.rs": "5a66c8b9833e2f19dd8b0773f3593d97ff5941d3c5b773896b98049efa1395ba",
"crates/horizon-assets/src/blockstate.rs": "a4299dfd7adaeb4173982ffaa8e9c9eda2925739ae579a714193c99da2e7ce56",
"crates/horizon-assets/src/json.rs": "99fe8af4fbf5d4eed408a92e829ac1a39597a0d92471a6bff73771fad9c830a8",
"crates/horizon-assets/src/lib.rs": "e39f21c59a2c3e1c53d977b29bd5e0638e5fc41d86ff0fcc1882a6d90fd961e4",
"crates/horizon-assets/src/model.rs": "57ddb3d65e88e7a8aa22c62bc298a2dae7f4e994326a873a31f06c0f36ed051b",
"crates/horizon-assets/src/resolve.rs": "3927ac926cdcbd7d334901cc32d0ecc1e498b1bec98f76a46bca6d4964c13541",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaGallerySelectionOracle.java": "dc5433f1ce1de629b30cb70f031a43a691fc1df1fb218ce23de89769c164d562",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCuboidModelOracle.java": "7526f20513c549483122ab0d5ad24b9e87f38dc2f6aae55addd701a91ac85e43",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaHeightmapOracle.java": "145c943637ed177cc4ef8a85f2484da8afd164868e84a8463882feec1653a860",
"tools/test_model_baking_parity.py": "392ffec44918fb91740ca4a1316d684480d39f14bd34d46175f7f44946d15bd7",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"tools/prepare_native_client.py": "159c12846058954a35ce86d415dc12fc89a6f11d46d21d1616ee686b7af4eee4",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"crates/horizon-core/src/bin/density_parity.rs": "e5b1dd33b7d01306c73cf072629b4fb186e9ab87b672a00108999d1a72263fd0",
"crates/horizon-core/src/bin/float_log_parity.rs": "4a655fcf8822ee7668c4bd126bc84d0b118864a6fc7f5a6aeee667d8bf2590b1",
"crates/horizon-core/src/bin/geometry_parity.rs": "27f6c09fe5018ac3de8e70e0f0bbf78f9abb14f5e4783bcaf46e8ca87b9c6f8a",
"crates/horizon-core/src/bin/noise_parity.rs": "c135bfc708d853e7061e81487d2cfe10de64b2f65677d3b4837cbfe0b8341010",
"crates/horizon-core/src/bin/parity.rs": "f35d928c66f958de39fac5e7e836a657eed95f83599e84899f7ea7a5802ba481",
"crates/horizon-core/src/bin/tick_parity.rs": "a54c164fe4814034d369947a887f5273966f5a878ba849204b80d1c729526a8f",
"crates/horizon-core/src/biome/seed_hash.rs": "5afbb4921c750826b395a08bf06f382fc7f01b5759a93de02a2749c523e2a317",
"crates/horizon-core/src/biome.rs": "908efa8cd4aa0a7adf1cb5e1a222e3dfb640eed5e9172e0fe7f0d1287afae7e8",
"crates/horizon-core/src/carving/ellipsoid.rs": "09232a7588610e8a9176fd9c62d40afb1fb89f2ecab6d555536a1d847b142d86",
"crates/horizon-core/src/carving.rs": "0aa3093caa0437868a8c0ed52a6c6e1993bd51c03583c670a2837e749eae5426",
"crates/horizon-core/src/density/arithmetic.rs": "372faec96c923e2cf4aa6c66c1ac398e676853274557823850dbc8933dd15ab1",
"crates/horizon-core/src/density/beardifier.rs": "bb1052e27dae4a01954ca78d7d5babafef85f3b2c704ccaf1920cb85a098cb50",
"crates/horizon-core/src/density/cache.rs": "38d0b6c9dd04ffef979fdad3f29cfebf98d331c8c9d430be5f39aa34f6c30975",
"crates/horizon-core/src/density/end_islands.rs": "168b9384237bd2e41d0ae5a74e944da4dc74e493bdec31fb73184c9a49e3de55",
"crates/horizon-core/src/density/graph/compiler.rs": "ac67deeb16f16d0859aa20e5a165811a29aca0b910037ee6bf5098211f3a6ede",
"crates/horizon-core/src/density/graph/mod.rs": "b776e7da934cb03051a3053d56d461c71e9978e084922fe4194147aa580c07bf",
"crates/horizon-core/src/density/graph/seeded.rs": "6bcdcaa3dffcfa9df673bbbea35120057a16ba3d2b506c52709c36cf8976b74a",
"crates/horizon-core/src/density/graph/tests.rs": "6bfb8cbff462587dd147b0775ea01d370abbd97544b9bd596c792df1b5f7e634",
"crates/horizon-core/src/density/interpolation.rs": "8c890f52b6467f38a94c654986a6a484b8e0b296ab98c398e60a6ce465b5b010",
"crates/horizon-core/src/density/interval.rs": "b42629163baa6b599a233afe8596d1c370cd81d015cc6fc36a9663aa47b98424",
"crates/horizon-core/src/density/mod.rs": "ca0d77d3282e3746ddcbc92bee97dbf640b9a56214e6ac1537f51f9a5b63d6e7",
"crates/horizon-core/src/density/power.rs": "d5b7270a128d4264268cd772109ad16d71a8ec3ff2d3b63b84cb985296d54a91",
"crates/horizon-core/src/density/rounding.rs": "71840c5206ff8d218ac29bf6f66915d5212764ba270c675711a866ba5b55a7a6",
"crates/horizon-core/src/density/selection.rs": "0dd26af2e85004ec5e053039ad11c384c17c56ace9ab45eb3f5cb3503c0b0330",
"crates/horizon-core/src/density/slice.rs": "5d77605573c0deda47778f1f78f7fa3fbf1944d8f5efbcc65cf589181cadf80b",
"crates/horizon-core/src/density/spline.rs": "6bb2e40f940fc6544d6fb09cb0b8cac722be03bc663dbdfb0f61faae207400bc",
"crates/horizon-core/src/density/surface.rs": "159e0e69cda74f870e80ea64fe523c4397e64af4ccb861bb9fd07b2c3cb91b00",
"crates/horizon-core/src/density/terrain_noise.rs": "8d0059d25eb5d248cb97a4c5a2e670d61528928ea151495c004f25adb723fe3e",
"crates/horizon-core/src/density/tests.rs": "7817796ee40d0ae241bfbebec6bca190e0a8e7d5a1caa8ddf858c3eaa58b8858",
"crates/horizon-core/src/density/world_fields.rs": "c1ce305cb8046b384d90c564cafb24af7365d580389637910f3d8b0cc18eb583",
"crates/horizon-core/src/geometry/border.rs": "1386f8080521231d05ba3e84d94a3e1d5218d35ccb3d5e9fe2bbb05a8739e573",
"crates/horizon-core/src/geometry/mod.rs": "c650386f9860e44a96c55f18c8f1428ca715fcb0bc5c2434db5b1caa43df27fe",
"crates/horizon-core/src/geometry/movement.rs": "bcfb452752940ce53ae6dc267a3c4eb29459046a063c1f884684ab4f4bd0068f",
"crates/horizon-core/src/geometry/shape/create.rs": "189812b91d5e0e3ad963afcd1a6e2831b31b8188df91a904ef27061e644806ad",
"crates/horizon-core/src/geometry/shape/face.rs": "f243bce81384040a95ce7984b02b5699206c596c537b2713097e86005b4d3a5c",
"crates/horizon-core/src/geometry/shape/join.rs": "f1b51887b7bf9482557e3ffa99e136f2e5db07ceeb05fdb116adf45e87129075",
"crates/horizon-core/src/geometry/shape.rs": "e8d88a763de1525f77a30b99591641e8a8b80946263acbde035a9bcc356df960",
"crates/horizon-core/src/geometry/sweep.rs": "abd6009c61555161ef2f18b431b2aa384b126c0871cae8b96a62358498a56a1d",
"crates/horizon-core/src/geometry/traversal.rs": "77a3da570a0b85582b669cf4d841cba4b06327006dda26d4a26df4e8ce05bae4",
"crates/horizon-core/src/geometry/trig.rs": "05cef9341a298a474221a0556a11ddf47650393ea7a97b4b2022a4da6628fe37",
"crates/horizon-core/src/lib.rs": "4255e16837fde42a52ba118f60581d197c571bb530b60d635e506184ebf4db0b",
"crates/horizon-core/src/noise/mod.rs": "1dab5a713abf702402e69ace1bf9e476bba544b0ede5a61c3c3afc60af0a03f3",
"crates/horizon-core/src/noise/normal.rs": "e9e7a46472a54a02c98c46da819842090567153b32fe0c84249009ef19af7aad",
"crates/horizon-core/src/noise/perlin.rs": "e73815447432eab7542f67366cb3f1b368d164e33f6c9cdbd045ac8e4db0932a",
"crates/horizon-core/src/noise/simplex.rs": "6c0dbc15b2b7510195dd28fceca01dcaac1847ccc4a84d299c351589c642fe7a",
"crates/horizon-core/src/noise/stack.rs": "7f6ef0e7d920139ef1a6ad3ec5640f92765715f86dcc5ec29f1a149984f45fa3",
"crates/horizon-core/src/noise/volume.rs": "3f05d2b1780acfdfee60037677d309937a5033b45ef428fc2d540942d4b56b43",
"crates/horizon-core/src/position/iter.rs": "32d2d8e74821cc4e49e3354202d35d3120e4415bfdda9375a73f2137ef651129",
"crates/horizon-core/src/position.rs": "e10101088e6902386b9b6d27773d44312f1ff72bebb19e57967a54945dde9dcd",
"crates/horizon-core/src/random/hash.rs": "0f88a127a1ba2705d3d6c0ebd009324d6ba86ffa2d27edf2d2a84765e690e4a3",
"crates/horizon-core/src/random/positional.rs": "35494745e5d4cf89e282c3ae0ee245e9f2640ddbbc03bc0055df742006a9c862",
"crates/horizon-core/src/random/worldgen.rs": "9f07ff33bcc038d34e27aa5465753bb21df18f2975e43cae201f709bc186945a",
"crates/horizon-core/src/random.rs": "ddb95d3a83e28ad605ff1f49f5df270cc543ca5ef1130e37d989dc74c8d861e6",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/src/text.rs": "e6553ddb5db5039e8dc4614b6a6dc9f35a26dc3d1673b68a04e72e7983b67abb",
"crates/horizon-core/src/ticks/generation.rs": "be1237e790693f633a61714ddae68c6506a777588a8a3ab5efbe53a35774dbd2",
"crates/horizon-core/src/ticks/heap.rs": "bf28afab8af77c3d243aa96cd8a1fb8d934140a4dbd07dbfdbf4e7908bb4b845",
"crates/horizon-core/src/ticks/index.rs": "1f1a6a568c2a30eafecb020ca4d5f5fc414860de85b8b381fc419a2e3e65c24a",
"crates/horizon-core/src/ticks/mod.rs": "01634630668172516b8b79d0907bad47f6e2c543a6d499c2fa4b201823b375cb",
"crates/horizon-world/Cargo.toml": "18bbad377a8047e4d4ecd0fc87d83d46d1c0f1ce2b8c47bbe64633e7b4420b57",
"crates/horizon-world/src/active_effect_tick.rs": "88f19cfc3532c47a58c646bb3e9d99ff239a900752302b6a444dda3013e95cbf",
"crates/horizon-world/src/active_effects.rs": "daaf352a69511a7d69fb329997f783b86585e486e0379c84ab0a55641771646c",
"crates/horizon-world/src/attribute_health.rs": "1420a80787d10dd2e2954a3ee6193ff313289d00c7c78ca26ece8bafa21f4380",
"crates/horizon-world/src/attribute_map.rs": "3d871cd530f5c035e0753f3ba065c2b9c5b49cdee75d4119f7dd584b22af67e6",
"crates/horizon-world/src/attribute_updates.rs": "4cb322d75a50d222298994607097ba7f7e6674021128fa02a98a74c057ad05f1",
"crates/horizon-world/src/attributes/entity.rs": "64ac99682a3aa06b1fb94b776b47794234c76b1cf70f1f54933d51e545e69279",
"crates/horizon-world/src/attributes/live.rs": "8198c45134f69135d48ef203e71b6e702529568fd1ed9174d0aa843570bbf9e7",
"crates/horizon-world/src/attributes/mod.rs": "5c2fcbbde58c19261874d227ea98332f00336c9fa53446da2e9adb6aa64a5e5a",
"crates/horizon-world/src/attributes/operation_map.rs": "fc5bc8921d78ea6721a2eaa915e67483e2a33683927467bdba24f0492356ad97",
"crates/horizon-world/src/bin/worldgen_parity.rs": "3143ceb9b56eecfd7667e5feb5f9f0cd13cfb8754b38d4ea338dbba97f2819da",
"crates/horizon-world/src/block_collision.rs": "39207247f2f6dd3ddc77640229044246f91b32054563f88a435f1bd92ad2092c",
"crates/horizon-world/src/block_collision_scan.rs": "20802862364c110ff85eeaf48606596a8468b83768dda46b412d337958790b41",
"crates/horizon-world/src/block_entities.rs": "a9deae92e6e5a1fcf4f0476c33ea4d170ddad6fd4b3303e1bb66d933973d5e06",
"crates/horizon-world/src/block_entity_push.rs": "12ee91bf604946234b24a0da4333f07d1830ab9743a422d41c8d0afac7d49cfd",
"crates/horizon-world/src/block_landing.rs": "33083fe39266fbefec1b3ea1a19f2afc609791d189da247c895e116ad6eb266a",
"crates/horizon-world/src/block_placement.rs": "524f4892d50bab77b7d89d19f7b048ffe746996f2ed7f376db2c6ab00ed75c24",
"crates/horizon-world/src/block_properties.rs": "b0bd8a983336c48e488a20caa77dd5c39b1a74bbd14ebc03b3b64556a1c864fc",
"crates/horizon-world/src/block_render.rs": "8df52ee11aef406a1571198a64048062a0ef6864e0058d9293a57f64b73c916a",
"crates/horizon-world/src/block_support.rs": "ade4fbd47284b450dabdd682dc86138b2ac05a0fd379525d7110648908245476",
"crates/horizon-world/src/block_survival.rs": "28ce64375e09819a4f13da9cfbe37c08b5ad0daf01b289c1c360b4567e50e811",
"crates/horizon-world/src/blocking_item_damage.rs": "afea3cb5761e8b82ee4d9bb4ef3c6fd10182a324dbaec99e6c9ebfac255dda09",
"crates/horizon-world/src/blocking_rules.rs": "83c5e2105cec56a90182ce582e1c67ade2b189be6de1a34d08035000cc07c492",
"crates/horizon-world/src/bundle_weight.rs": "a0e7b0587ab5d46cd55588f25d55a088b7a4725099c13ba6df146957be36014c",
"crates/horizon-world/src/chunk.rs": "795895284d6e615bcb2082fceacdfe7025c152fb2934bb43f598f17a00ab46f1",
"crates/horizon-world/src/chunk_status.rs": "dbb8583cfa775203c544d24d69e03720385428f15a267a561356c21f5025e9c7",
"crates/horizon-world/src/climbing.rs": "6cd2f919872ff0b726effddaa57eccb805b8eae43f9d01144716010853891879",
"crates/horizon-world/src/collision.rs": "a749794d5c27ccd6c0d964ad02f9dc31d49d9f4fe4b7366cd4bd8155e681b00b",
"crates/horizon-world/src/collision_context.rs": "2176c7034e07f547510a8327cdad9d3b63f26e4754032b76b7d5fe13166c333c",
"crates/horizon-world/src/combat_rules.rs": "01131f70d1acdd96a910e7f96deaa12e51a1e3bb9208085f04e3ec7b657d3cd4",
"crates/horizon-world/src/component_durability.rs": "37a46e184f95bc5027e2b9af72ff52f729ad03601d08e1827f181fca383a35af",
"crates/horizon-world/src/component_patch.rs": "f6f8992f241dfb25e012a06a7ba3fecab8d958686dddd096595a4806e56f0ab3",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/consumable.rs": "ba3575cb85866cb940f33a1ac86455d71cf0cc6395b848588a8ee1fe33f5c326",
"crates/horizon-world/src/consume_effect.rs": "03f2aac6879ce133347d42f6f6667d62c06d956ff9faac5dc14182a788b6a236",
"crates/horizon-world/src/damage_immunity.rs": "fd39c41124d694e755cf7faadcf93c636df4042c78ec345092a856b5f952dbcf",
"crates/horizon-world/src/damage_reduction.rs": "f5a599ab11e077f526237018aeda803ea3c420c5b35c78ae9d85e32267e23bf3",
"crates/horizon-world/src/damage_source.rs": "24945e397a926d34695652980923609e4723e02fe6b6e56d4aaf673e45d759f7",
"crates/horizon-world/src/dynamic_support.rs": "5996bc1c436fb6215d8fc3d0bb4de5dd9b966d842d432580d624195771697fb8",
"crates/horizon-world/src/edge_backoff.rs": "5259d7aa44e64f88351d1556c44dd0edcad3b400a099c659755792efba7b5773",
"crates/horizon-world/src/effect_attribute_modifiers.rs": "0bc7ab63d0f3f34a7133fe20364cae0ec1fdbd3773cba90faa1f08e0d63a5646",
"crates/horizon-world/src/effect_notifications.rs": "ea66bfa010d6d44aee97b9672902f41cd99d0d80239f41c6d4eae5c9a9472d3d",
"crates/horizon-world/src/effect_particles.rs": "a42dc4ec55929dce1db0f22f8816ecf7621fdce1cd2ac0c90f6a57fea4e0afd2",
"crates/horizon-world/src/effect_sync.rs": "1388d4a69b42a14ff4cd474f5e36f0fad5a2874031e64fa2b19b2ea179deed2b",
"crates/horizon-world/src/entity_collision.rs": "09f2fd7f6cd56fc282f468ecfa765a94506929e9684bd3a5c90123e5b51cd627",
"crates/horizon-world/src/entity_fluid.rs": "02991040ae879a8914f09913128a3506e9e7a1ca33ffc0a22b5729a168346600",
"crates/horizon-world/src/entity_fluid_tick.rs": "4f9e070b88a73c98a4e2e659360ddd6edee636bca29377f1ea9011fd5a556f64",
"crates/horizon-world/src/entity_move.rs": "a40a50d3e841625a75d4cfbb7c2630ab5a62a574456567e7234f401ae8441b32",
"crates/horizon-world/src/entity_obstruction.rs": "a4b28a19bf83b23611c59d94535c488db37e4aee24b22c973c545910894a809f",
"crates/horizon-world/src/extra_items.rs": "6eba0a0c795d5fd841d31471708e78324b4852adebb2e6ed700dcc0caab668cd",
"crates/horizon-world/src/fall_damage.rs": "8c28e2933493569fe05dea22332024287d28b0746b514dd465681040b003296b",
"crates/horizon-world/src/fluid.rs": "a0a1f34ba94d8b59dc975becee8952960764d67ae08cf2d6a8bcd40a614b15c4",
"crates/horizon-world/src/fluid_box.rs": "b586af72b1c04a9354fe66205c28dc8b619e205ab9ea19a68232722e4b6e96c1",
"crates/horizon-world/src/fluid_flow.rs": "7c7e486b5c565df3602799648b37b879bcca51414337f607962d6c7951b86d05",
"crates/horizon-world/src/fluid_occupancy.rs": "26037579caeef6c8a5a2bde2c3d142d278558b76d77ebff401cee6e35f2ea961",
"crates/horizon-world/src/fluid_shape.rs": "28bb65a72f5bd074a354ba38a1b1707fcb0947537977a11540bba0adb85995c2",
"crates/horizon-world/src/food.rs": "3cf416fa632a5555a8116bb528a6e80bcb5b6b754b0748b4959ed310102418d3",
"crates/horizon-world/src/food_properties.rs": "0926fa3f3bc3d0608c45d02f564355825ca3c3526a82bf9c1375c7a191fa5e12",
"crates/horizon-world/src/food_storage.rs": "58c433801a285efcc973638c11d694a41f85dc96703a3a7ce8d3673f3eb31d52",
"crates/horizon-world/src/free_space.rs": "913536bf4c85ddeeb378d76d1b5110b4175f5688e1a749f32fe6a6d86fbb478e",
"crates/horizon-world/src/ground_support.rs": "3e371d74ecede4d30beef0a7e8a2ee33463584a5b1ed3d852b394efcce1ffbe0",
"crates/horizon-world/src/heightmap.rs": "a5edef082b5af40d814421ea17e129b3b06d70abee6434ed263e4bba58571698",
"crates/horizon-world/src/identifier.rs": "37c921889c4f5d91f7c09ab2ee68d1a5e5a3c4fb1c49b4b189c987b4615fd2d6",
"crates/horizon-world/src/interaction_shapes.rs": "f321284ddab440a394372b6dedc8b5cc29a653c0745251a9e96c650f21c33dea",
"crates/horizon-world/src/inventory_pickup.rs": "ea830c7916e7f2d95c6db7ef48be1e876e6ebafcb438e47fc72f9a5bd7c37d07",
"crates/horizon-world/src/inventory_tick.rs": "293a3d57a1689337cfd58e5a73dcdbed4cb360f94d98ff5458f0df92de387365",
"crates/horizon-world/src/inventory_use.rs": "6a6c2ecc73c83dda4cd798c0304df12ace6096eb110d899f4f0c7ffd852bf001",
"crates/horizon-world/src/item_after_use.rs": "2b6598ce5b7b304dea2c8057b4a1eb6530264ac4d0546c3da0c76deed9609da5",
"crates/horizon-world/src/item_blocking.rs": "f6eee0d6d177cc3148960122327ba1b459a2f0e85241c1d9a3e40f0b8c169296",
"crates/horizon-world/src/item_cooldowns.rs": "7b625868509ab3c51e72db0ac714bb0e7ec5e2610d37271005a1a737f4d14431",
"crates/horizon-world/src/item_durability.rs": "9fdf835e5c7bd0e1dd63ef2ba0076b770cdd4d6d14cdcd11de27690f0702f94e",
"crates/horizon-world/src/item_particles.rs": "861b14f65adb9b14f8158fe9f0b7128beac3df8107b1337c31b8b9b49434ba3f",
"crates/horizon-world/src/item_stack_refs.rs": "18d3ca85cac0daf59200857513761359e5690f719cb3f7f64ae552f0c4169ea3",
"crates/horizon-world/src/item_stack_storage.rs": "b4dcb83dcaa346848c5484161feb3e2cf08e83f7793d7ed83be25b14b9d12884",
"crates/horizon-world/src/item_template.rs": "dc80025215d1867e656924ea2a9d273aacbcaea21293d986ba42d0004ee93b69",
"crates/horizon-world/src/item_use.rs": "b1c79428986efbf9dd5ede703a39eb387fb6dcc7d9950f0e49243a353a5b8070",
"crates/horizon-world/src/item_use_catalog.rs": "a9b53d2e816583239a75c3c61e78dacc5e3b27dee595be34b1c7fa169f17a571",
"crates/horizon-world/src/item_use_lifecycle.rs": "4639b70440cf811e79de09c48a3e035143fcb6be8a64c2f61b10ae55a2f133b7",
"crates/horizon-world/src/item_use_start.rs": "a84092dfb8b8f0a89d0928bb2f8ac252bd9bfd3f8d74fce1a7f7a5b3c3f4f50b",
"crates/horizon-world/src/java_hash_map.rs": "955502e696d7b0b33bae3ec485c8eb1453a8956116aad68226cf1fc67d60babc",
"crates/horizon-world/src/lib.rs": "577c16c021352b706d123f0f1c734375fc4a5a67b508caccbc38c1e1f693f6f4",
"crates/horizon-world/src/liquid_collision.rs": "0f0a83b04e5a5bc9d98ed05fde4d6584ba69642e93522e726e4cfc325d6fcb1d",
"crates/horizon-world/src/live_attribute_updates.rs": "778171faaaf7077deb0b62c4cc1db16351eba41adb8bb07656ba65e827056199",
"crates/horizon-world/src/living_air.rs": "b2de36bb50bed15e2808fe4a874fcef07f9fea0d2c96385b7b5e8ee9560d4442",
"crates/horizon-world/src/living_damage.rs": "2b448209629b9bf2e678d667ad0d6c7fa22146892dd106b169d96b31b0df12bb",
"crates/horizon-world/src/living_fall.rs": "da0f176f4731e1c86e08bfeee8167742fd1b86380ff0e9304c13c1ce3f1c67ab",
"crates/horizon-world/src/living_fluid.rs": "d7cd914cfb2a1f4876ce0ae95e999bf0ff1af732cce3ab4a3aa2d1ab881c7339",
"crates/horizon-world/src/living_health.rs": "221659f85552424e937d503bba6d8003006b106ced042b32d3a6f6cc23e12ed0",
"crates/horizon-world/src/living_hurt.rs": "844239ad7d15c39629bb3cfc06ebae6d1cff20b7627468f26e0ee8dff3abdcb8",
"crates/horizon-world/src/living_landing.rs": "8bca4eb7977abc2b14fb7174be4ea355352106ea1e76ff5f3ad8696969d9eefd",
"crates/horizon-world/src/living_motion.rs": "56f8c84cfbe205a7a69912d5f76b52ef1efca149c1b6801d4684e25fb179aeb9",
"crates/horizon-world/src/living_use_flags.rs": "826f4fdeba7e208368cbbf910fa408db0afbc6442d842d178a70fae53e0d0ea6",
"crates/horizon-world/src/main.rs": "fce57418b8c22a6a0a9044baa89ed3d9c243bc2e8413fea3ff0f32985daba021",
"crates/horizon-world/src/movement_emission.rs": "76e7d6f5b19c94676190f54389f9c4ce12cf89945ccfcb9c750de473223e7753",
"crates/horizon-world/src/movement_properties.rs": "6f01ab920b376a13f5ae12c3718f4dd067e1dff2b829585af00a8b2100f3775d",
"crates/horizon-world/src/movement_restitution.rs": "04b4fe0947e7e52576145bd8ed15920278e8a538afcc74d125eaca513dffa0ef",
"crates/horizon-world/src/movement_support.rs": "02d85cf572847f2e60b5a7f9d60b856888a67b3c1f4df03e81998c66fdf874be",
"crates/horizon-world/src/nbt.rs": "60262c3de8c8f68bc2da0370ccb17393d32b85f5f5022c6358599a7d32119ea6",
"crates/horizon-world/src/object_open_map.rs": "b4934a9cc38df93ed206ab0bc3bbc4499acd8e40b41b7def7d47067b7170065b",
"crates/horizon-world/src/object_open_set.rs": "d3e0373bf1b652dd054345d5a8e25ec828e06dd7cad65aada35163c95df4e637",
"crates/horizon-world/src/piston_movement.rs": "7a3fd2549a582b5f3a5c21aa05d67d944d62ca1105856679e100ac5b44e9a52f",
"crates/horizon-world/src/piston_shape.rs": "399c2337103b8e7e0eb5667227c5aa14f9549d6a467b7be7da3d0717f0263500",
"crates/horizon-world/src/player_equipment.rs": "1fa8c53e67624c4641246249d79a800a28a4858c62482bd880b4e3b866b936ef",
"crates/horizon-world/src/player_food.rs": "f188dc110745bcc7acc15e6c521db943b06b404f69cd251bf74a345516070304",
"crates/horizon-world/src/player_health.rs": "8155b315453c569db2fbe46228886c5881d1fd55eb095c5849e69bdb500ba2bd",
"crates/horizon-world/src/player_hurt.rs": "99c9bbd8587ec2dc287806049897b8034d2f5349ad47fc497b70d54148844a36",
"crates/horizon-world/src/player_inventory.rs": "f4f67d8312793f25930626c4ac06db688fcf2e2292d6675071d105fb1708d952",
"crates/horizon-world/src/player_travel.rs": "6841a677a900495eb6223031ef3ebe8d859bb98908dda0e2209e5f28839dc593",
"crates/horizon-world/src/powder_snow_collision.rs": "7289946a21478d11abfd2bdcdddff3d7f98e25bf6a68564fed45c3cc01ac2a36",
"crates/horizon-world/src/region.rs": "72b642e87fed37ed17f54d4c30f96c3b64d26c14bc0589c31ef40ff1616188fc",
"crates/horizon-world/src/registry/json.rs": "7a683afcd1742c5307756927d7f0aa779c7d7992af87d8d371dd98108728e235",
"crates/horizon-world/src/registry.rs": "f2e58b2b4d944ac8fc6226bd3352cefc3d2052d8473e02ccf7dc402b176df435",
"crates/horizon-world/src/registry_collision_scan.rs": "97cc950a9a4ba387b78e368f36d595f8664ab7730d132900d220ce23b92826ea",
"crates/horizon-world/src/registry_fall_ray.rs": "52935436132df505691144840dcbd858b15d00d8305997284e3a542ecf6bc0dc",
"crates/horizon-world/src/registry_fluid.rs": "b8959c05850cfeaaad1e4de8ca7c7d0d6ac56da9b2c1de3ebefa5871a11ed35e",
"crates/horizon-world/src/retrogen.rs": "6efd36a6293756688c1990a7965bd65609d7c5e2bf2a5f4f01d54932d2b9386b",
"crates/horizon-world/src/server_player_combat.rs": "0a94885c4b7a0d294ba7f4cee18b96ee59649b50112988250b53cc224059a979",
"crates/horizon-world/src/server_player_damage.rs": "29af22dec321fe01776cee5334f050c5bc3e27a688f99c8c3da4c0ad8bc8254e",
"crates/horizon-world/src/simple_container.rs": "0fedbc7e974b1db79b88bd6aff977654189a5d553cf42852fe8bf0885cf90b30",
"crates/horizon-world/src/status_effect.rs": "588bfcf4d93f50be86cb89545bd5c431edbc71771f704ff55cb52906b1964c37",
"crates/horizon-world/src/stored_consume.rs": "621a52c9fba447c393e561f881a16cf1f97d336e3a0ce493725ef51e2db12ffd",
"crates/horizon-world/src/stored_effect_attributes.rs": "c79f6a52d3cfee1a5288225bf8fa91a7bf3ea8cd21faea9f6dc748ecefc6309a",
"crates/horizon-world/src/suffocation.rs": "bed219dd5bbab6263b98fbe3d0eb512cb96c52ae847210efe49514d05f22f11e",
"crates/horizon-world/src/swimming.rs": "49d2dae13c109b37ff832cde98a857944ff45247b864a527b9c4f03ecca7a7b7",
"crates/horizon-world/src/synced_floats.rs": "0152f2752bafaf68769d56dbc88494a976496a680c6b113d6b48a446158ba072",
"crates/horizon-world/src/synced_values.rs": "a1d4b53ae77d1899ba2b4ead67c9ec1e3c96615558e446f9d0760c1b4a520169",
"crates/horizon-world/src/teleport_consume.rs": "d6a53bbb6ac4dbbd4c0591d0646017898a95beb8ef093dc5d81b9833963be6c3",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/use_remainder.rs": "f555335afeca7970888131a6da2f5a614a73253b631185d1ba804593a349535e",
"crates/horizon-world/src/view_direction.rs": "e18120ae26dc5cf702b29fc4c8487088bab133c8ce5abce01226833fafb0d5a4",
"crates/horizon-world/src/water_splash.rs": "e0461ae1b2e8c851cca6e3251a188334293292201d7f80dc9e7d60fd1815f4d1",
"crates/horizon-world/src/world_movement.rs": "f8fe9e34f2395d2a04c839d1c8ba78e09ce493c26de6f6e4e237b9c19c061da5",
"crates/horizon-world/src/world_ray.rs": "879bdbbe12f56deb705cc183933431489e840b71eade40c33391eed5949c2e61",
"crates/horizon-world/src/worldgen/anchor.rs": "d156b8a0b147a274cdd143409b441f4f43edecde6e8ee14ef9cf0309f743143a",
"crates/horizon-world/src/worldgen/aquifer/config.rs": "fcd2cc3a520c1527c88f095a3b5d38487e7ebb1ccecc5f757f93d04a069add4f",
"crates/horizon-world/src/worldgen/aquifer/noise_based.rs": "74daaa389b5c3dfdc99214dfff256a9e172f83548d2326cbc941d9637cc53fb7",
"crates/horizon-world/src/worldgen/aquifer.rs": "cb4b66d87de3f9f79ae6ffe4badd6f0f44886cd42ad9de2771b8b56c4f1e28c7",
"crates/horizon-world/src/worldgen/bamboo.rs": "d9b47113c99be34256e58308bc6f40072ff25c579d6bf995182aa862c0006102",
"crates/horizon-world/src/worldgen/biome.rs": "3fe316b875aa32683759c337dc71f624910faf0812a2d6d83b8098d6d0bac7a0",
"crates/horizon-world/src/worldgen/biome_chunk.rs": "8fdfe6ebe3ffeca97611fd5991a5bc6b2783ea1c62f4d8ef3b2dd53c04a5dc1d",
"crates/horizon-world/src/worldgen/biome_predicate.rs": "bfc581bc40077cc74ffda43e990a55fe997adc04c7130f98e039c3305ca79aac",
"crates/horizon-world/src/worldgen/biome_source/codec.rs": "2b9e4f5d679eb444cb73174f511e3b9f32e9eb138248ab12cffc6cfd76adf3a8",
"crates/horizon-world/src/worldgen/biome_source/runtime.rs": "f0b02c1521178e4d0377c6ca62694604b6a773f1f234f070ff0cde4685911d45",
"crates/horizon-world/src/worldgen/biome_source.rs": "e181e1736f3e0b75f7091a24c88de3fd116e01b98424d02382aea7a503d1eb54",
"crates/horizon-world/src/worldgen/biome_temperature.rs": "cde4bbab5e260c4065b113376c423b8511ade93c5aa5fd976e245ee8a58b5ad1",
"crates/horizon-world/src/worldgen/biome_weather.rs": "96b1f9494559ed31d06257b83d604d00cc069ccc8c7b68094117e034b4a71bd7",
"crates/horizon-world/src/worldgen/block_blob.rs": "c608c57b3d77279646ecb89e50677dd8e452b0422ffd357ba755536c5589eb89",
"crates/horizon-world/src/worldgen/block_column.rs": "f72c21a9066ee0aa68c2fb79fba436d05afb14c6ef5a2cb012f1ed35fc17cd22",
"crates/horizon-world/src/worldgen/block_feature.rs": "36b4e46ee7f7f73bcb94d8bce8d99013e4b16234c9a03542eeb3186e88dd1c21",
"crates/horizon-world/src/worldgen/block_pile.rs": "623e369b77e0526ed2756485a6c0bb09683cd28ad8876dea907360ca6665b39d",
"crates/horizon-world/src/worldgen/block_predicate.rs": "074c692367e3f2191a1bb28d87b23402430a843c246bd30a4ea838ee3500280e",
"crates/horizon-world/src/worldgen/blue_ice.rs": "eedd77bdaff808330b864166d303378096daa5c7d235e925770b171c05109247",
"crates/horizon-world/src/worldgen/bonus_chest.rs": "05d0f63fbc7412f13ba1fa37a7238114b8f70bfff318beb2dece590482d49cc0",
"crates/horizon-world/src/worldgen/bulk_section.rs": "eecf61532d7793f853884c5a18a7f436a59835c7b13d3ec9075804511553c9ba",
"crates/horizon-world/src/worldgen/carver/canyon.rs": "509c4d5a9d689849e98e894ab14a9fbf82d10707d38e9cc688ded3c4778df3e2",
"crates/horizon-world/src/worldgen/carver/generation.rs": "a4498d0d1457536de3922a08e9c40ccce8d2ef9cc263801c15a412327513c098",
"crates/horizon-world/src/worldgen/carver.rs": "46b251e28225fe1250de38f49dec5dacda4e2c4ba1e556e21e6d1e14e2651fc3",
"crates/horizon-world/src/worldgen/carving.rs": "4e77d4e5c4a0ca55ca3563b9bdf6f379342e0bdf9d019d60f7bc57ce4afb5fbd",
"crates/horizon-world/src/worldgen/chorus_plant.rs": "29224c164ede919e280a65a68f155c873e2c8fd0aa7d7e244d8fa9e468760250",
"crates/horizon-world/src/worldgen/climate/codec.rs": "d567adeb5d837816fca69102db51d790f71aec1b51c09298230d24612e400a14",
"crates/horizon-world/src/worldgen/climate/index.rs": "c5ce61679a5f0e0f2f0af2a373424effa124d0cce8250609eff38b7034650756",
"crates/horizon-world/src/worldgen/climate.rs": "1b9ad44407f40aee4c1cd5357a5c9c443c1b105728f01cf5c644072f99f8357e",
"crates/horizon-world/src/worldgen/decoration.rs": "75a79b20b21e133816e729f16e758be6165d0db18a64bfbd5fd3618325a2adf3",
"crates/horizon-world/src/worldgen/delta.rs": "c2bf49ddf3231d28c109e68871429bc13d76a7bebe14eb33e84aa856bdd66145",
"crates/horizon-world/src/worldgen/density.rs": "65a98c156a290a6b374ef670d28cd5dfbe0aa93171824d1bbd96422536273f84",
"crates/horizon-world/src/worldgen/disk.rs": "6f8f9e059755af44c9bfa1b91eba54a7d13fad811dce31717c5502d7f6df33d7",
"crates/horizon-world/src/worldgen/end_gateway.rs": "f53fde77d6a36a525cd15d890003b2c129d0689a4cbfa2cf443a0c2e3acae040",
"crates/horizon-world/src/worldgen/end_podium.rs": "8f6d0d6d60ff0fde63de5781e867239db321f82cf12639f0537d410a3731ee1d",
"crates/horizon-world/src/worldgen/feature.rs": "40500af71ee6628dfb27518262d99f08d0383ae6c7b9397452feef0c213eadd9",
"crates/horizon-world/src/worldgen/feature_catalog.rs": "efc7b17b227e71622ef34108be9abd010f5675b68ea0409fcab82581d9aab88a",
"crates/horizon-world/src/worldgen/feature_graph.rs": "da132fca9fdafb0d89a917d5f4b68c60b70fb33cadf948a107da0e35d83dcd91",
"crates/horizon-world/src/worldgen/feature_region.rs": "df0ff142a461cafa9a3b42b949ad3376887f2be8d4ea5cc794a3ed2e977bb499",
"crates/horizon-world/src/worldgen/feature_sort.rs": "3488a093dfe1321aaa29d8a30cfb115d8e666a81bf195514e87b170de626835c",
"crates/horizon-world/src/worldgen/fluid_predicate.rs": "64197c9e63bebf1ce04bc280bfe980bb6c1b9aa887ca5cded904aeb0d9ae6c46",
"crates/horizon-world/src/worldgen/height_provider.rs": "368d4dc119854742a045c4a717679c921456da681fc5f71aa9b37102d6f33b47",
"crates/horizon-world/src/worldgen/material_condition/codec.rs": "09b909bc384472f76d163c8069ec6b507c7d5c6a028a36d5e0e3df20deff7b3b",
"crates/horizon-world/src/worldgen/material_condition/density.rs": "df9d0761e978e5010663ae8b44f2d6c1ecb4907331e333bdb6a2b487c1e107de",
"crates/horizon-world/src/worldgen/material_condition/library.rs": "a55534c5da97575a819af5a7dc0dbec9069993fa8b2619c6c9d5576946e683fa",
"crates/horizon-world/src/worldgen/material_condition/noise.rs": "ffb59cc6be2275d7a5621bf7d768527e74a8326ed7ad78618746711540921675",
"crates/horizon-world/src/worldgen/material_condition/rule.rs": "fed643352efbcb1f68f29b6241896617db889fc7c577a6247564e01922fec1fe",
"crates/horizon-world/src/worldgen/material_condition.rs": "d638dcb8cbcb5da20b3cb29602b0ae6a86c4fdf9d8c0fb725de8ec5fc108717e",
"crates/horizon-world/src/worldgen/material_extensions.rs": "ab806eb679d5116e1aebb64fca70e1499ae71f83c9507a8cb4c3201c2b1bf037",
"crates/horizon-world/src/worldgen/material_stage.rs": "698cbc786eff13c246e2bc2ea062401918cd4265899fbc3d53abc87e45a8e7a1",
"crates/horizon-world/src/worldgen/material_surface.rs": "5d37b90099df3d6da0845dab164e71469fb287019c2ee74bc6714f3b9d6d6d5b",
"crates/horizon-world/src/worldgen/ore_feature.rs": "83b89fd3be691c5412c0215b6abefdcaa44119a05aa41217e061970eb7e12ebd",
"crates/horizon-world/src/worldgen/placement/chain.rs": "9218399b4d3757f7bbc550d7729a7201f32a1c83a7030865e0c12aab8a80d116",
"crates/horizon-world/src/worldgen/placement/context.rs": "a278304795136677ad4b4933ea50c972b9729a1c671c03fa309c193e224b1fd6",
"crates/horizon-world/src/worldgen/placement/layer.rs": "a0f5ca776f33f9d4f72b8fdcd163426152e5e43cb4a7572fc1d4fc57bf965de1",
"crates/horizon-world/src/worldgen/placement.rs": "b0397e5818fae84358546193a95f84bcb0b5bffafce909e6fcb3386179ee8023",
"crates/horizon-world/src/worldgen/replace_blobs.rs": "bf3377d86d2570cd15288ba69dde64a2cf67c5bcbb9a31d0c23421964af74afa",
"crates/horizon-world/src/worldgen/router.rs": "2cee7cf15a0d2ada12be6b39d83e78177fd3033922e4f4cce87a64073cec2847",
"crates/horizon-world/src/worldgen/rule_test.rs": "d1662ec492489ebaa4b87e20f9a8c809dcf3a223a151211bd65ec241a63692fc",
"crates/horizon-world/src/worldgen/settings.rs": "a8fe87752e1982ef11cb67f8d80d8e3428b2c27db178044cb425ba803e689e59",
"crates/horizon-world/src/worldgen/simple_block.rs": "9ba1a88d5db4925f8c37366557887f776c805f9a6444781615b5dbaff52e92a4",
"crates/horizon-world/src/worldgen/snow_freeze.rs": "9040be3d5c7f8f0fd812d2df45e154bf8a9eeef038530b83fa4159d246eac35f",
"crates/horizon-world/src/worldgen/speleothem.rs": "c71651c1c97818a8a85863e14414d6139ea3bdeb897fa422043bcc1499d99aae",
"crates/horizon-world/src/worldgen/spike.rs": "eacf0d9d3d2bc3d4bcf62bc87555f90031138236a5bfef0eb5270204f7c2a4fc",
"crates/horizon-world/src/worldgen/spring.rs": "830849e9b89fcdf09e9b06fbefdcdebe3c8c3f82804f60b8bd5de04ba303cb62",
"crates/horizon-world/src/worldgen/state_provider/catalog.rs": "c8687e15a4887a9200c8d365857d801efaa8f90e669eee3e600a1db4905119eb",
"crates/horizon-world/src/worldgen/state_provider/noise.rs": "7ee369c2a032e5620cb9bdf9ee7adad1f70870fb0a27efb7b7c514d92f83491f",
"crates/horizon-world/src/worldgen/state_provider/properties.rs": "9909139aaca1dc4f743957257fadaa9d423d21fa401fa9abc050505f79365139",
"crates/horizon-world/src/worldgen/state_provider.rs": "be29ada818826a90afe01ab60916360fdfc4cbde5af15c9359cd56b1f1f7b156",
"crates/horizon-world/src/worldgen/tags.rs": "74e4110fb19c4c4047192fd65c38015b8afc7f9fc50404d75380b5063808148c",
"crates/horizon-world/src/worldgen/terrain.rs": "fd1f2e0afc15daf66f484ea40a1f2b7013650bda0941b23c64c81ee9f79cb673",
"crates/horizon-world/src/worldgen/underwater_magma.rs": "7317e40af5ee5a9780f90ce358fa5d3e7f5b3d513b731df6ff97754d9c2a0154",
"crates/horizon-world/src/worldgen/value_provider.rs": "3358b563db8cb0bc8a9cfbbe2b8b3e70941cd2d37a0b519fbb6545f8d0dcbb69",
"crates/horizon-world/src/worldgen/vines.rs": "ee9b79b65012bd86a838241d2ef708680f7fe8eafc8aa656dae9cf2abf3c6418",
"crates/horizon-world/src/worldgen/weighted.rs": "839840aae25302933bbd97a81a2336330e2d03a0ad1684e1e16ac769ed408e6b",
"crates/horizon-world/src/worldgen/write_zone.rs": "8e17a179764d3f68c05882aef35f6810c28a0000f9a83e58bd6030660b76e64e",
"crates/horizon-world/src/worldgen.rs": "e8e9f099ee1fcec8eedce31805d676d3f89c18e84f494a147ffcbfee23d3d54f"
}
}
@@ -1,790 +0,0 @@
{
"adapter": {
"backend": "Vulkan",
"device": 0,
"device_type": "Cpu",
"name": "llvmpipe (LLVM 21.1.8, 256 bits)",
"vendor": 65541
},
"animated_sprites": 1,
"animation_uploads": 1,
"arch": "x86_64",
"camera_pitch": -0.3839724354387525,
"camera_position": [
25.0,
18.0,
25.0
],
"camera_yaw": -2.356194490192345,
"collision_camera": false,
"culled_model_faces": 59636,
"elapsed_seconds": 0.547517663,
"error": null,
"fall_damage_requests": 0,
"last_requested_fall_damage": null,
"merged_quads": 3169,
"mesh_revision": 0,
"model_blocks": 10919,
"model_gallery": [
{
"block": "minecraft:oak_stairs",
"models": [
{
"model": "minecraft:block/oak_stairs_inner",
"rotations": [
2,
3,
0
],
"uv_lock": true
}
],
"position": [
-7,
4,
14
],
"properties": {
"facing": "north",
"half": "top",
"shape": "inner_left",
"waterlogged": "false"
},
"state_id": 5466
},
{
"block": "minecraft:stone_slab",
"models": [
{
"model": "minecraft:block/stone_slab_top",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
-3,
4,
14
],
"properties": {
"type": "top",
"waterlogged": "false"
},
"state_id": 15250
},
{
"block": "minecraft:anvil",
"models": [
{
"model": "minecraft:block/anvil",
"rotations": [
0,
3,
0
],
"uv_lock": false
}
],
"position": [
1,
4,
14
],
"properties": {
"facing": "east"
},
"state_id": 12965
},
{
"block": "minecraft:torch",
"models": [
{
"model": "minecraft:block/torch",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
14
],
"properties": {},
"state_id": 4926
},
{
"block": "minecraft:lantern",
"models": [
{
"model": "minecraft:block/lantern",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
-7,
4,
18
],
"properties": {
"hanging": "false",
"waterlogged": "false"
},
"state_id": 24197
},
{
"block": "minecraft:oak_fence",
"models": [
{
"model": "minecraft:block/oak_fence_post",
"rotations": [
0,
0,
0
],
"uv_lock": false
},
{
"model": "minecraft:block/oak_fence_side",
"rotations": [
0,
0,
0
],
"uv_lock": true
},
{
"model": "minecraft:block/oak_fence_side",
"rotations": [
0,
1,
0
],
"uv_lock": true
}
],
"position": [
-3,
4,
18
],
"properties": {
"east": "true",
"north": "true",
"south": "false",
"waterlogged": "false",
"west": "false"
},
"state_id": 8642
},
{
"block": "minecraft:oak_fence_gate",
"models": [
{
"model": "minecraft:block/oak_fence_gate_open",
"rotations": [
0,
1,
0
],
"uv_lock": true
}
],
"position": [
1,
4,
18
],
"properties": {
"facing": "west",
"in_wall": "false",
"open": "true",
"powered": "false"
},
"state_id": 10401
},
{
"block": "minecraft:iron_bars",
"models": [
{
"model": "minecraft:block/iron_bars_post_ends",
"rotations": [
0,
0,
0
],
"uv_lock": false
},
{
"model": "minecraft:block/iron_bars_side",
"rotations": [
0,
0,
0
],
"uv_lock": false
},
{
"model": "minecraft:block/iron_bars_side_alt",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
18
],
"properties": {
"east": "false",
"north": "true",
"south": "true",
"waterlogged": "false",
"west": "false"
},
"state_id": 9711
},
{
"block": "minecraft:cobweb",
"models": [
{
"model": "minecraft:block/cobweb",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
-7,
4,
22
],
"properties": {},
"state_id": 2362
},
{
"block": "minecraft:grindstone",
"models": [
{
"model": "minecraft:block/grindstone",
"rotations": [
1,
3,
0
],
"uv_lock": false
}
],
"position": [
-3,
4,
22
],
"properties": {
"face": "wall",
"facing": "west"
},
"state_id": 24135
},
{
"block": "minecraft:ladder",
"models": [
{
"model": "minecraft:block/ladder",
"rotations": [
0,
3,
0
],
"uv_lock": false
}
],
"position": [
1,
4,
22
],
"properties": {
"facing": "west",
"waterlogged": "false"
},
"state_id": 7312
},
{
"block": "minecraft:amethyst_cluster",
"models": [
{
"model": "minecraft:block/amethyst_cluster",
"rotations": [
1,
1,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
22
],
"properties": {
"facing": "east",
"waterlogged": "false"
},
"state_id": 26764
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone",
"rotations": [
0,
2,
0
],
"uv_lock": false
}
],
"position": [
-7,
4,
26
],
"properties": {},
"state_id": 1
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone_mirrored",
"rotations": [
0,
2,
0
],
"uv_lock": false
}
],
"position": [
-3,
4,
26
],
"properties": {},
"state_id": 1
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
1,
4,
26
],
"properties": {},
"state_id": 1
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone",
"rotations": [
0,
2,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
26
],
"properties": {},
"state_id": 1
}
],
"model_quads": 179,
"movement_ticks": 0,
"os": "linux",
"player_fall_distance": null,
"player_on_ground": null,
"player_position": null,
"player_velocity": null,
"presented_frames": 30,
"project": "Horizon",
"resident_chunks": 9,
"schema": 1,
"scope": "Native resident-scene renderer with inspection camera and optional fixed-rate dry walking test; full gameplay remains unfinished",
"sprite_layers": 18,
"visible_model_faces": 5991,
"walking": false,
"window_size": [
1280,
720
],
"world_revision": 0,
"native_scene_culling": {
"blocks": 10919,
"culled_faces": 59636,
"visible_faces": 5991
},
"native_selection": {
"matched_placements": 16,
"selected_parts": 20,
"client_jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "a2ff1c890d6f3a5292c3a9402f02ca5404a993dc117853b25cbe64ac92b76d30",
"scope": "Actual native registry states, blockstate dispatch, tagged root baking and legacy collection using state.getSeed(position). All 16 featured placements match model names/transforms. An independently constructed native scene also matches total occupied blocks and visible/culled model faces using native parent resolution, rotated culling directions and Block.shouldRenderFace. No shader/pixel parity claim."
},
"resource_files": {
"files": 5586,
"sha256": "df3e6624ad08800f224dbe4c90fd3753ba84e7643f93475701957108a73acb25"
},
"executable_sha256": "fcfd655b756ed003cd5b97fe9ca5afba8b965813b2d7cb30e7639168f8d17e22",
"resource_manifest_sha256": "91491cf250a0032f6a7fc8e4a10807f7384310d927babe178ffc75ded8ef25b0",
"sources": {
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "6884c7209f007ab9ee742b9c3c73828cfa1c6753d35b5fe25a87cab5955b33f8",
"tools/test_native_client.py": "9310a571c3a8908c6c4804a8b14935882382da0f4755ffc4d1087d379824bb32",
"crates/horizon-client/Cargo.toml": "d56524457d761c2613c0699b20e21ad6977d93e009d59ef150bbd9fc20d7a025",
"crates/horizon-assets/Cargo.toml": "2f2cffacec0b4e22dd7cb032d594289bc51c94ae6cc4e985fee3e310f441d751",
"crates/horizon-client/src/assets.rs": "e595afa610e0425d0b3ad694218794bf9e680e46ae80f3925c278ef1a823c914",
"crates/horizon-client/src/camera.rs": "d386a56ca8fb3b37ba2b2ed9d09342f61b409a575bb21590e934120b4ccebfa6",
"crates/horizon-client/src/clock.rs": "4851ada3e8e65d935eda8c0b57d3b51233b34f74aab4f040fd53db0e0d40b8df",
"crates/horizon-client/src/collisions.rs": "112286b07c4cd11b36da8b6799e0e069e69dfddf9a8a3f9ce36dcb282c791d67",
"crates/horizon-client/src/input.rs": "55b259ca6425c502270e7abc4d3ae1b3838633e2bd77d3817c6e00d9143a2beb",
"crates/horizon-client/src/landing.rs": "4192ce43717696b2c893b69f7f156b3084cd5a92dd275f0c5be1ee7c6228918b",
"crates/horizon-client/src/lib.rs": "6eb8caa81741cabc56651603f9be8d15a8d219be5a5ae4dc2045c557fc24bb79",
"crates/horizon-client/src/main.rs": "aa602d14ab9512de90165c9aeee40dd04d5cd602d8fc2a9d2d7139f12a7db1ec",
"crates/horizon-client/src/mesh.rs": "4ac8d85b30f599b37a98b92adcc016b16434816b93c401bd39b8215f591f9330",
"crates/horizon-client/src/models/catalog.rs": "620103719167fc9ab76e730d68eeacb50014e95b7ad209ae7adf2cbbe69f70f7",
"crates/horizon-client/src/models/cube.rs": "1067229f9dd9b276950bf7ec0c5f67061ce3d40a21932dca8034b9748e7439a4",
"crates/horizon-client/src/models.rs": "98dd3b969947c2b297862a934e6235067ddc1fc8cda5adcc6276d19014d4b048",
"crates/horizon-client/src/motion.rs": "0b2ecde5118b60a158e18aa5cf7746ef88566a0ad0fc3c97594b8d5ee00b1cdb",
"crates/horizon-client/src/render.rs": "75cb40c257cf61e51009d292a06cd96532f59320b12ed7c3a509bbdbe1accdd4",
"crates/horizon-client/src/sprites.rs": "292f844a31f6e8884008df9630e2b8862db1acfbc4640cc07d526e25f21f0bc5",
"crates/horizon-client/src/world.rs": "66c921c4a0c4e5bf97f2594ed243f6769d0dcebe9fe227177df928df22d6d03e",
"crates/horizon-client/src/world.wgsl": "972a58ccb34e9965515adbb30c47a93fceca5b742390db6d9f69cba1ec31f559",
"crates/horizon-assets/src/animation.rs": "ebbf7952146a0e66b41396174492f5702627170b03a57e6cd5a45c97a08c975e",
"crates/horizon-assets/src/bake/transform.rs": "a95e658fef85b21bcb2f9f7512f98f98d57022d62c1199885b7133beae35a09d",
"crates/horizon-assets/src/bake.rs": "f55dda6b6cee5ac6e65a8ee4837fdd2c6674437d59e59b4c45718f6324d4a4d5",
"crates/horizon-assets/src/blockstate/bind.rs": "6278962e55c9786bba8184bdf2939af9c6e3b9002b08c3022129964b49a60009",
"crates/horizon-assets/src/blockstate/choice.rs": "5a66c8b9833e2f19dd8b0773f3593d97ff5941d3c5b773896b98049efa1395ba",
"crates/horizon-assets/src/blockstate.rs": "a4299dfd7adaeb4173982ffaa8e9c9eda2925739ae579a714193c99da2e7ce56",
"crates/horizon-assets/src/json.rs": "99fe8af4fbf5d4eed408a92e829ac1a39597a0d92471a6bff73771fad9c830a8",
"crates/horizon-assets/src/lib.rs": "e39f21c59a2c3e1c53d977b29bd5e0638e5fc41d86ff0fcc1882a6d90fd961e4",
"crates/horizon-assets/src/model.rs": "57ddb3d65e88e7a8aa22c62bc298a2dae7f4e994326a873a31f06c0f36ed051b",
"crates/horizon-assets/src/resolve.rs": "3927ac926cdcbd7d334901cc32d0ecc1e498b1bec98f76a46bca6d4964c13541",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaGallerySelectionOracle.java": "dc5433f1ce1de629b30cb70f031a43a691fc1df1fb218ce23de89769c164d562",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCuboidModelOracle.java": "7526f20513c549483122ab0d5ad24b9e87f38dc2f6aae55addd701a91ac85e43",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaHeightmapOracle.java": "145c943637ed177cc4ef8a85f2484da8afd164868e84a8463882feec1653a860",
"tools/test_model_baking_parity.py": "392ffec44918fb91740ca4a1316d684480d39f14bd34d46175f7f44946d15bd7",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"tools/prepare_native_client.py": "3a02b5f384235eb2d7002396cbddffb3bf3840534c205c85aefac090562b76c4",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"crates/horizon-core/src/bin/density_parity.rs": "e5b1dd33b7d01306c73cf072629b4fb186e9ab87b672a00108999d1a72263fd0",
"crates/horizon-core/src/bin/float_log_parity.rs": "4a655fcf8822ee7668c4bd126bc84d0b118864a6fc7f5a6aeee667d8bf2590b1",
"crates/horizon-core/src/bin/geometry_parity.rs": "27f6c09fe5018ac3de8e70e0f0bbf78f9abb14f5e4783bcaf46e8ca87b9c6f8a",
"crates/horizon-core/src/bin/noise_parity.rs": "c135bfc708d853e7061e81487d2cfe10de64b2f65677d3b4837cbfe0b8341010",
"crates/horizon-core/src/bin/parity.rs": "f35d928c66f958de39fac5e7e836a657eed95f83599e84899f7ea7a5802ba481",
"crates/horizon-core/src/bin/tick_parity.rs": "a54c164fe4814034d369947a887f5273966f5a878ba849204b80d1c729526a8f",
"crates/horizon-core/src/biome/seed_hash.rs": "5afbb4921c750826b395a08bf06f382fc7f01b5759a93de02a2749c523e2a317",
"crates/horizon-core/src/biome.rs": "908efa8cd4aa0a7adf1cb5e1a222e3dfb640eed5e9172e0fe7f0d1287afae7e8",
"crates/horizon-core/src/carving/ellipsoid.rs": "09232a7588610e8a9176fd9c62d40afb1fb89f2ecab6d555536a1d847b142d86",
"crates/horizon-core/src/carving.rs": "0aa3093caa0437868a8c0ed52a6c6e1993bd51c03583c670a2837e749eae5426",
"crates/horizon-core/src/density/arithmetic.rs": "372faec96c923e2cf4aa6c66c1ac398e676853274557823850dbc8933dd15ab1",
"crates/horizon-core/src/density/beardifier.rs": "bb1052e27dae4a01954ca78d7d5babafef85f3b2c704ccaf1920cb85a098cb50",
"crates/horizon-core/src/density/cache.rs": "38d0b6c9dd04ffef979fdad3f29cfebf98d331c8c9d430be5f39aa34f6c30975",
"crates/horizon-core/src/density/end_islands.rs": "168b9384237bd2e41d0ae5a74e944da4dc74e493bdec31fb73184c9a49e3de55",
"crates/horizon-core/src/density/graph/compiler.rs": "ac67deeb16f16d0859aa20e5a165811a29aca0b910037ee6bf5098211f3a6ede",
"crates/horizon-core/src/density/graph/mod.rs": "b776e7da934cb03051a3053d56d461c71e9978e084922fe4194147aa580c07bf",
"crates/horizon-core/src/density/graph/seeded.rs": "6bcdcaa3dffcfa9df673bbbea35120057a16ba3d2b506c52709c36cf8976b74a",
"crates/horizon-core/src/density/graph/tests.rs": "6bfb8cbff462587dd147b0775ea01d370abbd97544b9bd596c792df1b5f7e634",
"crates/horizon-core/src/density/interpolation.rs": "8c890f52b6467f38a94c654986a6a484b8e0b296ab98c398e60a6ce465b5b010",
"crates/horizon-core/src/density/interval.rs": "b42629163baa6b599a233afe8596d1c370cd81d015cc6fc36a9663aa47b98424",
"crates/horizon-core/src/density/mod.rs": "ca0d77d3282e3746ddcbc92bee97dbf640b9a56214e6ac1537f51f9a5b63d6e7",
"crates/horizon-core/src/density/power.rs": "d5b7270a128d4264268cd772109ad16d71a8ec3ff2d3b63b84cb985296d54a91",
"crates/horizon-core/src/density/rounding.rs": "71840c5206ff8d218ac29bf6f66915d5212764ba270c675711a866ba5b55a7a6",
"crates/horizon-core/src/density/selection.rs": "0dd26af2e85004ec5e053039ad11c384c17c56ace9ab45eb3f5cb3503c0b0330",
"crates/horizon-core/src/density/slice.rs": "5d77605573c0deda47778f1f78f7fa3fbf1944d8f5efbcc65cf589181cadf80b",
"crates/horizon-core/src/density/spline.rs": "6bb2e40f940fc6544d6fb09cb0b8cac722be03bc663dbdfb0f61faae207400bc",
"crates/horizon-core/src/density/surface.rs": "159e0e69cda74f870e80ea64fe523c4397e64af4ccb861bb9fd07b2c3cb91b00",
"crates/horizon-core/src/density/terrain_noise.rs": "8d0059d25eb5d248cb97a4c5a2e670d61528928ea151495c004f25adb723fe3e",
"crates/horizon-core/src/density/tests.rs": "7817796ee40d0ae241bfbebec6bca190e0a8e7d5a1caa8ddf858c3eaa58b8858",
"crates/horizon-core/src/density/world_fields.rs": "c1ce305cb8046b384d90c564cafb24af7365d580389637910f3d8b0cc18eb583",
"crates/horizon-core/src/geometry/border.rs": "1386f8080521231d05ba3e84d94a3e1d5218d35ccb3d5e9fe2bbb05a8739e573",
"crates/horizon-core/src/geometry/mod.rs": "c650386f9860e44a96c55f18c8f1428ca715fcb0bc5c2434db5b1caa43df27fe",
"crates/horizon-core/src/geometry/movement.rs": "bcfb452752940ce53ae6dc267a3c4eb29459046a063c1f884684ab4f4bd0068f",
"crates/horizon-core/src/geometry/shape/create.rs": "189812b91d5e0e3ad963afcd1a6e2831b31b8188df91a904ef27061e644806ad",
"crates/horizon-core/src/geometry/shape/face.rs": "f243bce81384040a95ce7984b02b5699206c596c537b2713097e86005b4d3a5c",
"crates/horizon-core/src/geometry/shape/join.rs": "f1b51887b7bf9482557e3ffa99e136f2e5db07ceeb05fdb116adf45e87129075",
"crates/horizon-core/src/geometry/shape.rs": "e8d88a763de1525f77a30b99591641e8a8b80946263acbde035a9bcc356df960",
"crates/horizon-core/src/geometry/sweep.rs": "abd6009c61555161ef2f18b431b2aa384b126c0871cae8b96a62358498a56a1d",
"crates/horizon-core/src/geometry/traversal.rs": "77a3da570a0b85582b669cf4d841cba4b06327006dda26d4a26df4e8ce05bae4",
"crates/horizon-core/src/geometry/trig.rs": "05cef9341a298a474221a0556a11ddf47650393ea7a97b4b2022a4da6628fe37",
"crates/horizon-core/src/lib.rs": "4255e16837fde42a52ba118f60581d197c571bb530b60d635e506184ebf4db0b",
"crates/horizon-core/src/noise/mod.rs": "1dab5a713abf702402e69ace1bf9e476bba544b0ede5a61c3c3afc60af0a03f3",
"crates/horizon-core/src/noise/normal.rs": "e9e7a46472a54a02c98c46da819842090567153b32fe0c84249009ef19af7aad",
"crates/horizon-core/src/noise/perlin.rs": "e73815447432eab7542f67366cb3f1b368d164e33f6c9cdbd045ac8e4db0932a",
"crates/horizon-core/src/noise/simplex.rs": "6c0dbc15b2b7510195dd28fceca01dcaac1847ccc4a84d299c351589c642fe7a",
"crates/horizon-core/src/noise/stack.rs": "7f6ef0e7d920139ef1a6ad3ec5640f92765715f86dcc5ec29f1a149984f45fa3",
"crates/horizon-core/src/noise/volume.rs": "3f05d2b1780acfdfee60037677d309937a5033b45ef428fc2d540942d4b56b43",
"crates/horizon-core/src/position/iter.rs": "32d2d8e74821cc4e49e3354202d35d3120e4415bfdda9375a73f2137ef651129",
"crates/horizon-core/src/position.rs": "e10101088e6902386b9b6d27773d44312f1ff72bebb19e57967a54945dde9dcd",
"crates/horizon-core/src/random/hash.rs": "0f88a127a1ba2705d3d6c0ebd009324d6ba86ffa2d27edf2d2a84765e690e4a3",
"crates/horizon-core/src/random/positional.rs": "35494745e5d4cf89e282c3ae0ee245e9f2640ddbbc03bc0055df742006a9c862",
"crates/horizon-core/src/random/worldgen.rs": "9f07ff33bcc038d34e27aa5465753bb21df18f2975e43cae201f709bc186945a",
"crates/horizon-core/src/random.rs": "ddb95d3a83e28ad605ff1f49f5df270cc543ca5ef1130e37d989dc74c8d861e6",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/src/text.rs": "e6553ddb5db5039e8dc4614b6a6dc9f35a26dc3d1673b68a04e72e7983b67abb",
"crates/horizon-core/src/ticks/generation.rs": "be1237e790693f633a61714ddae68c6506a777588a8a3ab5efbe53a35774dbd2",
"crates/horizon-core/src/ticks/heap.rs": "bf28afab8af77c3d243aa96cd8a1fb8d934140a4dbd07dbfdbf4e7908bb4b845",
"crates/horizon-core/src/ticks/index.rs": "1f1a6a568c2a30eafecb020ca4d5f5fc414860de85b8b381fc419a2e3e65c24a",
"crates/horizon-core/src/ticks/mod.rs": "01634630668172516b8b79d0907bad47f6e2c543a6d499c2fa4b201823b375cb",
"crates/horizon-world/Cargo.toml": "18bbad377a8047e4d4ecd0fc87d83d46d1c0f1ce2b8c47bbe64633e7b4420b57",
"crates/horizon-world/src/active_effect_tick.rs": "88f19cfc3532c47a58c646bb3e9d99ff239a900752302b6a444dda3013e95cbf",
"crates/horizon-world/src/active_effects.rs": "daaf352a69511a7d69fb329997f783b86585e486e0379c84ab0a55641771646c",
"crates/horizon-world/src/attribute_health.rs": "1420a80787d10dd2e2954a3ee6193ff313289d00c7c78ca26ece8bafa21f4380",
"crates/horizon-world/src/attribute_map.rs": "3d871cd530f5c035e0753f3ba065c2b9c5b49cdee75d4119f7dd584b22af67e6",
"crates/horizon-world/src/attribute_updates.rs": "4cb322d75a50d222298994607097ba7f7e6674021128fa02a98a74c057ad05f1",
"crates/horizon-world/src/attributes/entity.rs": "64ac99682a3aa06b1fb94b776b47794234c76b1cf70f1f54933d51e545e69279",
"crates/horizon-world/src/attributes/live.rs": "8198c45134f69135d48ef203e71b6e702529568fd1ed9174d0aa843570bbf9e7",
"crates/horizon-world/src/attributes/mod.rs": "5c2fcbbde58c19261874d227ea98332f00336c9fa53446da2e9adb6aa64a5e5a",
"crates/horizon-world/src/attributes/operation_map.rs": "fc5bc8921d78ea6721a2eaa915e67483e2a33683927467bdba24f0492356ad97",
"crates/horizon-world/src/bin/worldgen_parity.rs": "3143ceb9b56eecfd7667e5feb5f9f0cd13cfb8754b38d4ea338dbba97f2819da",
"crates/horizon-world/src/block_collision.rs": "39207247f2f6dd3ddc77640229044246f91b32054563f88a435f1bd92ad2092c",
"crates/horizon-world/src/block_collision_scan.rs": "20802862364c110ff85eeaf48606596a8468b83768dda46b412d337958790b41",
"crates/horizon-world/src/block_entities.rs": "a9deae92e6e5a1fcf4f0476c33ea4d170ddad6fd4b3303e1bb66d933973d5e06",
"crates/horizon-world/src/block_entity_push.rs": "12ee91bf604946234b24a0da4333f07d1830ab9743a422d41c8d0afac7d49cfd",
"crates/horizon-world/src/block_landing.rs": "33083fe39266fbefec1b3ea1a19f2afc609791d189da247c895e116ad6eb266a",
"crates/horizon-world/src/block_placement.rs": "524f4892d50bab77b7d89d19f7b048ffe746996f2ed7f376db2c6ab00ed75c24",
"crates/horizon-world/src/block_properties.rs": "b0bd8a983336c48e488a20caa77dd5c39b1a74bbd14ebc03b3b64556a1c864fc",
"crates/horizon-world/src/block_render.rs": "8df52ee11aef406a1571198a64048062a0ef6864e0058d9293a57f64b73c916a",
"crates/horizon-world/src/block_support.rs": "ade4fbd47284b450dabdd682dc86138b2ac05a0fd379525d7110648908245476",
"crates/horizon-world/src/block_survival.rs": "28ce64375e09819a4f13da9cfbe37c08b5ad0daf01b289c1c360b4567e50e811",
"crates/horizon-world/src/blocking_item_damage.rs": "afea3cb5761e8b82ee4d9bb4ef3c6fd10182a324dbaec99e6c9ebfac255dda09",
"crates/horizon-world/src/blocking_rules.rs": "83c5e2105cec56a90182ce582e1c67ade2b189be6de1a34d08035000cc07c492",
"crates/horizon-world/src/bundle_weight.rs": "a0e7b0587ab5d46cd55588f25d55a088b7a4725099c13ba6df146957be36014c",
"crates/horizon-world/src/chunk.rs": "795895284d6e615bcb2082fceacdfe7025c152fb2934bb43f598f17a00ab46f1",
"crates/horizon-world/src/chunk_status.rs": "dbb8583cfa775203c544d24d69e03720385428f15a267a561356c21f5025e9c7",
"crates/horizon-world/src/climbing.rs": "6cd2f919872ff0b726effddaa57eccb805b8eae43f9d01144716010853891879",
"crates/horizon-world/src/collision.rs": "a749794d5c27ccd6c0d964ad02f9dc31d49d9f4fe4b7366cd4bd8155e681b00b",
"crates/horizon-world/src/collision_context.rs": "2176c7034e07f547510a8327cdad9d3b63f26e4754032b76b7d5fe13166c333c",
"crates/horizon-world/src/combat_rules.rs": "01131f70d1acdd96a910e7f96deaa12e51a1e3bb9208085f04e3ec7b657d3cd4",
"crates/horizon-world/src/component_durability.rs": "37a46e184f95bc5027e2b9af72ff52f729ad03601d08e1827f181fca383a35af",
"crates/horizon-world/src/component_patch.rs": "f6f8992f241dfb25e012a06a7ba3fecab8d958686dddd096595a4806e56f0ab3",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/consumable.rs": "ba3575cb85866cb940f33a1ac86455d71cf0cc6395b848588a8ee1fe33f5c326",
"crates/horizon-world/src/consume_effect.rs": "03f2aac6879ce133347d42f6f6667d62c06d956ff9faac5dc14182a788b6a236",
"crates/horizon-world/src/damage_immunity.rs": "fd39c41124d694e755cf7faadcf93c636df4042c78ec345092a856b5f952dbcf",
"crates/horizon-world/src/damage_reduction.rs": "f5a599ab11e077f526237018aeda803ea3c420c5b35c78ae9d85e32267e23bf3",
"crates/horizon-world/src/damage_source.rs": "24945e397a926d34695652980923609e4723e02fe6b6e56d4aaf673e45d759f7",
"crates/horizon-world/src/dynamic_support.rs": "5996bc1c436fb6215d8fc3d0bb4de5dd9b966d842d432580d624195771697fb8",
"crates/horizon-world/src/edge_backoff.rs": "5259d7aa44e64f88351d1556c44dd0edcad3b400a099c659755792efba7b5773",
"crates/horizon-world/src/effect_attribute_modifiers.rs": "0bc7ab63d0f3f34a7133fe20364cae0ec1fdbd3773cba90faa1f08e0d63a5646",
"crates/horizon-world/src/effect_notifications.rs": "ea66bfa010d6d44aee97b9672902f41cd99d0d80239f41c6d4eae5c9a9472d3d",
"crates/horizon-world/src/effect_particles.rs": "a42dc4ec55929dce1db0f22f8816ecf7621fdce1cd2ac0c90f6a57fea4e0afd2",
"crates/horizon-world/src/effect_sync.rs": "1388d4a69b42a14ff4cd474f5e36f0fad5a2874031e64fa2b19b2ea179deed2b",
"crates/horizon-world/src/entity_collision.rs": "09f2fd7f6cd56fc282f468ecfa765a94506929e9684bd3a5c90123e5b51cd627",
"crates/horizon-world/src/entity_fluid.rs": "02991040ae879a8914f09913128a3506e9e7a1ca33ffc0a22b5729a168346600",
"crates/horizon-world/src/entity_fluid_tick.rs": "4f9e070b88a73c98a4e2e659360ddd6edee636bca29377f1ea9011fd5a556f64",
"crates/horizon-world/src/entity_move.rs": "a40a50d3e841625a75d4cfbb7c2630ab5a62a574456567e7234f401ae8441b32",
"crates/horizon-world/src/entity_obstruction.rs": "a4b28a19bf83b23611c59d94535c488db37e4aee24b22c973c545910894a809f",
"crates/horizon-world/src/extra_items.rs": "6eba0a0c795d5fd841d31471708e78324b4852adebb2e6ed700dcc0caab668cd",
"crates/horizon-world/src/fall_damage.rs": "8c28e2933493569fe05dea22332024287d28b0746b514dd465681040b003296b",
"crates/horizon-world/src/fluid.rs": "a0a1f34ba94d8b59dc975becee8952960764d67ae08cf2d6a8bcd40a614b15c4",
"crates/horizon-world/src/fluid_box.rs": "b586af72b1c04a9354fe66205c28dc8b619e205ab9ea19a68232722e4b6e96c1",
"crates/horizon-world/src/fluid_flow.rs": "7c7e486b5c565df3602799648b37b879bcca51414337f607962d6c7951b86d05",
"crates/horizon-world/src/fluid_occupancy.rs": "26037579caeef6c8a5a2bde2c3d142d278558b76d77ebff401cee6e35f2ea961",
"crates/horizon-world/src/fluid_shape.rs": "28bb65a72f5bd074a354ba38a1b1707fcb0947537977a11540bba0adb85995c2",
"crates/horizon-world/src/food.rs": "3cf416fa632a5555a8116bb528a6e80bcb5b6b754b0748b4959ed310102418d3",
"crates/horizon-world/src/food_properties.rs": "0926fa3f3bc3d0608c45d02f564355825ca3c3526a82bf9c1375c7a191fa5e12",
"crates/horizon-world/src/food_storage.rs": "58c433801a285efcc973638c11d694a41f85dc96703a3a7ce8d3673f3eb31d52",
"crates/horizon-world/src/free_space.rs": "913536bf4c85ddeeb378d76d1b5110b4175f5688e1a749f32fe6a6d86fbb478e",
"crates/horizon-world/src/ground_support.rs": "3e371d74ecede4d30beef0a7e8a2ee33463584a5b1ed3d852b394efcce1ffbe0",
"crates/horizon-world/src/heightmap.rs": "a5edef082b5af40d814421ea17e129b3b06d70abee6434ed263e4bba58571698",
"crates/horizon-world/src/identifier.rs": "37c921889c4f5d91f7c09ab2ee68d1a5e5a3c4fb1c49b4b189c987b4615fd2d6",
"crates/horizon-world/src/interaction_shapes.rs": "f321284ddab440a394372b6dedc8b5cc29a653c0745251a9e96c650f21c33dea",
"crates/horizon-world/src/inventory_pickup.rs": "ea830c7916e7f2d95c6db7ef48be1e876e6ebafcb438e47fc72f9a5bd7c37d07",
"crates/horizon-world/src/inventory_tick.rs": "293a3d57a1689337cfd58e5a73dcdbed4cb360f94d98ff5458f0df92de387365",
"crates/horizon-world/src/inventory_use.rs": "6a6c2ecc73c83dda4cd798c0304df12ace6096eb110d899f4f0c7ffd852bf001",
"crates/horizon-world/src/item_after_use.rs": "2b6598ce5b7b304dea2c8057b4a1eb6530264ac4d0546c3da0c76deed9609da5",
"crates/horizon-world/src/item_blocking.rs": "f6eee0d6d177cc3148960122327ba1b459a2f0e85241c1d9a3e40f0b8c169296",
"crates/horizon-world/src/item_cooldowns.rs": "7b625868509ab3c51e72db0ac714bb0e7ec5e2610d37271005a1a737f4d14431",
"crates/horizon-world/src/item_durability.rs": "9fdf835e5c7bd0e1dd63ef2ba0076b770cdd4d6d14cdcd11de27690f0702f94e",
"crates/horizon-world/src/item_particles.rs": "861b14f65adb9b14f8158fe9f0b7128beac3df8107b1337c31b8b9b49434ba3f",
"crates/horizon-world/src/item_stack_refs.rs": "18d3ca85cac0daf59200857513761359e5690f719cb3f7f64ae552f0c4169ea3",
"crates/horizon-world/src/item_stack_storage.rs": "b4dcb83dcaa346848c5484161feb3e2cf08e83f7793d7ed83be25b14b9d12884",
"crates/horizon-world/src/item_template.rs": "dc80025215d1867e656924ea2a9d273aacbcaea21293d986ba42d0004ee93b69",
"crates/horizon-world/src/item_use.rs": "b1c79428986efbf9dd5ede703a39eb387fb6dcc7d9950f0e49243a353a5b8070",
"crates/horizon-world/src/item_use_catalog.rs": "a9b53d2e816583239a75c3c61e78dacc5e3b27dee595be34b1c7fa169f17a571",
"crates/horizon-world/src/item_use_lifecycle.rs": "4639b70440cf811e79de09c48a3e035143fcb6be8a64c2f61b10ae55a2f133b7",
"crates/horizon-world/src/item_use_start.rs": "a84092dfb8b8f0a89d0928bb2f8ac252bd9bfd3f8d74fce1a7f7a5b3c3f4f50b",
"crates/horizon-world/src/java_hash_map.rs": "955502e696d7b0b33bae3ec485c8eb1453a8956116aad68226cf1fc67d60babc",
"crates/horizon-world/src/lib.rs": "577c16c021352b706d123f0f1c734375fc4a5a67b508caccbc38c1e1f693f6f4",
"crates/horizon-world/src/liquid_collision.rs": "0f0a83b04e5a5bc9d98ed05fde4d6584ba69642e93522e726e4cfc325d6fcb1d",
"crates/horizon-world/src/live_attribute_updates.rs": "778171faaaf7077deb0b62c4cc1db16351eba41adb8bb07656ba65e827056199",
"crates/horizon-world/src/living_air.rs": "b2de36bb50bed15e2808fe4a874fcef07f9fea0d2c96385b7b5e8ee9560d4442",
"crates/horizon-world/src/living_damage.rs": "2b448209629b9bf2e678d667ad0d6c7fa22146892dd106b169d96b31b0df12bb",
"crates/horizon-world/src/living_fall.rs": "da0f176f4731e1c86e08bfeee8167742fd1b86380ff0e9304c13c1ce3f1c67ab",
"crates/horizon-world/src/living_fluid.rs": "d7cd914cfb2a1f4876ce0ae95e999bf0ff1af732cce3ab4a3aa2d1ab881c7339",
"crates/horizon-world/src/living_health.rs": "221659f85552424e937d503bba6d8003006b106ced042b32d3a6f6cc23e12ed0",
"crates/horizon-world/src/living_hurt.rs": "844239ad7d15c39629bb3cfc06ebae6d1cff20b7627468f26e0ee8dff3abdcb8",
"crates/horizon-world/src/living_landing.rs": "8bca4eb7977abc2b14fb7174be4ea355352106ea1e76ff5f3ad8696969d9eefd",
"crates/horizon-world/src/living_motion.rs": "56f8c84cfbe205a7a69912d5f76b52ef1efca149c1b6801d4684e25fb179aeb9",
"crates/horizon-world/src/living_use_flags.rs": "826f4fdeba7e208368cbbf910fa408db0afbc6442d842d178a70fae53e0d0ea6",
"crates/horizon-world/src/main.rs": "fce57418b8c22a6a0a9044baa89ed3d9c243bc2e8413fea3ff0f32985daba021",
"crates/horizon-world/src/movement_emission.rs": "76e7d6f5b19c94676190f54389f9c4ce12cf89945ccfcb9c750de473223e7753",
"crates/horizon-world/src/movement_properties.rs": "6f01ab920b376a13f5ae12c3718f4dd067e1dff2b829585af00a8b2100f3775d",
"crates/horizon-world/src/movement_restitution.rs": "04b4fe0947e7e52576145bd8ed15920278e8a538afcc74d125eaca513dffa0ef",
"crates/horizon-world/src/movement_support.rs": "02d85cf572847f2e60b5a7f9d60b856888a67b3c1f4df03e81998c66fdf874be",
"crates/horizon-world/src/nbt.rs": "60262c3de8c8f68bc2da0370ccb17393d32b85f5f5022c6358599a7d32119ea6",
"crates/horizon-world/src/object_open_map.rs": "b4934a9cc38df93ed206ab0bc3bbc4499acd8e40b41b7def7d47067b7170065b",
"crates/horizon-world/src/object_open_set.rs": "d3e0373bf1b652dd054345d5a8e25ec828e06dd7cad65aada35163c95df4e637",
"crates/horizon-world/src/piston_movement.rs": "7a3fd2549a582b5f3a5c21aa05d67d944d62ca1105856679e100ac5b44e9a52f",
"crates/horizon-world/src/piston_shape.rs": "399c2337103b8e7e0eb5667227c5aa14f9549d6a467b7be7da3d0717f0263500",
"crates/horizon-world/src/player_equipment.rs": "1fa8c53e67624c4641246249d79a800a28a4858c62482bd880b4e3b866b936ef",
"crates/horizon-world/src/player_food.rs": "f188dc110745bcc7acc15e6c521db943b06b404f69cd251bf74a345516070304",
"crates/horizon-world/src/player_health.rs": "79ecb6b4d7a044dc98e5552c53a5ac2724545b1c1cec4d797eb52576728e3480",
"crates/horizon-world/src/player_hurt.rs": "99c9bbd8587ec2dc287806049897b8034d2f5349ad47fc497b70d54148844a36",
"crates/horizon-world/src/player_inventory.rs": "f4f67d8312793f25930626c4ac06db688fcf2e2292d6675071d105fb1708d952",
"crates/horizon-world/src/player_travel.rs": "6841a677a900495eb6223031ef3ebe8d859bb98908dda0e2209e5f28839dc593",
"crates/horizon-world/src/powder_snow_collision.rs": "7289946a21478d11abfd2bdcdddff3d7f98e25bf6a68564fed45c3cc01ac2a36",
"crates/horizon-world/src/region.rs": "72b642e87fed37ed17f54d4c30f96c3b64d26c14bc0589c31ef40ff1616188fc",
"crates/horizon-world/src/registry/json.rs": "7a683afcd1742c5307756927d7f0aa779c7d7992af87d8d371dd98108728e235",
"crates/horizon-world/src/registry.rs": "f2e58b2b4d944ac8fc6226bd3352cefc3d2052d8473e02ccf7dc402b176df435",
"crates/horizon-world/src/registry_collision_scan.rs": "97cc950a9a4ba387b78e368f36d595f8664ab7730d132900d220ce23b92826ea",
"crates/horizon-world/src/registry_fall_ray.rs": "52935436132df505691144840dcbd858b15d00d8305997284e3a542ecf6bc0dc",
"crates/horizon-world/src/registry_fluid.rs": "b8959c05850cfeaaad1e4de8ca7c7d0d6ac56da9b2c1de3ebefa5871a11ed35e",
"crates/horizon-world/src/retrogen.rs": "6efd36a6293756688c1990a7965bd65609d7c5e2bf2a5f4f01d54932d2b9386b",
"crates/horizon-world/src/server_player_combat.rs": "a9743971581af86d926eeba42004d932caf83382c470dd98bf613cb9c417db58",
"crates/horizon-world/src/server_player_damage.rs": "828a4649fec3e9bda2dfe20aced8c95922c697321de2be4127bd4e5712ecbb7c",
"crates/horizon-world/src/simple_container.rs": "0fedbc7e974b1db79b88bd6aff977654189a5d553cf42852fe8bf0885cf90b30",
"crates/horizon-world/src/status_effect.rs": "588bfcf4d93f50be86cb89545bd5c431edbc71771f704ff55cb52906b1964c37",
"crates/horizon-world/src/stored_consume.rs": "621a52c9fba447c393e561f881a16cf1f97d336e3a0ce493725ef51e2db12ffd",
"crates/horizon-world/src/stored_effect_attributes.rs": "c79f6a52d3cfee1a5288225bf8fa91a7bf3ea8cd21faea9f6dc748ecefc6309a",
"crates/horizon-world/src/suffocation.rs": "bed219dd5bbab6263b98fbe3d0eb512cb96c52ae847210efe49514d05f22f11e",
"crates/horizon-world/src/swimming.rs": "49d2dae13c109b37ff832cde98a857944ff45247b864a527b9c4f03ecca7a7b7",
"crates/horizon-world/src/synced_floats.rs": "0152f2752bafaf68769d56dbc88494a976496a680c6b113d6b48a446158ba072",
"crates/horizon-world/src/synced_values.rs": "a1d4b53ae77d1899ba2b4ead67c9ec1e3c96615558e446f9d0760c1b4a520169",
"crates/horizon-world/src/teleport_consume.rs": "d6a53bbb6ac4dbbd4c0591d0646017898a95beb8ef093dc5d81b9833963be6c3",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/use_remainder.rs": "f555335afeca7970888131a6da2f5a614a73253b631185d1ba804593a349535e",
"crates/horizon-world/src/view_direction.rs": "e18120ae26dc5cf702b29fc4c8487088bab133c8ce5abce01226833fafb0d5a4",
"crates/horizon-world/src/water_splash.rs": "e0461ae1b2e8c851cca6e3251a188334293292201d7f80dc9e7d60fd1815f4d1",
"crates/horizon-world/src/world_movement.rs": "f8fe9e34f2395d2a04c839d1c8ba78e09ce493c26de6f6e4e237b9c19c061da5",
"crates/horizon-world/src/world_ray.rs": "879bdbbe12f56deb705cc183933431489e840b71eade40c33391eed5949c2e61",
"crates/horizon-world/src/worldgen/anchor.rs": "d156b8a0b147a274cdd143409b441f4f43edecde6e8ee14ef9cf0309f743143a",
"crates/horizon-world/src/worldgen/aquifer/config.rs": "fcd2cc3a520c1527c88f095a3b5d38487e7ebb1ccecc5f757f93d04a069add4f",
"crates/horizon-world/src/worldgen/aquifer/noise_based.rs": "74daaa389b5c3dfdc99214dfff256a9e172f83548d2326cbc941d9637cc53fb7",
"crates/horizon-world/src/worldgen/aquifer.rs": "cb4b66d87de3f9f79ae6ffe4badd6f0f44886cd42ad9de2771b8b56c4f1e28c7",
"crates/horizon-world/src/worldgen/bamboo.rs": "d9b47113c99be34256e58308bc6f40072ff25c579d6bf995182aa862c0006102",
"crates/horizon-world/src/worldgen/biome.rs": "3fe316b875aa32683759c337dc71f624910faf0812a2d6d83b8098d6d0bac7a0",
"crates/horizon-world/src/worldgen/biome_chunk.rs": "8fdfe6ebe3ffeca97611fd5991a5bc6b2783ea1c62f4d8ef3b2dd53c04a5dc1d",
"crates/horizon-world/src/worldgen/biome_predicate.rs": "bfc581bc40077cc74ffda43e990a55fe997adc04c7130f98e039c3305ca79aac",
"crates/horizon-world/src/worldgen/biome_source/codec.rs": "2b9e4f5d679eb444cb73174f511e3b9f32e9eb138248ab12cffc6cfd76adf3a8",
"crates/horizon-world/src/worldgen/biome_source/runtime.rs": "f0b02c1521178e4d0377c6ca62694604b6a773f1f234f070ff0cde4685911d45",
"crates/horizon-world/src/worldgen/biome_source.rs": "e181e1736f3e0b75f7091a24c88de3fd116e01b98424d02382aea7a503d1eb54",
"crates/horizon-world/src/worldgen/biome_temperature.rs": "cde4bbab5e260c4065b113376c423b8511ade93c5aa5fd976e245ee8a58b5ad1",
"crates/horizon-world/src/worldgen/biome_weather.rs": "96b1f9494559ed31d06257b83d604d00cc069ccc8c7b68094117e034b4a71bd7",
"crates/horizon-world/src/worldgen/block_blob.rs": "c608c57b3d77279646ecb89e50677dd8e452b0422ffd357ba755536c5589eb89",
"crates/horizon-world/src/worldgen/block_column.rs": "f72c21a9066ee0aa68c2fb79fba436d05afb14c6ef5a2cb012f1ed35fc17cd22",
"crates/horizon-world/src/worldgen/block_feature.rs": "36b4e46ee7f7f73bcb94d8bce8d99013e4b16234c9a03542eeb3186e88dd1c21",
"crates/horizon-world/src/worldgen/block_pile.rs": "623e369b77e0526ed2756485a6c0bb09683cd28ad8876dea907360ca6665b39d",
"crates/horizon-world/src/worldgen/block_predicate.rs": "074c692367e3f2191a1bb28d87b23402430a843c246bd30a4ea838ee3500280e",
"crates/horizon-world/src/worldgen/blue_ice.rs": "eedd77bdaff808330b864166d303378096daa5c7d235e925770b171c05109247",
"crates/horizon-world/src/worldgen/bonus_chest.rs": "05d0f63fbc7412f13ba1fa37a7238114b8f70bfff318beb2dece590482d49cc0",
"crates/horizon-world/src/worldgen/bulk_section.rs": "eecf61532d7793f853884c5a18a7f436a59835c7b13d3ec9075804511553c9ba",
"crates/horizon-world/src/worldgen/carver/canyon.rs": "509c4d5a9d689849e98e894ab14a9fbf82d10707d38e9cc688ded3c4778df3e2",
"crates/horizon-world/src/worldgen/carver/generation.rs": "a4498d0d1457536de3922a08e9c40ccce8d2ef9cc263801c15a412327513c098",
"crates/horizon-world/src/worldgen/carver.rs": "46b251e28225fe1250de38f49dec5dacda4e2c4ba1e556e21e6d1e14e2651fc3",
"crates/horizon-world/src/worldgen/carving.rs": "4e77d4e5c4a0ca55ca3563b9bdf6f379342e0bdf9d019d60f7bc57ce4afb5fbd",
"crates/horizon-world/src/worldgen/chorus_plant.rs": "29224c164ede919e280a65a68f155c873e2c8fd0aa7d7e244d8fa9e468760250",
"crates/horizon-world/src/worldgen/climate/codec.rs": "d567adeb5d837816fca69102db51d790f71aec1b51c09298230d24612e400a14",
"crates/horizon-world/src/worldgen/climate/index.rs": "c5ce61679a5f0e0f2f0af2a373424effa124d0cce8250609eff38b7034650756",
"crates/horizon-world/src/worldgen/climate.rs": "1b9ad44407f40aee4c1cd5357a5c9c443c1b105728f01cf5c644072f99f8357e",
"crates/horizon-world/src/worldgen/decoration.rs": "75a79b20b21e133816e729f16e758be6165d0db18a64bfbd5fd3618325a2adf3",
"crates/horizon-world/src/worldgen/delta.rs": "c2bf49ddf3231d28c109e68871429bc13d76a7bebe14eb33e84aa856bdd66145",
"crates/horizon-world/src/worldgen/density.rs": "65a98c156a290a6b374ef670d28cd5dfbe0aa93171824d1bbd96422536273f84",
"crates/horizon-world/src/worldgen/disk.rs": "6f8f9e059755af44c9bfa1b91eba54a7d13fad811dce31717c5502d7f6df33d7",
"crates/horizon-world/src/worldgen/end_gateway.rs": "f53fde77d6a36a525cd15d890003b2c129d0689a4cbfa2cf443a0c2e3acae040",
"crates/horizon-world/src/worldgen/end_podium.rs": "8f6d0d6d60ff0fde63de5781e867239db321f82cf12639f0537d410a3731ee1d",
"crates/horizon-world/src/worldgen/feature.rs": "40500af71ee6628dfb27518262d99f08d0383ae6c7b9397452feef0c213eadd9",
"crates/horizon-world/src/worldgen/feature_catalog.rs": "efc7b17b227e71622ef34108be9abd010f5675b68ea0409fcab82581d9aab88a",
"crates/horizon-world/src/worldgen/feature_graph.rs": "da132fca9fdafb0d89a917d5f4b68c60b70fb33cadf948a107da0e35d83dcd91",
"crates/horizon-world/src/worldgen/feature_region.rs": "df0ff142a461cafa9a3b42b949ad3376887f2be8d4ea5cc794a3ed2e977bb499",
"crates/horizon-world/src/worldgen/feature_sort.rs": "3488a093dfe1321aaa29d8a30cfb115d8e666a81bf195514e87b170de626835c",
"crates/horizon-world/src/worldgen/fluid_predicate.rs": "64197c9e63bebf1ce04bc280bfe980bb6c1b9aa887ca5cded904aeb0d9ae6c46",
"crates/horizon-world/src/worldgen/height_provider.rs": "368d4dc119854742a045c4a717679c921456da681fc5f71aa9b37102d6f33b47",
"crates/horizon-world/src/worldgen/material_condition/codec.rs": "09b909bc384472f76d163c8069ec6b507c7d5c6a028a36d5e0e3df20deff7b3b",
"crates/horizon-world/src/worldgen/material_condition/density.rs": "df9d0761e978e5010663ae8b44f2d6c1ecb4907331e333bdb6a2b487c1e107de",
"crates/horizon-world/src/worldgen/material_condition/library.rs": "a55534c5da97575a819af5a7dc0dbec9069993fa8b2619c6c9d5576946e683fa",
"crates/horizon-world/src/worldgen/material_condition/noise.rs": "ffb59cc6be2275d7a5621bf7d768527e74a8326ed7ad78618746711540921675",
"crates/horizon-world/src/worldgen/material_condition/rule.rs": "fed643352efbcb1f68f29b6241896617db889fc7c577a6247564e01922fec1fe",
"crates/horizon-world/src/worldgen/material_condition.rs": "d638dcb8cbcb5da20b3cb29602b0ae6a86c4fdf9d8c0fb725de8ec5fc108717e",
"crates/horizon-world/src/worldgen/material_extensions.rs": "ab806eb679d5116e1aebb64fca70e1499ae71f83c9507a8cb4c3201c2b1bf037",
"crates/horizon-world/src/worldgen/material_stage.rs": "698cbc786eff13c246e2bc2ea062401918cd4265899fbc3d53abc87e45a8e7a1",
"crates/horizon-world/src/worldgen/material_surface.rs": "5d37b90099df3d6da0845dab164e71469fb287019c2ee74bc6714f3b9d6d6d5b",
"crates/horizon-world/src/worldgen/ore_feature.rs": "83b89fd3be691c5412c0215b6abefdcaa44119a05aa41217e061970eb7e12ebd",
"crates/horizon-world/src/worldgen/placement/chain.rs": "9218399b4d3757f7bbc550d7729a7201f32a1c83a7030865e0c12aab8a80d116",
"crates/horizon-world/src/worldgen/placement/context.rs": "a278304795136677ad4b4933ea50c972b9729a1c671c03fa309c193e224b1fd6",
"crates/horizon-world/src/worldgen/placement/layer.rs": "a0f5ca776f33f9d4f72b8fdcd163426152e5e43cb4a7572fc1d4fc57bf965de1",
"crates/horizon-world/src/worldgen/placement.rs": "b0397e5818fae84358546193a95f84bcb0b5bffafce909e6fcb3386179ee8023",
"crates/horizon-world/src/worldgen/replace_blobs.rs": "bf3377d86d2570cd15288ba69dde64a2cf67c5bcbb9a31d0c23421964af74afa",
"crates/horizon-world/src/worldgen/router.rs": "2cee7cf15a0d2ada12be6b39d83e78177fd3033922e4f4cce87a64073cec2847",
"crates/horizon-world/src/worldgen/rule_test.rs": "d1662ec492489ebaa4b87e20f9a8c809dcf3a223a151211bd65ec241a63692fc",
"crates/horizon-world/src/worldgen/settings.rs": "a8fe87752e1982ef11cb67f8d80d8e3428b2c27db178044cb425ba803e689e59",
"crates/horizon-world/src/worldgen/simple_block.rs": "9ba1a88d5db4925f8c37366557887f776c805f9a6444781615b5dbaff52e92a4",
"crates/horizon-world/src/worldgen/snow_freeze.rs": "9040be3d5c7f8f0fd812d2df45e154bf8a9eeef038530b83fa4159d246eac35f",
"crates/horizon-world/src/worldgen/speleothem.rs": "c71651c1c97818a8a85863e14414d6139ea3bdeb897fa422043bcc1499d99aae",
"crates/horizon-world/src/worldgen/spike.rs": "eacf0d9d3d2bc3d4bcf62bc87555f90031138236a5bfef0eb5270204f7c2a4fc",
"crates/horizon-world/src/worldgen/spring.rs": "830849e9b89fcdf09e9b06fbefdcdebe3c8c3f82804f60b8bd5de04ba303cb62",
"crates/horizon-world/src/worldgen/state_provider/catalog.rs": "c8687e15a4887a9200c8d365857d801efaa8f90e669eee3e600a1db4905119eb",
"crates/horizon-world/src/worldgen/state_provider/noise.rs": "7ee369c2a032e5620cb9bdf9ee7adad1f70870fb0a27efb7b7c514d92f83491f",
"crates/horizon-world/src/worldgen/state_provider/properties.rs": "9909139aaca1dc4f743957257fadaa9d423d21fa401fa9abc050505f79365139",
"crates/horizon-world/src/worldgen/state_provider.rs": "be29ada818826a90afe01ab60916360fdfc4cbde5af15c9359cd56b1f1f7b156",
"crates/horizon-world/src/worldgen/tags.rs": "74e4110fb19c4c4047192fd65c38015b8afc7f9fc50404d75380b5063808148c",
"crates/horizon-world/src/worldgen/terrain.rs": "fd1f2e0afc15daf66f484ea40a1f2b7013650bda0941b23c64c81ee9f79cb673",
"crates/horizon-world/src/worldgen/underwater_magma.rs": "7317e40af5ee5a9780f90ce358fa5d3e7f5b3d513b731df6ff97754d9c2a0154",
"crates/horizon-world/src/worldgen/value_provider.rs": "3358b563db8cb0bc8a9cfbbe2b8b3e70941cd2d37a0b519fbb6545f8d0dcbb69",
"crates/horizon-world/src/worldgen/vines.rs": "ee9b79b65012bd86a838241d2ef708680f7fe8eafc8aa656dae9cf2abf3c6418",
"crates/horizon-world/src/worldgen/weighted.rs": "839840aae25302933bbd97a81a2336330e2d03a0ad1684e1e16ac769ed408e6b",
"crates/horizon-world/src/worldgen/write_zone.rs": "8e17a179764d3f68c05882aef35f6810c28a0000f9a83e58bd6030660b76e64e",
"crates/horizon-world/src/worldgen.rs": "e8e9f099ee1fcec8eedce31805d676d3f89c18e84f494a147ffcbfee23d3d54f"
}
}
@@ -1,801 +0,0 @@
{
"adapter": {
"backend": "Vulkan",
"device": 0,
"device_type": "Cpu",
"name": "llvmpipe (LLVM 21.1.8, 256 bits)",
"vendor": 65541
},
"animated_sprites": 1,
"animation_uploads": 1,
"arch": "x86_64",
"camera_pitch": -0.3839724354387525,
"camera_position": [
25.0,
18.0,
25.0
],
"camera_yaw": -2.356194490192345,
"collision_camera": false,
"culled_model_faces": 59636,
"elapsed_seconds": 0.556021335,
"error": null,
"fall_damage_requests": 0,
"last_requested_fall_damage": null,
"merged_quads": 3169,
"mesh_revision": 0,
"model_blocks": 10919,
"model_gallery": [
{
"block": "minecraft:oak_stairs",
"models": [
{
"model": "minecraft:block/oak_stairs_inner",
"rotations": [
2,
3,
0
],
"uv_lock": true
}
],
"position": [
-7,
4,
14
],
"properties": {
"facing": "north",
"half": "top",
"shape": "inner_left",
"waterlogged": "false"
},
"state_id": 5466
},
{
"block": "minecraft:stone_slab",
"models": [
{
"model": "minecraft:block/stone_slab_top",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
-3,
4,
14
],
"properties": {
"type": "top",
"waterlogged": "false"
},
"state_id": 15250
},
{
"block": "minecraft:anvil",
"models": [
{
"model": "minecraft:block/anvil",
"rotations": [
0,
3,
0
],
"uv_lock": false
}
],
"position": [
1,
4,
14
],
"properties": {
"facing": "east"
},
"state_id": 12965
},
{
"block": "minecraft:torch",
"models": [
{
"model": "minecraft:block/torch",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
14
],
"properties": {},
"state_id": 4926
},
{
"block": "minecraft:lantern",
"models": [
{
"model": "minecraft:block/lantern",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
-7,
4,
18
],
"properties": {
"hanging": "false",
"waterlogged": "false"
},
"state_id": 24197
},
{
"block": "minecraft:oak_fence",
"models": [
{
"model": "minecraft:block/oak_fence_post",
"rotations": [
0,
0,
0
],
"uv_lock": false
},
{
"model": "minecraft:block/oak_fence_side",
"rotations": [
0,
0,
0
],
"uv_lock": true
},
{
"model": "minecraft:block/oak_fence_side",
"rotations": [
0,
1,
0
],
"uv_lock": true
}
],
"position": [
-3,
4,
18
],
"properties": {
"east": "true",
"north": "true",
"south": "false",
"waterlogged": "false",
"west": "false"
},
"state_id": 8642
},
{
"block": "minecraft:oak_fence_gate",
"models": [
{
"model": "minecraft:block/oak_fence_gate_open",
"rotations": [
0,
1,
0
],
"uv_lock": true
}
],
"position": [
1,
4,
18
],
"properties": {
"facing": "west",
"in_wall": "false",
"open": "true",
"powered": "false"
},
"state_id": 10401
},
{
"block": "minecraft:iron_bars",
"models": [
{
"model": "minecraft:block/iron_bars_post_ends",
"rotations": [
0,
0,
0
],
"uv_lock": false
},
{
"model": "minecraft:block/iron_bars_side",
"rotations": [
0,
0,
0
],
"uv_lock": false
},
{
"model": "minecraft:block/iron_bars_side_alt",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
18
],
"properties": {
"east": "false",
"north": "true",
"south": "true",
"waterlogged": "false",
"west": "false"
},
"state_id": 9711
},
{
"block": "minecraft:cobweb",
"models": [
{
"model": "minecraft:block/cobweb",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
-7,
4,
22
],
"properties": {},
"state_id": 2362
},
{
"block": "minecraft:grindstone",
"models": [
{
"model": "minecraft:block/grindstone",
"rotations": [
1,
3,
0
],
"uv_lock": false
}
],
"position": [
-3,
4,
22
],
"properties": {
"face": "wall",
"facing": "west"
},
"state_id": 24135
},
{
"block": "minecraft:ladder",
"models": [
{
"model": "minecraft:block/ladder",
"rotations": [
0,
3,
0
],
"uv_lock": false
}
],
"position": [
1,
4,
22
],
"properties": {
"facing": "west",
"waterlogged": "false"
},
"state_id": 7312
},
{
"block": "minecraft:amethyst_cluster",
"models": [
{
"model": "minecraft:block/amethyst_cluster",
"rotations": [
1,
1,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
22
],
"properties": {
"facing": "east",
"waterlogged": "false"
},
"state_id": 26764
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone",
"rotations": [
0,
2,
0
],
"uv_lock": false
}
],
"position": [
-7,
4,
26
],
"properties": {},
"state_id": 1
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone_mirrored",
"rotations": [
0,
2,
0
],
"uv_lock": false
}
],
"position": [
-3,
4,
26
],
"properties": {},
"state_id": 1
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
1,
4,
26
],
"properties": {},
"state_id": 1
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone",
"rotations": [
0,
2,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
26
],
"properties": {},
"state_id": 1
}
],
"model_quads": 179,
"movement_ticks": 0,
"os": "linux",
"player_absorption": null,
"player_dead": null,
"player_exhaustion": null,
"player_fall_distance": null,
"player_food": null,
"player_food_timer": null,
"player_health": null,
"player_hurt_cooldown": null,
"player_on_ground": null,
"player_position": null,
"player_saturation": null,
"player_velocity": null,
"presented_frames": 30,
"project": "Horizon",
"resident_chunks": 9,
"schema": 1,
"scope": "Native resident-scene renderer with inspection camera and optional fixed-rate dry walking test; full gameplay remains unfinished",
"sprite_layers": 18,
"visible_model_faces": 5991,
"walking": false,
"window_size": [
1280,
720
],
"world_revision": 0,
"native_scene_culling": {
"blocks": 10919,
"culled_faces": 59636,
"visible_faces": 5991
},
"native_selection": {
"matched_placements": 16,
"selected_parts": 20,
"client_jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "a2ff1c890d6f3a5292c3a9402f02ca5404a993dc117853b25cbe64ac92b76d30",
"scope": "Actual native registry states, blockstate dispatch, tagged root baking and legacy collection using state.getSeed(position). All 16 featured placements match model names/transforms. An independently constructed native scene also matches total occupied blocks and visible/culled model faces using native parent resolution, rotated culling directions and Block.shouldRenderFace. No shader/pixel parity claim."
},
"resource_files": {
"files": 5590,
"sha256": "62f859d4d21b82158ab73e26cfa4973d58ab5926ab63d71c70c7a4d173502b7b"
},
"executable_sha256": "ac49c3978800a25550c082b05c1a56fc73a8d806ee1bdb0e4825a02051bf802b",
"resource_manifest_sha256": "92a51de578be0e7c37d21e94caa3f22503f7d88b73827a5fce109b1b889e5d18",
"sources": {
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "6884c7209f007ab9ee742b9c3c73828cfa1c6753d35b5fe25a87cab5955b33f8",
"tools/test_native_client.py": "6c615fed67fd7bcf09b3184216e08a82012049880a0d4da7c89f86553090cbda",
"crates/horizon-client/Cargo.toml": "d56524457d761c2613c0699b20e21ad6977d93e009d59ef150bbd9fc20d7a025",
"crates/horizon-assets/Cargo.toml": "2f2cffacec0b4e22dd7cb032d594289bc51c94ae6cc4e985fee3e310f441d751",
"crates/horizon-client/src/assets.rs": "e595afa610e0425d0b3ad694218794bf9e680e46ae80f3925c278ef1a823c914",
"crates/horizon-client/src/camera.rs": "d386a56ca8fb3b37ba2b2ed9d09342f61b409a575bb21590e934120b4ccebfa6",
"crates/horizon-client/src/clock.rs": "4851ada3e8e65d935eda8c0b57d3b51233b34f74aab4f040fd53db0e0d40b8df",
"crates/horizon-client/src/collisions.rs": "112286b07c4cd11b36da8b6799e0e069e69dfddf9a8a3f9ce36dcb282c791d67",
"crates/horizon-client/src/health.rs": "b5e2d3cde4bd58d906e6f6d47cd756ed23aa6706c71b10c3aedde30c11806403",
"crates/horizon-client/src/hunger.rs": "01d8a35f570f2a0991ac17a078f2066a5a83037a728158585765723d208b4611",
"crates/horizon-client/src/input.rs": "55b259ca6425c502270e7abc4d3ae1b3838633e2bd77d3817c6e00d9143a2beb",
"crates/horizon-client/src/landing.rs": "b9d0ecc5ec60a09d75ab9fe778e0a2e5bbb36fd8364a7ce996405f3dc9cb3b9f",
"crates/horizon-client/src/lib.rs": "bc1d0a7e42c11a9090abfebc4ed1f595415dd8b72a6a04b63c765b0deba29f6f",
"crates/horizon-client/src/main.rs": "aeb6b5220f8b89a1c9e85bf23fa2bbbafbc876108e59a222d383ad6e6fa238a6",
"crates/horizon-client/src/mesh.rs": "4ac8d85b30f599b37a98b92adcc016b16434816b93c401bd39b8215f591f9330",
"crates/horizon-client/src/models/catalog.rs": "620103719167fc9ab76e730d68eeacb50014e95b7ad209ae7adf2cbbe69f70f7",
"crates/horizon-client/src/models/cube.rs": "1067229f9dd9b276950bf7ec0c5f67061ce3d40a21932dca8034b9748e7439a4",
"crates/horizon-client/src/models.rs": "98dd3b969947c2b297862a934e6235067ddc1fc8cda5adcc6276d19014d4b048",
"crates/horizon-client/src/motion.rs": "833d7e14ee37f82bef05094c1f0fa681b5ead3b3bcf4e915fbd5bc94e46dd7ad",
"crates/horizon-client/src/render.rs": "75cb40c257cf61e51009d292a06cd96532f59320b12ed7c3a509bbdbe1accdd4",
"crates/horizon-client/src/sprites.rs": "292f844a31f6e8884008df9630e2b8862db1acfbc4640cc07d526e25f21f0bc5",
"crates/horizon-client/src/world.rs": "0333ecf3e18ccc63117295feb2cf77661462ba13feb293eeec667c12811423b5",
"crates/horizon-client/src/world.wgsl": "972a58ccb34e9965515adbb30c47a93fceca5b742390db6d9f69cba1ec31f559",
"crates/horizon-assets/src/animation.rs": "ebbf7952146a0e66b41396174492f5702627170b03a57e6cd5a45c97a08c975e",
"crates/horizon-assets/src/bake/transform.rs": "a95e658fef85b21bcb2f9f7512f98f98d57022d62c1199885b7133beae35a09d",
"crates/horizon-assets/src/bake.rs": "f55dda6b6cee5ac6e65a8ee4837fdd2c6674437d59e59b4c45718f6324d4a4d5",
"crates/horizon-assets/src/blockstate/bind.rs": "6278962e55c9786bba8184bdf2939af9c6e3b9002b08c3022129964b49a60009",
"crates/horizon-assets/src/blockstate/choice.rs": "5a66c8b9833e2f19dd8b0773f3593d97ff5941d3c5b773896b98049efa1395ba",
"crates/horizon-assets/src/blockstate.rs": "a4299dfd7adaeb4173982ffaa8e9c9eda2925739ae579a714193c99da2e7ce56",
"crates/horizon-assets/src/json.rs": "99fe8af4fbf5d4eed408a92e829ac1a39597a0d92471a6bff73771fad9c830a8",
"crates/horizon-assets/src/lib.rs": "e39f21c59a2c3e1c53d977b29bd5e0638e5fc41d86ff0fcc1882a6d90fd961e4",
"crates/horizon-assets/src/model.rs": "57ddb3d65e88e7a8aa22c62bc298a2dae7f4e994326a873a31f06c0f36ed051b",
"crates/horizon-assets/src/resolve.rs": "3927ac926cdcbd7d334901cc32d0ecc1e498b1bec98f76a46bca6d4964c13541",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaGallerySelectionOracle.java": "dc5433f1ce1de629b30cb70f031a43a691fc1df1fb218ce23de89769c164d562",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCuboidModelOracle.java": "7526f20513c549483122ab0d5ad24b9e87f38dc2f6aae55addd701a91ac85e43",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaHeightmapOracle.java": "145c943637ed177cc4ef8a85f2484da8afd164868e84a8463882feec1653a860",
"tools/test_model_baking_parity.py": "392ffec44918fb91740ca4a1316d684480d39f14bd34d46175f7f44946d15bd7",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"tools/prepare_native_client.py": "159c12846058954a35ce86d415dc12fc89a6f11d46d21d1616ee686b7af4eee4",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"crates/horizon-core/src/bin/density_parity.rs": "e5b1dd33b7d01306c73cf072629b4fb186e9ab87b672a00108999d1a72263fd0",
"crates/horizon-core/src/bin/float_log_parity.rs": "4a655fcf8822ee7668c4bd126bc84d0b118864a6fc7f5a6aeee667d8bf2590b1",
"crates/horizon-core/src/bin/geometry_parity.rs": "27f6c09fe5018ac3de8e70e0f0bbf78f9abb14f5e4783bcaf46e8ca87b9c6f8a",
"crates/horizon-core/src/bin/noise_parity.rs": "c135bfc708d853e7061e81487d2cfe10de64b2f65677d3b4837cbfe0b8341010",
"crates/horizon-core/src/bin/parity.rs": "f35d928c66f958de39fac5e7e836a657eed95f83599e84899f7ea7a5802ba481",
"crates/horizon-core/src/bin/tick_parity.rs": "a54c164fe4814034d369947a887f5273966f5a878ba849204b80d1c729526a8f",
"crates/horizon-core/src/biome/seed_hash.rs": "5afbb4921c750826b395a08bf06f382fc7f01b5759a93de02a2749c523e2a317",
"crates/horizon-core/src/biome.rs": "908efa8cd4aa0a7adf1cb5e1a222e3dfb640eed5e9172e0fe7f0d1287afae7e8",
"crates/horizon-core/src/carving/ellipsoid.rs": "09232a7588610e8a9176fd9c62d40afb1fb89f2ecab6d555536a1d847b142d86",
"crates/horizon-core/src/carving.rs": "0aa3093caa0437868a8c0ed52a6c6e1993bd51c03583c670a2837e749eae5426",
"crates/horizon-core/src/density/arithmetic.rs": "372faec96c923e2cf4aa6c66c1ac398e676853274557823850dbc8933dd15ab1",
"crates/horizon-core/src/density/beardifier.rs": "bb1052e27dae4a01954ca78d7d5babafef85f3b2c704ccaf1920cb85a098cb50",
"crates/horizon-core/src/density/cache.rs": "38d0b6c9dd04ffef979fdad3f29cfebf98d331c8c9d430be5f39aa34f6c30975",
"crates/horizon-core/src/density/end_islands.rs": "168b9384237bd2e41d0ae5a74e944da4dc74e493bdec31fb73184c9a49e3de55",
"crates/horizon-core/src/density/graph/compiler.rs": "ac67deeb16f16d0859aa20e5a165811a29aca0b910037ee6bf5098211f3a6ede",
"crates/horizon-core/src/density/graph/mod.rs": "b776e7da934cb03051a3053d56d461c71e9978e084922fe4194147aa580c07bf",
"crates/horizon-core/src/density/graph/seeded.rs": "6bcdcaa3dffcfa9df673bbbea35120057a16ba3d2b506c52709c36cf8976b74a",
"crates/horizon-core/src/density/graph/tests.rs": "6bfb8cbff462587dd147b0775ea01d370abbd97544b9bd596c792df1b5f7e634",
"crates/horizon-core/src/density/interpolation.rs": "8c890f52b6467f38a94c654986a6a484b8e0b296ab98c398e60a6ce465b5b010",
"crates/horizon-core/src/density/interval.rs": "b42629163baa6b599a233afe8596d1c370cd81d015cc6fc36a9663aa47b98424",
"crates/horizon-core/src/density/mod.rs": "ca0d77d3282e3746ddcbc92bee97dbf640b9a56214e6ac1537f51f9a5b63d6e7",
"crates/horizon-core/src/density/power.rs": "d5b7270a128d4264268cd772109ad16d71a8ec3ff2d3b63b84cb985296d54a91",
"crates/horizon-core/src/density/rounding.rs": "71840c5206ff8d218ac29bf6f66915d5212764ba270c675711a866ba5b55a7a6",
"crates/horizon-core/src/density/selection.rs": "0dd26af2e85004ec5e053039ad11c384c17c56ace9ab45eb3f5cb3503c0b0330",
"crates/horizon-core/src/density/slice.rs": "5d77605573c0deda47778f1f78f7fa3fbf1944d8f5efbcc65cf589181cadf80b",
"crates/horizon-core/src/density/spline.rs": "6bb2e40f940fc6544d6fb09cb0b8cac722be03bc663dbdfb0f61faae207400bc",
"crates/horizon-core/src/density/surface.rs": "159e0e69cda74f870e80ea64fe523c4397e64af4ccb861bb9fd07b2c3cb91b00",
"crates/horizon-core/src/density/terrain_noise.rs": "8d0059d25eb5d248cb97a4c5a2e670d61528928ea151495c004f25adb723fe3e",
"crates/horizon-core/src/density/tests.rs": "7817796ee40d0ae241bfbebec6bca190e0a8e7d5a1caa8ddf858c3eaa58b8858",
"crates/horizon-core/src/density/world_fields.rs": "c1ce305cb8046b384d90c564cafb24af7365d580389637910f3d8b0cc18eb583",
"crates/horizon-core/src/geometry/border.rs": "1386f8080521231d05ba3e84d94a3e1d5218d35ccb3d5e9fe2bbb05a8739e573",
"crates/horizon-core/src/geometry/mod.rs": "c650386f9860e44a96c55f18c8f1428ca715fcb0bc5c2434db5b1caa43df27fe",
"crates/horizon-core/src/geometry/movement.rs": "bcfb452752940ce53ae6dc267a3c4eb29459046a063c1f884684ab4f4bd0068f",
"crates/horizon-core/src/geometry/shape/create.rs": "189812b91d5e0e3ad963afcd1a6e2831b31b8188df91a904ef27061e644806ad",
"crates/horizon-core/src/geometry/shape/face.rs": "f243bce81384040a95ce7984b02b5699206c596c537b2713097e86005b4d3a5c",
"crates/horizon-core/src/geometry/shape/join.rs": "f1b51887b7bf9482557e3ffa99e136f2e5db07ceeb05fdb116adf45e87129075",
"crates/horizon-core/src/geometry/shape.rs": "e8d88a763de1525f77a30b99591641e8a8b80946263acbde035a9bcc356df960",
"crates/horizon-core/src/geometry/sweep.rs": "abd6009c61555161ef2f18b431b2aa384b126c0871cae8b96a62358498a56a1d",
"crates/horizon-core/src/geometry/traversal.rs": "77a3da570a0b85582b669cf4d841cba4b06327006dda26d4a26df4e8ce05bae4",
"crates/horizon-core/src/geometry/trig.rs": "05cef9341a298a474221a0556a11ddf47650393ea7a97b4b2022a4da6628fe37",
"crates/horizon-core/src/lib.rs": "4255e16837fde42a52ba118f60581d197c571bb530b60d635e506184ebf4db0b",
"crates/horizon-core/src/noise/mod.rs": "1dab5a713abf702402e69ace1bf9e476bba544b0ede5a61c3c3afc60af0a03f3",
"crates/horizon-core/src/noise/normal.rs": "e9e7a46472a54a02c98c46da819842090567153b32fe0c84249009ef19af7aad",
"crates/horizon-core/src/noise/perlin.rs": "e73815447432eab7542f67366cb3f1b368d164e33f6c9cdbd045ac8e4db0932a",
"crates/horizon-core/src/noise/simplex.rs": "6c0dbc15b2b7510195dd28fceca01dcaac1847ccc4a84d299c351589c642fe7a",
"crates/horizon-core/src/noise/stack.rs": "7f6ef0e7d920139ef1a6ad3ec5640f92765715f86dcc5ec29f1a149984f45fa3",
"crates/horizon-core/src/noise/volume.rs": "3f05d2b1780acfdfee60037677d309937a5033b45ef428fc2d540942d4b56b43",
"crates/horizon-core/src/position/iter.rs": "32d2d8e74821cc4e49e3354202d35d3120e4415bfdda9375a73f2137ef651129",
"crates/horizon-core/src/position.rs": "e10101088e6902386b9b6d27773d44312f1ff72bebb19e57967a54945dde9dcd",
"crates/horizon-core/src/random/hash.rs": "0f88a127a1ba2705d3d6c0ebd009324d6ba86ffa2d27edf2d2a84765e690e4a3",
"crates/horizon-core/src/random/positional.rs": "35494745e5d4cf89e282c3ae0ee245e9f2640ddbbc03bc0055df742006a9c862",
"crates/horizon-core/src/random/worldgen.rs": "9f07ff33bcc038d34e27aa5465753bb21df18f2975e43cae201f709bc186945a",
"crates/horizon-core/src/random.rs": "ddb95d3a83e28ad605ff1f49f5df270cc543ca5ef1130e37d989dc74c8d861e6",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/src/text.rs": "e6553ddb5db5039e8dc4614b6a6dc9f35a26dc3d1673b68a04e72e7983b67abb",
"crates/horizon-core/src/ticks/generation.rs": "be1237e790693f633a61714ddae68c6506a777588a8a3ab5efbe53a35774dbd2",
"crates/horizon-core/src/ticks/heap.rs": "bf28afab8af77c3d243aa96cd8a1fb8d934140a4dbd07dbfdbf4e7908bb4b845",
"crates/horizon-core/src/ticks/index.rs": "1f1a6a568c2a30eafecb020ca4d5f5fc414860de85b8b381fc419a2e3e65c24a",
"crates/horizon-core/src/ticks/mod.rs": "01634630668172516b8b79d0907bad47f6e2c543a6d499c2fa4b201823b375cb",
"crates/horizon-world/Cargo.toml": "18bbad377a8047e4d4ecd0fc87d83d46d1c0f1ce2b8c47bbe64633e7b4420b57",
"crates/horizon-world/src/active_effect_tick.rs": "88f19cfc3532c47a58c646bb3e9d99ff239a900752302b6a444dda3013e95cbf",
"crates/horizon-world/src/active_effects.rs": "daaf352a69511a7d69fb329997f783b86585e486e0379c84ab0a55641771646c",
"crates/horizon-world/src/attribute_health.rs": "1420a80787d10dd2e2954a3ee6193ff313289d00c7c78ca26ece8bafa21f4380",
"crates/horizon-world/src/attribute_map.rs": "3d871cd530f5c035e0753f3ba065c2b9c5b49cdee75d4119f7dd584b22af67e6",
"crates/horizon-world/src/attribute_updates.rs": "4cb322d75a50d222298994607097ba7f7e6674021128fa02a98a74c057ad05f1",
"crates/horizon-world/src/attributes/entity.rs": "64ac99682a3aa06b1fb94b776b47794234c76b1cf70f1f54933d51e545e69279",
"crates/horizon-world/src/attributes/live.rs": "8198c45134f69135d48ef203e71b6e702529568fd1ed9174d0aa843570bbf9e7",
"crates/horizon-world/src/attributes/mod.rs": "5c2fcbbde58c19261874d227ea98332f00336c9fa53446da2e9adb6aa64a5e5a",
"crates/horizon-world/src/attributes/operation_map.rs": "fc5bc8921d78ea6721a2eaa915e67483e2a33683927467bdba24f0492356ad97",
"crates/horizon-world/src/bin/worldgen_parity.rs": "3143ceb9b56eecfd7667e5feb5f9f0cd13cfb8754b38d4ea338dbba97f2819da",
"crates/horizon-world/src/block_collision.rs": "39207247f2f6dd3ddc77640229044246f91b32054563f88a435f1bd92ad2092c",
"crates/horizon-world/src/block_collision_scan.rs": "20802862364c110ff85eeaf48606596a8468b83768dda46b412d337958790b41",
"crates/horizon-world/src/block_entities.rs": "a9deae92e6e5a1fcf4f0476c33ea4d170ddad6fd4b3303e1bb66d933973d5e06",
"crates/horizon-world/src/block_entity_push.rs": "12ee91bf604946234b24a0da4333f07d1830ab9743a422d41c8d0afac7d49cfd",
"crates/horizon-world/src/block_landing.rs": "33083fe39266fbefec1b3ea1a19f2afc609791d189da247c895e116ad6eb266a",
"crates/horizon-world/src/block_placement.rs": "524f4892d50bab77b7d89d19f7b048ffe746996f2ed7f376db2c6ab00ed75c24",
"crates/horizon-world/src/block_properties.rs": "b0bd8a983336c48e488a20caa77dd5c39b1a74bbd14ebc03b3b64556a1c864fc",
"crates/horizon-world/src/block_render.rs": "8df52ee11aef406a1571198a64048062a0ef6864e0058d9293a57f64b73c916a",
"crates/horizon-world/src/block_support.rs": "ade4fbd47284b450dabdd682dc86138b2ac05a0fd379525d7110648908245476",
"crates/horizon-world/src/block_survival.rs": "28ce64375e09819a4f13da9cfbe37c08b5ad0daf01b289c1c360b4567e50e811",
"crates/horizon-world/src/blocking_item_damage.rs": "afea3cb5761e8b82ee4d9bb4ef3c6fd10182a324dbaec99e6c9ebfac255dda09",
"crates/horizon-world/src/blocking_rules.rs": "83c5e2105cec56a90182ce582e1c67ade2b189be6de1a34d08035000cc07c492",
"crates/horizon-world/src/bundle_weight.rs": "a0e7b0587ab5d46cd55588f25d55a088b7a4725099c13ba6df146957be36014c",
"crates/horizon-world/src/chunk.rs": "795895284d6e615bcb2082fceacdfe7025c152fb2934bb43f598f17a00ab46f1",
"crates/horizon-world/src/chunk_status.rs": "dbb8583cfa775203c544d24d69e03720385428f15a267a561356c21f5025e9c7",
"crates/horizon-world/src/climbing.rs": "6cd2f919872ff0b726effddaa57eccb805b8eae43f9d01144716010853891879",
"crates/horizon-world/src/collision.rs": "a749794d5c27ccd6c0d964ad02f9dc31d49d9f4fe4b7366cd4bd8155e681b00b",
"crates/horizon-world/src/collision_context.rs": "2176c7034e07f547510a8327cdad9d3b63f26e4754032b76b7d5fe13166c333c",
"crates/horizon-world/src/combat_rules.rs": "01131f70d1acdd96a910e7f96deaa12e51a1e3bb9208085f04e3ec7b657d3cd4",
"crates/horizon-world/src/component_durability.rs": "37a46e184f95bc5027e2b9af72ff52f729ad03601d08e1827f181fca383a35af",
"crates/horizon-world/src/component_patch.rs": "f6f8992f241dfb25e012a06a7ba3fecab8d958686dddd096595a4806e56f0ab3",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/consumable.rs": "ba3575cb85866cb940f33a1ac86455d71cf0cc6395b848588a8ee1fe33f5c326",
"crates/horizon-world/src/consume_effect.rs": "03f2aac6879ce133347d42f6f6667d62c06d956ff9faac5dc14182a788b6a236",
"crates/horizon-world/src/damage_immunity.rs": "fd39c41124d694e755cf7faadcf93c636df4042c78ec345092a856b5f952dbcf",
"crates/horizon-world/src/damage_reduction.rs": "f5a599ab11e077f526237018aeda803ea3c420c5b35c78ae9d85e32267e23bf3",
"crates/horizon-world/src/damage_source.rs": "24945e397a926d34695652980923609e4723e02fe6b6e56d4aaf673e45d759f7",
"crates/horizon-world/src/dynamic_support.rs": "5996bc1c436fb6215d8fc3d0bb4de5dd9b966d842d432580d624195771697fb8",
"crates/horizon-world/src/edge_backoff.rs": "5259d7aa44e64f88351d1556c44dd0edcad3b400a099c659755792efba7b5773",
"crates/horizon-world/src/effect_attribute_modifiers.rs": "0bc7ab63d0f3f34a7133fe20364cae0ec1fdbd3773cba90faa1f08e0d63a5646",
"crates/horizon-world/src/effect_notifications.rs": "ea66bfa010d6d44aee97b9672902f41cd99d0d80239f41c6d4eae5c9a9472d3d",
"crates/horizon-world/src/effect_particles.rs": "a42dc4ec55929dce1db0f22f8816ecf7621fdce1cd2ac0c90f6a57fea4e0afd2",
"crates/horizon-world/src/effect_sync.rs": "1388d4a69b42a14ff4cd474f5e36f0fad5a2874031e64fa2b19b2ea179deed2b",
"crates/horizon-world/src/entity_collision.rs": "09f2fd7f6cd56fc282f468ecfa765a94506929e9684bd3a5c90123e5b51cd627",
"crates/horizon-world/src/entity_fluid.rs": "02991040ae879a8914f09913128a3506e9e7a1ca33ffc0a22b5729a168346600",
"crates/horizon-world/src/entity_fluid_tick.rs": "4f9e070b88a73c98a4e2e659360ddd6edee636bca29377f1ea9011fd5a556f64",
"crates/horizon-world/src/entity_move.rs": "a40a50d3e841625a75d4cfbb7c2630ab5a62a574456567e7234f401ae8441b32",
"crates/horizon-world/src/entity_obstruction.rs": "a4b28a19bf83b23611c59d94535c488db37e4aee24b22c973c545910894a809f",
"crates/horizon-world/src/extra_items.rs": "6eba0a0c795d5fd841d31471708e78324b4852adebb2e6ed700dcc0caab668cd",
"crates/horizon-world/src/fall_damage.rs": "8c28e2933493569fe05dea22332024287d28b0746b514dd465681040b003296b",
"crates/horizon-world/src/fluid.rs": "a0a1f34ba94d8b59dc975becee8952960764d67ae08cf2d6a8bcd40a614b15c4",
"crates/horizon-world/src/fluid_box.rs": "b586af72b1c04a9354fe66205c28dc8b619e205ab9ea19a68232722e4b6e96c1",
"crates/horizon-world/src/fluid_flow.rs": "7c7e486b5c565df3602799648b37b879bcca51414337f607962d6c7951b86d05",
"crates/horizon-world/src/fluid_occupancy.rs": "26037579caeef6c8a5a2bde2c3d142d278558b76d77ebff401cee6e35f2ea961",
"crates/horizon-world/src/fluid_shape.rs": "28bb65a72f5bd074a354ba38a1b1707fcb0947537977a11540bba0adb85995c2",
"crates/horizon-world/src/food.rs": "3cf416fa632a5555a8116bb528a6e80bcb5b6b754b0748b4959ed310102418d3",
"crates/horizon-world/src/food_properties.rs": "0926fa3f3bc3d0608c45d02f564355825ca3c3526a82bf9c1375c7a191fa5e12",
"crates/horizon-world/src/food_storage.rs": "58c433801a285efcc973638c11d694a41f85dc96703a3a7ce8d3673f3eb31d52",
"crates/horizon-world/src/free_space.rs": "913536bf4c85ddeeb378d76d1b5110b4175f5688e1a749f32fe6a6d86fbb478e",
"crates/horizon-world/src/ground_support.rs": "3e371d74ecede4d30beef0a7e8a2ee33463584a5b1ed3d852b394efcce1ffbe0",
"crates/horizon-world/src/heightmap.rs": "a5edef082b5af40d814421ea17e129b3b06d70abee6434ed263e4bba58571698",
"crates/horizon-world/src/identifier.rs": "37c921889c4f5d91f7c09ab2ee68d1a5e5a3c4fb1c49b4b189c987b4615fd2d6",
"crates/horizon-world/src/interaction_shapes.rs": "f321284ddab440a394372b6dedc8b5cc29a653c0745251a9e96c650f21c33dea",
"crates/horizon-world/src/inventory_pickup.rs": "ea830c7916e7f2d95c6db7ef48be1e876e6ebafcb438e47fc72f9a5bd7c37d07",
"crates/horizon-world/src/inventory_tick.rs": "293a3d57a1689337cfd58e5a73dcdbed4cb360f94d98ff5458f0df92de387365",
"crates/horizon-world/src/inventory_use.rs": "6a6c2ecc73c83dda4cd798c0304df12ace6096eb110d899f4f0c7ffd852bf001",
"crates/horizon-world/src/item_after_use.rs": "2b6598ce5b7b304dea2c8057b4a1eb6530264ac4d0546c3da0c76deed9609da5",
"crates/horizon-world/src/item_blocking.rs": "f6eee0d6d177cc3148960122327ba1b459a2f0e85241c1d9a3e40f0b8c169296",
"crates/horizon-world/src/item_cooldowns.rs": "7b625868509ab3c51e72db0ac714bb0e7ec5e2610d37271005a1a737f4d14431",
"crates/horizon-world/src/item_durability.rs": "9fdf835e5c7bd0e1dd63ef2ba0076b770cdd4d6d14cdcd11de27690f0702f94e",
"crates/horizon-world/src/item_particles.rs": "861b14f65adb9b14f8158fe9f0b7128beac3df8107b1337c31b8b9b49434ba3f",
"crates/horizon-world/src/item_stack_refs.rs": "18d3ca85cac0daf59200857513761359e5690f719cb3f7f64ae552f0c4169ea3",
"crates/horizon-world/src/item_stack_storage.rs": "b4dcb83dcaa346848c5484161feb3e2cf08e83f7793d7ed83be25b14b9d12884",
"crates/horizon-world/src/item_template.rs": "dc80025215d1867e656924ea2a9d273aacbcaea21293d986ba42d0004ee93b69",
"crates/horizon-world/src/item_use.rs": "b1c79428986efbf9dd5ede703a39eb387fb6dcc7d9950f0e49243a353a5b8070",
"crates/horizon-world/src/item_use_catalog.rs": "a9b53d2e816583239a75c3c61e78dacc5e3b27dee595be34b1c7fa169f17a571",
"crates/horizon-world/src/item_use_lifecycle.rs": "4639b70440cf811e79de09c48a3e035143fcb6be8a64c2f61b10ae55a2f133b7",
"crates/horizon-world/src/item_use_start.rs": "a84092dfb8b8f0a89d0928bb2f8ac252bd9bfd3f8d74fce1a7f7a5b3c3f4f50b",
"crates/horizon-world/src/java_hash_map.rs": "955502e696d7b0b33bae3ec485c8eb1453a8956116aad68226cf1fc67d60babc",
"crates/horizon-world/src/lib.rs": "e25b3543c07f31c2a9d23d811792de9a33290263c7c7445549a0682f6935d8a5",
"crates/horizon-world/src/liquid_collision.rs": "0f0a83b04e5a5bc9d98ed05fde4d6584ba69642e93522e726e4cfc325d6fcb1d",
"crates/horizon-world/src/live_attribute_updates.rs": "778171faaaf7077deb0b62c4cc1db16351eba41adb8bb07656ba65e827056199",
"crates/horizon-world/src/living_air.rs": "b2de36bb50bed15e2808fe4a874fcef07f9fea0d2c96385b7b5e8ee9560d4442",
"crates/horizon-world/src/living_damage.rs": "2b448209629b9bf2e678d667ad0d6c7fa22146892dd106b169d96b31b0df12bb",
"crates/horizon-world/src/living_fall.rs": "da0f176f4731e1c86e08bfeee8167742fd1b86380ff0e9304c13c1ce3f1c67ab",
"crates/horizon-world/src/living_fluid.rs": "d7cd914cfb2a1f4876ce0ae95e999bf0ff1af732cce3ab4a3aa2d1ab881c7339",
"crates/horizon-world/src/living_health.rs": "221659f85552424e937d503bba6d8003006b106ced042b32d3a6f6cc23e12ed0",
"crates/horizon-world/src/living_hurt.rs": "844239ad7d15c39629bb3cfc06ebae6d1cff20b7627468f26e0ee8dff3abdcb8",
"crates/horizon-world/src/living_landing.rs": "8bca4eb7977abc2b14fb7174be4ea355352106ea1e76ff5f3ad8696969d9eefd",
"crates/horizon-world/src/living_motion.rs": "56f8c84cfbe205a7a69912d5f76b52ef1efca149c1b6801d4684e25fb179aeb9",
"crates/horizon-world/src/living_use_flags.rs": "826f4fdeba7e208368cbbf910fa408db0afbc6442d842d178a70fae53e0d0ea6",
"crates/horizon-world/src/main.rs": "fce57418b8c22a6a0a9044baa89ed3d9c243bc2e8413fea3ff0f32985daba021",
"crates/horizon-world/src/movement_emission.rs": "76e7d6f5b19c94676190f54389f9c4ce12cf89945ccfcb9c750de473223e7753",
"crates/horizon-world/src/movement_properties.rs": "6f01ab920b376a13f5ae12c3718f4dd067e1dff2b829585af00a8b2100f3775d",
"crates/horizon-world/src/movement_restitution.rs": "04b4fe0947e7e52576145bd8ed15920278e8a538afcc74d125eaca513dffa0ef",
"crates/horizon-world/src/movement_statistics.rs": "fe28061e29c41f8f399d29cce8c468a63854613702b5aa525c0f0fd98cb87f9a",
"crates/horizon-world/src/movement_support.rs": "02d85cf572847f2e60b5a7f9d60b856888a67b3c1f4df03e81998c66fdf874be",
"crates/horizon-world/src/nbt.rs": "60262c3de8c8f68bc2da0370ccb17393d32b85f5f5022c6358599a7d32119ea6",
"crates/horizon-world/src/object_open_map.rs": "b4934a9cc38df93ed206ab0bc3bbc4499acd8e40b41b7def7d47067b7170065b",
"crates/horizon-world/src/object_open_set.rs": "d3e0373bf1b652dd054345d5a8e25ec828e06dd7cad65aada35163c95df4e637",
"crates/horizon-world/src/piston_movement.rs": "7a3fd2549a582b5f3a5c21aa05d67d944d62ca1105856679e100ac5b44e9a52f",
"crates/horizon-world/src/piston_shape.rs": "399c2337103b8e7e0eb5667227c5aa14f9549d6a467b7be7da3d0717f0263500",
"crates/horizon-world/src/player_equipment.rs": "1fa8c53e67624c4641246249d79a800a28a4858c62482bd880b4e3b866b936ef",
"crates/horizon-world/src/player_food.rs": "f188dc110745bcc7acc15e6c521db943b06b404f69cd251bf74a345516070304",
"crates/horizon-world/src/player_health.rs": "8155b315453c569db2fbe46228886c5881d1fd55eb095c5849e69bdb500ba2bd",
"crates/horizon-world/src/player_hurt.rs": "99c9bbd8587ec2dc287806049897b8034d2f5349ad47fc497b70d54148844a36",
"crates/horizon-world/src/player_inventory.rs": "f4f67d8312793f25930626c4ac06db688fcf2e2292d6675071d105fb1708d952",
"crates/horizon-world/src/player_travel.rs": "6841a677a900495eb6223031ef3ebe8d859bb98908dda0e2209e5f28839dc593",
"crates/horizon-world/src/powder_snow_collision.rs": "7289946a21478d11abfd2bdcdddff3d7f98e25bf6a68564fed45c3cc01ac2a36",
"crates/horizon-world/src/region.rs": "72b642e87fed37ed17f54d4c30f96c3b64d26c14bc0589c31ef40ff1616188fc",
"crates/horizon-world/src/registry/json.rs": "7a683afcd1742c5307756927d7f0aa779c7d7992af87d8d371dd98108728e235",
"crates/horizon-world/src/registry.rs": "f2e58b2b4d944ac8fc6226bd3352cefc3d2052d8473e02ccf7dc402b176df435",
"crates/horizon-world/src/registry_collision_scan.rs": "97cc950a9a4ba387b78e368f36d595f8664ab7730d132900d220ce23b92826ea",
"crates/horizon-world/src/registry_fall_ray.rs": "52935436132df505691144840dcbd858b15d00d8305997284e3a542ecf6bc0dc",
"crates/horizon-world/src/registry_fluid.rs": "b8959c05850cfeaaad1e4de8ca7c7d0d6ac56da9b2c1de3ebefa5871a11ed35e",
"crates/horizon-world/src/retrogen.rs": "6efd36a6293756688c1990a7965bd65609d7c5e2bf2a5f4f01d54932d2b9386b",
"crates/horizon-world/src/server_player_combat.rs": "0a94885c4b7a0d294ba7f4cee18b96ee59649b50112988250b53cc224059a979",
"crates/horizon-world/src/server_player_damage.rs": "29af22dec321fe01776cee5334f050c5bc3e27a688f99c8c3da4c0ad8bc8254e",
"crates/horizon-world/src/simple_container.rs": "0fedbc7e974b1db79b88bd6aff977654189a5d553cf42852fe8bf0885cf90b30",
"crates/horizon-world/src/status_effect.rs": "588bfcf4d93f50be86cb89545bd5c431edbc71771f704ff55cb52906b1964c37",
"crates/horizon-world/src/stored_consume.rs": "621a52c9fba447c393e561f881a16cf1f97d336e3a0ce493725ef51e2db12ffd",
"crates/horizon-world/src/stored_effect_attributes.rs": "c79f6a52d3cfee1a5288225bf8fa91a7bf3ea8cd21faea9f6dc748ecefc6309a",
"crates/horizon-world/src/suffocation.rs": "bed219dd5bbab6263b98fbe3d0eb512cb96c52ae847210efe49514d05f22f11e",
"crates/horizon-world/src/swimming.rs": "49d2dae13c109b37ff832cde98a857944ff45247b864a527b9c4f03ecca7a7b7",
"crates/horizon-world/src/synced_floats.rs": "0152f2752bafaf68769d56dbc88494a976496a680c6b113d6b48a446158ba072",
"crates/horizon-world/src/synced_values.rs": "a1d4b53ae77d1899ba2b4ead67c9ec1e3c96615558e446f9d0760c1b4a520169",
"crates/horizon-world/src/teleport_consume.rs": "d6a53bbb6ac4dbbd4c0591d0646017898a95beb8ef093dc5d81b9833963be6c3",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/use_remainder.rs": "f555335afeca7970888131a6da2f5a614a73253b631185d1ba804593a349535e",
"crates/horizon-world/src/view_direction.rs": "e18120ae26dc5cf702b29fc4c8487088bab133c8ce5abce01226833fafb0d5a4",
"crates/horizon-world/src/water_splash.rs": "e0461ae1b2e8c851cca6e3251a188334293292201d7f80dc9e7d60fd1815f4d1",
"crates/horizon-world/src/world_movement.rs": "f8fe9e34f2395d2a04c839d1c8ba78e09ce493c26de6f6e4e237b9c19c061da5",
"crates/horizon-world/src/world_ray.rs": "879bdbbe12f56deb705cc183933431489e840b71eade40c33391eed5949c2e61",
"crates/horizon-world/src/worldgen/anchor.rs": "d156b8a0b147a274cdd143409b441f4f43edecde6e8ee14ef9cf0309f743143a",
"crates/horizon-world/src/worldgen/aquifer/config.rs": "fcd2cc3a520c1527c88f095a3b5d38487e7ebb1ccecc5f757f93d04a069add4f",
"crates/horizon-world/src/worldgen/aquifer/noise_based.rs": "74daaa389b5c3dfdc99214dfff256a9e172f83548d2326cbc941d9637cc53fb7",
"crates/horizon-world/src/worldgen/aquifer.rs": "cb4b66d87de3f9f79ae6ffe4badd6f0f44886cd42ad9de2771b8b56c4f1e28c7",
"crates/horizon-world/src/worldgen/bamboo.rs": "d9b47113c99be34256e58308bc6f40072ff25c579d6bf995182aa862c0006102",
"crates/horizon-world/src/worldgen/biome.rs": "3fe316b875aa32683759c337dc71f624910faf0812a2d6d83b8098d6d0bac7a0",
"crates/horizon-world/src/worldgen/biome_chunk.rs": "8fdfe6ebe3ffeca97611fd5991a5bc6b2783ea1c62f4d8ef3b2dd53c04a5dc1d",
"crates/horizon-world/src/worldgen/biome_predicate.rs": "bfc581bc40077cc74ffda43e990a55fe997adc04c7130f98e039c3305ca79aac",
"crates/horizon-world/src/worldgen/biome_source/codec.rs": "2b9e4f5d679eb444cb73174f511e3b9f32e9eb138248ab12cffc6cfd76adf3a8",
"crates/horizon-world/src/worldgen/biome_source/runtime.rs": "f0b02c1521178e4d0377c6ca62694604b6a773f1f234f070ff0cde4685911d45",
"crates/horizon-world/src/worldgen/biome_source.rs": "e181e1736f3e0b75f7091a24c88de3fd116e01b98424d02382aea7a503d1eb54",
"crates/horizon-world/src/worldgen/biome_temperature.rs": "cde4bbab5e260c4065b113376c423b8511ade93c5aa5fd976e245ee8a58b5ad1",
"crates/horizon-world/src/worldgen/biome_weather.rs": "96b1f9494559ed31d06257b83d604d00cc069ccc8c7b68094117e034b4a71bd7",
"crates/horizon-world/src/worldgen/block_blob.rs": "c608c57b3d77279646ecb89e50677dd8e452b0422ffd357ba755536c5589eb89",
"crates/horizon-world/src/worldgen/block_column.rs": "f72c21a9066ee0aa68c2fb79fba436d05afb14c6ef5a2cb012f1ed35fc17cd22",
"crates/horizon-world/src/worldgen/block_feature.rs": "36b4e46ee7f7f73bcb94d8bce8d99013e4b16234c9a03542eeb3186e88dd1c21",
"crates/horizon-world/src/worldgen/block_pile.rs": "623e369b77e0526ed2756485a6c0bb09683cd28ad8876dea907360ca6665b39d",
"crates/horizon-world/src/worldgen/block_predicate.rs": "074c692367e3f2191a1bb28d87b23402430a843c246bd30a4ea838ee3500280e",
"crates/horizon-world/src/worldgen/blue_ice.rs": "eedd77bdaff808330b864166d303378096daa5c7d235e925770b171c05109247",
"crates/horizon-world/src/worldgen/bonus_chest.rs": "05d0f63fbc7412f13ba1fa37a7238114b8f70bfff318beb2dece590482d49cc0",
"crates/horizon-world/src/worldgen/bulk_section.rs": "eecf61532d7793f853884c5a18a7f436a59835c7b13d3ec9075804511553c9ba",
"crates/horizon-world/src/worldgen/carver/canyon.rs": "509c4d5a9d689849e98e894ab14a9fbf82d10707d38e9cc688ded3c4778df3e2",
"crates/horizon-world/src/worldgen/carver/generation.rs": "a4498d0d1457536de3922a08e9c40ccce8d2ef9cc263801c15a412327513c098",
"crates/horizon-world/src/worldgen/carver.rs": "46b251e28225fe1250de38f49dec5dacda4e2c4ba1e556e21e6d1e14e2651fc3",
"crates/horizon-world/src/worldgen/carving.rs": "4e77d4e5c4a0ca55ca3563b9bdf6f379342e0bdf9d019d60f7bc57ce4afb5fbd",
"crates/horizon-world/src/worldgen/chorus_plant.rs": "29224c164ede919e280a65a68f155c873e2c8fd0aa7d7e244d8fa9e468760250",
"crates/horizon-world/src/worldgen/climate/codec.rs": "d567adeb5d837816fca69102db51d790f71aec1b51c09298230d24612e400a14",
"crates/horizon-world/src/worldgen/climate/index.rs": "c5ce61679a5f0e0f2f0af2a373424effa124d0cce8250609eff38b7034650756",
"crates/horizon-world/src/worldgen/climate.rs": "1b9ad44407f40aee4c1cd5357a5c9c443c1b105728f01cf5c644072f99f8357e",
"crates/horizon-world/src/worldgen/decoration.rs": "75a79b20b21e133816e729f16e758be6165d0db18a64bfbd5fd3618325a2adf3",
"crates/horizon-world/src/worldgen/delta.rs": "c2bf49ddf3231d28c109e68871429bc13d76a7bebe14eb33e84aa856bdd66145",
"crates/horizon-world/src/worldgen/density.rs": "65a98c156a290a6b374ef670d28cd5dfbe0aa93171824d1bbd96422536273f84",
"crates/horizon-world/src/worldgen/disk.rs": "6f8f9e059755af44c9bfa1b91eba54a7d13fad811dce31717c5502d7f6df33d7",
"crates/horizon-world/src/worldgen/end_gateway.rs": "f53fde77d6a36a525cd15d890003b2c129d0689a4cbfa2cf443a0c2e3acae040",
"crates/horizon-world/src/worldgen/end_podium.rs": "8f6d0d6d60ff0fde63de5781e867239db321f82cf12639f0537d410a3731ee1d",
"crates/horizon-world/src/worldgen/feature.rs": "40500af71ee6628dfb27518262d99f08d0383ae6c7b9397452feef0c213eadd9",
"crates/horizon-world/src/worldgen/feature_catalog.rs": "efc7b17b227e71622ef34108be9abd010f5675b68ea0409fcab82581d9aab88a",
"crates/horizon-world/src/worldgen/feature_graph.rs": "da132fca9fdafb0d89a917d5f4b68c60b70fb33cadf948a107da0e35d83dcd91",
"crates/horizon-world/src/worldgen/feature_region.rs": "df0ff142a461cafa9a3b42b949ad3376887f2be8d4ea5cc794a3ed2e977bb499",
"crates/horizon-world/src/worldgen/feature_sort.rs": "3488a093dfe1321aaa29d8a30cfb115d8e666a81bf195514e87b170de626835c",
"crates/horizon-world/src/worldgen/fluid_predicate.rs": "64197c9e63bebf1ce04bc280bfe980bb6c1b9aa887ca5cded904aeb0d9ae6c46",
"crates/horizon-world/src/worldgen/height_provider.rs": "368d4dc119854742a045c4a717679c921456da681fc5f71aa9b37102d6f33b47",
"crates/horizon-world/src/worldgen/material_condition/codec.rs": "09b909bc384472f76d163c8069ec6b507c7d5c6a028a36d5e0e3df20deff7b3b",
"crates/horizon-world/src/worldgen/material_condition/density.rs": "df9d0761e978e5010663ae8b44f2d6c1ecb4907331e333bdb6a2b487c1e107de",
"crates/horizon-world/src/worldgen/material_condition/library.rs": "a55534c5da97575a819af5a7dc0dbec9069993fa8b2619c6c9d5576946e683fa",
"crates/horizon-world/src/worldgen/material_condition/noise.rs": "ffb59cc6be2275d7a5621bf7d768527e74a8326ed7ad78618746711540921675",
"crates/horizon-world/src/worldgen/material_condition/rule.rs": "fed643352efbcb1f68f29b6241896617db889fc7c577a6247564e01922fec1fe",
"crates/horizon-world/src/worldgen/material_condition.rs": "d638dcb8cbcb5da20b3cb29602b0ae6a86c4fdf9d8c0fb725de8ec5fc108717e",
"crates/horizon-world/src/worldgen/material_extensions.rs": "ab806eb679d5116e1aebb64fca70e1499ae71f83c9507a8cb4c3201c2b1bf037",
"crates/horizon-world/src/worldgen/material_stage.rs": "698cbc786eff13c246e2bc2ea062401918cd4265899fbc3d53abc87e45a8e7a1",
"crates/horizon-world/src/worldgen/material_surface.rs": "5d37b90099df3d6da0845dab164e71469fb287019c2ee74bc6714f3b9d6d6d5b",
"crates/horizon-world/src/worldgen/ore_feature.rs": "83b89fd3be691c5412c0215b6abefdcaa44119a05aa41217e061970eb7e12ebd",
"crates/horizon-world/src/worldgen/placement/chain.rs": "9218399b4d3757f7bbc550d7729a7201f32a1c83a7030865e0c12aab8a80d116",
"crates/horizon-world/src/worldgen/placement/context.rs": "a278304795136677ad4b4933ea50c972b9729a1c671c03fa309c193e224b1fd6",
"crates/horizon-world/src/worldgen/placement/layer.rs": "a0f5ca776f33f9d4f72b8fdcd163426152e5e43cb4a7572fc1d4fc57bf965de1",
"crates/horizon-world/src/worldgen/placement.rs": "b0397e5818fae84358546193a95f84bcb0b5bffafce909e6fcb3386179ee8023",
"crates/horizon-world/src/worldgen/replace_blobs.rs": "bf3377d86d2570cd15288ba69dde64a2cf67c5bcbb9a31d0c23421964af74afa",
"crates/horizon-world/src/worldgen/router.rs": "2cee7cf15a0d2ada12be6b39d83e78177fd3033922e4f4cce87a64073cec2847",
"crates/horizon-world/src/worldgen/rule_test.rs": "d1662ec492489ebaa4b87e20f9a8c809dcf3a223a151211bd65ec241a63692fc",
"crates/horizon-world/src/worldgen/settings.rs": "a8fe87752e1982ef11cb67f8d80d8e3428b2c27db178044cb425ba803e689e59",
"crates/horizon-world/src/worldgen/simple_block.rs": "9ba1a88d5db4925f8c37366557887f776c805f9a6444781615b5dbaff52e92a4",
"crates/horizon-world/src/worldgen/snow_freeze.rs": "9040be3d5c7f8f0fd812d2df45e154bf8a9eeef038530b83fa4159d246eac35f",
"crates/horizon-world/src/worldgen/speleothem.rs": "c71651c1c97818a8a85863e14414d6139ea3bdeb897fa422043bcc1499d99aae",
"crates/horizon-world/src/worldgen/spike.rs": "eacf0d9d3d2bc3d4bcf62bc87555f90031138236a5bfef0eb5270204f7c2a4fc",
"crates/horizon-world/src/worldgen/spring.rs": "830849e9b89fcdf09e9b06fbefdcdebe3c8c3f82804f60b8bd5de04ba303cb62",
"crates/horizon-world/src/worldgen/state_provider/catalog.rs": "c8687e15a4887a9200c8d365857d801efaa8f90e669eee3e600a1db4905119eb",
"crates/horizon-world/src/worldgen/state_provider/noise.rs": "7ee369c2a032e5620cb9bdf9ee7adad1f70870fb0a27efb7b7c514d92f83491f",
"crates/horizon-world/src/worldgen/state_provider/properties.rs": "9909139aaca1dc4f743957257fadaa9d423d21fa401fa9abc050505f79365139",
"crates/horizon-world/src/worldgen/state_provider.rs": "be29ada818826a90afe01ab60916360fdfc4cbde5af15c9359cd56b1f1f7b156",
"crates/horizon-world/src/worldgen/tags.rs": "74e4110fb19c4c4047192fd65c38015b8afc7f9fc50404d75380b5063808148c",
"crates/horizon-world/src/worldgen/terrain.rs": "fd1f2e0afc15daf66f484ea40a1f2b7013650bda0941b23c64c81ee9f79cb673",
"crates/horizon-world/src/worldgen/underwater_magma.rs": "7317e40af5ee5a9780f90ce358fa5d3e7f5b3d513b731df6ff97754d9c2a0154",
"crates/horizon-world/src/worldgen/value_provider.rs": "3358b563db8cb0bc8a9cfbbe2b8b3e70941cd2d37a0b519fbb6545f8d0dcbb69",
"crates/horizon-world/src/worldgen/vines.rs": "ee9b79b65012bd86a838241d2ef708680f7fe8eafc8aa656dae9cf2abf3c6418",
"crates/horizon-world/src/worldgen/weighted.rs": "839840aae25302933bbd97a81a2336330e2d03a0ad1684e1e16ac769ed408e6b",
"crates/horizon-world/src/worldgen/write_zone.rs": "8e17a179764d3f68c05882aef35f6810c28a0000f9a83e58bd6030660b76e64e",
"crates/horizon-world/src/worldgen.rs": "e8e9f099ee1fcec8eedce31805d676d3f89c18e84f494a147ffcbfee23d3d54f"
}
}
@@ -1,807 +0,0 @@
{
"adapter": {
"backend": "Vulkan",
"device": 0,
"device_type": "Cpu",
"name": "llvmpipe (LLVM 21.1.8, 256 bits)",
"vendor": 65541
},
"animated_sprites": 1,
"animation_uploads": 1,
"arch": "x86_64",
"camera_pitch": -0.3839724354387525,
"camera_position": [
25.0,
18.0,
25.0
],
"camera_yaw": -2.356194490192345,
"collision_camera": false,
"culled_model_faces": 59636,
"elapsed_seconds": 0.545908777,
"error": null,
"fall_damage_requests": 0,
"last_requested_fall_damage": null,
"merged_quads": 3169,
"mesh_revision": 0,
"model_blocks": 10919,
"model_gallery": [
{
"block": "minecraft:oak_stairs",
"models": [
{
"model": "minecraft:block/oak_stairs_inner",
"rotations": [
2,
3,
0
],
"uv_lock": true
}
],
"position": [
-7,
4,
14
],
"properties": {
"facing": "north",
"half": "top",
"shape": "inner_left",
"waterlogged": "false"
},
"state_id": 5466
},
{
"block": "minecraft:stone_slab",
"models": [
{
"model": "minecraft:block/stone_slab_top",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
-3,
4,
14
],
"properties": {
"type": "top",
"waterlogged": "false"
},
"state_id": 15250
},
{
"block": "minecraft:anvil",
"models": [
{
"model": "minecraft:block/anvil",
"rotations": [
0,
3,
0
],
"uv_lock": false
}
],
"position": [
1,
4,
14
],
"properties": {
"facing": "east"
},
"state_id": 12965
},
{
"block": "minecraft:torch",
"models": [
{
"model": "minecraft:block/torch",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
14
],
"properties": {},
"state_id": 4926
},
{
"block": "minecraft:lantern",
"models": [
{
"model": "minecraft:block/lantern",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
-7,
4,
18
],
"properties": {
"hanging": "false",
"waterlogged": "false"
},
"state_id": 24197
},
{
"block": "minecraft:oak_fence",
"models": [
{
"model": "minecraft:block/oak_fence_post",
"rotations": [
0,
0,
0
],
"uv_lock": false
},
{
"model": "minecraft:block/oak_fence_side",
"rotations": [
0,
0,
0
],
"uv_lock": true
},
{
"model": "minecraft:block/oak_fence_side",
"rotations": [
0,
1,
0
],
"uv_lock": true
}
],
"position": [
-3,
4,
18
],
"properties": {
"east": "true",
"north": "true",
"south": "false",
"waterlogged": "false",
"west": "false"
},
"state_id": 8642
},
{
"block": "minecraft:oak_fence_gate",
"models": [
{
"model": "minecraft:block/oak_fence_gate_open",
"rotations": [
0,
1,
0
],
"uv_lock": true
}
],
"position": [
1,
4,
18
],
"properties": {
"facing": "west",
"in_wall": "false",
"open": "true",
"powered": "false"
},
"state_id": 10401
},
{
"block": "minecraft:iron_bars",
"models": [
{
"model": "minecraft:block/iron_bars_post_ends",
"rotations": [
0,
0,
0
],
"uv_lock": false
},
{
"model": "minecraft:block/iron_bars_side",
"rotations": [
0,
0,
0
],
"uv_lock": false
},
{
"model": "minecraft:block/iron_bars_side_alt",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
18
],
"properties": {
"east": "false",
"north": "true",
"south": "true",
"waterlogged": "false",
"west": "false"
},
"state_id": 9711
},
{
"block": "minecraft:cobweb",
"models": [
{
"model": "minecraft:block/cobweb",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
-7,
4,
22
],
"properties": {},
"state_id": 2362
},
{
"block": "minecraft:grindstone",
"models": [
{
"model": "minecraft:block/grindstone",
"rotations": [
1,
3,
0
],
"uv_lock": false
}
],
"position": [
-3,
4,
22
],
"properties": {
"face": "wall",
"facing": "west"
},
"state_id": 24135
},
{
"block": "minecraft:ladder",
"models": [
{
"model": "minecraft:block/ladder",
"rotations": [
0,
3,
0
],
"uv_lock": false
}
],
"position": [
1,
4,
22
],
"properties": {
"facing": "west",
"waterlogged": "false"
},
"state_id": 7312
},
{
"block": "minecraft:amethyst_cluster",
"models": [
{
"model": "minecraft:block/amethyst_cluster",
"rotations": [
1,
1,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
22
],
"properties": {
"facing": "east",
"waterlogged": "false"
},
"state_id": 26764
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone",
"rotations": [
0,
2,
0
],
"uv_lock": false
}
],
"position": [
-7,
4,
26
],
"properties": {},
"state_id": 1
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone_mirrored",
"rotations": [
0,
2,
0
],
"uv_lock": false
}
],
"position": [
-3,
4,
26
],
"properties": {},
"state_id": 1
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone",
"rotations": [
0,
0,
0
],
"uv_lock": false
}
],
"position": [
1,
4,
26
],
"properties": {},
"state_id": 1
},
{
"block": "minecraft:stone",
"models": [
{
"model": "minecraft:block/stone",
"rotations": [
0,
2,
0
],
"uv_lock": false
}
],
"position": [
5,
4,
26
],
"properties": {},
"state_id": 1
}
],
"model_quads": 179,
"movement_ticks": 0,
"os": "linux",
"player_absorption": null,
"player_dead": null,
"player_exhaustion": null,
"player_fall_distance": null,
"player_food": null,
"player_food_timer": null,
"player_health": null,
"player_hurt_cooldown": null,
"player_on_ground": null,
"player_position": null,
"player_saturation": null,
"player_sprint_trigger": null,
"player_sprinting": null,
"player_velocity": null,
"presented_frames": 30,
"project": "Horizon",
"resident_chunks": 9,
"schema": 1,
"scope": "Native resident-scene renderer with inspection camera and optional fixed-rate dry walking test; full gameplay remains unfinished",
"sprint_distance_cm": 0,
"sprint_ticks": 0,
"sprite_layers": 18,
"visible_model_faces": 5991,
"walk_distance_cm": 0,
"walking": false,
"window_size": [
1280,
720
],
"world_revision": 0,
"native_scene_culling": {
"blocks": 10919,
"culled_faces": 59636,
"visible_faces": 5991
},
"native_selection": {
"matched_placements": 16,
"selected_parts": 20,
"client_jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "a2ff1c890d6f3a5292c3a9402f02ca5404a993dc117853b25cbe64ac92b76d30",
"scope": "Actual native registry states, blockstate dispatch, tagged root baking and legacy collection using state.getSeed(position). All 16 featured placements match model names/transforms. An independently constructed native scene also matches total occupied blocks and visible/culled model faces using native parent resolution, rotated culling directions and Block.shouldRenderFace. No shader/pixel parity claim."
},
"resource_files": {
"files": 5590,
"sha256": "62f859d4d21b82158ab73e26cfa4973d58ab5926ab63d71c70c7a4d173502b7b"
},
"executable_sha256": "632eb61d13b3274d5c991f2f2daffd56891abf472b99085cf04f9237b5f21f28",
"resource_manifest_sha256": "92a51de578be0e7c37d21e94caa3f22503f7d88b73827a5fce109b1b889e5d18",
"sources": {
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "6884c7209f007ab9ee742b9c3c73828cfa1c6753d35b5fe25a87cab5955b33f8",
"tools/test_native_client.py": "6c615fed67fd7bcf09b3184216e08a82012049880a0d4da7c89f86553090cbda",
"crates/horizon-client/Cargo.toml": "d56524457d761c2613c0699b20e21ad6977d93e009d59ef150bbd9fc20d7a025",
"crates/horizon-assets/Cargo.toml": "2f2cffacec0b4e22dd7cb032d594289bc51c94ae6cc4e985fee3e310f441d751",
"crates/horizon-client/src/assets.rs": "e595afa610e0425d0b3ad694218794bf9e680e46ae80f3925c278ef1a823c914",
"crates/horizon-client/src/camera.rs": "d386a56ca8fb3b37ba2b2ed9d09342f61b409a575bb21590e934120b4ccebfa6",
"crates/horizon-client/src/clock.rs": "4851ada3e8e65d935eda8c0b57d3b51233b34f74aab4f040fd53db0e0d40b8df",
"crates/horizon-client/src/collisions.rs": "112286b07c4cd11b36da8b6799e0e069e69dfddf9a8a3f9ce36dcb282c791d67",
"crates/horizon-client/src/health.rs": "b5e2d3cde4bd58d906e6f6d47cd756ed23aa6706c71b10c3aedde30c11806403",
"crates/horizon-client/src/hunger.rs": "01d8a35f570f2a0991ac17a078f2066a5a83037a728158585765723d208b4611",
"crates/horizon-client/src/input.rs": "55b259ca6425c502270e7abc4d3ae1b3838633e2bd77d3817c6e00d9143a2beb",
"crates/horizon-client/src/landing.rs": "b9d0ecc5ec60a09d75ab9fe778e0a2e5bbb36fd8364a7ce996405f3dc9cb3b9f",
"crates/horizon-client/src/lib.rs": "d34c467ee87b869c6645052f286305e218c80ba258603317e9d951f1b4c5345d",
"crates/horizon-client/src/main.rs": "14a459150f8dcc0a9bda2d91138e7e232d1e33e7b5f15fa17af8228653cbca2a",
"crates/horizon-client/src/mesh.rs": "4ac8d85b30f599b37a98b92adcc016b16434816b93c401bd39b8215f591f9330",
"crates/horizon-client/src/models/catalog.rs": "620103719167fc9ab76e730d68eeacb50014e95b7ad209ae7adf2cbbe69f70f7",
"crates/horizon-client/src/models/cube.rs": "1067229f9dd9b276950bf7ec0c5f67061ce3d40a21932dca8034b9748e7439a4",
"crates/horizon-client/src/models.rs": "98dd3b969947c2b297862a934e6235067ddc1fc8cda5adcc6276d19014d4b048",
"crates/horizon-client/src/motion.rs": "1949f35da0e65ee71c52f53a2faf22601fbbb43387fbd411d6c9281b2221bc42",
"crates/horizon-client/src/render.rs": "75cb40c257cf61e51009d292a06cd96532f59320b12ed7c3a509bbdbe1accdd4",
"crates/horizon-client/src/sprint.rs": "6f5ba5ea8e9a19872b26c1d7b5073e29549f2d820a0fe46e5450c9e7446e98b2",
"crates/horizon-client/src/sprites.rs": "292f844a31f6e8884008df9630e2b8862db1acfbc4640cc07d526e25f21f0bc5",
"crates/horizon-client/src/world.rs": "0333ecf3e18ccc63117295feb2cf77661462ba13feb293eeec667c12811423b5",
"crates/horizon-client/src/world.wgsl": "972a58ccb34e9965515adbb30c47a93fceca5b742390db6d9f69cba1ec31f559",
"crates/horizon-assets/src/animation.rs": "ebbf7952146a0e66b41396174492f5702627170b03a57e6cd5a45c97a08c975e",
"crates/horizon-assets/src/bake/transform.rs": "a95e658fef85b21bcb2f9f7512f98f98d57022d62c1199885b7133beae35a09d",
"crates/horizon-assets/src/bake.rs": "f55dda6b6cee5ac6e65a8ee4837fdd2c6674437d59e59b4c45718f6324d4a4d5",
"crates/horizon-assets/src/blockstate/bind.rs": "6278962e55c9786bba8184bdf2939af9c6e3b9002b08c3022129964b49a60009",
"crates/horizon-assets/src/blockstate/choice.rs": "5a66c8b9833e2f19dd8b0773f3593d97ff5941d3c5b773896b98049efa1395ba",
"crates/horizon-assets/src/blockstate.rs": "a4299dfd7adaeb4173982ffaa8e9c9eda2925739ae579a714193c99da2e7ce56",
"crates/horizon-assets/src/json.rs": "99fe8af4fbf5d4eed408a92e829ac1a39597a0d92471a6bff73771fad9c830a8",
"crates/horizon-assets/src/lib.rs": "e39f21c59a2c3e1c53d977b29bd5e0638e5fc41d86ff0fcc1882a6d90fd961e4",
"crates/horizon-assets/src/model.rs": "57ddb3d65e88e7a8aa22c62bc298a2dae7f4e994326a873a31f06c0f36ed051b",
"crates/horizon-assets/src/resolve.rs": "3927ac926cdcbd7d334901cc32d0ecc1e498b1bec98f76a46bca6d4964c13541",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaGallerySelectionOracle.java": "dc5433f1ce1de629b30cb70f031a43a691fc1df1fb218ce23de89769c164d562",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCuboidModelOracle.java": "7526f20513c549483122ab0d5ad24b9e87f38dc2f6aae55addd701a91ac85e43",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaHeightmapOracle.java": "145c943637ed177cc4ef8a85f2484da8afd164868e84a8463882feec1653a860",
"tools/test_model_baking_parity.py": "392ffec44918fb91740ca4a1316d684480d39f14bd34d46175f7f44946d15bd7",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"tools/prepare_native_client.py": "159c12846058954a35ce86d415dc12fc89a6f11d46d21d1616ee686b7af4eee4",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"crates/horizon-core/src/bin/density_parity.rs": "e5b1dd33b7d01306c73cf072629b4fb186e9ab87b672a00108999d1a72263fd0",
"crates/horizon-core/src/bin/float_log_parity.rs": "4a655fcf8822ee7668c4bd126bc84d0b118864a6fc7f5a6aeee667d8bf2590b1",
"crates/horizon-core/src/bin/geometry_parity.rs": "27f6c09fe5018ac3de8e70e0f0bbf78f9abb14f5e4783bcaf46e8ca87b9c6f8a",
"crates/horizon-core/src/bin/noise_parity.rs": "c135bfc708d853e7061e81487d2cfe10de64b2f65677d3b4837cbfe0b8341010",
"crates/horizon-core/src/bin/parity.rs": "f35d928c66f958de39fac5e7e836a657eed95f83599e84899f7ea7a5802ba481",
"crates/horizon-core/src/bin/tick_parity.rs": "a54c164fe4814034d369947a887f5273966f5a878ba849204b80d1c729526a8f",
"crates/horizon-core/src/biome/seed_hash.rs": "5afbb4921c750826b395a08bf06f382fc7f01b5759a93de02a2749c523e2a317",
"crates/horizon-core/src/biome.rs": "908efa8cd4aa0a7adf1cb5e1a222e3dfb640eed5e9172e0fe7f0d1287afae7e8",
"crates/horizon-core/src/carving/ellipsoid.rs": "09232a7588610e8a9176fd9c62d40afb1fb89f2ecab6d555536a1d847b142d86",
"crates/horizon-core/src/carving.rs": "0aa3093caa0437868a8c0ed52a6c6e1993bd51c03583c670a2837e749eae5426",
"crates/horizon-core/src/density/arithmetic.rs": "372faec96c923e2cf4aa6c66c1ac398e676853274557823850dbc8933dd15ab1",
"crates/horizon-core/src/density/beardifier.rs": "bb1052e27dae4a01954ca78d7d5babafef85f3b2c704ccaf1920cb85a098cb50",
"crates/horizon-core/src/density/cache.rs": "38d0b6c9dd04ffef979fdad3f29cfebf98d331c8c9d430be5f39aa34f6c30975",
"crates/horizon-core/src/density/end_islands.rs": "168b9384237bd2e41d0ae5a74e944da4dc74e493bdec31fb73184c9a49e3de55",
"crates/horizon-core/src/density/graph/compiler.rs": "ac67deeb16f16d0859aa20e5a165811a29aca0b910037ee6bf5098211f3a6ede",
"crates/horizon-core/src/density/graph/mod.rs": "b776e7da934cb03051a3053d56d461c71e9978e084922fe4194147aa580c07bf",
"crates/horizon-core/src/density/graph/seeded.rs": "6bcdcaa3dffcfa9df673bbbea35120057a16ba3d2b506c52709c36cf8976b74a",
"crates/horizon-core/src/density/graph/tests.rs": "6bfb8cbff462587dd147b0775ea01d370abbd97544b9bd596c792df1b5f7e634",
"crates/horizon-core/src/density/interpolation.rs": "8c890f52b6467f38a94c654986a6a484b8e0b296ab98c398e60a6ce465b5b010",
"crates/horizon-core/src/density/interval.rs": "b42629163baa6b599a233afe8596d1c370cd81d015cc6fc36a9663aa47b98424",
"crates/horizon-core/src/density/mod.rs": "ca0d77d3282e3746ddcbc92bee97dbf640b9a56214e6ac1537f51f9a5b63d6e7",
"crates/horizon-core/src/density/power.rs": "d5b7270a128d4264268cd772109ad16d71a8ec3ff2d3b63b84cb985296d54a91",
"crates/horizon-core/src/density/rounding.rs": "71840c5206ff8d218ac29bf6f66915d5212764ba270c675711a866ba5b55a7a6",
"crates/horizon-core/src/density/selection.rs": "0dd26af2e85004ec5e053039ad11c384c17c56ace9ab45eb3f5cb3503c0b0330",
"crates/horizon-core/src/density/slice.rs": "5d77605573c0deda47778f1f78f7fa3fbf1944d8f5efbcc65cf589181cadf80b",
"crates/horizon-core/src/density/spline.rs": "6bb2e40f940fc6544d6fb09cb0b8cac722be03bc663dbdfb0f61faae207400bc",
"crates/horizon-core/src/density/surface.rs": "159e0e69cda74f870e80ea64fe523c4397e64af4ccb861bb9fd07b2c3cb91b00",
"crates/horizon-core/src/density/terrain_noise.rs": "8d0059d25eb5d248cb97a4c5a2e670d61528928ea151495c004f25adb723fe3e",
"crates/horizon-core/src/density/tests.rs": "7817796ee40d0ae241bfbebec6bca190e0a8e7d5a1caa8ddf858c3eaa58b8858",
"crates/horizon-core/src/density/world_fields.rs": "c1ce305cb8046b384d90c564cafb24af7365d580389637910f3d8b0cc18eb583",
"crates/horizon-core/src/geometry/border.rs": "1386f8080521231d05ba3e84d94a3e1d5218d35ccb3d5e9fe2bbb05a8739e573",
"crates/horizon-core/src/geometry/mod.rs": "c650386f9860e44a96c55f18c8f1428ca715fcb0bc5c2434db5b1caa43df27fe",
"crates/horizon-core/src/geometry/movement.rs": "bcfb452752940ce53ae6dc267a3c4eb29459046a063c1f884684ab4f4bd0068f",
"crates/horizon-core/src/geometry/shape/create.rs": "189812b91d5e0e3ad963afcd1a6e2831b31b8188df91a904ef27061e644806ad",
"crates/horizon-core/src/geometry/shape/face.rs": "f243bce81384040a95ce7984b02b5699206c596c537b2713097e86005b4d3a5c",
"crates/horizon-core/src/geometry/shape/join.rs": "f1b51887b7bf9482557e3ffa99e136f2e5db07ceeb05fdb116adf45e87129075",
"crates/horizon-core/src/geometry/shape.rs": "e8d88a763de1525f77a30b99591641e8a8b80946263acbde035a9bcc356df960",
"crates/horizon-core/src/geometry/sweep.rs": "abd6009c61555161ef2f18b431b2aa384b126c0871cae8b96a62358498a56a1d",
"crates/horizon-core/src/geometry/traversal.rs": "77a3da570a0b85582b669cf4d841cba4b06327006dda26d4a26df4e8ce05bae4",
"crates/horizon-core/src/geometry/trig.rs": "05cef9341a298a474221a0556a11ddf47650393ea7a97b4b2022a4da6628fe37",
"crates/horizon-core/src/lib.rs": "4255e16837fde42a52ba118f60581d197c571bb530b60d635e506184ebf4db0b",
"crates/horizon-core/src/noise/mod.rs": "1dab5a713abf702402e69ace1bf9e476bba544b0ede5a61c3c3afc60af0a03f3",
"crates/horizon-core/src/noise/normal.rs": "e9e7a46472a54a02c98c46da819842090567153b32fe0c84249009ef19af7aad",
"crates/horizon-core/src/noise/perlin.rs": "e73815447432eab7542f67366cb3f1b368d164e33f6c9cdbd045ac8e4db0932a",
"crates/horizon-core/src/noise/simplex.rs": "6c0dbc15b2b7510195dd28fceca01dcaac1847ccc4a84d299c351589c642fe7a",
"crates/horizon-core/src/noise/stack.rs": "7f6ef0e7d920139ef1a6ad3ec5640f92765715f86dcc5ec29f1a149984f45fa3",
"crates/horizon-core/src/noise/volume.rs": "3f05d2b1780acfdfee60037677d309937a5033b45ef428fc2d540942d4b56b43",
"crates/horizon-core/src/position/iter.rs": "32d2d8e74821cc4e49e3354202d35d3120e4415bfdda9375a73f2137ef651129",
"crates/horizon-core/src/position.rs": "e10101088e6902386b9b6d27773d44312f1ff72bebb19e57967a54945dde9dcd",
"crates/horizon-core/src/random/hash.rs": "0f88a127a1ba2705d3d6c0ebd009324d6ba86ffa2d27edf2d2a84765e690e4a3",
"crates/horizon-core/src/random/positional.rs": "35494745e5d4cf89e282c3ae0ee245e9f2640ddbbc03bc0055df742006a9c862",
"crates/horizon-core/src/random/worldgen.rs": "9f07ff33bcc038d34e27aa5465753bb21df18f2975e43cae201f709bc186945a",
"crates/horizon-core/src/random.rs": "ddb95d3a83e28ad605ff1f49f5df270cc543ca5ef1130e37d989dc74c8d861e6",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/src/text.rs": "e6553ddb5db5039e8dc4614b6a6dc9f35a26dc3d1673b68a04e72e7983b67abb",
"crates/horizon-core/src/ticks/generation.rs": "be1237e790693f633a61714ddae68c6506a777588a8a3ab5efbe53a35774dbd2",
"crates/horizon-core/src/ticks/heap.rs": "bf28afab8af77c3d243aa96cd8a1fb8d934140a4dbd07dbfdbf4e7908bb4b845",
"crates/horizon-core/src/ticks/index.rs": "1f1a6a568c2a30eafecb020ca4d5f5fc414860de85b8b381fc419a2e3e65c24a",
"crates/horizon-core/src/ticks/mod.rs": "01634630668172516b8b79d0907bad47f6e2c543a6d499c2fa4b201823b375cb",
"crates/horizon-world/Cargo.toml": "18bbad377a8047e4d4ecd0fc87d83d46d1c0f1ce2b8c47bbe64633e7b4420b57",
"crates/horizon-world/src/active_effect_tick.rs": "88f19cfc3532c47a58c646bb3e9d99ff239a900752302b6a444dda3013e95cbf",
"crates/horizon-world/src/active_effects.rs": "daaf352a69511a7d69fb329997f783b86585e486e0379c84ab0a55641771646c",
"crates/horizon-world/src/attribute_health.rs": "1420a80787d10dd2e2954a3ee6193ff313289d00c7c78ca26ece8bafa21f4380",
"crates/horizon-world/src/attribute_map.rs": "3d871cd530f5c035e0753f3ba065c2b9c5b49cdee75d4119f7dd584b22af67e6",
"crates/horizon-world/src/attribute_updates.rs": "4cb322d75a50d222298994607097ba7f7e6674021128fa02a98a74c057ad05f1",
"crates/horizon-world/src/attributes/entity.rs": "64ac99682a3aa06b1fb94b776b47794234c76b1cf70f1f54933d51e545e69279",
"crates/horizon-world/src/attributes/live.rs": "8198c45134f69135d48ef203e71b6e702529568fd1ed9174d0aa843570bbf9e7",
"crates/horizon-world/src/attributes/mod.rs": "5c2fcbbde58c19261874d227ea98332f00336c9fa53446da2e9adb6aa64a5e5a",
"crates/horizon-world/src/attributes/operation_map.rs": "fc5bc8921d78ea6721a2eaa915e67483e2a33683927467bdba24f0492356ad97",
"crates/horizon-world/src/bin/worldgen_parity.rs": "3143ceb9b56eecfd7667e5feb5f9f0cd13cfb8754b38d4ea338dbba97f2819da",
"crates/horizon-world/src/block_collision.rs": "39207247f2f6dd3ddc77640229044246f91b32054563f88a435f1bd92ad2092c",
"crates/horizon-world/src/block_collision_scan.rs": "20802862364c110ff85eeaf48606596a8468b83768dda46b412d337958790b41",
"crates/horizon-world/src/block_entities.rs": "a9deae92e6e5a1fcf4f0476c33ea4d170ddad6fd4b3303e1bb66d933973d5e06",
"crates/horizon-world/src/block_entity_push.rs": "12ee91bf604946234b24a0da4333f07d1830ab9743a422d41c8d0afac7d49cfd",
"crates/horizon-world/src/block_landing.rs": "33083fe39266fbefec1b3ea1a19f2afc609791d189da247c895e116ad6eb266a",
"crates/horizon-world/src/block_placement.rs": "524f4892d50bab77b7d89d19f7b048ffe746996f2ed7f376db2c6ab00ed75c24",
"crates/horizon-world/src/block_properties.rs": "b0bd8a983336c48e488a20caa77dd5c39b1a74bbd14ebc03b3b64556a1c864fc",
"crates/horizon-world/src/block_render.rs": "8df52ee11aef406a1571198a64048062a0ef6864e0058d9293a57f64b73c916a",
"crates/horizon-world/src/block_support.rs": "ade4fbd47284b450dabdd682dc86138b2ac05a0fd379525d7110648908245476",
"crates/horizon-world/src/block_survival.rs": "28ce64375e09819a4f13da9cfbe37c08b5ad0daf01b289c1c360b4567e50e811",
"crates/horizon-world/src/blocking_item_damage.rs": "afea3cb5761e8b82ee4d9bb4ef3c6fd10182a324dbaec99e6c9ebfac255dda09",
"crates/horizon-world/src/blocking_rules.rs": "83c5e2105cec56a90182ce582e1c67ade2b189be6de1a34d08035000cc07c492",
"crates/horizon-world/src/bundle_weight.rs": "a0e7b0587ab5d46cd55588f25d55a088b7a4725099c13ba6df146957be36014c",
"crates/horizon-world/src/chunk.rs": "795895284d6e615bcb2082fceacdfe7025c152fb2934bb43f598f17a00ab46f1",
"crates/horizon-world/src/chunk_status.rs": "dbb8583cfa775203c544d24d69e03720385428f15a267a561356c21f5025e9c7",
"crates/horizon-world/src/climbing.rs": "6cd2f919872ff0b726effddaa57eccb805b8eae43f9d01144716010853891879",
"crates/horizon-world/src/collision.rs": "a749794d5c27ccd6c0d964ad02f9dc31d49d9f4fe4b7366cd4bd8155e681b00b",
"crates/horizon-world/src/collision_context.rs": "2176c7034e07f547510a8327cdad9d3b63f26e4754032b76b7d5fe13166c333c",
"crates/horizon-world/src/combat_rules.rs": "01131f70d1acdd96a910e7f96deaa12e51a1e3bb9208085f04e3ec7b657d3cd4",
"crates/horizon-world/src/component_durability.rs": "37a46e184f95bc5027e2b9af72ff52f729ad03601d08e1827f181fca383a35af",
"crates/horizon-world/src/component_patch.rs": "f6f8992f241dfb25e012a06a7ba3fecab8d958686dddd096595a4806e56f0ab3",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/consumable.rs": "ba3575cb85866cb940f33a1ac86455d71cf0cc6395b848588a8ee1fe33f5c326",
"crates/horizon-world/src/consume_effect.rs": "03f2aac6879ce133347d42f6f6667d62c06d956ff9faac5dc14182a788b6a236",
"crates/horizon-world/src/damage_immunity.rs": "fd39c41124d694e755cf7faadcf93c636df4042c78ec345092a856b5f952dbcf",
"crates/horizon-world/src/damage_reduction.rs": "f5a599ab11e077f526237018aeda803ea3c420c5b35c78ae9d85e32267e23bf3",
"crates/horizon-world/src/damage_source.rs": "24945e397a926d34695652980923609e4723e02fe6b6e56d4aaf673e45d759f7",
"crates/horizon-world/src/dynamic_support.rs": "5996bc1c436fb6215d8fc3d0bb4de5dd9b966d842d432580d624195771697fb8",
"crates/horizon-world/src/edge_backoff.rs": "5259d7aa44e64f88351d1556c44dd0edcad3b400a099c659755792efba7b5773",
"crates/horizon-world/src/effect_attribute_modifiers.rs": "0bc7ab63d0f3f34a7133fe20364cae0ec1fdbd3773cba90faa1f08e0d63a5646",
"crates/horizon-world/src/effect_notifications.rs": "ea66bfa010d6d44aee97b9672902f41cd99d0d80239f41c6d4eae5c9a9472d3d",
"crates/horizon-world/src/effect_particles.rs": "a42dc4ec55929dce1db0f22f8816ecf7621fdce1cd2ac0c90f6a57fea4e0afd2",
"crates/horizon-world/src/effect_sync.rs": "1388d4a69b42a14ff4cd474f5e36f0fad5a2874031e64fa2b19b2ea179deed2b",
"crates/horizon-world/src/entity_collision.rs": "09f2fd7f6cd56fc282f468ecfa765a94506929e9684bd3a5c90123e5b51cd627",
"crates/horizon-world/src/entity_fluid.rs": "02991040ae879a8914f09913128a3506e9e7a1ca33ffc0a22b5729a168346600",
"crates/horizon-world/src/entity_fluid_tick.rs": "4f9e070b88a73c98a4e2e659360ddd6edee636bca29377f1ea9011fd5a556f64",
"crates/horizon-world/src/entity_move.rs": "a40a50d3e841625a75d4cfbb7c2630ab5a62a574456567e7234f401ae8441b32",
"crates/horizon-world/src/entity_obstruction.rs": "a4b28a19bf83b23611c59d94535c488db37e4aee24b22c973c545910894a809f",
"crates/horizon-world/src/extra_items.rs": "6eba0a0c795d5fd841d31471708e78324b4852adebb2e6ed700dcc0caab668cd",
"crates/horizon-world/src/fall_damage.rs": "8c28e2933493569fe05dea22332024287d28b0746b514dd465681040b003296b",
"crates/horizon-world/src/fluid.rs": "a0a1f34ba94d8b59dc975becee8952960764d67ae08cf2d6a8bcd40a614b15c4",
"crates/horizon-world/src/fluid_box.rs": "b586af72b1c04a9354fe66205c28dc8b619e205ab9ea19a68232722e4b6e96c1",
"crates/horizon-world/src/fluid_flow.rs": "7c7e486b5c565df3602799648b37b879bcca51414337f607962d6c7951b86d05",
"crates/horizon-world/src/fluid_occupancy.rs": "26037579caeef6c8a5a2bde2c3d142d278558b76d77ebff401cee6e35f2ea961",
"crates/horizon-world/src/fluid_shape.rs": "28bb65a72f5bd074a354ba38a1b1707fcb0947537977a11540bba0adb85995c2",
"crates/horizon-world/src/food.rs": "3cf416fa632a5555a8116bb528a6e80bcb5b6b754b0748b4959ed310102418d3",
"crates/horizon-world/src/food_properties.rs": "0926fa3f3bc3d0608c45d02f564355825ca3c3526a82bf9c1375c7a191fa5e12",
"crates/horizon-world/src/food_storage.rs": "58c433801a285efcc973638c11d694a41f85dc96703a3a7ce8d3673f3eb31d52",
"crates/horizon-world/src/free_space.rs": "913536bf4c85ddeeb378d76d1b5110b4175f5688e1a749f32fe6a6d86fbb478e",
"crates/horizon-world/src/ground_support.rs": "3e371d74ecede4d30beef0a7e8a2ee33463584a5b1ed3d852b394efcce1ffbe0",
"crates/horizon-world/src/heightmap.rs": "a5edef082b5af40d814421ea17e129b3b06d70abee6434ed263e4bba58571698",
"crates/horizon-world/src/identifier.rs": "37c921889c4f5d91f7c09ab2ee68d1a5e5a3c4fb1c49b4b189c987b4615fd2d6",
"crates/horizon-world/src/interaction_shapes.rs": "f321284ddab440a394372b6dedc8b5cc29a653c0745251a9e96c650f21c33dea",
"crates/horizon-world/src/inventory_pickup.rs": "ea830c7916e7f2d95c6db7ef48be1e876e6ebafcb438e47fc72f9a5bd7c37d07",
"crates/horizon-world/src/inventory_tick.rs": "293a3d57a1689337cfd58e5a73dcdbed4cb360f94d98ff5458f0df92de387365",
"crates/horizon-world/src/inventory_use.rs": "6a6c2ecc73c83dda4cd798c0304df12ace6096eb110d899f4f0c7ffd852bf001",
"crates/horizon-world/src/item_after_use.rs": "2b6598ce5b7b304dea2c8057b4a1eb6530264ac4d0546c3da0c76deed9609da5",
"crates/horizon-world/src/item_blocking.rs": "f6eee0d6d177cc3148960122327ba1b459a2f0e85241c1d9a3e40f0b8c169296",
"crates/horizon-world/src/item_cooldowns.rs": "7b625868509ab3c51e72db0ac714bb0e7ec5e2610d37271005a1a737f4d14431",
"crates/horizon-world/src/item_durability.rs": "9fdf835e5c7bd0e1dd63ef2ba0076b770cdd4d6d14cdcd11de27690f0702f94e",
"crates/horizon-world/src/item_particles.rs": "861b14f65adb9b14f8158fe9f0b7128beac3df8107b1337c31b8b9b49434ba3f",
"crates/horizon-world/src/item_stack_refs.rs": "18d3ca85cac0daf59200857513761359e5690f719cb3f7f64ae552f0c4169ea3",
"crates/horizon-world/src/item_stack_storage.rs": "b4dcb83dcaa346848c5484161feb3e2cf08e83f7793d7ed83be25b14b9d12884",
"crates/horizon-world/src/item_template.rs": "dc80025215d1867e656924ea2a9d273aacbcaea21293d986ba42d0004ee93b69",
"crates/horizon-world/src/item_use.rs": "b1c79428986efbf9dd5ede703a39eb387fb6dcc7d9950f0e49243a353a5b8070",
"crates/horizon-world/src/item_use_catalog.rs": "a9b53d2e816583239a75c3c61e78dacc5e3b27dee595be34b1c7fa169f17a571",
"crates/horizon-world/src/item_use_lifecycle.rs": "4639b70440cf811e79de09c48a3e035143fcb6be8a64c2f61b10ae55a2f133b7",
"crates/horizon-world/src/item_use_start.rs": "a84092dfb8b8f0a89d0928bb2f8ac252bd9bfd3f8d74fce1a7f7a5b3c3f4f50b",
"crates/horizon-world/src/java_hash_map.rs": "955502e696d7b0b33bae3ec485c8eb1453a8956116aad68226cf1fc67d60babc",
"crates/horizon-world/src/lib.rs": "e25b3543c07f31c2a9d23d811792de9a33290263c7c7445549a0682f6935d8a5",
"crates/horizon-world/src/liquid_collision.rs": "0f0a83b04e5a5bc9d98ed05fde4d6584ba69642e93522e726e4cfc325d6fcb1d",
"crates/horizon-world/src/live_attribute_updates.rs": "778171faaaf7077deb0b62c4cc1db16351eba41adb8bb07656ba65e827056199",
"crates/horizon-world/src/living_air.rs": "b2de36bb50bed15e2808fe4a874fcef07f9fea0d2c96385b7b5e8ee9560d4442",
"crates/horizon-world/src/living_damage.rs": "2b448209629b9bf2e678d667ad0d6c7fa22146892dd106b169d96b31b0df12bb",
"crates/horizon-world/src/living_fall.rs": "da0f176f4731e1c86e08bfeee8167742fd1b86380ff0e9304c13c1ce3f1c67ab",
"crates/horizon-world/src/living_fluid.rs": "d7cd914cfb2a1f4876ce0ae95e999bf0ff1af732cce3ab4a3aa2d1ab881c7339",
"crates/horizon-world/src/living_health.rs": "221659f85552424e937d503bba6d8003006b106ced042b32d3a6f6cc23e12ed0",
"crates/horizon-world/src/living_hurt.rs": "844239ad7d15c39629bb3cfc06ebae6d1cff20b7627468f26e0ee8dff3abdcb8",
"crates/horizon-world/src/living_landing.rs": "8bca4eb7977abc2b14fb7174be4ea355352106ea1e76ff5f3ad8696969d9eefd",
"crates/horizon-world/src/living_motion.rs": "56f8c84cfbe205a7a69912d5f76b52ef1efca149c1b6801d4684e25fb179aeb9",
"crates/horizon-world/src/living_use_flags.rs": "826f4fdeba7e208368cbbf910fa408db0afbc6442d842d178a70fae53e0d0ea6",
"crates/horizon-world/src/main.rs": "fce57418b8c22a6a0a9044baa89ed3d9c243bc2e8413fea3ff0f32985daba021",
"crates/horizon-world/src/movement_emission.rs": "76e7d6f5b19c94676190f54389f9c4ce12cf89945ccfcb9c750de473223e7753",
"crates/horizon-world/src/movement_properties.rs": "6f01ab920b376a13f5ae12c3718f4dd067e1dff2b829585af00a8b2100f3775d",
"crates/horizon-world/src/movement_restitution.rs": "04b4fe0947e7e52576145bd8ed15920278e8a538afcc74d125eaca513dffa0ef",
"crates/horizon-world/src/movement_statistics.rs": "fe28061e29c41f8f399d29cce8c468a63854613702b5aa525c0f0fd98cb87f9a",
"crates/horizon-world/src/movement_support.rs": "02d85cf572847f2e60b5a7f9d60b856888a67b3c1f4df03e81998c66fdf874be",
"crates/horizon-world/src/nbt.rs": "60262c3de8c8f68bc2da0370ccb17393d32b85f5f5022c6358599a7d32119ea6",
"crates/horizon-world/src/object_open_map.rs": "b4934a9cc38df93ed206ab0bc3bbc4499acd8e40b41b7def7d47067b7170065b",
"crates/horizon-world/src/object_open_set.rs": "d3e0373bf1b652dd054345d5a8e25ec828e06dd7cad65aada35163c95df4e637",
"crates/horizon-world/src/piston_movement.rs": "7a3fd2549a582b5f3a5c21aa05d67d944d62ca1105856679e100ac5b44e9a52f",
"crates/horizon-world/src/piston_shape.rs": "399c2337103b8e7e0eb5667227c5aa14f9549d6a467b7be7da3d0717f0263500",
"crates/horizon-world/src/player_equipment.rs": "1fa8c53e67624c4641246249d79a800a28a4858c62482bd880b4e3b866b936ef",
"crates/horizon-world/src/player_food.rs": "f188dc110745bcc7acc15e6c521db943b06b404f69cd251bf74a345516070304",
"crates/horizon-world/src/player_health.rs": "8155b315453c569db2fbe46228886c5881d1fd55eb095c5849e69bdb500ba2bd",
"crates/horizon-world/src/player_hurt.rs": "99c9bbd8587ec2dc287806049897b8034d2f5349ad47fc497b70d54148844a36",
"crates/horizon-world/src/player_inventory.rs": "f4f67d8312793f25930626c4ac06db688fcf2e2292d6675071d105fb1708d952",
"crates/horizon-world/src/player_travel.rs": "6841a677a900495eb6223031ef3ebe8d859bb98908dda0e2209e5f28839dc593",
"crates/horizon-world/src/powder_snow_collision.rs": "7289946a21478d11abfd2bdcdddff3d7f98e25bf6a68564fed45c3cc01ac2a36",
"crates/horizon-world/src/region.rs": "72b642e87fed37ed17f54d4c30f96c3b64d26c14bc0589c31ef40ff1616188fc",
"crates/horizon-world/src/registry/json.rs": "7a683afcd1742c5307756927d7f0aa779c7d7992af87d8d371dd98108728e235",
"crates/horizon-world/src/registry.rs": "f2e58b2b4d944ac8fc6226bd3352cefc3d2052d8473e02ccf7dc402b176df435",
"crates/horizon-world/src/registry_collision_scan.rs": "97cc950a9a4ba387b78e368f36d595f8664ab7730d132900d220ce23b92826ea",
"crates/horizon-world/src/registry_fall_ray.rs": "52935436132df505691144840dcbd858b15d00d8305997284e3a542ecf6bc0dc",
"crates/horizon-world/src/registry_fluid.rs": "b8959c05850cfeaaad1e4de8ca7c7d0d6ac56da9b2c1de3ebefa5871a11ed35e",
"crates/horizon-world/src/retrogen.rs": "6efd36a6293756688c1990a7965bd65609d7c5e2bf2a5f4f01d54932d2b9386b",
"crates/horizon-world/src/server_player_combat.rs": "0a94885c4b7a0d294ba7f4cee18b96ee59649b50112988250b53cc224059a979",
"crates/horizon-world/src/server_player_damage.rs": "29af22dec321fe01776cee5334f050c5bc3e27a688f99c8c3da4c0ad8bc8254e",
"crates/horizon-world/src/simple_container.rs": "0fedbc7e974b1db79b88bd6aff977654189a5d553cf42852fe8bf0885cf90b30",
"crates/horizon-world/src/status_effect.rs": "588bfcf4d93f50be86cb89545bd5c431edbc71771f704ff55cb52906b1964c37",
"crates/horizon-world/src/stored_consume.rs": "621a52c9fba447c393e561f881a16cf1f97d336e3a0ce493725ef51e2db12ffd",
"crates/horizon-world/src/stored_effect_attributes.rs": "c79f6a52d3cfee1a5288225bf8fa91a7bf3ea8cd21faea9f6dc748ecefc6309a",
"crates/horizon-world/src/suffocation.rs": "bed219dd5bbab6263b98fbe3d0eb512cb96c52ae847210efe49514d05f22f11e",
"crates/horizon-world/src/swimming.rs": "49d2dae13c109b37ff832cde98a857944ff45247b864a527b9c4f03ecca7a7b7",
"crates/horizon-world/src/synced_floats.rs": "0152f2752bafaf68769d56dbc88494a976496a680c6b113d6b48a446158ba072",
"crates/horizon-world/src/synced_values.rs": "a1d4b53ae77d1899ba2b4ead67c9ec1e3c96615558e446f9d0760c1b4a520169",
"crates/horizon-world/src/teleport_consume.rs": "d6a53bbb6ac4dbbd4c0591d0646017898a95beb8ef093dc5d81b9833963be6c3",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/use_remainder.rs": "f555335afeca7970888131a6da2f5a614a73253b631185d1ba804593a349535e",
"crates/horizon-world/src/view_direction.rs": "e18120ae26dc5cf702b29fc4c8487088bab133c8ce5abce01226833fafb0d5a4",
"crates/horizon-world/src/water_splash.rs": "e0461ae1b2e8c851cca6e3251a188334293292201d7f80dc9e7d60fd1815f4d1",
"crates/horizon-world/src/world_movement.rs": "f8fe9e34f2395d2a04c839d1c8ba78e09ce493c26de6f6e4e237b9c19c061da5",
"crates/horizon-world/src/world_ray.rs": "879bdbbe12f56deb705cc183933431489e840b71eade40c33391eed5949c2e61",
"crates/horizon-world/src/worldgen/anchor.rs": "d156b8a0b147a274cdd143409b441f4f43edecde6e8ee14ef9cf0309f743143a",
"crates/horizon-world/src/worldgen/aquifer/config.rs": "fcd2cc3a520c1527c88f095a3b5d38487e7ebb1ccecc5f757f93d04a069add4f",
"crates/horizon-world/src/worldgen/aquifer/noise_based.rs": "74daaa389b5c3dfdc99214dfff256a9e172f83548d2326cbc941d9637cc53fb7",
"crates/horizon-world/src/worldgen/aquifer.rs": "cb4b66d87de3f9f79ae6ffe4badd6f0f44886cd42ad9de2771b8b56c4f1e28c7",
"crates/horizon-world/src/worldgen/bamboo.rs": "d9b47113c99be34256e58308bc6f40072ff25c579d6bf995182aa862c0006102",
"crates/horizon-world/src/worldgen/biome.rs": "3fe316b875aa32683759c337dc71f624910faf0812a2d6d83b8098d6d0bac7a0",
"crates/horizon-world/src/worldgen/biome_chunk.rs": "8fdfe6ebe3ffeca97611fd5991a5bc6b2783ea1c62f4d8ef3b2dd53c04a5dc1d",
"crates/horizon-world/src/worldgen/biome_predicate.rs": "bfc581bc40077cc74ffda43e990a55fe997adc04c7130f98e039c3305ca79aac",
"crates/horizon-world/src/worldgen/biome_source/codec.rs": "2b9e4f5d679eb444cb73174f511e3b9f32e9eb138248ab12cffc6cfd76adf3a8",
"crates/horizon-world/src/worldgen/biome_source/runtime.rs": "f0b02c1521178e4d0377c6ca62694604b6a773f1f234f070ff0cde4685911d45",
"crates/horizon-world/src/worldgen/biome_source.rs": "e181e1736f3e0b75f7091a24c88de3fd116e01b98424d02382aea7a503d1eb54",
"crates/horizon-world/src/worldgen/biome_temperature.rs": "cde4bbab5e260c4065b113376c423b8511ade93c5aa5fd976e245ee8a58b5ad1",
"crates/horizon-world/src/worldgen/biome_weather.rs": "96b1f9494559ed31d06257b83d604d00cc069ccc8c7b68094117e034b4a71bd7",
"crates/horizon-world/src/worldgen/block_blob.rs": "c608c57b3d77279646ecb89e50677dd8e452b0422ffd357ba755536c5589eb89",
"crates/horizon-world/src/worldgen/block_column.rs": "f72c21a9066ee0aa68c2fb79fba436d05afb14c6ef5a2cb012f1ed35fc17cd22",
"crates/horizon-world/src/worldgen/block_feature.rs": "36b4e46ee7f7f73bcb94d8bce8d99013e4b16234c9a03542eeb3186e88dd1c21",
"crates/horizon-world/src/worldgen/block_pile.rs": "623e369b77e0526ed2756485a6c0bb09683cd28ad8876dea907360ca6665b39d",
"crates/horizon-world/src/worldgen/block_predicate.rs": "074c692367e3f2191a1bb28d87b23402430a843c246bd30a4ea838ee3500280e",
"crates/horizon-world/src/worldgen/blue_ice.rs": "eedd77bdaff808330b864166d303378096daa5c7d235e925770b171c05109247",
"crates/horizon-world/src/worldgen/bonus_chest.rs": "05d0f63fbc7412f13ba1fa37a7238114b8f70bfff318beb2dece590482d49cc0",
"crates/horizon-world/src/worldgen/bulk_section.rs": "eecf61532d7793f853884c5a18a7f436a59835c7b13d3ec9075804511553c9ba",
"crates/horizon-world/src/worldgen/carver/canyon.rs": "509c4d5a9d689849e98e894ab14a9fbf82d10707d38e9cc688ded3c4778df3e2",
"crates/horizon-world/src/worldgen/carver/generation.rs": "a4498d0d1457536de3922a08e9c40ccce8d2ef9cc263801c15a412327513c098",
"crates/horizon-world/src/worldgen/carver.rs": "46b251e28225fe1250de38f49dec5dacda4e2c4ba1e556e21e6d1e14e2651fc3",
"crates/horizon-world/src/worldgen/carving.rs": "4e77d4e5c4a0ca55ca3563b9bdf6f379342e0bdf9d019d60f7bc57ce4afb5fbd",
"crates/horizon-world/src/worldgen/chorus_plant.rs": "29224c164ede919e280a65a68f155c873e2c8fd0aa7d7e244d8fa9e468760250",
"crates/horizon-world/src/worldgen/climate/codec.rs": "d567adeb5d837816fca69102db51d790f71aec1b51c09298230d24612e400a14",
"crates/horizon-world/src/worldgen/climate/index.rs": "c5ce61679a5f0e0f2f0af2a373424effa124d0cce8250609eff38b7034650756",
"crates/horizon-world/src/worldgen/climate.rs": "1b9ad44407f40aee4c1cd5357a5c9c443c1b105728f01cf5c644072f99f8357e",
"crates/horizon-world/src/worldgen/decoration.rs": "75a79b20b21e133816e729f16e758be6165d0db18a64bfbd5fd3618325a2adf3",
"crates/horizon-world/src/worldgen/delta.rs": "c2bf49ddf3231d28c109e68871429bc13d76a7bebe14eb33e84aa856bdd66145",
"crates/horizon-world/src/worldgen/density.rs": "65a98c156a290a6b374ef670d28cd5dfbe0aa93171824d1bbd96422536273f84",
"crates/horizon-world/src/worldgen/disk.rs": "6f8f9e059755af44c9bfa1b91eba54a7d13fad811dce31717c5502d7f6df33d7",
"crates/horizon-world/src/worldgen/end_gateway.rs": "f53fde77d6a36a525cd15d890003b2c129d0689a4cbfa2cf443a0c2e3acae040",
"crates/horizon-world/src/worldgen/end_podium.rs": "8f6d0d6d60ff0fde63de5781e867239db321f82cf12639f0537d410a3731ee1d",
"crates/horizon-world/src/worldgen/feature.rs": "40500af71ee6628dfb27518262d99f08d0383ae6c7b9397452feef0c213eadd9",
"crates/horizon-world/src/worldgen/feature_catalog.rs": "efc7b17b227e71622ef34108be9abd010f5675b68ea0409fcab82581d9aab88a",
"crates/horizon-world/src/worldgen/feature_graph.rs": "da132fca9fdafb0d89a917d5f4b68c60b70fb33cadf948a107da0e35d83dcd91",
"crates/horizon-world/src/worldgen/feature_region.rs": "df0ff142a461cafa9a3b42b949ad3376887f2be8d4ea5cc794a3ed2e977bb499",
"crates/horizon-world/src/worldgen/feature_sort.rs": "3488a093dfe1321aaa29d8a30cfb115d8e666a81bf195514e87b170de626835c",
"crates/horizon-world/src/worldgen/fluid_predicate.rs": "64197c9e63bebf1ce04bc280bfe980bb6c1b9aa887ca5cded904aeb0d9ae6c46",
"crates/horizon-world/src/worldgen/height_provider.rs": "368d4dc119854742a045c4a717679c921456da681fc5f71aa9b37102d6f33b47",
"crates/horizon-world/src/worldgen/material_condition/codec.rs": "09b909bc384472f76d163c8069ec6b507c7d5c6a028a36d5e0e3df20deff7b3b",
"crates/horizon-world/src/worldgen/material_condition/density.rs": "df9d0761e978e5010663ae8b44f2d6c1ecb4907331e333bdb6a2b487c1e107de",
"crates/horizon-world/src/worldgen/material_condition/library.rs": "a55534c5da97575a819af5a7dc0dbec9069993fa8b2619c6c9d5576946e683fa",
"crates/horizon-world/src/worldgen/material_condition/noise.rs": "ffb59cc6be2275d7a5621bf7d768527e74a8326ed7ad78618746711540921675",
"crates/horizon-world/src/worldgen/material_condition/rule.rs": "fed643352efbcb1f68f29b6241896617db889fc7c577a6247564e01922fec1fe",
"crates/horizon-world/src/worldgen/material_condition.rs": "d638dcb8cbcb5da20b3cb29602b0ae6a86c4fdf9d8c0fb725de8ec5fc108717e",
"crates/horizon-world/src/worldgen/material_extensions.rs": "ab806eb679d5116e1aebb64fca70e1499ae71f83c9507a8cb4c3201c2b1bf037",
"crates/horizon-world/src/worldgen/material_stage.rs": "698cbc786eff13c246e2bc2ea062401918cd4265899fbc3d53abc87e45a8e7a1",
"crates/horizon-world/src/worldgen/material_surface.rs": "5d37b90099df3d6da0845dab164e71469fb287019c2ee74bc6714f3b9d6d6d5b",
"crates/horizon-world/src/worldgen/ore_feature.rs": "83b89fd3be691c5412c0215b6abefdcaa44119a05aa41217e061970eb7e12ebd",
"crates/horizon-world/src/worldgen/placement/chain.rs": "9218399b4d3757f7bbc550d7729a7201f32a1c83a7030865e0c12aab8a80d116",
"crates/horizon-world/src/worldgen/placement/context.rs": "a278304795136677ad4b4933ea50c972b9729a1c671c03fa309c193e224b1fd6",
"crates/horizon-world/src/worldgen/placement/layer.rs": "a0f5ca776f33f9d4f72b8fdcd163426152e5e43cb4a7572fc1d4fc57bf965de1",
"crates/horizon-world/src/worldgen/placement.rs": "b0397e5818fae84358546193a95f84bcb0b5bffafce909e6fcb3386179ee8023",
"crates/horizon-world/src/worldgen/replace_blobs.rs": "bf3377d86d2570cd15288ba69dde64a2cf67c5bcbb9a31d0c23421964af74afa",
"crates/horizon-world/src/worldgen/router.rs": "2cee7cf15a0d2ada12be6b39d83e78177fd3033922e4f4cce87a64073cec2847",
"crates/horizon-world/src/worldgen/rule_test.rs": "d1662ec492489ebaa4b87e20f9a8c809dcf3a223a151211bd65ec241a63692fc",
"crates/horizon-world/src/worldgen/settings.rs": "a8fe87752e1982ef11cb67f8d80d8e3428b2c27db178044cb425ba803e689e59",
"crates/horizon-world/src/worldgen/simple_block.rs": "9ba1a88d5db4925f8c37366557887f776c805f9a6444781615b5dbaff52e92a4",
"crates/horizon-world/src/worldgen/snow_freeze.rs": "9040be3d5c7f8f0fd812d2df45e154bf8a9eeef038530b83fa4159d246eac35f",
"crates/horizon-world/src/worldgen/speleothem.rs": "c71651c1c97818a8a85863e14414d6139ea3bdeb897fa422043bcc1499d99aae",
"crates/horizon-world/src/worldgen/spike.rs": "eacf0d9d3d2bc3d4bcf62bc87555f90031138236a5bfef0eb5270204f7c2a4fc",
"crates/horizon-world/src/worldgen/spring.rs": "830849e9b89fcdf09e9b06fbefdcdebe3c8c3f82804f60b8bd5de04ba303cb62",
"crates/horizon-world/src/worldgen/state_provider/catalog.rs": "c8687e15a4887a9200c8d365857d801efaa8f90e669eee3e600a1db4905119eb",
"crates/horizon-world/src/worldgen/state_provider/noise.rs": "7ee369c2a032e5620cb9bdf9ee7adad1f70870fb0a27efb7b7c514d92f83491f",
"crates/horizon-world/src/worldgen/state_provider/properties.rs": "9909139aaca1dc4f743957257fadaa9d423d21fa401fa9abc050505f79365139",
"crates/horizon-world/src/worldgen/state_provider.rs": "be29ada818826a90afe01ab60916360fdfc4cbde5af15c9359cd56b1f1f7b156",
"crates/horizon-world/src/worldgen/tags.rs": "74e4110fb19c4c4047192fd65c38015b8afc7f9fc50404d75380b5063808148c",
"crates/horizon-world/src/worldgen/terrain.rs": "fd1f2e0afc15daf66f484ea40a1f2b7013650bda0941b23c64c81ee9f79cb673",
"crates/horizon-world/src/worldgen/underwater_magma.rs": "7317e40af5ee5a9780f90ce358fa5d3e7f5b3d513b731df6ff97754d9c2a0154",
"crates/horizon-world/src/worldgen/value_provider.rs": "3358b563db8cb0bc8a9cfbbe2b8b3e70941cd2d37a0b519fbb6545f8d0dcbb69",
"crates/horizon-world/src/worldgen/vines.rs": "ee9b79b65012bd86a838241d2ef708680f7fe8eafc8aa656dae9cf2abf3c6418",
"crates/horizon-world/src/worldgen/weighted.rs": "839840aae25302933bbd97a81a2336330e2d03a0ad1684e1e16ac769ed408e6b",
"crates/horizon-world/src/worldgen/write_zone.rs": "8e17a179764d3f68c05882aef35f6810c28a0000f9a83e58bd6030660b76e64e",
"crates/horizon-world/src/worldgen.rs": "e8e9f099ee1fcec8eedce31805d676d3f89c18e84f494a147ffcbfee23d3d54f"
}
}
@@ -1,203 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"manifest_sha1": "4fe1aa1ef8da1cb95c5bad1fb98890ca56dd8ca3",
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"java": "openjdk 25.0.4.1 2026-08-18",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"fixtures": 8338,
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCollisionContextOracle.java": "b9c34e7f7a7c14001e03373cbbd468a228c5301eb639460b4ce465d14e946113",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaFaceSupportOracle.java": "9ce939a435842867786fed648951bbe77f6ab843f6df09af15f3deb1948c4877",
"tools/test_collision_context_parity.py": "75d6f01e072867d2bd286d2e518e123fcfe055a11ac1705ec99ecec3975cb8d2",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "cb1e87d449114a63edd904c0559d631e8fa9feeb27efd6539aacdcfeae178876",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"crates/horizon-world/Cargo.toml": "977338bf3e654193685b015d383493b9f59ff6f5d6210bec212cef8ac4a50bed",
"crates/horizon-core/src/bin/density_parity.rs": "e5b1dd33b7d01306c73cf072629b4fb186e9ab87b672a00108999d1a72263fd0",
"crates/horizon-core/src/bin/float_log_parity.rs": "4a655fcf8822ee7668c4bd126bc84d0b118864a6fc7f5a6aeee667d8bf2590b1",
"crates/horizon-core/src/bin/geometry_parity.rs": "27f6c09fe5018ac3de8e70e0f0bbf78f9abb14f5e4783bcaf46e8ca87b9c6f8a",
"crates/horizon-core/src/bin/noise_parity.rs": "c135bfc708d853e7061e81487d2cfe10de64b2f65677d3b4837cbfe0b8341010",
"crates/horizon-core/src/bin/parity.rs": "f35d928c66f958de39fac5e7e836a657eed95f83599e84899f7ea7a5802ba481",
"crates/horizon-core/src/bin/tick_parity.rs": "a54c164fe4814034d369947a887f5273966f5a878ba849204b80d1c729526a8f",
"crates/horizon-core/src/biome/seed_hash.rs": "5afbb4921c750826b395a08bf06f382fc7f01b5759a93de02a2749c523e2a317",
"crates/horizon-core/src/biome.rs": "908efa8cd4aa0a7adf1cb5e1a222e3dfb640eed5e9172e0fe7f0d1287afae7e8",
"crates/horizon-core/src/carving/ellipsoid.rs": "09232a7588610e8a9176fd9c62d40afb1fb89f2ecab6d555536a1d847b142d86",
"crates/horizon-core/src/carving.rs": "0aa3093caa0437868a8c0ed52a6c6e1993bd51c03583c670a2837e749eae5426",
"crates/horizon-core/src/density/arithmetic.rs": "372faec96c923e2cf4aa6c66c1ac398e676853274557823850dbc8933dd15ab1",
"crates/horizon-core/src/density/beardifier.rs": "bb1052e27dae4a01954ca78d7d5babafef85f3b2c704ccaf1920cb85a098cb50",
"crates/horizon-core/src/density/cache.rs": "38d0b6c9dd04ffef979fdad3f29cfebf98d331c8c9d430be5f39aa34f6c30975",
"crates/horizon-core/src/density/end_islands.rs": "168b9384237bd2e41d0ae5a74e944da4dc74e493bdec31fb73184c9a49e3de55",
"crates/horizon-core/src/density/graph/compiler.rs": "ac67deeb16f16d0859aa20e5a165811a29aca0b910037ee6bf5098211f3a6ede",
"crates/horizon-core/src/density/graph/mod.rs": "b776e7da934cb03051a3053d56d461c71e9978e084922fe4194147aa580c07bf",
"crates/horizon-core/src/density/graph/seeded.rs": "6bcdcaa3dffcfa9df673bbbea35120057a16ba3d2b506c52709c36cf8976b74a",
"crates/horizon-core/src/density/graph/tests.rs": "6bfb8cbff462587dd147b0775ea01d370abbd97544b9bd596c792df1b5f7e634",
"crates/horizon-core/src/density/interpolation.rs": "8c890f52b6467f38a94c654986a6a484b8e0b296ab98c398e60a6ce465b5b010",
"crates/horizon-core/src/density/interval.rs": "b42629163baa6b599a233afe8596d1c370cd81d015cc6fc36a9663aa47b98424",
"crates/horizon-core/src/density/mod.rs": "ca0d77d3282e3746ddcbc92bee97dbf640b9a56214e6ac1537f51f9a5b63d6e7",
"crates/horizon-core/src/density/power.rs": "d5b7270a128d4264268cd772109ad16d71a8ec3ff2d3b63b84cb985296d54a91",
"crates/horizon-core/src/density/rounding.rs": "71840c5206ff8d218ac29bf6f66915d5212764ba270c675711a866ba5b55a7a6",
"crates/horizon-core/src/density/selection.rs": "0dd26af2e85004ec5e053039ad11c384c17c56ace9ab45eb3f5cb3503c0b0330",
"crates/horizon-core/src/density/slice.rs": "5d77605573c0deda47778f1f78f7fa3fbf1944d8f5efbcc65cf589181cadf80b",
"crates/horizon-core/src/density/spline.rs": "6bb2e40f940fc6544d6fb09cb0b8cac722be03bc663dbdfb0f61faae207400bc",
"crates/horizon-core/src/density/surface.rs": "159e0e69cda74f870e80ea64fe523c4397e64af4ccb861bb9fd07b2c3cb91b00",
"crates/horizon-core/src/density/terrain_noise.rs": "8d0059d25eb5d248cb97a4c5a2e670d61528928ea151495c004f25adb723fe3e",
"crates/horizon-core/src/density/tests.rs": "7817796ee40d0ae241bfbebec6bca190e0a8e7d5a1caa8ddf858c3eaa58b8858",
"crates/horizon-core/src/density/world_fields.rs": "c1ce305cb8046b384d90c564cafb24af7365d580389637910f3d8b0cc18eb583",
"crates/horizon-core/src/geometry/mod.rs": "dc92f73885dd0a7760743bf74f1ab8afa839d61cef2dfef890f8a23b67b4742e",
"crates/horizon-core/src/geometry/movement.rs": "930e34abef6f6eeec1ee7a6c920b5ba01bfe37b90678884490f4be53241f6b96",
"crates/horizon-core/src/geometry/shape/create.rs": "189812b91d5e0e3ad963afcd1a6e2831b31b8188df91a904ef27061e644806ad",
"crates/horizon-core/src/geometry/shape/face.rs": "f243bce81384040a95ce7984b02b5699206c596c537b2713097e86005b4d3a5c",
"crates/horizon-core/src/geometry/shape/join.rs": "f1b51887b7bf9482557e3ffa99e136f2e5db07ceeb05fdb116adf45e87129075",
"crates/horizon-core/src/geometry/shape.rs": "e8d88a763de1525f77a30b99591641e8a8b80946263acbde035a9bcc356df960",
"crates/horizon-core/src/geometry/sweep.rs": "abd6009c61555161ef2f18b431b2aa384b126c0871cae8b96a62358498a56a1d",
"crates/horizon-core/src/geometry/traversal.rs": "77a3da570a0b85582b669cf4d841cba4b06327006dda26d4a26df4e8ce05bae4",
"crates/horizon-core/src/geometry/trig.rs": "05cef9341a298a474221a0556a11ddf47650393ea7a97b4b2022a4da6628fe37",
"crates/horizon-core/src/lib.rs": "4255e16837fde42a52ba118f60581d197c571bb530b60d635e506184ebf4db0b",
"crates/horizon-core/src/noise/mod.rs": "1dab5a713abf702402e69ace1bf9e476bba544b0ede5a61c3c3afc60af0a03f3",
"crates/horizon-core/src/noise/normal.rs": "e9e7a46472a54a02c98c46da819842090567153b32fe0c84249009ef19af7aad",
"crates/horizon-core/src/noise/perlin.rs": "e73815447432eab7542f67366cb3f1b368d164e33f6c9cdbd045ac8e4db0932a",
"crates/horizon-core/src/noise/simplex.rs": "6c0dbc15b2b7510195dd28fceca01dcaac1847ccc4a84d299c351589c642fe7a",
"crates/horizon-core/src/noise/stack.rs": "7f6ef0e7d920139ef1a6ad3ec5640f92765715f86dcc5ec29f1a149984f45fa3",
"crates/horizon-core/src/noise/volume.rs": "3f05d2b1780acfdfee60037677d309937a5033b45ef428fc2d540942d4b56b43",
"crates/horizon-core/src/position/iter.rs": "32d2d8e74821cc4e49e3354202d35d3120e4415bfdda9375a73f2137ef651129",
"crates/horizon-core/src/position.rs": "e10101088e6902386b9b6d27773d44312f1ff72bebb19e57967a54945dde9dcd",
"crates/horizon-core/src/random/hash.rs": "0f88a127a1ba2705d3d6c0ebd009324d6ba86ffa2d27edf2d2a84765e690e4a3",
"crates/horizon-core/src/random/positional.rs": "35494745e5d4cf89e282c3ae0ee245e9f2640ddbbc03bc0055df742006a9c862",
"crates/horizon-core/src/random/worldgen.rs": "9f07ff33bcc038d34e27aa5465753bb21df18f2975e43cae201f709bc186945a",
"crates/horizon-core/src/random.rs": "ddb95d3a83e28ad605ff1f49f5df270cc543ca5ef1130e37d989dc74c8d861e6",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/src/text.rs": "e6553ddb5db5039e8dc4614b6a6dc9f35a26dc3d1673b68a04e72e7983b67abb",
"crates/horizon-core/src/ticks/generation.rs": "be1237e790693f633a61714ddae68c6506a777588a8a3ab5efbe53a35774dbd2",
"crates/horizon-core/src/ticks/heap.rs": "bf28afab8af77c3d243aa96cd8a1fb8d934140a4dbd07dbfdbf4e7908bb4b845",
"crates/horizon-core/src/ticks/index.rs": "1f1a6a568c2a30eafecb020ca4d5f5fc414860de85b8b381fc419a2e3e65c24a",
"crates/horizon-core/src/ticks/mod.rs": "01634630668172516b8b79d0907bad47f6e2c543a6d499c2fa4b201823b375cb",
"crates/horizon-world/src/bin/worldgen_parity.rs": "3143ceb9b56eecfd7667e5feb5f9f0cd13cfb8754b38d4ea338dbba97f2819da",
"crates/horizon-world/src/block_collision.rs": "a40c9d7a4e0a734c124dc856e31359fd4d8de3d1bfc79c86787afa8e8e05e480",
"crates/horizon-world/src/block_entities.rs": "a9deae92e6e5a1fcf4f0476c33ea4d170ddad6fd4b3303e1bb66d933973d5e06",
"crates/horizon-world/src/block_placement.rs": "524f4892d50bab77b7d89d19f7b048ffe746996f2ed7f376db2c6ab00ed75c24",
"crates/horizon-world/src/block_properties.rs": "b0bd8a983336c48e488a20caa77dd5c39b1a74bbd14ebc03b3b64556a1c864fc",
"crates/horizon-world/src/block_render.rs": "8df52ee11aef406a1571198a64048062a0ef6864e0058d9293a57f64b73c916a",
"crates/horizon-world/src/block_support.rs": "ade4fbd47284b450dabdd682dc86138b2ac05a0fd379525d7110648908245476",
"crates/horizon-world/src/block_survival.rs": "28ce64375e09819a4f13da9cfbe37c08b5ad0daf01b289c1c360b4567e50e811",
"crates/horizon-world/src/chunk.rs": "8843e6f48dbbc4245ce4e95564dfba3a4d7a051ba0b1577fb038c07adb0ff0f9",
"crates/horizon-world/src/chunk_status.rs": "dbb8583cfa775203c544d24d69e03720385428f15a267a561356c21f5025e9c7",
"crates/horizon-world/src/collision.rs": "05313e0c1f3089524fe029f9aac3e439cd47f1c9584c8c7e154c9adcfa88c335",
"crates/horizon-world/src/collision_context.rs": "2176c7034e07f547510a8327cdad9d3b63f26e4754032b76b7d5fe13166c333c",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/dynamic_support.rs": "5996bc1c436fb6215d8fc3d0bb4de5dd9b966d842d432580d624195771697fb8",
"crates/horizon-world/src/entity_obstruction.rs": "a4b28a19bf83b23611c59d94535c488db37e4aee24b22c973c545910894a809f",
"crates/horizon-world/src/fluid.rs": "a0a1f34ba94d8b59dc975becee8952960764d67ae08cf2d6a8bcd40a614b15c4",
"crates/horizon-world/src/heightmap.rs": "a5edef082b5af40d814421ea17e129b3b06d70abee6434ed263e4bba58571698",
"crates/horizon-world/src/lib.rs": "f0997b21c8083de75f4f8883e8855e1d2d9f1876a2053a8a97b081deed5b0bcd",
"crates/horizon-world/src/liquid_collision.rs": "0f0a83b04e5a5bc9d98ed05fde4d6584ba69642e93522e726e4cfc325d6fcb1d",
"crates/horizon-world/src/main.rs": "fce57418b8c22a6a0a9044baa89ed3d9c243bc2e8413fea3ff0f32985daba021",
"crates/horizon-world/src/nbt.rs": "60262c3de8c8f68bc2da0370ccb17393d32b85f5f5022c6358599a7d32119ea6",
"crates/horizon-world/src/piston_shape.rs": "399c2337103b8e7e0eb5667227c5aa14f9549d6a467b7be7da3d0717f0263500",
"crates/horizon-world/src/powder_snow_collision.rs": "7289946a21478d11abfd2bdcdddff3d7f98e25bf6a68564fed45c3cc01ac2a36",
"crates/horizon-world/src/region.rs": "72b642e87fed37ed17f54d4c30f96c3b64d26c14bc0589c31ef40ff1616188fc",
"crates/horizon-world/src/registry/json.rs": "7a683afcd1742c5307756927d7f0aa779c7d7992af87d8d371dd98108728e235",
"crates/horizon-world/src/registry.rs": "f2e58b2b4d944ac8fc6226bd3352cefc3d2052d8473e02ccf7dc402b176df435",
"crates/horizon-world/src/retrogen.rs": "6efd36a6293756688c1990a7965bd65609d7c5e2bf2a5f4f01d54932d2b9386b",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/worldgen/anchor.rs": "d156b8a0b147a274cdd143409b441f4f43edecde6e8ee14ef9cf0309f743143a",
"crates/horizon-world/src/worldgen/aquifer/config.rs": "fcd2cc3a520c1527c88f095a3b5d38487e7ebb1ccecc5f757f93d04a069add4f",
"crates/horizon-world/src/worldgen/aquifer/noise_based.rs": "74daaa389b5c3dfdc99214dfff256a9e172f83548d2326cbc941d9637cc53fb7",
"crates/horizon-world/src/worldgen/aquifer.rs": "cb4b66d87de3f9f79ae6ffe4badd6f0f44886cd42ad9de2771b8b56c4f1e28c7",
"crates/horizon-world/src/worldgen/bamboo.rs": "d9b47113c99be34256e58308bc6f40072ff25c579d6bf995182aa862c0006102",
"crates/horizon-world/src/worldgen/biome.rs": "3fe316b875aa32683759c337dc71f624910faf0812a2d6d83b8098d6d0bac7a0",
"crates/horizon-world/src/worldgen/biome_chunk.rs": "8fdfe6ebe3ffeca97611fd5991a5bc6b2783ea1c62f4d8ef3b2dd53c04a5dc1d",
"crates/horizon-world/src/worldgen/biome_predicate.rs": "bfc581bc40077cc74ffda43e990a55fe997adc04c7130f98e039c3305ca79aac",
"crates/horizon-world/src/worldgen/biome_source/codec.rs": "2b9e4f5d679eb444cb73174f511e3b9f32e9eb138248ab12cffc6cfd76adf3a8",
"crates/horizon-world/src/worldgen/biome_source/runtime.rs": "f0b02c1521178e4d0377c6ca62694604b6a773f1f234f070ff0cde4685911d45",
"crates/horizon-world/src/worldgen/biome_source.rs": "e181e1736f3e0b75f7091a24c88de3fd116e01b98424d02382aea7a503d1eb54",
"crates/horizon-world/src/worldgen/biome_temperature.rs": "cde4bbab5e260c4065b113376c423b8511ade93c5aa5fd976e245ee8a58b5ad1",
"crates/horizon-world/src/worldgen/biome_weather.rs": "96b1f9494559ed31d06257b83d604d00cc069ccc8c7b68094117e034b4a71bd7",
"crates/horizon-world/src/worldgen/block_blob.rs": "c608c57b3d77279646ecb89e50677dd8e452b0422ffd357ba755536c5589eb89",
"crates/horizon-world/src/worldgen/block_column.rs": "f72c21a9066ee0aa68c2fb79fba436d05afb14c6ef5a2cb012f1ed35fc17cd22",
"crates/horizon-world/src/worldgen/block_feature.rs": "36b4e46ee7f7f73bcb94d8bce8d99013e4b16234c9a03542eeb3186e88dd1c21",
"crates/horizon-world/src/worldgen/block_pile.rs": "623e369b77e0526ed2756485a6c0bb09683cd28ad8876dea907360ca6665b39d",
"crates/horizon-world/src/worldgen/block_predicate.rs": "074c692367e3f2191a1bb28d87b23402430a843c246bd30a4ea838ee3500280e",
"crates/horizon-world/src/worldgen/blue_ice.rs": "eedd77bdaff808330b864166d303378096daa5c7d235e925770b171c05109247",
"crates/horizon-world/src/worldgen/bonus_chest.rs": "05d0f63fbc7412f13ba1fa37a7238114b8f70bfff318beb2dece590482d49cc0",
"crates/horizon-world/src/worldgen/bulk_section.rs": "eecf61532d7793f853884c5a18a7f436a59835c7b13d3ec9075804511553c9ba",
"crates/horizon-world/src/worldgen/carver/canyon.rs": "509c4d5a9d689849e98e894ab14a9fbf82d10707d38e9cc688ded3c4778df3e2",
"crates/horizon-world/src/worldgen/carver/generation.rs": "a4498d0d1457536de3922a08e9c40ccce8d2ef9cc263801c15a412327513c098",
"crates/horizon-world/src/worldgen/carver.rs": "46b251e28225fe1250de38f49dec5dacda4e2c4ba1e556e21e6d1e14e2651fc3",
"crates/horizon-world/src/worldgen/carving.rs": "4e77d4e5c4a0ca55ca3563b9bdf6f379342e0bdf9d019d60f7bc57ce4afb5fbd",
"crates/horizon-world/src/worldgen/chorus_plant.rs": "29224c164ede919e280a65a68f155c873e2c8fd0aa7d7e244d8fa9e468760250",
"crates/horizon-world/src/worldgen/climate/codec.rs": "d567adeb5d837816fca69102db51d790f71aec1b51c09298230d24612e400a14",
"crates/horizon-world/src/worldgen/climate/index.rs": "c5ce61679a5f0e0f2f0af2a373424effa124d0cce8250609eff38b7034650756",
"crates/horizon-world/src/worldgen/climate.rs": "1b9ad44407f40aee4c1cd5357a5c9c443c1b105728f01cf5c644072f99f8357e",
"crates/horizon-world/src/worldgen/decoration.rs": "75a79b20b21e133816e729f16e758be6165d0db18a64bfbd5fd3618325a2adf3",
"crates/horizon-world/src/worldgen/delta.rs": "c2bf49ddf3231d28c109e68871429bc13d76a7bebe14eb33e84aa856bdd66145",
"crates/horizon-world/src/worldgen/density.rs": "65a98c156a290a6b374ef670d28cd5dfbe0aa93171824d1bbd96422536273f84",
"crates/horizon-world/src/worldgen/disk.rs": "6f8f9e059755af44c9bfa1b91eba54a7d13fad811dce31717c5502d7f6df33d7",
"crates/horizon-world/src/worldgen/end_gateway.rs": "f53fde77d6a36a525cd15d890003b2c129d0689a4cbfa2cf443a0c2e3acae040",
"crates/horizon-world/src/worldgen/end_podium.rs": "8f6d0d6d60ff0fde63de5781e867239db321f82cf12639f0537d410a3731ee1d",
"crates/horizon-world/src/worldgen/feature.rs": "40500af71ee6628dfb27518262d99f08d0383ae6c7b9397452feef0c213eadd9",
"crates/horizon-world/src/worldgen/feature_catalog.rs": "efc7b17b227e71622ef34108be9abd010f5675b68ea0409fcab82581d9aab88a",
"crates/horizon-world/src/worldgen/feature_graph.rs": "da132fca9fdafb0d89a917d5f4b68c60b70fb33cadf948a107da0e35d83dcd91",
"crates/horizon-world/src/worldgen/feature_region.rs": "df0ff142a461cafa9a3b42b949ad3376887f2be8d4ea5cc794a3ed2e977bb499",
"crates/horizon-world/src/worldgen/feature_sort.rs": "3488a093dfe1321aaa29d8a30cfb115d8e666a81bf195514e87b170de626835c",
"crates/horizon-world/src/worldgen/fluid_predicate.rs": "64197c9e63bebf1ce04bc280bfe980bb6c1b9aa887ca5cded904aeb0d9ae6c46",
"crates/horizon-world/src/worldgen/height_provider.rs": "368d4dc119854742a045c4a717679c921456da681fc5f71aa9b37102d6f33b47",
"crates/horizon-world/src/worldgen/material_condition/codec.rs": "09b909bc384472f76d163c8069ec6b507c7d5c6a028a36d5e0e3df20deff7b3b",
"crates/horizon-world/src/worldgen/material_condition/density.rs": "df9d0761e978e5010663ae8b44f2d6c1ecb4907331e333bdb6a2b487c1e107de",
"crates/horizon-world/src/worldgen/material_condition/library.rs": "a55534c5da97575a819af5a7dc0dbec9069993fa8b2619c6c9d5576946e683fa",
"crates/horizon-world/src/worldgen/material_condition/noise.rs": "ffb59cc6be2275d7a5621bf7d768527e74a8326ed7ad78618746711540921675",
"crates/horizon-world/src/worldgen/material_condition/rule.rs": "fed643352efbcb1f68f29b6241896617db889fc7c577a6247564e01922fec1fe",
"crates/horizon-world/src/worldgen/material_condition.rs": "d638dcb8cbcb5da20b3cb29602b0ae6a86c4fdf9d8c0fb725de8ec5fc108717e",
"crates/horizon-world/src/worldgen/material_extensions.rs": "ab806eb679d5116e1aebb64fca70e1499ae71f83c9507a8cb4c3201c2b1bf037",
"crates/horizon-world/src/worldgen/material_stage.rs": "698cbc786eff13c246e2bc2ea062401918cd4265899fbc3d53abc87e45a8e7a1",
"crates/horizon-world/src/worldgen/material_surface.rs": "5d37b90099df3d6da0845dab164e71469fb287019c2ee74bc6714f3b9d6d6d5b",
"crates/horizon-world/src/worldgen/ore_feature.rs": "83b89fd3be691c5412c0215b6abefdcaa44119a05aa41217e061970eb7e12ebd",
"crates/horizon-world/src/worldgen/placement/chain.rs": "9218399b4d3757f7bbc550d7729a7201f32a1c83a7030865e0c12aab8a80d116",
"crates/horizon-world/src/worldgen/placement/context.rs": "a278304795136677ad4b4933ea50c972b9729a1c671c03fa309c193e224b1fd6",
"crates/horizon-world/src/worldgen/placement/layer.rs": "a0f5ca776f33f9d4f72b8fdcd163426152e5e43cb4a7572fc1d4fc57bf965de1",
"crates/horizon-world/src/worldgen/placement.rs": "b0397e5818fae84358546193a95f84bcb0b5bffafce909e6fcb3386179ee8023",
"crates/horizon-world/src/worldgen/replace_blobs.rs": "bf3377d86d2570cd15288ba69dde64a2cf67c5bcbb9a31d0c23421964af74afa",
"crates/horizon-world/src/worldgen/router.rs": "2cee7cf15a0d2ada12be6b39d83e78177fd3033922e4f4cce87a64073cec2847",
"crates/horizon-world/src/worldgen/rule_test.rs": "d1662ec492489ebaa4b87e20f9a8c809dcf3a223a151211bd65ec241a63692fc",
"crates/horizon-world/src/worldgen/settings.rs": "a8fe87752e1982ef11cb67f8d80d8e3428b2c27db178044cb425ba803e689e59",
"crates/horizon-world/src/worldgen/simple_block.rs": "9ba1a88d5db4925f8c37366557887f776c805f9a6444781615b5dbaff52e92a4",
"crates/horizon-world/src/worldgen/snow_freeze.rs": "9040be3d5c7f8f0fd812d2df45e154bf8a9eeef038530b83fa4159d246eac35f",
"crates/horizon-world/src/worldgen/speleothem.rs": "c71651c1c97818a8a85863e14414d6139ea3bdeb897fa422043bcc1499d99aae",
"crates/horizon-world/src/worldgen/spike.rs": "eacf0d9d3d2bc3d4bcf62bc87555f90031138236a5bfef0eb5270204f7c2a4fc",
"crates/horizon-world/src/worldgen/spring.rs": "830849e9b89fcdf09e9b06fbefdcdebe3c8c3f82804f60b8bd5de04ba303cb62",
"crates/horizon-world/src/worldgen/state_provider/catalog.rs": "c8687e15a4887a9200c8d365857d801efaa8f90e669eee3e600a1db4905119eb",
"crates/horizon-world/src/worldgen/state_provider/noise.rs": "7ee369c2a032e5620cb9bdf9ee7adad1f70870fb0a27efb7b7c514d92f83491f",
"crates/horizon-world/src/worldgen/state_provider/properties.rs": "9909139aaca1dc4f743957257fadaa9d423d21fa401fa9abc050505f79365139",
"crates/horizon-world/src/worldgen/state_provider.rs": "be29ada818826a90afe01ab60916360fdfc4cbde5af15c9359cd56b1f1f7b156",
"crates/horizon-world/src/worldgen/tags.rs": "d35ded93fe6e95ea045cadcf4925e656dc34ef832b742179b9ad0cc49f902f31",
"crates/horizon-world/src/worldgen/terrain.rs": "fd1f2e0afc15daf66f484ea40a1f2b7013650bda0941b23c64c81ee9f79cb673",
"crates/horizon-world/src/worldgen/underwater_magma.rs": "7317e40af5ee5a9780f90ce358fa5d3e7f5b3d513b731df6ff97754d9c2a0154",
"crates/horizon-world/src/worldgen/value_provider.rs": "3358b563db8cb0bc8a9cfbbe2b8b3e70941cd2d37a0b519fbb6545f8d0dcbb69",
"crates/horizon-world/src/worldgen/vines.rs": "ee9b79b65012bd86a838241d2ef708680f7fe8eafc8aa656dae9cf2abf3c6418",
"crates/horizon-world/src/worldgen/weighted.rs": "839840aae25302933bbd97a81a2336330e2d03a0ad1684e1e16ac769ed408e6b",
"crates/horizon-world/src/worldgen/write_zone.rs": "8e17a179764d3f68c05882aef35f6810c28a0000f9a83e58bd6030660b76e64e",
"crates/horizon-world/src/worldgen.rs": "e8e9f099ee1fcec8eedce31805d676d3f89c18e84f494a147ffcbfee23d3d54f",
"crates/horizon-world/examples/collision_context_fixture.rs": "b7bf0f48f7dc0129c1ebe43c11cb4cad00194b501c2bcbb3220bc8779e695ba4"
},
"fixtures_sha256": {
".local/rust-collision-context-parity/inputs.txt": "60b49e91a7a4999cfb8eb6ac3fbc6ec0a931d68cd53f9737959a2bd2b42be7a5"
},
"rust_output_sha256": "7b23eb34c86c3db5a9e90bdd8ef772b79b2a06c8460542e032589f7962fd8f64",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "7b23eb34c86c3db5a9e90bdd8ef772b79b2a06c8460542e032589f7962fd8f64",
"matched_output_lines": 225126
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "7b23eb34c86c3db5a9e90bdd8ef772b79b2a06c8460542e032589f7962fd8f64",
"matched_output_lines": 225126
}
],
"scope": "Actual CollisionContext factories and EntityCollisionContext/Empty/PositionCollisionContext queries on controlled player and marker snapshots. Checks entity identity, captured descending and placement flags, fluid collision flags, empty-stack AIR identity, height thresholds including f32 epsilon, null factories, callback arguments/order/failures and all five fluid type pairs. Entity lifecycle, inventory mutations after capture, experimental minecart contexts, contextual block shape dispatch and live movement integration remain pending."
}
@@ -1,205 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"manifest_sha1": "4fe1aa1ef8da1cb95c5bad1fb98890ca56dd8ca3",
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"java": "openjdk 25.0.4.1 2026-08-18",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"fixtures": 58344,
"block_states": 32,
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCollisionContextOracle.java": "b9c34e7f7a7c14001e03373cbbd468a228c5301eb639460b4ce465d14e946113",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaFaceSupportOracle.java": "9ce939a435842867786fed648951bbe77f6ab843f6df09af15f3deb1948c4877",
"tools/test_collision_context_parity.py": "75d6f01e072867d2bd286d2e518e123fcfe055a11ac1705ec99ecec3975cb8d2",
"tools/test_liquid_collision_parity.py": "dd77dfef7d3a66e81d92b66680d9626b6d69c54fc742bf5122674f05342fe788",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "cb1e87d449114a63edd904c0559d631e8fa9feeb27efd6539aacdcfeae178876",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"crates/horizon-world/Cargo.toml": "977338bf3e654193685b015d383493b9f59ff6f5d6210bec212cef8ac4a50bed",
"crates/horizon-core/src/bin/density_parity.rs": "e5b1dd33b7d01306c73cf072629b4fb186e9ab87b672a00108999d1a72263fd0",
"crates/horizon-core/src/bin/float_log_parity.rs": "4a655fcf8822ee7668c4bd126bc84d0b118864a6fc7f5a6aeee667d8bf2590b1",
"crates/horizon-core/src/bin/geometry_parity.rs": "27f6c09fe5018ac3de8e70e0f0bbf78f9abb14f5e4783bcaf46e8ca87b9c6f8a",
"crates/horizon-core/src/bin/noise_parity.rs": "c135bfc708d853e7061e81487d2cfe10de64b2f65677d3b4837cbfe0b8341010",
"crates/horizon-core/src/bin/parity.rs": "f35d928c66f958de39fac5e7e836a657eed95f83599e84899f7ea7a5802ba481",
"crates/horizon-core/src/bin/tick_parity.rs": "a54c164fe4814034d369947a887f5273966f5a878ba849204b80d1c729526a8f",
"crates/horizon-core/src/biome/seed_hash.rs": "5afbb4921c750826b395a08bf06f382fc7f01b5759a93de02a2749c523e2a317",
"crates/horizon-core/src/biome.rs": "908efa8cd4aa0a7adf1cb5e1a222e3dfb640eed5e9172e0fe7f0d1287afae7e8",
"crates/horizon-core/src/carving/ellipsoid.rs": "09232a7588610e8a9176fd9c62d40afb1fb89f2ecab6d555536a1d847b142d86",
"crates/horizon-core/src/carving.rs": "0aa3093caa0437868a8c0ed52a6c6e1993bd51c03583c670a2837e749eae5426",
"crates/horizon-core/src/density/arithmetic.rs": "372faec96c923e2cf4aa6c66c1ac398e676853274557823850dbc8933dd15ab1",
"crates/horizon-core/src/density/beardifier.rs": "bb1052e27dae4a01954ca78d7d5babafef85f3b2c704ccaf1920cb85a098cb50",
"crates/horizon-core/src/density/cache.rs": "38d0b6c9dd04ffef979fdad3f29cfebf98d331c8c9d430be5f39aa34f6c30975",
"crates/horizon-core/src/density/end_islands.rs": "168b9384237bd2e41d0ae5a74e944da4dc74e493bdec31fb73184c9a49e3de55",
"crates/horizon-core/src/density/graph/compiler.rs": "ac67deeb16f16d0859aa20e5a165811a29aca0b910037ee6bf5098211f3a6ede",
"crates/horizon-core/src/density/graph/mod.rs": "b776e7da934cb03051a3053d56d461c71e9978e084922fe4194147aa580c07bf",
"crates/horizon-core/src/density/graph/seeded.rs": "6bcdcaa3dffcfa9df673bbbea35120057a16ba3d2b506c52709c36cf8976b74a",
"crates/horizon-core/src/density/graph/tests.rs": "6bfb8cbff462587dd147b0775ea01d370abbd97544b9bd596c792df1b5f7e634",
"crates/horizon-core/src/density/interpolation.rs": "8c890f52b6467f38a94c654986a6a484b8e0b296ab98c398e60a6ce465b5b010",
"crates/horizon-core/src/density/interval.rs": "b42629163baa6b599a233afe8596d1c370cd81d015cc6fc36a9663aa47b98424",
"crates/horizon-core/src/density/mod.rs": "ca0d77d3282e3746ddcbc92bee97dbf640b9a56214e6ac1537f51f9a5b63d6e7",
"crates/horizon-core/src/density/power.rs": "d5b7270a128d4264268cd772109ad16d71a8ec3ff2d3b63b84cb985296d54a91",
"crates/horizon-core/src/density/rounding.rs": "71840c5206ff8d218ac29bf6f66915d5212764ba270c675711a866ba5b55a7a6",
"crates/horizon-core/src/density/selection.rs": "0dd26af2e85004ec5e053039ad11c384c17c56ace9ab45eb3f5cb3503c0b0330",
"crates/horizon-core/src/density/slice.rs": "5d77605573c0deda47778f1f78f7fa3fbf1944d8f5efbcc65cf589181cadf80b",
"crates/horizon-core/src/density/spline.rs": "6bb2e40f940fc6544d6fb09cb0b8cac722be03bc663dbdfb0f61faae207400bc",
"crates/horizon-core/src/density/surface.rs": "159e0e69cda74f870e80ea64fe523c4397e64af4ccb861bb9fd07b2c3cb91b00",
"crates/horizon-core/src/density/terrain_noise.rs": "8d0059d25eb5d248cb97a4c5a2e670d61528928ea151495c004f25adb723fe3e",
"crates/horizon-core/src/density/tests.rs": "7817796ee40d0ae241bfbebec6bca190e0a8e7d5a1caa8ddf858c3eaa58b8858",
"crates/horizon-core/src/density/world_fields.rs": "c1ce305cb8046b384d90c564cafb24af7365d580389637910f3d8b0cc18eb583",
"crates/horizon-core/src/geometry/mod.rs": "dc92f73885dd0a7760743bf74f1ab8afa839d61cef2dfef890f8a23b67b4742e",
"crates/horizon-core/src/geometry/movement.rs": "930e34abef6f6eeec1ee7a6c920b5ba01bfe37b90678884490f4be53241f6b96",
"crates/horizon-core/src/geometry/shape/create.rs": "189812b91d5e0e3ad963afcd1a6e2831b31b8188df91a904ef27061e644806ad",
"crates/horizon-core/src/geometry/shape/face.rs": "f243bce81384040a95ce7984b02b5699206c596c537b2713097e86005b4d3a5c",
"crates/horizon-core/src/geometry/shape/join.rs": "f1b51887b7bf9482557e3ffa99e136f2e5db07ceeb05fdb116adf45e87129075",
"crates/horizon-core/src/geometry/shape.rs": "e8d88a763de1525f77a30b99591641e8a8b80946263acbde035a9bcc356df960",
"crates/horizon-core/src/geometry/sweep.rs": "abd6009c61555161ef2f18b431b2aa384b126c0871cae8b96a62358498a56a1d",
"crates/horizon-core/src/geometry/traversal.rs": "77a3da570a0b85582b669cf4d841cba4b06327006dda26d4a26df4e8ce05bae4",
"crates/horizon-core/src/geometry/trig.rs": "05cef9341a298a474221a0556a11ddf47650393ea7a97b4b2022a4da6628fe37",
"crates/horizon-core/src/lib.rs": "4255e16837fde42a52ba118f60581d197c571bb530b60d635e506184ebf4db0b",
"crates/horizon-core/src/noise/mod.rs": "1dab5a713abf702402e69ace1bf9e476bba544b0ede5a61c3c3afc60af0a03f3",
"crates/horizon-core/src/noise/normal.rs": "e9e7a46472a54a02c98c46da819842090567153b32fe0c84249009ef19af7aad",
"crates/horizon-core/src/noise/perlin.rs": "e73815447432eab7542f67366cb3f1b368d164e33f6c9cdbd045ac8e4db0932a",
"crates/horizon-core/src/noise/simplex.rs": "6c0dbc15b2b7510195dd28fceca01dcaac1847ccc4a84d299c351589c642fe7a",
"crates/horizon-core/src/noise/stack.rs": "7f6ef0e7d920139ef1a6ad3ec5640f92765715f86dcc5ec29f1a149984f45fa3",
"crates/horizon-core/src/noise/volume.rs": "3f05d2b1780acfdfee60037677d309937a5033b45ef428fc2d540942d4b56b43",
"crates/horizon-core/src/position/iter.rs": "32d2d8e74821cc4e49e3354202d35d3120e4415bfdda9375a73f2137ef651129",
"crates/horizon-core/src/position.rs": "e10101088e6902386b9b6d27773d44312f1ff72bebb19e57967a54945dde9dcd",
"crates/horizon-core/src/random/hash.rs": "0f88a127a1ba2705d3d6c0ebd009324d6ba86ffa2d27edf2d2a84765e690e4a3",
"crates/horizon-core/src/random/positional.rs": "35494745e5d4cf89e282c3ae0ee245e9f2640ddbbc03bc0055df742006a9c862",
"crates/horizon-core/src/random/worldgen.rs": "9f07ff33bcc038d34e27aa5465753bb21df18f2975e43cae201f709bc186945a",
"crates/horizon-core/src/random.rs": "ddb95d3a83e28ad605ff1f49f5df270cc543ca5ef1130e37d989dc74c8d861e6",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/src/text.rs": "e6553ddb5db5039e8dc4614b6a6dc9f35a26dc3d1673b68a04e72e7983b67abb",
"crates/horizon-core/src/ticks/generation.rs": "be1237e790693f633a61714ddae68c6506a777588a8a3ab5efbe53a35774dbd2",
"crates/horizon-core/src/ticks/heap.rs": "bf28afab8af77c3d243aa96cd8a1fb8d934140a4dbd07dbfdbf4e7908bb4b845",
"crates/horizon-core/src/ticks/index.rs": "1f1a6a568c2a30eafecb020ca4d5f5fc414860de85b8b381fc419a2e3e65c24a",
"crates/horizon-core/src/ticks/mod.rs": "01634630668172516b8b79d0907bad47f6e2c543a6d499c2fa4b201823b375cb",
"crates/horizon-world/src/bin/worldgen_parity.rs": "3143ceb9b56eecfd7667e5feb5f9f0cd13cfb8754b38d4ea338dbba97f2819da",
"crates/horizon-world/src/block_collision.rs": "a40c9d7a4e0a734c124dc856e31359fd4d8de3d1bfc79c86787afa8e8e05e480",
"crates/horizon-world/src/block_entities.rs": "a9deae92e6e5a1fcf4f0476c33ea4d170ddad6fd4b3303e1bb66d933973d5e06",
"crates/horizon-world/src/block_placement.rs": "524f4892d50bab77b7d89d19f7b048ffe746996f2ed7f376db2c6ab00ed75c24",
"crates/horizon-world/src/block_properties.rs": "b0bd8a983336c48e488a20caa77dd5c39b1a74bbd14ebc03b3b64556a1c864fc",
"crates/horizon-world/src/block_render.rs": "8df52ee11aef406a1571198a64048062a0ef6864e0058d9293a57f64b73c916a",
"crates/horizon-world/src/block_support.rs": "ade4fbd47284b450dabdd682dc86138b2ac05a0fd379525d7110648908245476",
"crates/horizon-world/src/block_survival.rs": "28ce64375e09819a4f13da9cfbe37c08b5ad0daf01b289c1c360b4567e50e811",
"crates/horizon-world/src/chunk.rs": "8843e6f48dbbc4245ce4e95564dfba3a4d7a051ba0b1577fb038c07adb0ff0f9",
"crates/horizon-world/src/chunk_status.rs": "dbb8583cfa775203c544d24d69e03720385428f15a267a561356c21f5025e9c7",
"crates/horizon-world/src/collision.rs": "05313e0c1f3089524fe029f9aac3e439cd47f1c9584c8c7e154c9adcfa88c335",
"crates/horizon-world/src/collision_context.rs": "2176c7034e07f547510a8327cdad9d3b63f26e4754032b76b7d5fe13166c333c",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/dynamic_support.rs": "5996bc1c436fb6215d8fc3d0bb4de5dd9b966d842d432580d624195771697fb8",
"crates/horizon-world/src/entity_obstruction.rs": "a4b28a19bf83b23611c59d94535c488db37e4aee24b22c973c545910894a809f",
"crates/horizon-world/src/fluid.rs": "a0a1f34ba94d8b59dc975becee8952960764d67ae08cf2d6a8bcd40a614b15c4",
"crates/horizon-world/src/heightmap.rs": "a5edef082b5af40d814421ea17e129b3b06d70abee6434ed263e4bba58571698",
"crates/horizon-world/src/lib.rs": "f0997b21c8083de75f4f8883e8855e1d2d9f1876a2053a8a97b081deed5b0bcd",
"crates/horizon-world/src/liquid_collision.rs": "0f0a83b04e5a5bc9d98ed05fde4d6584ba69642e93522e726e4cfc325d6fcb1d",
"crates/horizon-world/src/main.rs": "fce57418b8c22a6a0a9044baa89ed3d9c243bc2e8413fea3ff0f32985daba021",
"crates/horizon-world/src/nbt.rs": "60262c3de8c8f68bc2da0370ccb17393d32b85f5f5022c6358599a7d32119ea6",
"crates/horizon-world/src/piston_shape.rs": "399c2337103b8e7e0eb5667227c5aa14f9549d6a467b7be7da3d0717f0263500",
"crates/horizon-world/src/powder_snow_collision.rs": "7289946a21478d11abfd2bdcdddff3d7f98e25bf6a68564fed45c3cc01ac2a36",
"crates/horizon-world/src/region.rs": "72b642e87fed37ed17f54d4c30f96c3b64d26c14bc0589c31ef40ff1616188fc",
"crates/horizon-world/src/registry/json.rs": "7a683afcd1742c5307756927d7f0aa779c7d7992af87d8d371dd98108728e235",
"crates/horizon-world/src/registry.rs": "f2e58b2b4d944ac8fc6226bd3352cefc3d2052d8473e02ccf7dc402b176df435",
"crates/horizon-world/src/retrogen.rs": "6efd36a6293756688c1990a7965bd65609d7c5e2bf2a5f4f01d54932d2b9386b",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/worldgen/anchor.rs": "d156b8a0b147a274cdd143409b441f4f43edecde6e8ee14ef9cf0309f743143a",
"crates/horizon-world/src/worldgen/aquifer/config.rs": "fcd2cc3a520c1527c88f095a3b5d38487e7ebb1ccecc5f757f93d04a069add4f",
"crates/horizon-world/src/worldgen/aquifer/noise_based.rs": "74daaa389b5c3dfdc99214dfff256a9e172f83548d2326cbc941d9637cc53fb7",
"crates/horizon-world/src/worldgen/aquifer.rs": "cb4b66d87de3f9f79ae6ffe4badd6f0f44886cd42ad9de2771b8b56c4f1e28c7",
"crates/horizon-world/src/worldgen/bamboo.rs": "d9b47113c99be34256e58308bc6f40072ff25c579d6bf995182aa862c0006102",
"crates/horizon-world/src/worldgen/biome.rs": "3fe316b875aa32683759c337dc71f624910faf0812a2d6d83b8098d6d0bac7a0",
"crates/horizon-world/src/worldgen/biome_chunk.rs": "8fdfe6ebe3ffeca97611fd5991a5bc6b2783ea1c62f4d8ef3b2dd53c04a5dc1d",
"crates/horizon-world/src/worldgen/biome_predicate.rs": "bfc581bc40077cc74ffda43e990a55fe997adc04c7130f98e039c3305ca79aac",
"crates/horizon-world/src/worldgen/biome_source/codec.rs": "2b9e4f5d679eb444cb73174f511e3b9f32e9eb138248ab12cffc6cfd76adf3a8",
"crates/horizon-world/src/worldgen/biome_source/runtime.rs": "f0b02c1521178e4d0377c6ca62694604b6a773f1f234f070ff0cde4685911d45",
"crates/horizon-world/src/worldgen/biome_source.rs": "e181e1736f3e0b75f7091a24c88de3fd116e01b98424d02382aea7a503d1eb54",
"crates/horizon-world/src/worldgen/biome_temperature.rs": "cde4bbab5e260c4065b113376c423b8511ade93c5aa5fd976e245ee8a58b5ad1",
"crates/horizon-world/src/worldgen/biome_weather.rs": "96b1f9494559ed31d06257b83d604d00cc069ccc8c7b68094117e034b4a71bd7",
"crates/horizon-world/src/worldgen/block_blob.rs": "c608c57b3d77279646ecb89e50677dd8e452b0422ffd357ba755536c5589eb89",
"crates/horizon-world/src/worldgen/block_column.rs": "f72c21a9066ee0aa68c2fb79fba436d05afb14c6ef5a2cb012f1ed35fc17cd22",
"crates/horizon-world/src/worldgen/block_feature.rs": "36b4e46ee7f7f73bcb94d8bce8d99013e4b16234c9a03542eeb3186e88dd1c21",
"crates/horizon-world/src/worldgen/block_pile.rs": "623e369b77e0526ed2756485a6c0bb09683cd28ad8876dea907360ca6665b39d",
"crates/horizon-world/src/worldgen/block_predicate.rs": "074c692367e3f2191a1bb28d87b23402430a843c246bd30a4ea838ee3500280e",
"crates/horizon-world/src/worldgen/blue_ice.rs": "eedd77bdaff808330b864166d303378096daa5c7d235e925770b171c05109247",
"crates/horizon-world/src/worldgen/bonus_chest.rs": "05d0f63fbc7412f13ba1fa37a7238114b8f70bfff318beb2dece590482d49cc0",
"crates/horizon-world/src/worldgen/bulk_section.rs": "eecf61532d7793f853884c5a18a7f436a59835c7b13d3ec9075804511553c9ba",
"crates/horizon-world/src/worldgen/carver/canyon.rs": "509c4d5a9d689849e98e894ab14a9fbf82d10707d38e9cc688ded3c4778df3e2",
"crates/horizon-world/src/worldgen/carver/generation.rs": "a4498d0d1457536de3922a08e9c40ccce8d2ef9cc263801c15a412327513c098",
"crates/horizon-world/src/worldgen/carver.rs": "46b251e28225fe1250de38f49dec5dacda4e2c4ba1e556e21e6d1e14e2651fc3",
"crates/horizon-world/src/worldgen/carving.rs": "4e77d4e5c4a0ca55ca3563b9bdf6f379342e0bdf9d019d60f7bc57ce4afb5fbd",
"crates/horizon-world/src/worldgen/chorus_plant.rs": "29224c164ede919e280a65a68f155c873e2c8fd0aa7d7e244d8fa9e468760250",
"crates/horizon-world/src/worldgen/climate/codec.rs": "d567adeb5d837816fca69102db51d790f71aec1b51c09298230d24612e400a14",
"crates/horizon-world/src/worldgen/climate/index.rs": "c5ce61679a5f0e0f2f0af2a373424effa124d0cce8250609eff38b7034650756",
"crates/horizon-world/src/worldgen/climate.rs": "1b9ad44407f40aee4c1cd5357a5c9c443c1b105728f01cf5c644072f99f8357e",
"crates/horizon-world/src/worldgen/decoration.rs": "75a79b20b21e133816e729f16e758be6165d0db18a64bfbd5fd3618325a2adf3",
"crates/horizon-world/src/worldgen/delta.rs": "c2bf49ddf3231d28c109e68871429bc13d76a7bebe14eb33e84aa856bdd66145",
"crates/horizon-world/src/worldgen/density.rs": "65a98c156a290a6b374ef670d28cd5dfbe0aa93171824d1bbd96422536273f84",
"crates/horizon-world/src/worldgen/disk.rs": "6f8f9e059755af44c9bfa1b91eba54a7d13fad811dce31717c5502d7f6df33d7",
"crates/horizon-world/src/worldgen/end_gateway.rs": "f53fde77d6a36a525cd15d890003b2c129d0689a4cbfa2cf443a0c2e3acae040",
"crates/horizon-world/src/worldgen/end_podium.rs": "8f6d0d6d60ff0fde63de5781e867239db321f82cf12639f0537d410a3731ee1d",
"crates/horizon-world/src/worldgen/feature.rs": "40500af71ee6628dfb27518262d99f08d0383ae6c7b9397452feef0c213eadd9",
"crates/horizon-world/src/worldgen/feature_catalog.rs": "efc7b17b227e71622ef34108be9abd010f5675b68ea0409fcab82581d9aab88a",
"crates/horizon-world/src/worldgen/feature_graph.rs": "da132fca9fdafb0d89a917d5f4b68c60b70fb33cadf948a107da0e35d83dcd91",
"crates/horizon-world/src/worldgen/feature_region.rs": "df0ff142a461cafa9a3b42b949ad3376887f2be8d4ea5cc794a3ed2e977bb499",
"crates/horizon-world/src/worldgen/feature_sort.rs": "3488a093dfe1321aaa29d8a30cfb115d8e666a81bf195514e87b170de626835c",
"crates/horizon-world/src/worldgen/fluid_predicate.rs": "64197c9e63bebf1ce04bc280bfe980bb6c1b9aa887ca5cded904aeb0d9ae6c46",
"crates/horizon-world/src/worldgen/height_provider.rs": "368d4dc119854742a045c4a717679c921456da681fc5f71aa9b37102d6f33b47",
"crates/horizon-world/src/worldgen/material_condition/codec.rs": "09b909bc384472f76d163c8069ec6b507c7d5c6a028a36d5e0e3df20deff7b3b",
"crates/horizon-world/src/worldgen/material_condition/density.rs": "df9d0761e978e5010663ae8b44f2d6c1ecb4907331e333bdb6a2b487c1e107de",
"crates/horizon-world/src/worldgen/material_condition/library.rs": "a55534c5da97575a819af5a7dc0dbec9069993fa8b2619c6c9d5576946e683fa",
"crates/horizon-world/src/worldgen/material_condition/noise.rs": "ffb59cc6be2275d7a5621bf7d768527e74a8326ed7ad78618746711540921675",
"crates/horizon-world/src/worldgen/material_condition/rule.rs": "fed643352efbcb1f68f29b6241896617db889fc7c577a6247564e01922fec1fe",
"crates/horizon-world/src/worldgen/material_condition.rs": "d638dcb8cbcb5da20b3cb29602b0ae6a86c4fdf9d8c0fb725de8ec5fc108717e",
"crates/horizon-world/src/worldgen/material_extensions.rs": "ab806eb679d5116e1aebb64fca70e1499ae71f83c9507a8cb4c3201c2b1bf037",
"crates/horizon-world/src/worldgen/material_stage.rs": "698cbc786eff13c246e2bc2ea062401918cd4265899fbc3d53abc87e45a8e7a1",
"crates/horizon-world/src/worldgen/material_surface.rs": "5d37b90099df3d6da0845dab164e71469fb287019c2ee74bc6714f3b9d6d6d5b",
"crates/horizon-world/src/worldgen/ore_feature.rs": "83b89fd3be691c5412c0215b6abefdcaa44119a05aa41217e061970eb7e12ebd",
"crates/horizon-world/src/worldgen/placement/chain.rs": "9218399b4d3757f7bbc550d7729a7201f32a1c83a7030865e0c12aab8a80d116",
"crates/horizon-world/src/worldgen/placement/context.rs": "a278304795136677ad4b4933ea50c972b9729a1c671c03fa309c193e224b1fd6",
"crates/horizon-world/src/worldgen/placement/layer.rs": "a0f5ca776f33f9d4f72b8fdcd163426152e5e43cb4a7572fc1d4fc57bf965de1",
"crates/horizon-world/src/worldgen/placement.rs": "b0397e5818fae84358546193a95f84bcb0b5bffafce909e6fcb3386179ee8023",
"crates/horizon-world/src/worldgen/replace_blobs.rs": "bf3377d86d2570cd15288ba69dde64a2cf67c5bcbb9a31d0c23421964af74afa",
"crates/horizon-world/src/worldgen/router.rs": "2cee7cf15a0d2ada12be6b39d83e78177fd3033922e4f4cce87a64073cec2847",
"crates/horizon-world/src/worldgen/rule_test.rs": "d1662ec492489ebaa4b87e20f9a8c809dcf3a223a151211bd65ec241a63692fc",
"crates/horizon-world/src/worldgen/settings.rs": "a8fe87752e1982ef11cb67f8d80d8e3428b2c27db178044cb425ba803e689e59",
"crates/horizon-world/src/worldgen/simple_block.rs": "9ba1a88d5db4925f8c37366557887f776c805f9a6444781615b5dbaff52e92a4",
"crates/horizon-world/src/worldgen/snow_freeze.rs": "9040be3d5c7f8f0fd812d2df45e154bf8a9eeef038530b83fa4159d246eac35f",
"crates/horizon-world/src/worldgen/speleothem.rs": "c71651c1c97818a8a85863e14414d6139ea3bdeb897fa422043bcc1499d99aae",
"crates/horizon-world/src/worldgen/spike.rs": "eacf0d9d3d2bc3d4bcf62bc87555f90031138236a5bfef0eb5270204f7c2a4fc",
"crates/horizon-world/src/worldgen/spring.rs": "830849e9b89fcdf09e9b06fbefdcdebe3c8c3f82804f60b8bd5de04ba303cb62",
"crates/horizon-world/src/worldgen/state_provider/catalog.rs": "c8687e15a4887a9200c8d365857d801efaa8f90e669eee3e600a1db4905119eb",
"crates/horizon-world/src/worldgen/state_provider/noise.rs": "7ee369c2a032e5620cb9bdf9ee7adad1f70870fb0a27efb7b7c514d92f83491f",
"crates/horizon-world/src/worldgen/state_provider/properties.rs": "9909139aaca1dc4f743957257fadaa9d423d21fa401fa9abc050505f79365139",
"crates/horizon-world/src/worldgen/state_provider.rs": "be29ada818826a90afe01ab60916360fdfc4cbde5af15c9359cd56b1f1f7b156",
"crates/horizon-world/src/worldgen/tags.rs": "d35ded93fe6e95ea045cadcf4925e656dc34ef832b742179b9ad0cc49f902f31",
"crates/horizon-world/src/worldgen/terrain.rs": "fd1f2e0afc15daf66f484ea40a1f2b7013650bda0941b23c64c81ee9f79cb673",
"crates/horizon-world/src/worldgen/underwater_magma.rs": "7317e40af5ee5a9780f90ce358fa5d3e7f5b3d513b731df6ff97754d9c2a0154",
"crates/horizon-world/src/worldgen/value_provider.rs": "3358b563db8cb0bc8a9cfbbe2b8b3e70941cd2d37a0b519fbb6545f8d0dcbb69",
"crates/horizon-world/src/worldgen/vines.rs": "ee9b79b65012bd86a838241d2ef708680f7fe8eafc8aa656dae9cf2abf3c6418",
"crates/horizon-world/src/worldgen/weighted.rs": "839840aae25302933bbd97a81a2336330e2d03a0ad1684e1e16ac769ed408e6b",
"crates/horizon-world/src/worldgen/write_zone.rs": "8e17a179764d3f68c05882aef35f6810c28a0000f9a83e58bd6030660b76e64e",
"crates/horizon-world/src/worldgen.rs": "e8e9f099ee1fcec8eedce31805d676d3f89c18e84f494a147ffcbfee23d3d54f",
"crates/horizon-world/examples/collision_context_fixture.rs": "b7bf0f48f7dc0129c1ebe43c11cb4cad00194b501c2bcbb3220bc8779e695ba4"
},
"fixtures_sha256": {
".local/rust-liquid-collision-parity/inputs.txt": "564e80e9a55a186cd70c21a1db14abf59849be90bc5493346e9e64ff9d3c9d8b"
},
"rust_output_sha256": "d845ce538e9ce157f6455b32e73e03e9d7df86ebc5c9ab80ebf94705500748ab",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "d845ce538e9ce157f6455b32e73e03e9d7df86ebc5c9ab80ebf94705500748ab",
"matched_output_lines": 571179
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "d845ce538e9ce157f6455b32e73e03e9d7df86ebc5c9ab80ebf94705500748ab",
"matched_output_lines": 571179
}
],
"scope": "Native contextual LiquidBlock collision dispatch for all 32 water/lava states. Checks the always-fluid bypass, source-only selection, living-entity gating, supplied entity standing shapes, exact height boundaries, all 33 above-block fluid states, callback order and failure propagation, null/placement contexts and wrapping above-block coordinates. Full selected shape data and callback traces are compared. Entity-specific standing shape implementations, liquid simulation and live movement remain pending."
}
@@ -1,205 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"manifest_sha1": "4fe1aa1ef8da1cb95c5bad1fb98890ca56dd8ca3",
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"java": "openjdk 25.0.4.1 2026-08-18",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"fixtures": 56448,
"block_states": 32,
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCollisionContextOracle.java": "b9c34e7f7a7c14001e03373cbbd468a228c5301eb639460b4ce465d14e946113",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaFaceSupportOracle.java": "9ce939a435842867786fed648951bbe77f6ab843f6df09af15f3deb1948c4877",
"tools/test_collision_context_parity.py": "75d6f01e072867d2bd286d2e518e123fcfe055a11ac1705ec99ecec3975cb8d2",
"tools/test_scaffolding_collision_parity.py": "bab75e2cad68a3193035a87497eaa372466c405293cc547e39dbd7bd4450d69d",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "cb1e87d449114a63edd904c0559d631e8fa9feeb27efd6539aacdcfeae178876",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"crates/horizon-world/Cargo.toml": "977338bf3e654193685b015d383493b9f59ff6f5d6210bec212cef8ac4a50bed",
"crates/horizon-core/src/bin/density_parity.rs": "e5b1dd33b7d01306c73cf072629b4fb186e9ab87b672a00108999d1a72263fd0",
"crates/horizon-core/src/bin/float_log_parity.rs": "4a655fcf8822ee7668c4bd126bc84d0b118864a6fc7f5a6aeee667d8bf2590b1",
"crates/horizon-core/src/bin/geometry_parity.rs": "27f6c09fe5018ac3de8e70e0f0bbf78f9abb14f5e4783bcaf46e8ca87b9c6f8a",
"crates/horizon-core/src/bin/noise_parity.rs": "c135bfc708d853e7061e81487d2cfe10de64b2f65677d3b4837cbfe0b8341010",
"crates/horizon-core/src/bin/parity.rs": "f35d928c66f958de39fac5e7e836a657eed95f83599e84899f7ea7a5802ba481",
"crates/horizon-core/src/bin/tick_parity.rs": "a54c164fe4814034d369947a887f5273966f5a878ba849204b80d1c729526a8f",
"crates/horizon-core/src/biome/seed_hash.rs": "5afbb4921c750826b395a08bf06f382fc7f01b5759a93de02a2749c523e2a317",
"crates/horizon-core/src/biome.rs": "908efa8cd4aa0a7adf1cb5e1a222e3dfb640eed5e9172e0fe7f0d1287afae7e8",
"crates/horizon-core/src/carving/ellipsoid.rs": "09232a7588610e8a9176fd9c62d40afb1fb89f2ecab6d555536a1d847b142d86",
"crates/horizon-core/src/carving.rs": "0aa3093caa0437868a8c0ed52a6c6e1993bd51c03583c670a2837e749eae5426",
"crates/horizon-core/src/density/arithmetic.rs": "372faec96c923e2cf4aa6c66c1ac398e676853274557823850dbc8933dd15ab1",
"crates/horizon-core/src/density/beardifier.rs": "bb1052e27dae4a01954ca78d7d5babafef85f3b2c704ccaf1920cb85a098cb50",
"crates/horizon-core/src/density/cache.rs": "38d0b6c9dd04ffef979fdad3f29cfebf98d331c8c9d430be5f39aa34f6c30975",
"crates/horizon-core/src/density/end_islands.rs": "168b9384237bd2e41d0ae5a74e944da4dc74e493bdec31fb73184c9a49e3de55",
"crates/horizon-core/src/density/graph/compiler.rs": "ac67deeb16f16d0859aa20e5a165811a29aca0b910037ee6bf5098211f3a6ede",
"crates/horizon-core/src/density/graph/mod.rs": "b776e7da934cb03051a3053d56d461c71e9978e084922fe4194147aa580c07bf",
"crates/horizon-core/src/density/graph/seeded.rs": "6bcdcaa3dffcfa9df673bbbea35120057a16ba3d2b506c52709c36cf8976b74a",
"crates/horizon-core/src/density/graph/tests.rs": "6bfb8cbff462587dd147b0775ea01d370abbd97544b9bd596c792df1b5f7e634",
"crates/horizon-core/src/density/interpolation.rs": "8c890f52b6467f38a94c654986a6a484b8e0b296ab98c398e60a6ce465b5b010",
"crates/horizon-core/src/density/interval.rs": "b42629163baa6b599a233afe8596d1c370cd81d015cc6fc36a9663aa47b98424",
"crates/horizon-core/src/density/mod.rs": "ca0d77d3282e3746ddcbc92bee97dbf640b9a56214e6ac1537f51f9a5b63d6e7",
"crates/horizon-core/src/density/power.rs": "d5b7270a128d4264268cd772109ad16d71a8ec3ff2d3b63b84cb985296d54a91",
"crates/horizon-core/src/density/rounding.rs": "71840c5206ff8d218ac29bf6f66915d5212764ba270c675711a866ba5b55a7a6",
"crates/horizon-core/src/density/selection.rs": "0dd26af2e85004ec5e053039ad11c384c17c56ace9ab45eb3f5cb3503c0b0330",
"crates/horizon-core/src/density/slice.rs": "5d77605573c0deda47778f1f78f7fa3fbf1944d8f5efbcc65cf589181cadf80b",
"crates/horizon-core/src/density/spline.rs": "6bb2e40f940fc6544d6fb09cb0b8cac722be03bc663dbdfb0f61faae207400bc",
"crates/horizon-core/src/density/surface.rs": "159e0e69cda74f870e80ea64fe523c4397e64af4ccb861bb9fd07b2c3cb91b00",
"crates/horizon-core/src/density/terrain_noise.rs": "8d0059d25eb5d248cb97a4c5a2e670d61528928ea151495c004f25adb723fe3e",
"crates/horizon-core/src/density/tests.rs": "7817796ee40d0ae241bfbebec6bca190e0a8e7d5a1caa8ddf858c3eaa58b8858",
"crates/horizon-core/src/density/world_fields.rs": "c1ce305cb8046b384d90c564cafb24af7365d580389637910f3d8b0cc18eb583",
"crates/horizon-core/src/geometry/mod.rs": "dc92f73885dd0a7760743bf74f1ab8afa839d61cef2dfef890f8a23b67b4742e",
"crates/horizon-core/src/geometry/movement.rs": "930e34abef6f6eeec1ee7a6c920b5ba01bfe37b90678884490f4be53241f6b96",
"crates/horizon-core/src/geometry/shape/create.rs": "189812b91d5e0e3ad963afcd1a6e2831b31b8188df91a904ef27061e644806ad",
"crates/horizon-core/src/geometry/shape/face.rs": "f243bce81384040a95ce7984b02b5699206c596c537b2713097e86005b4d3a5c",
"crates/horizon-core/src/geometry/shape/join.rs": "f1b51887b7bf9482557e3ffa99e136f2e5db07ceeb05fdb116adf45e87129075",
"crates/horizon-core/src/geometry/shape.rs": "e8d88a763de1525f77a30b99591641e8a8b80946263acbde035a9bcc356df960",
"crates/horizon-core/src/geometry/sweep.rs": "abd6009c61555161ef2f18b431b2aa384b126c0871cae8b96a62358498a56a1d",
"crates/horizon-core/src/geometry/traversal.rs": "77a3da570a0b85582b669cf4d841cba4b06327006dda26d4a26df4e8ce05bae4",
"crates/horizon-core/src/geometry/trig.rs": "05cef9341a298a474221a0556a11ddf47650393ea7a97b4b2022a4da6628fe37",
"crates/horizon-core/src/lib.rs": "4255e16837fde42a52ba118f60581d197c571bb530b60d635e506184ebf4db0b",
"crates/horizon-core/src/noise/mod.rs": "1dab5a713abf702402e69ace1bf9e476bba544b0ede5a61c3c3afc60af0a03f3",
"crates/horizon-core/src/noise/normal.rs": "e9e7a46472a54a02c98c46da819842090567153b32fe0c84249009ef19af7aad",
"crates/horizon-core/src/noise/perlin.rs": "e73815447432eab7542f67366cb3f1b368d164e33f6c9cdbd045ac8e4db0932a",
"crates/horizon-core/src/noise/simplex.rs": "6c0dbc15b2b7510195dd28fceca01dcaac1847ccc4a84d299c351589c642fe7a",
"crates/horizon-core/src/noise/stack.rs": "7f6ef0e7d920139ef1a6ad3ec5640f92765715f86dcc5ec29f1a149984f45fa3",
"crates/horizon-core/src/noise/volume.rs": "3f05d2b1780acfdfee60037677d309937a5033b45ef428fc2d540942d4b56b43",
"crates/horizon-core/src/position/iter.rs": "32d2d8e74821cc4e49e3354202d35d3120e4415bfdda9375a73f2137ef651129",
"crates/horizon-core/src/position.rs": "e10101088e6902386b9b6d27773d44312f1ff72bebb19e57967a54945dde9dcd",
"crates/horizon-core/src/random/hash.rs": "0f88a127a1ba2705d3d6c0ebd009324d6ba86ffa2d27edf2d2a84765e690e4a3",
"crates/horizon-core/src/random/positional.rs": "35494745e5d4cf89e282c3ae0ee245e9f2640ddbbc03bc0055df742006a9c862",
"crates/horizon-core/src/random/worldgen.rs": "9f07ff33bcc038d34e27aa5465753bb21df18f2975e43cae201f709bc186945a",
"crates/horizon-core/src/random.rs": "ddb95d3a83e28ad605ff1f49f5df270cc543ca5ef1130e37d989dc74c8d861e6",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/src/text.rs": "e6553ddb5db5039e8dc4614b6a6dc9f35a26dc3d1673b68a04e72e7983b67abb",
"crates/horizon-core/src/ticks/generation.rs": "be1237e790693f633a61714ddae68c6506a777588a8a3ab5efbe53a35774dbd2",
"crates/horizon-core/src/ticks/heap.rs": "bf28afab8af77c3d243aa96cd8a1fb8d934140a4dbd07dbfdbf4e7908bb4b845",
"crates/horizon-core/src/ticks/index.rs": "1f1a6a568c2a30eafecb020ca4d5f5fc414860de85b8b381fc419a2e3e65c24a",
"crates/horizon-core/src/ticks/mod.rs": "01634630668172516b8b79d0907bad47f6e2c543a6d499c2fa4b201823b375cb",
"crates/horizon-world/src/bin/worldgen_parity.rs": "3143ceb9b56eecfd7667e5feb5f9f0cd13cfb8754b38d4ea338dbba97f2819da",
"crates/horizon-world/src/block_collision.rs": "a40c9d7a4e0a734c124dc856e31359fd4d8de3d1bfc79c86787afa8e8e05e480",
"crates/horizon-world/src/block_entities.rs": "a9deae92e6e5a1fcf4f0476c33ea4d170ddad6fd4b3303e1bb66d933973d5e06",
"crates/horizon-world/src/block_placement.rs": "524f4892d50bab77b7d89d19f7b048ffe746996f2ed7f376db2c6ab00ed75c24",
"crates/horizon-world/src/block_properties.rs": "b0bd8a983336c48e488a20caa77dd5c39b1a74bbd14ebc03b3b64556a1c864fc",
"crates/horizon-world/src/block_render.rs": "8df52ee11aef406a1571198a64048062a0ef6864e0058d9293a57f64b73c916a",
"crates/horizon-world/src/block_support.rs": "ade4fbd47284b450dabdd682dc86138b2ac05a0fd379525d7110648908245476",
"crates/horizon-world/src/block_survival.rs": "28ce64375e09819a4f13da9cfbe37c08b5ad0daf01b289c1c360b4567e50e811",
"crates/horizon-world/src/chunk.rs": "8843e6f48dbbc4245ce4e95564dfba3a4d7a051ba0b1577fb038c07adb0ff0f9",
"crates/horizon-world/src/chunk_status.rs": "dbb8583cfa775203c544d24d69e03720385428f15a267a561356c21f5025e9c7",
"crates/horizon-world/src/collision.rs": "05313e0c1f3089524fe029f9aac3e439cd47f1c9584c8c7e154c9adcfa88c335",
"crates/horizon-world/src/collision_context.rs": "2176c7034e07f547510a8327cdad9d3b63f26e4754032b76b7d5fe13166c333c",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/dynamic_support.rs": "5996bc1c436fb6215d8fc3d0bb4de5dd9b966d842d432580d624195771697fb8",
"crates/horizon-world/src/entity_obstruction.rs": "a4b28a19bf83b23611c59d94535c488db37e4aee24b22c973c545910894a809f",
"crates/horizon-world/src/fluid.rs": "a0a1f34ba94d8b59dc975becee8952960764d67ae08cf2d6a8bcd40a614b15c4",
"crates/horizon-world/src/heightmap.rs": "a5edef082b5af40d814421ea17e129b3b06d70abee6434ed263e4bba58571698",
"crates/horizon-world/src/lib.rs": "f0997b21c8083de75f4f8883e8855e1d2d9f1876a2053a8a97b081deed5b0bcd",
"crates/horizon-world/src/liquid_collision.rs": "0f0a83b04e5a5bc9d98ed05fde4d6584ba69642e93522e726e4cfc325d6fcb1d",
"crates/horizon-world/src/main.rs": "fce57418b8c22a6a0a9044baa89ed3d9c243bc2e8413fea3ff0f32985daba021",
"crates/horizon-world/src/nbt.rs": "60262c3de8c8f68bc2da0370ccb17393d32b85f5f5022c6358599a7d32119ea6",
"crates/horizon-world/src/piston_shape.rs": "399c2337103b8e7e0eb5667227c5aa14f9549d6a467b7be7da3d0717f0263500",
"crates/horizon-world/src/powder_snow_collision.rs": "7289946a21478d11abfd2bdcdddff3d7f98e25bf6a68564fed45c3cc01ac2a36",
"crates/horizon-world/src/region.rs": "72b642e87fed37ed17f54d4c30f96c3b64d26c14bc0589c31ef40ff1616188fc",
"crates/horizon-world/src/registry/json.rs": "7a683afcd1742c5307756927d7f0aa779c7d7992af87d8d371dd98108728e235",
"crates/horizon-world/src/registry.rs": "f2e58b2b4d944ac8fc6226bd3352cefc3d2052d8473e02ccf7dc402b176df435",
"crates/horizon-world/src/retrogen.rs": "6efd36a6293756688c1990a7965bd65609d7c5e2bf2a5f4f01d54932d2b9386b",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/worldgen/anchor.rs": "d156b8a0b147a274cdd143409b441f4f43edecde6e8ee14ef9cf0309f743143a",
"crates/horizon-world/src/worldgen/aquifer/config.rs": "fcd2cc3a520c1527c88f095a3b5d38487e7ebb1ccecc5f757f93d04a069add4f",
"crates/horizon-world/src/worldgen/aquifer/noise_based.rs": "74daaa389b5c3dfdc99214dfff256a9e172f83548d2326cbc941d9637cc53fb7",
"crates/horizon-world/src/worldgen/aquifer.rs": "cb4b66d87de3f9f79ae6ffe4badd6f0f44886cd42ad9de2771b8b56c4f1e28c7",
"crates/horizon-world/src/worldgen/bamboo.rs": "d9b47113c99be34256e58308bc6f40072ff25c579d6bf995182aa862c0006102",
"crates/horizon-world/src/worldgen/biome.rs": "3fe316b875aa32683759c337dc71f624910faf0812a2d6d83b8098d6d0bac7a0",
"crates/horizon-world/src/worldgen/biome_chunk.rs": "8fdfe6ebe3ffeca97611fd5991a5bc6b2783ea1c62f4d8ef3b2dd53c04a5dc1d",
"crates/horizon-world/src/worldgen/biome_predicate.rs": "bfc581bc40077cc74ffda43e990a55fe997adc04c7130f98e039c3305ca79aac",
"crates/horizon-world/src/worldgen/biome_source/codec.rs": "2b9e4f5d679eb444cb73174f511e3b9f32e9eb138248ab12cffc6cfd76adf3a8",
"crates/horizon-world/src/worldgen/biome_source/runtime.rs": "f0b02c1521178e4d0377c6ca62694604b6a773f1f234f070ff0cde4685911d45",
"crates/horizon-world/src/worldgen/biome_source.rs": "e181e1736f3e0b75f7091a24c88de3fd116e01b98424d02382aea7a503d1eb54",
"crates/horizon-world/src/worldgen/biome_temperature.rs": "cde4bbab5e260c4065b113376c423b8511ade93c5aa5fd976e245ee8a58b5ad1",
"crates/horizon-world/src/worldgen/biome_weather.rs": "96b1f9494559ed31d06257b83d604d00cc069ccc8c7b68094117e034b4a71bd7",
"crates/horizon-world/src/worldgen/block_blob.rs": "c608c57b3d77279646ecb89e50677dd8e452b0422ffd357ba755536c5589eb89",
"crates/horizon-world/src/worldgen/block_column.rs": "f72c21a9066ee0aa68c2fb79fba436d05afb14c6ef5a2cb012f1ed35fc17cd22",
"crates/horizon-world/src/worldgen/block_feature.rs": "36b4e46ee7f7f73bcb94d8bce8d99013e4b16234c9a03542eeb3186e88dd1c21",
"crates/horizon-world/src/worldgen/block_pile.rs": "623e369b77e0526ed2756485a6c0bb09683cd28ad8876dea907360ca6665b39d",
"crates/horizon-world/src/worldgen/block_predicate.rs": "074c692367e3f2191a1bb28d87b23402430a843c246bd30a4ea838ee3500280e",
"crates/horizon-world/src/worldgen/blue_ice.rs": "eedd77bdaff808330b864166d303378096daa5c7d235e925770b171c05109247",
"crates/horizon-world/src/worldgen/bonus_chest.rs": "05d0f63fbc7412f13ba1fa37a7238114b8f70bfff318beb2dece590482d49cc0",
"crates/horizon-world/src/worldgen/bulk_section.rs": "eecf61532d7793f853884c5a18a7f436a59835c7b13d3ec9075804511553c9ba",
"crates/horizon-world/src/worldgen/carver/canyon.rs": "509c4d5a9d689849e98e894ab14a9fbf82d10707d38e9cc688ded3c4778df3e2",
"crates/horizon-world/src/worldgen/carver/generation.rs": "a4498d0d1457536de3922a08e9c40ccce8d2ef9cc263801c15a412327513c098",
"crates/horizon-world/src/worldgen/carver.rs": "46b251e28225fe1250de38f49dec5dacda4e2c4ba1e556e21e6d1e14e2651fc3",
"crates/horizon-world/src/worldgen/carving.rs": "4e77d4e5c4a0ca55ca3563b9bdf6f379342e0bdf9d019d60f7bc57ce4afb5fbd",
"crates/horizon-world/src/worldgen/chorus_plant.rs": "29224c164ede919e280a65a68f155c873e2c8fd0aa7d7e244d8fa9e468760250",
"crates/horizon-world/src/worldgen/climate/codec.rs": "d567adeb5d837816fca69102db51d790f71aec1b51c09298230d24612e400a14",
"crates/horizon-world/src/worldgen/climate/index.rs": "c5ce61679a5f0e0f2f0af2a373424effa124d0cce8250609eff38b7034650756",
"crates/horizon-world/src/worldgen/climate.rs": "1b9ad44407f40aee4c1cd5357a5c9c443c1b105728f01cf5c644072f99f8357e",
"crates/horizon-world/src/worldgen/decoration.rs": "75a79b20b21e133816e729f16e758be6165d0db18a64bfbd5fd3618325a2adf3",
"crates/horizon-world/src/worldgen/delta.rs": "c2bf49ddf3231d28c109e68871429bc13d76a7bebe14eb33e84aa856bdd66145",
"crates/horizon-world/src/worldgen/density.rs": "65a98c156a290a6b374ef670d28cd5dfbe0aa93171824d1bbd96422536273f84",
"crates/horizon-world/src/worldgen/disk.rs": "6f8f9e059755af44c9bfa1b91eba54a7d13fad811dce31717c5502d7f6df33d7",
"crates/horizon-world/src/worldgen/end_gateway.rs": "f53fde77d6a36a525cd15d890003b2c129d0689a4cbfa2cf443a0c2e3acae040",
"crates/horizon-world/src/worldgen/end_podium.rs": "8f6d0d6d60ff0fde63de5781e867239db321f82cf12639f0537d410a3731ee1d",
"crates/horizon-world/src/worldgen/feature.rs": "40500af71ee6628dfb27518262d99f08d0383ae6c7b9397452feef0c213eadd9",
"crates/horizon-world/src/worldgen/feature_catalog.rs": "efc7b17b227e71622ef34108be9abd010f5675b68ea0409fcab82581d9aab88a",
"crates/horizon-world/src/worldgen/feature_graph.rs": "da132fca9fdafb0d89a917d5f4b68c60b70fb33cadf948a107da0e35d83dcd91",
"crates/horizon-world/src/worldgen/feature_region.rs": "df0ff142a461cafa9a3b42b949ad3376887f2be8d4ea5cc794a3ed2e977bb499",
"crates/horizon-world/src/worldgen/feature_sort.rs": "3488a093dfe1321aaa29d8a30cfb115d8e666a81bf195514e87b170de626835c",
"crates/horizon-world/src/worldgen/fluid_predicate.rs": "64197c9e63bebf1ce04bc280bfe980bb6c1b9aa887ca5cded904aeb0d9ae6c46",
"crates/horizon-world/src/worldgen/height_provider.rs": "368d4dc119854742a045c4a717679c921456da681fc5f71aa9b37102d6f33b47",
"crates/horizon-world/src/worldgen/material_condition/codec.rs": "09b909bc384472f76d163c8069ec6b507c7d5c6a028a36d5e0e3df20deff7b3b",
"crates/horizon-world/src/worldgen/material_condition/density.rs": "df9d0761e978e5010663ae8b44f2d6c1ecb4907331e333bdb6a2b487c1e107de",
"crates/horizon-world/src/worldgen/material_condition/library.rs": "a55534c5da97575a819af5a7dc0dbec9069993fa8b2619c6c9d5576946e683fa",
"crates/horizon-world/src/worldgen/material_condition/noise.rs": "ffb59cc6be2275d7a5621bf7d768527e74a8326ed7ad78618746711540921675",
"crates/horizon-world/src/worldgen/material_condition/rule.rs": "fed643352efbcb1f68f29b6241896617db889fc7c577a6247564e01922fec1fe",
"crates/horizon-world/src/worldgen/material_condition.rs": "d638dcb8cbcb5da20b3cb29602b0ae6a86c4fdf9d8c0fb725de8ec5fc108717e",
"crates/horizon-world/src/worldgen/material_extensions.rs": "ab806eb679d5116e1aebb64fca70e1499ae71f83c9507a8cb4c3201c2b1bf037",
"crates/horizon-world/src/worldgen/material_stage.rs": "698cbc786eff13c246e2bc2ea062401918cd4265899fbc3d53abc87e45a8e7a1",
"crates/horizon-world/src/worldgen/material_surface.rs": "5d37b90099df3d6da0845dab164e71469fb287019c2ee74bc6714f3b9d6d6d5b",
"crates/horizon-world/src/worldgen/ore_feature.rs": "83b89fd3be691c5412c0215b6abefdcaa44119a05aa41217e061970eb7e12ebd",
"crates/horizon-world/src/worldgen/placement/chain.rs": "9218399b4d3757f7bbc550d7729a7201f32a1c83a7030865e0c12aab8a80d116",
"crates/horizon-world/src/worldgen/placement/context.rs": "a278304795136677ad4b4933ea50c972b9729a1c671c03fa309c193e224b1fd6",
"crates/horizon-world/src/worldgen/placement/layer.rs": "a0f5ca776f33f9d4f72b8fdcd163426152e5e43cb4a7572fc1d4fc57bf965de1",
"crates/horizon-world/src/worldgen/placement.rs": "b0397e5818fae84358546193a95f84bcb0b5bffafce909e6fcb3386179ee8023",
"crates/horizon-world/src/worldgen/replace_blobs.rs": "bf3377d86d2570cd15288ba69dde64a2cf67c5bcbb9a31d0c23421964af74afa",
"crates/horizon-world/src/worldgen/router.rs": "2cee7cf15a0d2ada12be6b39d83e78177fd3033922e4f4cce87a64073cec2847",
"crates/horizon-world/src/worldgen/rule_test.rs": "d1662ec492489ebaa4b87e20f9a8c809dcf3a223a151211bd65ec241a63692fc",
"crates/horizon-world/src/worldgen/settings.rs": "a8fe87752e1982ef11cb67f8d80d8e3428b2c27db178044cb425ba803e689e59",
"crates/horizon-world/src/worldgen/simple_block.rs": "9ba1a88d5db4925f8c37366557887f776c805f9a6444781615b5dbaff52e92a4",
"crates/horizon-world/src/worldgen/snow_freeze.rs": "9040be3d5c7f8f0fd812d2df45e154bf8a9eeef038530b83fa4159d246eac35f",
"crates/horizon-world/src/worldgen/speleothem.rs": "c71651c1c97818a8a85863e14414d6139ea3bdeb897fa422043bcc1499d99aae",
"crates/horizon-world/src/worldgen/spike.rs": "eacf0d9d3d2bc3d4bcf62bc87555f90031138236a5bfef0eb5270204f7c2a4fc",
"crates/horizon-world/src/worldgen/spring.rs": "830849e9b89fcdf09e9b06fbefdcdebe3c8c3f82804f60b8bd5de04ba303cb62",
"crates/horizon-world/src/worldgen/state_provider/catalog.rs": "c8687e15a4887a9200c8d365857d801efaa8f90e669eee3e600a1db4905119eb",
"crates/horizon-world/src/worldgen/state_provider/noise.rs": "7ee369c2a032e5620cb9bdf9ee7adad1f70870fb0a27efb7b7c514d92f83491f",
"crates/horizon-world/src/worldgen/state_provider/properties.rs": "9909139aaca1dc4f743957257fadaa9d423d21fa401fa9abc050505f79365139",
"crates/horizon-world/src/worldgen/state_provider.rs": "be29ada818826a90afe01ab60916360fdfc4cbde5af15c9359cd56b1f1f7b156",
"crates/horizon-world/src/worldgen/tags.rs": "d35ded93fe6e95ea045cadcf4925e656dc34ef832b742179b9ad0cc49f902f31",
"crates/horizon-world/src/worldgen/terrain.rs": "fd1f2e0afc15daf66f484ea40a1f2b7013650bda0941b23c64c81ee9f79cb673",
"crates/horizon-world/src/worldgen/underwater_magma.rs": "7317e40af5ee5a9780f90ce358fa5d3e7f5b3d513b731df6ff97754d9c2a0154",
"crates/horizon-world/src/worldgen/value_provider.rs": "3358b563db8cb0bc8a9cfbbe2b8b3e70941cd2d37a0b519fbb6545f8d0dcbb69",
"crates/horizon-world/src/worldgen/vines.rs": "ee9b79b65012bd86a838241d2ef708680f7fe8eafc8aa656dae9cf2abf3c6418",
"crates/horizon-world/src/worldgen/weighted.rs": "839840aae25302933bbd97a81a2336330e2d03a0ad1684e1e16ac769ed408e6b",
"crates/horizon-world/src/worldgen/write_zone.rs": "8e17a179764d3f68c05882aef35f6810c28a0000f9a83e58bd6030660b76e64e",
"crates/horizon-world/src/worldgen.rs": "e8e9f099ee1fcec8eedce31805d676d3f89c18e84f494a147ffcbfee23d3d54f",
"crates/horizon-world/examples/collision_context_fixture.rs": "b7bf0f48f7dc0129c1ebe43c11cb4cad00194b501c2bcbb3220bc8779e695ba4"
},
"fixtures_sha256": {
".local/rust-scaffolding-collision-parity/inputs.txt": "5945054e86700237a7b6de6b362a37a98bdc8afaa67004e8aaa92da1421b552c"
},
"rust_output_sha256": "33a33cd612c999ab21f1acbbdee522f2ec2b3f877d62f922c665715e3012e207",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "33a33cd612c999ab21f1acbbdee522f2ec2b3f877d62f922c665715e3012e207",
"matched_output_lines": 524300
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "33a33cd612c999ab21f1acbbdee522f2ec2b3f877d62f922c665715e3012e207",
"matched_output_lines": 524300
}
],
"scope": "Actual CollisionContext.getCollisionShape dispatch and native scaffolding behavior for all 32 scaffolding states, nine context variants, descending flags, integer Y extremes, nonfinite positions and adjacent double values around the top/bottom float-epsilon thresholds. Full shape coordinates, extrema, box ordering and cube metadata match. A rejecting world proxy verifies selection performs no world reads. Scaffolding placement/update/falling behavior and live movement remain pending."
}
@@ -1,201 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"manifest_sha1": "4fe1aa1ef8da1cb95c5bad1fb98890ca56dd8ca3",
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"java": "openjdk 25.0.4.1 2026-08-18",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"fixtures": 8338,
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCollisionContextOracle.java": "ee1525cc998c8b49fbc5318efffcec7b98cc8be3e4755d3bfc8458ac3c5e64c2",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaFaceSupportOracle.java": "9ce939a435842867786fed648951bbe77f6ab843f6df09af15f3deb1948c4877",
"tools/test_collision_context_parity.py": "75d6f01e072867d2bd286d2e518e123fcfe055a11ac1705ec99ecec3975cb8d2",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "cb1e87d449114a63edd904c0559d631e8fa9feeb27efd6539aacdcfeae178876",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"crates/horizon-world/Cargo.toml": "977338bf3e654193685b015d383493b9f59ff6f5d6210bec212cef8ac4a50bed",
"crates/horizon-core/src/bin/density_parity.rs": "e5b1dd33b7d01306c73cf072629b4fb186e9ab87b672a00108999d1a72263fd0",
"crates/horizon-core/src/bin/float_log_parity.rs": "4a655fcf8822ee7668c4bd126bc84d0b118864a6fc7f5a6aeee667d8bf2590b1",
"crates/horizon-core/src/bin/geometry_parity.rs": "27f6c09fe5018ac3de8e70e0f0bbf78f9abb14f5e4783bcaf46e8ca87b9c6f8a",
"crates/horizon-core/src/bin/noise_parity.rs": "c135bfc708d853e7061e81487d2cfe10de64b2f65677d3b4837cbfe0b8341010",
"crates/horizon-core/src/bin/parity.rs": "f35d928c66f958de39fac5e7e836a657eed95f83599e84899f7ea7a5802ba481",
"crates/horizon-core/src/bin/tick_parity.rs": "a54c164fe4814034d369947a887f5273966f5a878ba849204b80d1c729526a8f",
"crates/horizon-core/src/biome/seed_hash.rs": "5afbb4921c750826b395a08bf06f382fc7f01b5759a93de02a2749c523e2a317",
"crates/horizon-core/src/biome.rs": "908efa8cd4aa0a7adf1cb5e1a222e3dfb640eed5e9172e0fe7f0d1287afae7e8",
"crates/horizon-core/src/carving/ellipsoid.rs": "09232a7588610e8a9176fd9c62d40afb1fb89f2ecab6d555536a1d847b142d86",
"crates/horizon-core/src/carving.rs": "0aa3093caa0437868a8c0ed52a6c6e1993bd51c03583c670a2837e749eae5426",
"crates/horizon-core/src/density/arithmetic.rs": "372faec96c923e2cf4aa6c66c1ac398e676853274557823850dbc8933dd15ab1",
"crates/horizon-core/src/density/beardifier.rs": "bb1052e27dae4a01954ca78d7d5babafef85f3b2c704ccaf1920cb85a098cb50",
"crates/horizon-core/src/density/cache.rs": "38d0b6c9dd04ffef979fdad3f29cfebf98d331c8c9d430be5f39aa34f6c30975",
"crates/horizon-core/src/density/end_islands.rs": "168b9384237bd2e41d0ae5a74e944da4dc74e493bdec31fb73184c9a49e3de55",
"crates/horizon-core/src/density/graph/compiler.rs": "ac67deeb16f16d0859aa20e5a165811a29aca0b910037ee6bf5098211f3a6ede",
"crates/horizon-core/src/density/graph/mod.rs": "b776e7da934cb03051a3053d56d461c71e9978e084922fe4194147aa580c07bf",
"crates/horizon-core/src/density/graph/seeded.rs": "6bcdcaa3dffcfa9df673bbbea35120057a16ba3d2b506c52709c36cf8976b74a",
"crates/horizon-core/src/density/graph/tests.rs": "6bfb8cbff462587dd147b0775ea01d370abbd97544b9bd596c792df1b5f7e634",
"crates/horizon-core/src/density/interpolation.rs": "8c890f52b6467f38a94c654986a6a484b8e0b296ab98c398e60a6ce465b5b010",
"crates/horizon-core/src/density/interval.rs": "b42629163baa6b599a233afe8596d1c370cd81d015cc6fc36a9663aa47b98424",
"crates/horizon-core/src/density/mod.rs": "ca0d77d3282e3746ddcbc92bee97dbf640b9a56214e6ac1537f51f9a5b63d6e7",
"crates/horizon-core/src/density/power.rs": "d5b7270a128d4264268cd772109ad16d71a8ec3ff2d3b63b84cb985296d54a91",
"crates/horizon-core/src/density/rounding.rs": "71840c5206ff8d218ac29bf6f66915d5212764ba270c675711a866ba5b55a7a6",
"crates/horizon-core/src/density/selection.rs": "0dd26af2e85004ec5e053039ad11c384c17c56ace9ab45eb3f5cb3503c0b0330",
"crates/horizon-core/src/density/slice.rs": "5d77605573c0deda47778f1f78f7fa3fbf1944d8f5efbcc65cf589181cadf80b",
"crates/horizon-core/src/density/spline.rs": "6bb2e40f940fc6544d6fb09cb0b8cac722be03bc663dbdfb0f61faae207400bc",
"crates/horizon-core/src/density/surface.rs": "159e0e69cda74f870e80ea64fe523c4397e64af4ccb861bb9fd07b2c3cb91b00",
"crates/horizon-core/src/density/terrain_noise.rs": "8d0059d25eb5d248cb97a4c5a2e670d61528928ea151495c004f25adb723fe3e",
"crates/horizon-core/src/density/tests.rs": "7817796ee40d0ae241bfbebec6bca190e0a8e7d5a1caa8ddf858c3eaa58b8858",
"crates/horizon-core/src/density/world_fields.rs": "c1ce305cb8046b384d90c564cafb24af7365d580389637910f3d8b0cc18eb583",
"crates/horizon-core/src/geometry/mod.rs": "dc92f73885dd0a7760743bf74f1ab8afa839d61cef2dfef890f8a23b67b4742e",
"crates/horizon-core/src/geometry/movement.rs": "930e34abef6f6eeec1ee7a6c920b5ba01bfe37b90678884490f4be53241f6b96",
"crates/horizon-core/src/geometry/shape/create.rs": "189812b91d5e0e3ad963afcd1a6e2831b31b8188df91a904ef27061e644806ad",
"crates/horizon-core/src/geometry/shape/face.rs": "f243bce81384040a95ce7984b02b5699206c596c537b2713097e86005b4d3a5c",
"crates/horizon-core/src/geometry/shape/join.rs": "f1b51887b7bf9482557e3ffa99e136f2e5db07ceeb05fdb116adf45e87129075",
"crates/horizon-core/src/geometry/shape.rs": "e8d88a763de1525f77a30b99591641e8a8b80946263acbde035a9bcc356df960",
"crates/horizon-core/src/geometry/sweep.rs": "abd6009c61555161ef2f18b431b2aa384b126c0871cae8b96a62358498a56a1d",
"crates/horizon-core/src/geometry/traversal.rs": "77a3da570a0b85582b669cf4d841cba4b06327006dda26d4a26df4e8ce05bae4",
"crates/horizon-core/src/geometry/trig.rs": "05cef9341a298a474221a0556a11ddf47650393ea7a97b4b2022a4da6628fe37",
"crates/horizon-core/src/lib.rs": "4255e16837fde42a52ba118f60581d197c571bb530b60d635e506184ebf4db0b",
"crates/horizon-core/src/noise/mod.rs": "1dab5a713abf702402e69ace1bf9e476bba544b0ede5a61c3c3afc60af0a03f3",
"crates/horizon-core/src/noise/normal.rs": "e9e7a46472a54a02c98c46da819842090567153b32fe0c84249009ef19af7aad",
"crates/horizon-core/src/noise/perlin.rs": "e73815447432eab7542f67366cb3f1b368d164e33f6c9cdbd045ac8e4db0932a",
"crates/horizon-core/src/noise/simplex.rs": "6c0dbc15b2b7510195dd28fceca01dcaac1847ccc4a84d299c351589c642fe7a",
"crates/horizon-core/src/noise/stack.rs": "7f6ef0e7d920139ef1a6ad3ec5640f92765715f86dcc5ec29f1a149984f45fa3",
"crates/horizon-core/src/noise/volume.rs": "3f05d2b1780acfdfee60037677d309937a5033b45ef428fc2d540942d4b56b43",
"crates/horizon-core/src/position/iter.rs": "32d2d8e74821cc4e49e3354202d35d3120e4415bfdda9375a73f2137ef651129",
"crates/horizon-core/src/position.rs": "e10101088e6902386b9b6d27773d44312f1ff72bebb19e57967a54945dde9dcd",
"crates/horizon-core/src/random/hash.rs": "0f88a127a1ba2705d3d6c0ebd009324d6ba86ffa2d27edf2d2a84765e690e4a3",
"crates/horizon-core/src/random/positional.rs": "35494745e5d4cf89e282c3ae0ee245e9f2640ddbbc03bc0055df742006a9c862",
"crates/horizon-core/src/random/worldgen.rs": "9f07ff33bcc038d34e27aa5465753bb21df18f2975e43cae201f709bc186945a",
"crates/horizon-core/src/random.rs": "ddb95d3a83e28ad605ff1f49f5df270cc543ca5ef1130e37d989dc74c8d861e6",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/src/text.rs": "e6553ddb5db5039e8dc4614b6a6dc9f35a26dc3d1673b68a04e72e7983b67abb",
"crates/horizon-core/src/ticks/generation.rs": "be1237e790693f633a61714ddae68c6506a777588a8a3ab5efbe53a35774dbd2",
"crates/horizon-core/src/ticks/heap.rs": "bf28afab8af77c3d243aa96cd8a1fb8d934140a4dbd07dbfdbf4e7908bb4b845",
"crates/horizon-core/src/ticks/index.rs": "1f1a6a568c2a30eafecb020ca4d5f5fc414860de85b8b381fc419a2e3e65c24a",
"crates/horizon-core/src/ticks/mod.rs": "01634630668172516b8b79d0907bad47f6e2c543a6d499c2fa4b201823b375cb",
"crates/horizon-world/src/bin/worldgen_parity.rs": "3143ceb9b56eecfd7667e5feb5f9f0cd13cfb8754b38d4ea338dbba97f2819da",
"crates/horizon-world/src/block_collision.rs": "a40c9d7a4e0a734c124dc856e31359fd4d8de3d1bfc79c86787afa8e8e05e480",
"crates/horizon-world/src/block_entities.rs": "a9deae92e6e5a1fcf4f0476c33ea4d170ddad6fd4b3303e1bb66d933973d5e06",
"crates/horizon-world/src/block_placement.rs": "524f4892d50bab77b7d89d19f7b048ffe746996f2ed7f376db2c6ab00ed75c24",
"crates/horizon-world/src/block_properties.rs": "b0bd8a983336c48e488a20caa77dd5c39b1a74bbd14ebc03b3b64556a1c864fc",
"crates/horizon-world/src/block_render.rs": "8df52ee11aef406a1571198a64048062a0ef6864e0058d9293a57f64b73c916a",
"crates/horizon-world/src/block_support.rs": "ade4fbd47284b450dabdd682dc86138b2ac05a0fd379525d7110648908245476",
"crates/horizon-world/src/block_survival.rs": "28ce64375e09819a4f13da9cfbe37c08b5ad0daf01b289c1c360b4567e50e811",
"crates/horizon-world/src/chunk.rs": "8843e6f48dbbc4245ce4e95564dfba3a4d7a051ba0b1577fb038c07adb0ff0f9",
"crates/horizon-world/src/chunk_status.rs": "dbb8583cfa775203c544d24d69e03720385428f15a267a561356c21f5025e9c7",
"crates/horizon-world/src/collision.rs": "05313e0c1f3089524fe029f9aac3e439cd47f1c9584c8c7e154c9adcfa88c335",
"crates/horizon-world/src/collision_context.rs": "3053db15dff5776571a2c919634362fe43100978867f9e3ac46b2299563a6d4d",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/dynamic_support.rs": "5996bc1c436fb6215d8fc3d0bb4de5dd9b966d842d432580d624195771697fb8",
"crates/horizon-world/src/entity_obstruction.rs": "a4b28a19bf83b23611c59d94535c488db37e4aee24b22c973c545910894a809f",
"crates/horizon-world/src/fluid.rs": "a0a1f34ba94d8b59dc975becee8952960764d67ae08cf2d6a8bcd40a614b15c4",
"crates/horizon-world/src/heightmap.rs": "a5edef082b5af40d814421ea17e129b3b06d70abee6434ed263e4bba58571698",
"crates/horizon-world/src/lib.rs": "8f77b4a1c5e25ecf9336477c12e3141fafc0cd8884f3b198f2ec93b0eb47ae49",
"crates/horizon-world/src/main.rs": "fce57418b8c22a6a0a9044baa89ed3d9c243bc2e8413fea3ff0f32985daba021",
"crates/horizon-world/src/nbt.rs": "60262c3de8c8f68bc2da0370ccb17393d32b85f5f5022c6358599a7d32119ea6",
"crates/horizon-world/src/piston_shape.rs": "399c2337103b8e7e0eb5667227c5aa14f9549d6a467b7be7da3d0717f0263500",
"crates/horizon-world/src/region.rs": "72b642e87fed37ed17f54d4c30f96c3b64d26c14bc0589c31ef40ff1616188fc",
"crates/horizon-world/src/registry/json.rs": "7a683afcd1742c5307756927d7f0aa779c7d7992af87d8d371dd98108728e235",
"crates/horizon-world/src/registry.rs": "f2e58b2b4d944ac8fc6226bd3352cefc3d2052d8473e02ccf7dc402b176df435",
"crates/horizon-world/src/retrogen.rs": "6efd36a6293756688c1990a7965bd65609d7c5e2bf2a5f4f01d54932d2b9386b",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/worldgen/anchor.rs": "d156b8a0b147a274cdd143409b441f4f43edecde6e8ee14ef9cf0309f743143a",
"crates/horizon-world/src/worldgen/aquifer/config.rs": "fcd2cc3a520c1527c88f095a3b5d38487e7ebb1ccecc5f757f93d04a069add4f",
"crates/horizon-world/src/worldgen/aquifer/noise_based.rs": "74daaa389b5c3dfdc99214dfff256a9e172f83548d2326cbc941d9637cc53fb7",
"crates/horizon-world/src/worldgen/aquifer.rs": "cb4b66d87de3f9f79ae6ffe4badd6f0f44886cd42ad9de2771b8b56c4f1e28c7",
"crates/horizon-world/src/worldgen/bamboo.rs": "d9b47113c99be34256e58308bc6f40072ff25c579d6bf995182aa862c0006102",
"crates/horizon-world/src/worldgen/biome.rs": "3fe316b875aa32683759c337dc71f624910faf0812a2d6d83b8098d6d0bac7a0",
"crates/horizon-world/src/worldgen/biome_chunk.rs": "8fdfe6ebe3ffeca97611fd5991a5bc6b2783ea1c62f4d8ef3b2dd53c04a5dc1d",
"crates/horizon-world/src/worldgen/biome_predicate.rs": "bfc581bc40077cc74ffda43e990a55fe997adc04c7130f98e039c3305ca79aac",
"crates/horizon-world/src/worldgen/biome_source/codec.rs": "2b9e4f5d679eb444cb73174f511e3b9f32e9eb138248ab12cffc6cfd76adf3a8",
"crates/horizon-world/src/worldgen/biome_source/runtime.rs": "f0b02c1521178e4d0377c6ca62694604b6a773f1f234f070ff0cde4685911d45",
"crates/horizon-world/src/worldgen/biome_source.rs": "e181e1736f3e0b75f7091a24c88de3fd116e01b98424d02382aea7a503d1eb54",
"crates/horizon-world/src/worldgen/biome_temperature.rs": "cde4bbab5e260c4065b113376c423b8511ade93c5aa5fd976e245ee8a58b5ad1",
"crates/horizon-world/src/worldgen/biome_weather.rs": "96b1f9494559ed31d06257b83d604d00cc069ccc8c7b68094117e034b4a71bd7",
"crates/horizon-world/src/worldgen/block_blob.rs": "c608c57b3d77279646ecb89e50677dd8e452b0422ffd357ba755536c5589eb89",
"crates/horizon-world/src/worldgen/block_column.rs": "f72c21a9066ee0aa68c2fb79fba436d05afb14c6ef5a2cb012f1ed35fc17cd22",
"crates/horizon-world/src/worldgen/block_feature.rs": "36b4e46ee7f7f73bcb94d8bce8d99013e4b16234c9a03542eeb3186e88dd1c21",
"crates/horizon-world/src/worldgen/block_pile.rs": "623e369b77e0526ed2756485a6c0bb09683cd28ad8876dea907360ca6665b39d",
"crates/horizon-world/src/worldgen/block_predicate.rs": "074c692367e3f2191a1bb28d87b23402430a843c246bd30a4ea838ee3500280e",
"crates/horizon-world/src/worldgen/blue_ice.rs": "eedd77bdaff808330b864166d303378096daa5c7d235e925770b171c05109247",
"crates/horizon-world/src/worldgen/bonus_chest.rs": "05d0f63fbc7412f13ba1fa37a7238114b8f70bfff318beb2dece590482d49cc0",
"crates/horizon-world/src/worldgen/bulk_section.rs": "eecf61532d7793f853884c5a18a7f436a59835c7b13d3ec9075804511553c9ba",
"crates/horizon-world/src/worldgen/carver/canyon.rs": "509c4d5a9d689849e98e894ab14a9fbf82d10707d38e9cc688ded3c4778df3e2",
"crates/horizon-world/src/worldgen/carver/generation.rs": "a4498d0d1457536de3922a08e9c40ccce8d2ef9cc263801c15a412327513c098",
"crates/horizon-world/src/worldgen/carver.rs": "46b251e28225fe1250de38f49dec5dacda4e2c4ba1e556e21e6d1e14e2651fc3",
"crates/horizon-world/src/worldgen/carving.rs": "4e77d4e5c4a0ca55ca3563b9bdf6f379342e0bdf9d019d60f7bc57ce4afb5fbd",
"crates/horizon-world/src/worldgen/chorus_plant.rs": "29224c164ede919e280a65a68f155c873e2c8fd0aa7d7e244d8fa9e468760250",
"crates/horizon-world/src/worldgen/climate/codec.rs": "d567adeb5d837816fca69102db51d790f71aec1b51c09298230d24612e400a14",
"crates/horizon-world/src/worldgen/climate/index.rs": "c5ce61679a5f0e0f2f0af2a373424effa124d0cce8250609eff38b7034650756",
"crates/horizon-world/src/worldgen/climate.rs": "1b9ad44407f40aee4c1cd5357a5c9c443c1b105728f01cf5c644072f99f8357e",
"crates/horizon-world/src/worldgen/decoration.rs": "75a79b20b21e133816e729f16e758be6165d0db18a64bfbd5fd3618325a2adf3",
"crates/horizon-world/src/worldgen/delta.rs": "c2bf49ddf3231d28c109e68871429bc13d76a7bebe14eb33e84aa856bdd66145",
"crates/horizon-world/src/worldgen/density.rs": "65a98c156a290a6b374ef670d28cd5dfbe0aa93171824d1bbd96422536273f84",
"crates/horizon-world/src/worldgen/disk.rs": "6f8f9e059755af44c9bfa1b91eba54a7d13fad811dce31717c5502d7f6df33d7",
"crates/horizon-world/src/worldgen/end_gateway.rs": "f53fde77d6a36a525cd15d890003b2c129d0689a4cbfa2cf443a0c2e3acae040",
"crates/horizon-world/src/worldgen/end_podium.rs": "8f6d0d6d60ff0fde63de5781e867239db321f82cf12639f0537d410a3731ee1d",
"crates/horizon-world/src/worldgen/feature.rs": "40500af71ee6628dfb27518262d99f08d0383ae6c7b9397452feef0c213eadd9",
"crates/horizon-world/src/worldgen/feature_catalog.rs": "efc7b17b227e71622ef34108be9abd010f5675b68ea0409fcab82581d9aab88a",
"crates/horizon-world/src/worldgen/feature_graph.rs": "da132fca9fdafb0d89a917d5f4b68c60b70fb33cadf948a107da0e35d83dcd91",
"crates/horizon-world/src/worldgen/feature_region.rs": "df0ff142a461cafa9a3b42b949ad3376887f2be8d4ea5cc794a3ed2e977bb499",
"crates/horizon-world/src/worldgen/feature_sort.rs": "3488a093dfe1321aaa29d8a30cfb115d8e666a81bf195514e87b170de626835c",
"crates/horizon-world/src/worldgen/fluid_predicate.rs": "64197c9e63bebf1ce04bc280bfe980bb6c1b9aa887ca5cded904aeb0d9ae6c46",
"crates/horizon-world/src/worldgen/height_provider.rs": "368d4dc119854742a045c4a717679c921456da681fc5f71aa9b37102d6f33b47",
"crates/horizon-world/src/worldgen/material_condition/codec.rs": "09b909bc384472f76d163c8069ec6b507c7d5c6a028a36d5e0e3df20deff7b3b",
"crates/horizon-world/src/worldgen/material_condition/density.rs": "df9d0761e978e5010663ae8b44f2d6c1ecb4907331e333bdb6a2b487c1e107de",
"crates/horizon-world/src/worldgen/material_condition/library.rs": "a55534c5da97575a819af5a7dc0dbec9069993fa8b2619c6c9d5576946e683fa",
"crates/horizon-world/src/worldgen/material_condition/noise.rs": "ffb59cc6be2275d7a5621bf7d768527e74a8326ed7ad78618746711540921675",
"crates/horizon-world/src/worldgen/material_condition/rule.rs": "fed643352efbcb1f68f29b6241896617db889fc7c577a6247564e01922fec1fe",
"crates/horizon-world/src/worldgen/material_condition.rs": "d638dcb8cbcb5da20b3cb29602b0ae6a86c4fdf9d8c0fb725de8ec5fc108717e",
"crates/horizon-world/src/worldgen/material_extensions.rs": "ab806eb679d5116e1aebb64fca70e1499ae71f83c9507a8cb4c3201c2b1bf037",
"crates/horizon-world/src/worldgen/material_stage.rs": "698cbc786eff13c246e2bc2ea062401918cd4265899fbc3d53abc87e45a8e7a1",
"crates/horizon-world/src/worldgen/material_surface.rs": "5d37b90099df3d6da0845dab164e71469fb287019c2ee74bc6714f3b9d6d6d5b",
"crates/horizon-world/src/worldgen/ore_feature.rs": "83b89fd3be691c5412c0215b6abefdcaa44119a05aa41217e061970eb7e12ebd",
"crates/horizon-world/src/worldgen/placement/chain.rs": "9218399b4d3757f7bbc550d7729a7201f32a1c83a7030865e0c12aab8a80d116",
"crates/horizon-world/src/worldgen/placement/context.rs": "a278304795136677ad4b4933ea50c972b9729a1c671c03fa309c193e224b1fd6",
"crates/horizon-world/src/worldgen/placement/layer.rs": "a0f5ca776f33f9d4f72b8fdcd163426152e5e43cb4a7572fc1d4fc57bf965de1",
"crates/horizon-world/src/worldgen/placement.rs": "b0397e5818fae84358546193a95f84bcb0b5bffafce909e6fcb3386179ee8023",
"crates/horizon-world/src/worldgen/replace_blobs.rs": "bf3377d86d2570cd15288ba69dde64a2cf67c5bcbb9a31d0c23421964af74afa",
"crates/horizon-world/src/worldgen/router.rs": "2cee7cf15a0d2ada12be6b39d83e78177fd3033922e4f4cce87a64073cec2847",
"crates/horizon-world/src/worldgen/rule_test.rs": "d1662ec492489ebaa4b87e20f9a8c809dcf3a223a151211bd65ec241a63692fc",
"crates/horizon-world/src/worldgen/settings.rs": "a8fe87752e1982ef11cb67f8d80d8e3428b2c27db178044cb425ba803e689e59",
"crates/horizon-world/src/worldgen/simple_block.rs": "9ba1a88d5db4925f8c37366557887f776c805f9a6444781615b5dbaff52e92a4",
"crates/horizon-world/src/worldgen/snow_freeze.rs": "9040be3d5c7f8f0fd812d2df45e154bf8a9eeef038530b83fa4159d246eac35f",
"crates/horizon-world/src/worldgen/speleothem.rs": "c71651c1c97818a8a85863e14414d6139ea3bdeb897fa422043bcc1499d99aae",
"crates/horizon-world/src/worldgen/spike.rs": "eacf0d9d3d2bc3d4bcf62bc87555f90031138236a5bfef0eb5270204f7c2a4fc",
"crates/horizon-world/src/worldgen/spring.rs": "830849e9b89fcdf09e9b06fbefdcdebe3c8c3f82804f60b8bd5de04ba303cb62",
"crates/horizon-world/src/worldgen/state_provider/catalog.rs": "c8687e15a4887a9200c8d365857d801efaa8f90e669eee3e600a1db4905119eb",
"crates/horizon-world/src/worldgen/state_provider/noise.rs": "7ee369c2a032e5620cb9bdf9ee7adad1f70870fb0a27efb7b7c514d92f83491f",
"crates/horizon-world/src/worldgen/state_provider/properties.rs": "9909139aaca1dc4f743957257fadaa9d423d21fa401fa9abc050505f79365139",
"crates/horizon-world/src/worldgen/state_provider.rs": "be29ada818826a90afe01ab60916360fdfc4cbde5af15c9359cd56b1f1f7b156",
"crates/horizon-world/src/worldgen/tags.rs": "d35ded93fe6e95ea045cadcf4925e656dc34ef832b742179b9ad0cc49f902f31",
"crates/horizon-world/src/worldgen/terrain.rs": "fd1f2e0afc15daf66f484ea40a1f2b7013650bda0941b23c64c81ee9f79cb673",
"crates/horizon-world/src/worldgen/underwater_magma.rs": "7317e40af5ee5a9780f90ce358fa5d3e7f5b3d513b731df6ff97754d9c2a0154",
"crates/horizon-world/src/worldgen/value_provider.rs": "3358b563db8cb0bc8a9cfbbe2b8b3e70941cd2d37a0b519fbb6545f8d0dcbb69",
"crates/horizon-world/src/worldgen/vines.rs": "ee9b79b65012bd86a838241d2ef708680f7fe8eafc8aa656dae9cf2abf3c6418",
"crates/horizon-world/src/worldgen/weighted.rs": "839840aae25302933bbd97a81a2336330e2d03a0ad1684e1e16ac769ed408e6b",
"crates/horizon-world/src/worldgen/write_zone.rs": "8e17a179764d3f68c05882aef35f6810c28a0000f9a83e58bd6030660b76e64e",
"crates/horizon-world/src/worldgen.rs": "e8e9f099ee1fcec8eedce31805d676d3f89c18e84f494a147ffcbfee23d3d54f",
"crates/horizon-world/examples/collision_context_fixture.rs": "c4df3b01bf9d7e58076c848fbb41f93677ea4f0fdaab768a131d9e77c7bee5cd"
},
"fixtures_sha256": {
".local/rust-collision-context-parity/inputs.txt": "60b49e91a7a4999cfb8eb6ac3fbc6ec0a931d68cd53f9737959a2bd2b42be7a5"
},
"rust_output_sha256": "7b23eb34c86c3db5a9e90bdd8ef772b79b2a06c8460542e032589f7962fd8f64",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "7b23eb34c86c3db5a9e90bdd8ef772b79b2a06c8460542e032589f7962fd8f64",
"matched_output_lines": 225126
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "7b23eb34c86c3db5a9e90bdd8ef772b79b2a06c8460542e032589f7962fd8f64",
"matched_output_lines": 225126
}
],
"scope": "Actual CollisionContext factories and EntityCollisionContext/Empty/PositionCollisionContext queries on controlled player and marker snapshots. Checks entity identity, captured descending and placement flags, fluid collision flags, empty-stack AIR identity, height thresholds including f32 epsilon, null factories, callback arguments/order/failures and all five fluid type pairs. Entity lifecycle, inventory mutations after capture, experimental minecart contexts, contextual block shape dispatch and live movement integration remain pending."
}
@@ -1,307 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"java": "openjdk 25.0.4.1 2026-08-18",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"manifest_sha1": "4fe1aa1ef8da1cb95c5bad1fb98890ca56dd8ca3",
"commands": 16770,
"command_counts": {
"noise": 2111,
"quantize": 4116,
"index": 229,
"climate_parameter": 25,
"climate_point": 183,
"noise_settings": 217,
"settings_create": 182,
"aquifer": 9136,
"noise_aquifer": 379,
"registry": 24,
"router": 168
},
"noise_aquifer_injected_failures": {
"0": 3,
"1": 3,
"2": 3,
"3": 3,
"4": 3,
"5": 3
},
"noise_aquifer_outcomes": {
"1 false": 5800,
"0 false": 9995,
"default_solid false": 12655,
"2 false": 35365,
"0 true": 1114,
"2 true": 2021,
"1 true": 43,
"5 false": 443,
"5 true": 5,
"6 false": 295,
"6 true": 8,
"7 false": 49,
"7 true": 1,
"4 false": 51,
"4 true": 4,
"error false": 17,
"3 false": 81,
"error true": 2
},
"noise_registry_entries": 64,
"density_registry_entries": 55,
"noise_settings_entries": 7,
"biome_parameter_entries": {
"minecraft:nether": 5,
"minecraft:overworld": 7594
},
"biome_tables_sha256": {
"minecraft:nether": "09e477f851380a6e726ea85fee39cd1d41c7f160fe424f58cb3f0056b5c11218",
"minecraft:overworld": "6bc45ce2eed04b6afecdfaf2cf89273e83dad071aeb45638e181d33fe5180f57"
},
"fixtures_sha256": {
".local/rust-worldgen-parity/registries.json": "c6868228cc1002755dab31d947e953cc4be785a1b6ae82697755817a238b7de9",
".local/rust-worldgen-parity/inputs.txt": "4afb482c8aa6e654ef47b9696f76c16fa862414248202c9bf748941bfc8d0877",
".local/rust-worldgen-parity/biome-presets-client.json": "b03e2fbe85c191a22f333bc989bd2a73c66f0f9fbcd9ddb54774f17c247832e9",
".local/rust-worldgen-parity/biome-presets-server.json": "b03e2fbe85c191a22f333bc989bd2a73c66f0f9fbcd9ddb54774f17c247832e9"
},
"noise_resources_sha256": {
"data/minecraft/worldgen/noise/aquifer_barrier.json": "864a9d66a03b081adc8d4bf51a6d0cd5fdd94a0ebf1cecadec2aed9e549db7e4",
"data/minecraft/worldgen/noise/aquifer_fluid_level_floodedness.json": "e755b926628bc49edf48a3bd3b1e1bc3e2895b774f5e2e81f1d4340782a9fc56",
"data/minecraft/worldgen/noise/aquifer_fluid_level_spread.json": "6afc3f09b6616f799d739b5b114c4436059dcc60308af55fe96a8594de815214",
"data/minecraft/worldgen/noise/aquifer_lava.json": "96e1c4e411ffe302c5541cd2ee8462e1992f0290d623c560f353c39981737346",
"data/minecraft/worldgen/noise/badlands_pillar.json": "79c0d0628db949d3b83bbca145da427bcdc3ff585b0ad736f7cb20e4c593c9a2",
"data/minecraft/worldgen/noise/badlands_pillar_roof.json": "7f137a0382721b8c7b3227e65dc32a3f6d9c3d5893458b03e892797ae31d85d7",
"data/minecraft/worldgen/noise/badlands_surface.json": "79365a5c2017e93878d989a176520ba9cbdf8685cff8b3cb148730d949d98b09",
"data/minecraft/worldgen/noise/calcite.json": "331259d84572c32b4b268d069e0132da9e6623ba614080e34b815472c7f4ee0c",
"data/minecraft/worldgen/noise/cave_cheese.json": "24c6846b7fc1f7c652bf185797fe98b943146b6aaf8766d1bff2066c59b7ed24",
"data/minecraft/worldgen/noise/cave_entrance.json": "f75146a7b1a033998edd3c77319f78243fe933bdcda2067b78658940f145cac6",
"data/minecraft/worldgen/noise/cave_layer.json": "7f137a0382721b8c7b3227e65dc32a3f6d9c3d5893458b03e892797ae31d85d7",
"data/minecraft/worldgen/noise/clay_bands_offset.json": "7f137a0382721b8c7b3227e65dc32a3f6d9c3d5893458b03e892797ae31d85d7",
"data/minecraft/worldgen/noise/continentalness.json": "b7ce5ac29a2c7a7cfbfaa1e1eeca9ba8f4a52139e59318850fa2407242c69ba8",
"data/minecraft/worldgen/noise/continentalness_large.json": "76834cff0227d52b19b5932142925f4fc639e713c2180e489f813701ca45f53e",
"data/minecraft/worldgen/noise/erosion.json": "af8a7a0f16ff3e568ad646df9cbc28e04a31b16dad4f162705c0f7c747da6983",
"data/minecraft/worldgen/noise/erosion_large.json": "d20c2c6ec805a366b105924b3cee29ac5b84cc06d636b539ae0047aac413b60a",
"data/minecraft/worldgen/noise/gravel.json": "87d627634161e51a79512f3d3f42f990d2a185e35198eb5e2161939d866751e0",
"data/minecraft/worldgen/noise/gravel_layer.json": "a4b45bdb6efef2509b053b970f6e84250d7b16d54f3906bc7fcf2665ada2a692",
"data/minecraft/worldgen/noise/ice.json": "85d03cc06d6bc552dc399dcc90ca9749c2625ddf0049dc0f95684631a7c6e66e",
"data/minecraft/worldgen/noise/iceberg_pillar.json": "98816326f84a21ce29421a9cba3ad85e5a26069312c9819aaf5662691e777fd5",
"data/minecraft/worldgen/noise/iceberg_pillar_roof.json": "864a9d66a03b081adc8d4bf51a6d0cd5fdd94a0ebf1cecadec2aed9e549db7e4",
"data/minecraft/worldgen/noise/iceberg_surface.json": "79365a5c2017e93878d989a176520ba9cbdf8685cff8b3cb148730d949d98b09",
"data/minecraft/worldgen/noise/jagged.json": "d64347f4f9acb984075e3b4945b4699907ec6d893588388dd8f738f29f75f4d1",
"data/minecraft/worldgen/noise/nether/temperature.json": "5a67fbc28b5c2578b4ca5f6abdd115c715ea2ef1be3e1a7a8eb1a0de4c3a8f7c",
"data/minecraft/worldgen/noise/nether/vegetation.json": "5a67fbc28b5c2578b4ca5f6abdd115c715ea2ef1be3e1a7a8eb1a0de4c3a8f7c",
"data/minecraft/worldgen/noise/nether_state_selector.json": "116c8bf1d676fd3a3dea3908e074a4f4b7ee55d3263e93abf5889b41bfc77f5b",
"data/minecraft/worldgen/noise/nether_wart.json": "4518b186ffe4b65394a35276c8708037c6f3f73c7cb95ef6d41a5cd4b8d234f6",
"data/minecraft/worldgen/noise/netherrack.json": "cef60938a0304eec78a6bdebd24b80a45c5d1bad894c6c012e3413ecc485a81a",
"data/minecraft/worldgen/noise/noodle.json": "7f137a0382721b8c7b3227e65dc32a3f6d9c3d5893458b03e892797ae31d85d7",
"data/minecraft/worldgen/noise/noodle_ridge_a.json": "e755b926628bc49edf48a3bd3b1e1bc3e2895b774f5e2e81f1d4340782a9fc56",
"data/minecraft/worldgen/noise/noodle_ridge_b.json": "e755b926628bc49edf48a3bd3b1e1bc3e2895b774f5e2e81f1d4340782a9fc56",
"data/minecraft/worldgen/noise/noodle_thickness.json": "7f137a0382721b8c7b3227e65dc32a3f6d9c3d5893458b03e892797ae31d85d7",
"data/minecraft/worldgen/noise/offset.json": "45f51565587e2dc055271648037c0ec3466815e82f0d762e0198c16285fc8ae7",
"data/minecraft/worldgen/noise/ore_gap.json": "6afc3f09b6616f799d739b5b114c4436059dcc60308af55fe96a8594de815214",
"data/minecraft/worldgen/noise/ore_vein_a.json": "e755b926628bc49edf48a3bd3b1e1bc3e2895b774f5e2e81f1d4340782a9fc56",
"data/minecraft/worldgen/noise/ore_vein_b.json": "e755b926628bc49edf48a3bd3b1e1bc3e2895b774f5e2e81f1d4340782a9fc56",
"data/minecraft/worldgen/noise/ore_veininess.json": "7f137a0382721b8c7b3227e65dc32a3f6d9c3d5893458b03e892797ae31d85d7",
"data/minecraft/worldgen/noise/packed_ice.json": "0f51993727dcb0aa7c6cb9288e462443e711e9980c12927435126a3c45922786",
"data/minecraft/worldgen/noise/patch.json": "83a0052d4220c67c5513bce689d681e3af3325c18fec612cdd4941fc738f4be0",
"data/minecraft/worldgen/noise/pillar.json": "5a67fbc28b5c2578b4ca5f6abdd115c715ea2ef1be3e1a7a8eb1a0de4c3a8f7c",
"data/minecraft/worldgen/noise/pillar_rareness.json": "7f137a0382721b8c7b3227e65dc32a3f6d9c3d5893458b03e892797ae31d85d7",
"data/minecraft/worldgen/noise/pillar_thickness.json": "7f137a0382721b8c7b3227e65dc32a3f6d9c3d5893458b03e892797ae31d85d7",
"data/minecraft/worldgen/noise/powder_snow.json": "98816326f84a21ce29421a9cba3ad85e5a26069312c9819aaf5662691e777fd5",
"data/minecraft/worldgen/noise/ridge.json": "e05d077746b27d662a8c981807819df3e3bb1f1779d2245dd911c8193e03bbf8",
"data/minecraft/worldgen/noise/small_patch.json": "9ecc836feb68b42d717217e028f2a72112179f1097f5bd156b1d3f1db637732e",
"data/minecraft/worldgen/noise/soul_sand_layer.json": "a4b45bdb6efef2509b053b970f6e84250d7b16d54f3906bc7fcf2665ada2a692",
"data/minecraft/worldgen/noise/spaghetti_2d.json": "e755b926628bc49edf48a3bd3b1e1bc3e2895b774f5e2e81f1d4340782a9fc56",
"data/minecraft/worldgen/noise/spaghetti_2d_elevation.json": "7f137a0382721b8c7b3227e65dc32a3f6d9c3d5893458b03e892797ae31d85d7",
"data/minecraft/worldgen/noise/spaghetti_2d_modulator.json": "d210211c0c76c53f15908f0b004a7e98e9d753ed996cd5468f2068f2e23932d1",
"data/minecraft/worldgen/noise/spaghetti_2d_thickness.json": "d210211c0c76c53f15908f0b004a7e98e9d753ed996cd5468f2068f2e23932d1",
"data/minecraft/worldgen/noise/spaghetti_3d_1.json": "e755b926628bc49edf48a3bd3b1e1bc3e2895b774f5e2e81f1d4340782a9fc56",
"data/minecraft/worldgen/noise/spaghetti_3d_2.json": "e755b926628bc49edf48a3bd3b1e1bc3e2895b774f5e2e81f1d4340782a9fc56",
"data/minecraft/worldgen/noise/spaghetti_3d_rarity.json": "d210211c0c76c53f15908f0b004a7e98e9d753ed996cd5468f2068f2e23932d1",
"data/minecraft/worldgen/noise/spaghetti_3d_thickness.json": "7f137a0382721b8c7b3227e65dc32a3f6d9c3d5893458b03e892797ae31d85d7",
"data/minecraft/worldgen/noise/spaghetti_roughness.json": "6afc3f09b6616f799d739b5b114c4436059dcc60308af55fe96a8594de815214",
"data/minecraft/worldgen/noise/spaghetti_roughness_modulator.json": "7f137a0382721b8c7b3227e65dc32a3f6d9c3d5893458b03e892797ae31d85d7",
"data/minecraft/worldgen/noise/sulfur_cave_gradient.json": "4900ffd885ce33b220a673ba0a248504c78f9f2cdfce824106a237d9ad18a6a7",
"data/minecraft/worldgen/noise/surface.json": "79365a5c2017e93878d989a176520ba9cbdf8685cff8b3cb148730d949d98b09",
"data/minecraft/worldgen/noise/surface_secondary.json": "ae23cb210db7b64b66b327dbbf1e7b2acb5c15cb6fe5df0455eb29910d9312eb",
"data/minecraft/worldgen/noise/surface_swamp.json": "19e08e0d1dff257cf748d3cef79e939e8f25cc5e7226653c789008171f40695b",
"data/minecraft/worldgen/noise/temperature.json": "9b1d5a87d575abf2891882ec3e1544b964cd15fedc84ad14d2abbd3b48ee2e4b",
"data/minecraft/worldgen/noise/temperature_large.json": "4fe64b952b751eb7e45b4d1e274add508b504ee8bbc54cad417ce3a3b068d42e",
"data/minecraft/worldgen/noise/vegetation.json": "ff4c10776eb2822f9f66dec4e9878a1bc797aca711480bf8430f851ff9af77dc",
"data/minecraft/worldgen/noise/vegetation_large.json": "20f4a255e3f9452f4cf983b3efed71ead184d04f4070283f355ad4d97993d133"
},
"density_resources_sha256": {
"data/minecraft/worldgen/density_function/end/base_3d_noise.json": "38db7d590abc3144e3357a79562d649d9880bc2c62ddc99480d93f4b6401c9a6",
"data/minecraft/worldgen/density_function/end/islands.json": "6e4f02929580ecc34bfb059855b4e88d080dc7ca6c9984f216bdaa32e6b47700",
"data/minecraft/worldgen/density_function/end/sloped_cheese.json": "5dee072865321e57e5e231e60a57bfcd1919454f93da33b3c1651b3712f2cfb2",
"data/minecraft/worldgen/density_function/nether/base_3d_noise.json": "76cfd16e6fc2b1ce8bdb5f5ee277d431c167bc01afc2462bffff09eb5f0bd582",
"data/minecraft/worldgen/density_function/overworld/base_3d_noise.json": "2791a1e6c5c730eac1bd35aaea9a7ab22855872fdb92349192d045330fd4614f",
"data/minecraft/worldgen/density_function/overworld/caves/entrances.json": "63a1b8351e6dea212501c36f515f32e5a0e960228b5b5ccf0dc5b43855cbc1ab",
"data/minecraft/worldgen/density_function/overworld/caves/noodle.json": "3bce7453470fd37e3bfc11dc8584494aab094f9fd820038dc5592cb47e825a69",
"data/minecraft/worldgen/density_function/overworld/caves/pillars.json": "069d35fbdaed7d74521fc3e9355a94e778450b52a05f1efbd470ce3917b8a207",
"data/minecraft/worldgen/density_function/overworld/caves/spaghetti_2d.json": "a99c68ac415596788c84e93e81c96c9786e31db21a81157459a13272cda4cb1f",
"data/minecraft/worldgen/density_function/overworld/caves/spaghetti_2d_thickness_modulator.json": "4f987a0b9e8c0adb02df47034fa8b3cebfbfb2c8e607123614ef009a16bfaf6c",
"data/minecraft/worldgen/density_function/overworld/caves/spaghetti_roughness_function.json": "03bd1b405e53aeb75b6a3440d97975c25b6f11c7fc07149471b86c80fbdb6ea4",
"data/minecraft/worldgen/density_function/overworld/chunk_surface_level.json": "93a4e26ce4a1144c42040f52ca375f0dec94648c70ccdcc52db4a7f55ca526a5",
"data/minecraft/worldgen/density_function/overworld/continents.json": "0f2ff487c0556391ae2d56b7cab6990d45766ade2503236fe2669f83a64517be",
"data/minecraft/worldgen/density_function/overworld/depth.json": "9fcd7c8badcae4dc8e86303b0f72b05b5fd998d5bb7ac637729dd7e688688069",
"data/minecraft/worldgen/density_function/overworld/erosion.json": "8173a3df61a3c5cfe352fb4a8fa64e99840836e42f2f4b0ddf8035f4d28f97a5",
"data/minecraft/worldgen/density_function/overworld/factor.json": "f7cd1629f1a034504bd74fd38af5ea75a59257c565b5d919a6212e2e08778e30",
"data/minecraft/worldgen/density_function/overworld/final_density.json": "a7e6b9f4618e27cb08ec37a294d8ca2a96747128a8d65d788dc418fda372cfb1",
"data/minecraft/worldgen/density_function/overworld/jaggedness.json": "5e8acc680409ae0b56596be02954eb5b49a72069d004e5dcf9a92c5e106ccdb2",
"data/minecraft/worldgen/density_function/overworld/offset.json": "da6b4e686d8eb16c19443a1126168b6f2719712c02b690b9d7384ce53badf995",
"data/minecraft/worldgen/density_function/overworld/ore_vein/copper_density.json": "3b16d3a4499981f40bfd2b33786a99046bbca0c958f8f41692ffcbf44ae927d7",
"data/minecraft/worldgen/density_function/overworld/ore_vein/gap.json": "89ccfa58c6b8ae3e3954d2ff2dbcc42a8a3ae24a7b07437dbfb85fdced55945a",
"data/minecraft/worldgen/density_function/overworld/ore_vein/iron_density.json": "8de70a31c97e2a8299679770d53c8e366ace1aa8585e8d840375d25f85b72f8f",
"data/minecraft/worldgen/density_function/overworld/ore_vein/mask.json": "7f92df0b19e7d29fef01abc7025fea2bdae7a57453e186785cde2fc7d08aa5bc",
"data/minecraft/worldgen/density_function/overworld/ore_vein/richness.json": "3eb0183e295a5f9c54aab936b706b4b9d570ddf56c983ae89b91151e6e38fb9d",
"data/minecraft/worldgen/density_function/overworld/ore_vein/toggle.json": "49b9db48740578911d0f8a2de40f02eced3ae742f03ebb05fee381af579cc9ed",
"data/minecraft/worldgen/density_function/overworld/preliminary_surface_level.json": "4b6ce4c38ede0bec7485d4c029b9fcc7ceb5b26977c2c391a650fe8f3a3272b6",
"data/minecraft/worldgen/density_function/overworld/ridges.json": "bf66a03bd8474d09dad4da23f4b7e76816b83e23df9f53d9c0b7c529c25ed9c1",
"data/minecraft/worldgen/density_function/overworld/ridges_folded.json": "c8a4343b56273a476648a84fbbe07d8c473c1dd3769749260db6340ba5b37f9a",
"data/minecraft/worldgen/density_function/overworld/sloped_cheese.json": "5e2e7756881a4f2acf2e8c8dc826a04681939ff1dc7508ce868e865e92a069d7",
"data/minecraft/worldgen/density_function/overworld/temperature.json": "3c2f498cbf4636cd1fa7f555c14220a733c9d07fb5a1563f11c6144a27f31ce8",
"data/minecraft/worldgen/density_function/overworld/vegetation.json": "c902ef045f63a568ef4c3d834716c67b5835f0994997ee45756837de111a806c",
"data/minecraft/worldgen/density_function/overworld_amplified/chunk_surface_level.json": "378eef8542e7ee3adffeaf746e0c776d1e00ff75cf030d9244292acd796739f6",
"data/minecraft/worldgen/density_function/overworld_amplified/depth.json": "35bbe18bc8eaec3bc8d81f1b3130018874d6cc8fa516c1e8380bdb8caf68c803",
"data/minecraft/worldgen/density_function/overworld_amplified/factor.json": "b42bc13d4d3c1cbeb7c6dfa2e16f4ef532ad0cff3a92d20bace01711fee6edd4",
"data/minecraft/worldgen/density_function/overworld_amplified/final_density.json": "cde96d8a5efa63cd20cea615dd1172e5e6f2626e9275d359fa2864e77083ac4f",
"data/minecraft/worldgen/density_function/overworld_amplified/jaggedness.json": "9f9a8993ce50cd2f0736ef98c3f8ff55db02d47b2a3e4f6aacae7c45a3c95bcc",
"data/minecraft/worldgen/density_function/overworld_amplified/offset.json": "0bb9ae6088ea4dbfdf79f6f2b2eed789c68e9a4e919a31bf912f91ddeda28e8b",
"data/minecraft/worldgen/density_function/overworld_amplified/preliminary_surface_level.json": "e8a82a9dfe183f4e624ea7a268efa2c54376caf99139596a26ad1dd27e887e5f",
"data/minecraft/worldgen/density_function/overworld_amplified/sloped_cheese.json": "d8609154b76d0eefcfbc3746fa84f32cb04c5817a2fd1b80e72ee0ae9d88e96c",
"data/minecraft/worldgen/density_function/overworld_large_biomes/chunk_surface_level.json": "72f29b5fa9c01afa296d3679e6be662ee1b0bfdc1ba40cc2092ea74380be5c47",
"data/minecraft/worldgen/density_function/overworld_large_biomes/continents.json": "cfab013269cff17cfdf95497f87e70591378e7a39da44a241199fb64b304d411",
"data/minecraft/worldgen/density_function/overworld_large_biomes/depth.json": "9ec8ced85b58494f5400d4a5f6a27f1d4d44271d7a87adb8c5d842319eb5997f",
"data/minecraft/worldgen/density_function/overworld_large_biomes/erosion.json": "773d626db8e356d92a321270895ce085287d2befcb4504842371c38fd10102ac",
"data/minecraft/worldgen/density_function/overworld_large_biomes/factor.json": "0e7aa57eca20ebd6d2f089a9a4a34502efe902295812650f71b2ff087bb8b15f",
"data/minecraft/worldgen/density_function/overworld_large_biomes/final_density.json": "6f644644293c5489c499dc57663f2c12de60fc720bc4f1120efd343246eb159e",
"data/minecraft/worldgen/density_function/overworld_large_biomes/jaggedness.json": "30090703d4d9e493d40d60e06ee12f1310a608e20b73aeb8f86efa8e31b11453",
"data/minecraft/worldgen/density_function/overworld_large_biomes/offset.json": "75517306420732023e2dfeeb253439d8f0edcde9bb8b10ee7870d1bdb072ec22",
"data/minecraft/worldgen/density_function/overworld_large_biomes/preliminary_surface_level.json": "ece7767faac91980f5349ddfdc6040dc4ebbfce71a9f4d5842fa1b7bb169db3b",
"data/minecraft/worldgen/density_function/overworld_large_biomes/sloped_cheese.json": "347e160b5f951137b5f82a39c18572f8851c5a22484d11f31d1f90f5e5f6ac99",
"data/minecraft/worldgen/density_function/overworld_large_biomes/temperature.json": "051138f2c2f0ca4050b92f7320ddea461dca2038a49eb6f9931ecbf39129f4ef",
"data/minecraft/worldgen/density_function/overworld_large_biomes/vegetation.json": "187b08814a3831cd0ff2f405c6683e7213a79dc7eeec44cd46136e350b0718b7",
"data/minecraft/worldgen/density_function/shift_x.json": "0db6e5f781089feede9d8d2936d7564024752e34006b8bc9f2a138749f91e3e7",
"data/minecraft/worldgen/density_function/shift_z.json": "0b561cdfafa9e82f431a8051576eb2ddc386d01459df571d7040021b0debb762",
"data/minecraft/worldgen/density_function/y.json": "e7766e59792605f5c3d8e05ff6263db1dc6c91343c736b3ab7a58ddee9771282",
"data/minecraft/worldgen/density_function/zero.json": "8aed642bf5118b9d3c859bd4be35ecac75b6e873cce34e7b6f554b06f75550d7"
},
"noise_settings_resources_sha256": {
"data/minecraft/worldgen/noise_settings/amplified.json": "07fbadd0fd71e16e5497c575d3c86d997166087ccfaaba70a589a440b915024e",
"data/minecraft/worldgen/noise_settings/caves.json": "29a378b845f7bff27a8badecba7ecf2bb22d0d4224b751ab6d91677c83bc6a6a",
"data/minecraft/worldgen/noise_settings/end.json": "d0fd92ddd39081f1779ce5482041a837fb4a03841ea4d843556f17b557e31f4b",
"data/minecraft/worldgen/noise_settings/floating_islands.json": "54923e55bfad4274bea513eccb42e1eb3625fb47ae00905537e0d3d68f82045d",
"data/minecraft/worldgen/noise_settings/large_biomes.json": "dcb29a9e3fb630f2b76a52d759c6925b40e67cd13bc7f9ae93976f0633cc2c05",
"data/minecraft/worldgen/noise_settings/nether.json": "e6d7856fe4523e4c3fa4dce756b6b1e211bfc263c5e417fb6294d032b8f53e9b",
"data/minecraft/worldgen/noise_settings/overworld.json": "d093895d50edd79d53555b33b62d767115399764e32a4f9ae2687739f785d4b9"
},
"inputs_sha256": "4afb482c8aa6e654ef47b9696f76c16fa862414248202c9bf748941bfc8d0877",
"rust_output_sha256": "c39201a8d64b2ec12dc08d8eddcb962d336885a749200a0a33c0fefd7910c193",
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaWorldgenOracle.java": "272b7e7c90dfc1344f6964033b61ee27ac867da7b375e406586b88de08d02b08",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaBiomeExport.java": "f9a773713cf21b69bfa10018b76f27b953bda140ede9934f43d3aa3091101cf5",
"tools/test_worldgen_parity.py": "699826ef3d3f1ac5419b91153539bf0857e931fd128a39fc47d8c8071cc03268",
"tools/test_rust_parity.py": "7efa699a38c5820424f5fc8992ee601dbfe26d6482da9d2dab2c17c41fe8f12a",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"crates/horizon-core/src/bin/density_parity.rs": "e5b1dd33b7d01306c73cf072629b4fb186e9ab87b672a00108999d1a72263fd0",
"crates/horizon-core/src/bin/float_log_parity.rs": "4a655fcf8822ee7668c4bd126bc84d0b118864a6fc7f5a6aeee667d8bf2590b1",
"crates/horizon-core/src/bin/geometry_parity.rs": "27f6c09fe5018ac3de8e70e0f0bbf78f9abb14f5e4783bcaf46e8ca87b9c6f8a",
"crates/horizon-core/src/bin/noise_parity.rs": "c135bfc708d853e7061e81487d2cfe10de64b2f65677d3b4837cbfe0b8341010",
"crates/horizon-core/src/bin/parity.rs": "f35d928c66f958de39fac5e7e836a657eed95f83599e84899f7ea7a5802ba481",
"crates/horizon-core/src/bin/tick_parity.rs": "a54c164fe4814034d369947a887f5273966f5a878ba849204b80d1c729526a8f",
"crates/horizon-core/src/density/arithmetic.rs": "372faec96c923e2cf4aa6c66c1ac398e676853274557823850dbc8933dd15ab1",
"crates/horizon-core/src/density/cache.rs": "38d0b6c9dd04ffef979fdad3f29cfebf98d331c8c9d430be5f39aa34f6c30975",
"crates/horizon-core/src/density/end_islands.rs": "168b9384237bd2e41d0ae5a74e944da4dc74e493bdec31fb73184c9a49e3de55",
"crates/horizon-core/src/density/graph/compiler.rs": "ac67deeb16f16d0859aa20e5a165811a29aca0b910037ee6bf5098211f3a6ede",
"crates/horizon-core/src/density/graph/mod.rs": "b776e7da934cb03051a3053d56d461c71e9978e084922fe4194147aa580c07bf",
"crates/horizon-core/src/density/graph/seeded.rs": "6bcdcaa3dffcfa9df673bbbea35120057a16ba3d2b506c52709c36cf8976b74a",
"crates/horizon-core/src/density/graph/tests.rs": "6bfb8cbff462587dd147b0775ea01d370abbd97544b9bd596c792df1b5f7e634",
"crates/horizon-core/src/density/interpolation.rs": "8c890f52b6467f38a94c654986a6a484b8e0b296ab98c398e60a6ce465b5b010",
"crates/horizon-core/src/density/interval.rs": "b42629163baa6b599a233afe8596d1c370cd81d015cc6fc36a9663aa47b98424",
"crates/horizon-core/src/density/mod.rs": "69f89566a78456c29caaa39dacedfe711ca59e49b78f64e68b0414fb6a73d8fc",
"crates/horizon-core/src/density/power.rs": "d5b7270a128d4264268cd772109ad16d71a8ec3ff2d3b63b84cb985296d54a91",
"crates/horizon-core/src/density/rounding.rs": "71840c5206ff8d218ac29bf6f66915d5212764ba270c675711a866ba5b55a7a6",
"crates/horizon-core/src/density/selection.rs": "0dd26af2e85004ec5e053039ad11c384c17c56ace9ab45eb3f5cb3503c0b0330",
"crates/horizon-core/src/density/slice.rs": "5d77605573c0deda47778f1f78f7fa3fbf1944d8f5efbcc65cf589181cadf80b",
"crates/horizon-core/src/density/spline.rs": "6bb2e40f940fc6544d6fb09cb0b8cac722be03bc663dbdfb0f61faae207400bc",
"crates/horizon-core/src/density/surface.rs": "159e0e69cda74f870e80ea64fe523c4397e64af4ccb861bb9fd07b2c3cb91b00",
"crates/horizon-core/src/density/terrain_noise.rs": "8d0059d25eb5d248cb97a4c5a2e670d61528928ea151495c004f25adb723fe3e",
"crates/horizon-core/src/density/tests.rs": "7817796ee40d0ae241bfbebec6bca190e0a8e7d5a1caa8ddf858c3eaa58b8858",
"crates/horizon-core/src/density/world_fields.rs": "c1ce305cb8046b384d90c564cafb24af7365d580389637910f3d8b0cc18eb583",
"crates/horizon-core/src/geometry/mod.rs": "dc92f73885dd0a7760743bf74f1ab8afa839d61cef2dfef890f8a23b67b4742e",
"crates/horizon-core/src/geometry/movement.rs": "930e34abef6f6eeec1ee7a6c920b5ba01bfe37b90678884490f4be53241f6b96",
"crates/horizon-core/src/geometry/shape/create.rs": "189812b91d5e0e3ad963afcd1a6e2831b31b8188df91a904ef27061e644806ad",
"crates/horizon-core/src/geometry/shape/join.rs": "f1b51887b7bf9482557e3ffa99e136f2e5db07ceeb05fdb116adf45e87129075",
"crates/horizon-core/src/geometry/shape.rs": "de22acd7430df3f69ef3632d427c57dffe57f3bdb78950bc75eac7e179ccf9df",
"crates/horizon-core/src/geometry/sweep.rs": "abd6009c61555161ef2f18b431b2aa384b126c0871cae8b96a62358498a56a1d",
"crates/horizon-core/src/geometry/traversal.rs": "77a3da570a0b85582b669cf4d841cba4b06327006dda26d4a26df4e8ce05bae4",
"crates/horizon-core/src/geometry/trig.rs": "05cef9341a298a474221a0556a11ddf47650393ea7a97b4b2022a4da6628fe37",
"crates/horizon-core/src/lib.rs": "3968e2a337a6a23226c485057c79359e66df16683f00fb4ebc9fabb03910a015",
"crates/horizon-core/src/noise/mod.rs": "1dab5a713abf702402e69ace1bf9e476bba544b0ede5a61c3c3afc60af0a03f3",
"crates/horizon-core/src/noise/normal.rs": "e9e7a46472a54a02c98c46da819842090567153b32fe0c84249009ef19af7aad",
"crates/horizon-core/src/noise/perlin.rs": "e73815447432eab7542f67366cb3f1b368d164e33f6c9cdbd045ac8e4db0932a",
"crates/horizon-core/src/noise/simplex.rs": "6c0dbc15b2b7510195dd28fceca01dcaac1847ccc4a84d299c351589c642fe7a",
"crates/horizon-core/src/noise/stack.rs": "7f6ef0e7d920139ef1a6ad3ec5640f92765715f86dcc5ec29f1a149984f45fa3",
"crates/horizon-core/src/noise/volume.rs": "3f05d2b1780acfdfee60037677d309937a5033b45ef428fc2d540942d4b56b43",
"crates/horizon-core/src/position/iter.rs": "32d2d8e74821cc4e49e3354202d35d3120e4415bfdda9375a73f2137ef651129",
"crates/horizon-core/src/position.rs": "e10101088e6902386b9b6d27773d44312f1ff72bebb19e57967a54945dde9dcd",
"crates/horizon-core/src/random/hash.rs": "0f88a127a1ba2705d3d6c0ebd009324d6ba86ffa2d27edf2d2a84765e690e4a3",
"crates/horizon-core/src/random/positional.rs": "35494745e5d4cf89e282c3ae0ee245e9f2640ddbbc03bc0055df742006a9c862",
"crates/horizon-core/src/random.rs": "92135a94c79111cc810b4b071dbd76043ee47c2585fd431e7486ea381f19e5db",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/src/ticks/heap.rs": "bf28afab8af77c3d243aa96cd8a1fb8d934140a4dbd07dbfdbf4e7908bb4b845",
"crates/horizon-core/src/ticks/index.rs": "1f1a6a568c2a30eafecb020ca4d5f5fc414860de85b8b381fc419a2e3e65c24a",
"crates/horizon-core/src/ticks/mod.rs": "84852599dde78687d782f115a5b4b3ef6856c1f9cc92917255167e89c72ab01e",
"crates/horizon-core/tests/density_world_fields.rs": "e193e45080817ef92547828a8d106482a376b9f788e39d4d3831f44e9d693148",
"crates/horizon-world/examples/collision_fixture.rs": "ee754b5b42e0a51fe0a305b3f4bb56522ff3fffae564180aab8087b1b9e44afc",
"crates/horizon-world/examples/tick_fixture.rs": "df267c307e0491a238b2d93edf0384514f38f8ee3252e315b989de56c6e17990",
"crates/horizon-world/examples/world_fixture.rs": "a3c4c0f5131ae051b24662eff0ed11ed797c6fd5069fbfdf819f0e3fcdfb2cf4",
"crates/horizon-world/src/bin/worldgen_parity.rs": "5af97baa6681bc7aa04d981ec5c07c38cb27f28213abf34b1e83270828dd2980",
"crates/horizon-world/src/chunk.rs": "8843e6f48dbbc4245ce4e95564dfba3a4d7a051ba0b1577fb038c07adb0ff0f9",
"crates/horizon-world/src/collision.rs": "6c40ab491efd0332bd4e65a1a112f3598f9eb0ea2f32f9c8cc7e81278d003251",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/lib.rs": "a6376d79c90ebdee539f4b460a9dd18d75e0c049c24f028d00c9c45c85ebf668",
"crates/horizon-world/src/main.rs": "fce57418b8c22a6a0a9044baa89ed3d9c243bc2e8413fea3ff0f32985daba021",
"crates/horizon-world/src/nbt.rs": "60262c3de8c8f68bc2da0370ccb17393d32b85f5f5022c6358599a7d32119ea6",
"crates/horizon-world/src/region.rs": "72b642e87fed37ed17f54d4c30f96c3b64d26c14bc0589c31ef40ff1616188fc",
"crates/horizon-world/src/registry.rs": "f46065659e60eb5e84ad69b9f3b5e94dc87ee19de16408817e26f23d16b6c7e7",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/worldgen/aquifer/config.rs": "fcd2cc3a520c1527c88f095a3b5d38487e7ebb1ccecc5f757f93d04a069add4f",
"crates/horizon-world/src/worldgen/aquifer/noise_based.rs": "74daaa389b5c3dfdc99214dfff256a9e172f83548d2326cbc941d9637cc53fb7",
"crates/horizon-world/src/worldgen/aquifer.rs": "cb4b66d87de3f9f79ae6ffe4badd6f0f44886cd42ad9de2771b8b56c4f1e28c7",
"crates/horizon-world/src/worldgen/biome.rs": "b3b73091aa5ec989d916206567c5e4b0e997b007a5bb9c0ca5c53ada9d5fe81f",
"crates/horizon-world/src/worldgen/climate/codec.rs": "d567adeb5d837816fca69102db51d790f71aec1b51c09298230d24612e400a14",
"crates/horizon-world/src/worldgen/climate/index.rs": "c5ce61679a5f0e0f2f0af2a373424effa124d0cce8250609eff38b7034650756",
"crates/horizon-world/src/worldgen/climate.rs": "1b9ad44407f40aee4c1cd5357a5c9c443c1b105728f01cf5c644072f99f8357e",
"crates/horizon-world/src/worldgen/density.rs": "65a98c156a290a6b374ef670d28cd5dfbe0aa93171824d1bbd96422536273f84",
"crates/horizon-world/src/worldgen/router.rs": "2cee7cf15a0d2ada12be6b39d83e78177fd3033922e4f4cce87a64073cec2847",
"crates/horizon-world/src/worldgen/settings.rs": "a8fe87752e1982ef11cb67f8d80d8e3428b2c27db178044cb425ba803e689e59",
"crates/horizon-world/src/worldgen.rs": "24f440a4be7546e79b4f462dd18aad9031e94dc87c5f1d32b78912650f7dd162",
"crates/horizon-world/tests/biome_data.rs": "d4de462ccc3e6ad5760490330e0f0cd8a45734077708a2eca95ca06e65f779b0",
"crates/horizon-world/tests/collision_data.rs": "45f3d33b36efe720e99ebf75b9f4fbddd777cebea4618bba245ca106b3443391",
"crates/horizon-world/tests/tick_data.rs": "ab345209367db6963b987797992c4a06433bd2039e6021bd834f6305324c04d7",
"crates/horizon-world/tests/world_io.rs": "4a42630c99ce89b27cc2be1a1b961ad880f62762ab661f9e92ef9bcf7f3e76e0",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"crates/horizon-world/Cargo.toml": "977338bf3e654193685b015d383493b9f59ff6f5d6210bec212cef8ac4a50bed",
"Cargo.toml": "dc370d5fdde37238c3e4820046f11c3201020406a4edfa1308257c13edbdcda4",
"Cargo.lock": "7307d0c887364db36d327685ecf0671b75305e31e5ba5fbdcdbb15eaf156d20e"
},
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "c39201a8d64b2ec12dc08d8eddcb962d336885a749200a0a33c0fefd7910c193",
"matched_output_lines": 922238,
"biome_export_sha256": "b03e2fbe85c191a22f333bc989bd2a73c66f0f9fbcd9ddb54774f17c247832e9"
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "c39201a8d64b2ec12dc08d8eddcb962d336885a749200a0a33c0fefd7910c193",
"matched_output_lines": 922238,
"biome_export_sha256": "b03e2fbe85c191a22f333bc989bd2a73c66f0f9fbcd9ddb54774f17c247832e9"
}
],
"scope": "Direct normal-noise JSON decoding using the actual pinned vanilla CODEC. Every bundled noise registry resource, explicit/default parameters, empty and full amplitude modifiers, normalization modes, inclusive field bounds with signed-zero comparator ordering, malformed types, null fields, duplicate and ignored keys, decimal/exponent integer truncation and wrapping, signed zero, seeded modern/legacy and Nether construction, octave metadata, range and normalization bits, scalar noise values and parent random state. JSON resource contents stay private. Strict JSON parsing; no claim for Gson's permissive non-JSON syntax. Bundled density registries are also decoded with actual vanilla registry-aware CODECs: named forward references, all bundled function kinds, declared range/axes, raw compilation errors, seeded optimized roots, cache allocation, scalar values, strided bulk values, repeated cache hits and surface-volume errors are compared using RandomState's actual compile context. All seven bundled noise-setting resources contribute their actual eight-field NoiseRouter.CODEC objects to RandomState. Router fields are compiled in declaration order with a shared compiler/context; cache allocation, raw/optimized scalar and repeated strided volume values, successful single-layer surface volumes and invalid surface-volume shapes are compared. Actual RandomState climate sampler binding and quart-to-block coordinate wrapping are checked at ordinary and extreme positions. Float-to-long climate quantization and long-to-float conversion include subnormals, signed zeros, NaNs, infinities, cast saturation and seeded random bit patterns. Actual vanilla Climate.Parameter and ParameterPoint JSON codecs compare scalar, two-element list and min/max object intervals, float endpoint bounds/ordering, required coordinate/offset fields, negative zero, precision-sensitive float parsing, malformed types and duplicate keys. Climate parameter distances, wrapping squared fitness, stable search-tree leaf order and nearest lookup are compared across every supported branching value 2..32, sizes around branch powers, the 65536-entry API bound, duplicates, warm ties, fresh lookups, brute-force lookup and extreme signed-long endpoints/targets. The Rust tree is immutable with per-worker search state instead of hidden thread locals; invalid or degenerate searches return typed errors. Inline arbitrary distance metrics and behavior outside the bounded API are not covered. Built-in Overworld and Nether quantized biome parameter tables are exported independently by each authenticated JAR and required to agree before Rust consumes them. The Rust multi-noise resolver and actual vanilla MultiNoiseBiomeSource compare biome identities through scalar climate queries and prepared bulk quart volumes, including forward/reverse/repeated query order, wrapped extreme origins and shared previous-result state. Biome holder keys in the reference are registration placeholders; no biome property or gameplay behavior is evaluated. The Rust loader reads a Horizon quantized table format, not the vanilla biome codec, and the preset builders themselves have not been ported. Source and private fixture mutations during validation invalidate the report. The two-field 26.3 NoiseSettings codec, create helper and LevelHeightAccessor clamping are also compared across bundled noise members, dimension/alignment bounds, zero/negative runtime heights, disjoint ranges, wrapped integer arithmetic and decimal/exponent integer conversion. Global fluid cutoff selection and the actual disabled Aquifer implementation are compared with original default block-state identities, extreme sea levels/coordinates, signed-zero/subnormal/nonfinite density and counted picker calls; developer fluid-disable behavior is outside the regular-mode corpus. The actual noise-based Aquifer.Config codec and runtime are compared across bundled aquifer settings, modern/legacy world-seeded aquifer factories, synthetic density roots, nondefault water/lava states, cave/void air, nonfinite sampler overrides, strided volume extents, wrapped coordinates, repeated and reversed queries, counted picker calls, sampler call order/values, injected failures and retry state, scheduling flags, populated location/status caches and sorted surface-cache entries. Oversized or wrapped-invalid grid allocations and developer fluid-disable behavior are outside the bounded regular-mode API. Terrain filling is not yet validated. Router, vertical noise and optional aquifer members are decoded from each noise-setting resource; complete NoiseGeneratorSettings, material rules, nonempty world fields, biome registry/codecs and complete chunk biome assignment, generated chunks, gameplay and rendering remain pending. Inline noise holders and general codec behavior beyond the covered fixtures remain pending."
}
@@ -1,342 +0,0 @@
{
"schema": 1,
"measurement": "Shader world activation/startup probes; not FPS or physical M2 measurements",
"release": "0.20.0",
"original_mod_sha256": "e651ef49bc97486e8dacfd4b640465c442525cd645e2dba71ddea9fb64347dd8",
"local_source_commit": "99d6aae5e06a3fc9a9a69c433f48f32729776861",
"linux_opengl": {
"schema": 1,
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"architecture": "x86_64",
"minecraft": "26.3",
"original_mod_sha256": "e651ef49bc97486e8dacfd4b640465c442525cd645e2dba71ddea9fb64347dd8",
"results": [
{
"observed_mode": "world",
"title_screen_observed": false,
"world_loaded": true,
"ready_client_ticks": 40,
"window_active": true,
"overlay_present": false,
"overlay_wait_ticks": 79,
"heap_max_bytes": 6442450944,
"iris_capture_status": "available",
"iris_shaders_enabled": true,
"shader_required": true,
"iris_expected_pack_matches": true,
"framebuffer_width": 1280,
"framebuffer_height": 800,
"sampled_pixels": 4288,
"distinct_sampled_rgb": 3777,
"gpu": "llvmpipe (LLVM 21.1.8, 256 bits)",
"graphics_backend": "OpenGL",
"graphics_driver": "4.5 (Core Profile) Mesa 26.0.8-1ubuntu0.3",
"private_png_sha256": "1a221bb9bedb21770f08ffcde593539c02d4e7cad48516bf7fad4215d7b14cde",
"profile": "cinematic",
"preferred_backend": "opengl",
"launcher_exit_code": 0,
"backend_attempts": [
{
"backend": "OpenGL",
"operation": "load_library",
"result": "success"
},
{
"backend": "OpenGL",
"operation": "create_device",
"result": "success"
}
]
}
],
"limits": [
"Short scene startup and nonuniform framebuffer readback only.",
"World mode uses the ordinary limited demo; world files remain private.",
"No exhaustive gameplay, visual-correctness, FPS or M2 Pro performance claim.",
"Vulkan preference can fall back; inspect the observed backend.",
"PNG images, assets and full logs remain in the private runtime directory."
]
},
"linux_vulkan_failure": {
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.awt.AWTError",
"java.lang.NullPointerException",
"java.lang.RuntimeException",
"net.minecraft.ReportedException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "llvmpipe (LLVM 21.1.8, 256 bits)",
"graphics_backend": "Vulkan",
"graphics_driver": "1.4.335 llvmpipe Mesa 26.0.8-1ubuntu0.3 (LLVM 21.1.8)"
}
],
"client_initializer_reached": true,
"readback_requested": false,
"readback_callback_received": false,
"readback_inspections": [],
"probe_failure_categories": [],
"vulkan_error_codes": [],
"fatal_jvm_error": false,
"observed_graphics_stack_methods": [
"net.minecraft.client.renderer.Lightmap.handler$zzk000$distanthorizons$render",
"net.minecraft.client.renderer.Lightmap.render",
"net.minecraft.client.renderer.GameRenderer.render"
],
"profile": "cinematic",
"preferred_backend": "vulkan"
},
"linux_vulkan_without_dh": {
"private_dh_jar_removed": true,
"new_demo_world": true,
"exit_code": 1,
"result_count": 0,
"original_mod_sha256": "e651ef49bc97486e8dacfd4b640465c442525cd645e2dba71ddea9fb64347dd8",
"failure": {
"exit_code": 1,
"result_count": 0,
"java_exception_types": [
"java.lang.AssertionError",
"java.lang.RuntimeException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "llvmpipe (LLVM 21.1.8, 256 bits)",
"graphics_backend": "Vulkan",
"graphics_driver": "1.4.335 llvmpipe Mesa 26.0.8-1ubuntu0.3 (LLVM 21.1.8)"
}
],
"client_initializer_reached": true,
"readback_requested": true,
"readback_callback_received": true,
"readback_inspections": [
{
"framebuffer_width": 1280,
"framebuffer_height": 800,
"sampled_pixels": 4288,
"distinct_sampled_rgb": 1804
}
],
"probe_failure_categories": [
"shader_inactive"
],
"vulkan_error_codes": [],
"fatal_jvm_error": false,
"observed_graphics_stack_methods": [
"net.minecraft.client.Screenshot.lambda$takeScreenshot$1",
"com.mojang.renderpearl.backend.vulkan.DestructionQueue.rotate",
"com.mojang.renderpearl.backend.vulkan.VulkanCommandEncoder.submit",
"com.mojang.renderpearl.frontend.FrontendCommandEncoder.submit"
]
}
},
"mac_source_commit": "857c5a4aa553f83799631ad48340e43a13c78549",
"mac_run_url": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37198566508",
"mac_cases": [
{
"case": [
"--profile",
"cinematic",
"--backend",
"opengl",
"--world",
"--shaders"
],
"exit_code": 1,
"failure": [
{
"fixture": "client-graphics",
"profile": "cinematic",
"completed": false
}
]
},
{
"case": [
"--profile",
"cinematic",
"--backend",
"vulkan",
"--world",
"--shaders"
],
"exit_code": 1,
"failure": [
{
"fixture": "client-graphics",
"profile": "cinematic",
"completed": false
}
]
}
],
"limits": [
"Linux llvmpipe software renderer; no physical M2 shader performance or native GPU test.",
"OpenGL requires actual pinned shader activation and matching runtime pack identity, with nonuniform readback, focused gameplay, saved data and clean exit.",
"Linux Vulkan plus DH fails before readback; selected stack locations alone do not establish the root cause.",
"Removing DH privately produces an ordinary Vulkan world readback but Iris reports shaders inactive; the required-activation assertion rejects it.",
"Both hosted Mac cases hit the 240-second private fixture timeout; earlier diagnostics do not retain stages or waiting state. They do not establish shader compatibility or incompatibility.",
"Full logs, raw PNGs, world data, assets and shader ZIPs remain private.",
"Diagnostic repeat: OpenGL loads a world but retains a screen before readback; Vulkan initializes its device but records no waiting-state snapshot. Both time out; screen identity and root causes are unknown."
],
"mac_diagnostic_repeat": {
"source_commit": "ed416c91cf980f136b7431314bccea7f266fe049",
"run_url": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37199837867",
"cases": [
{
"case": [
"--profile",
"cinematic",
"--backend",
"opengl",
"--world",
"--shaders"
],
"exit_code": 1,
"failure": [
{
"exit_code": -15,
"result_count": 0,
"java_exception_types": [
"java.lang.IllegalStateException",
"java.lang.RuntimeException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "OpenGL",
"operation": "load_library",
"result": "success"
},
{
"backend": "OpenGL",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Software Renderer",
"graphics_backend": "OpenGL",
"graphics_driver": "4.1 APPLE-23.1.1"
}
],
"client_initializer_reached": true,
"readback_requested": false,
"readback_callback_received": false,
"readback_inspections": [],
"last_waiting_state": {
"world_loaded": true,
"player_present": true,
"overlay_present": false,
"screen_present": true,
"window_active": true,
"paused": false,
"ready_client_ticks": 0
},
"probe_failure_categories": [],
"vulkan_error_codes": [],
"fatal_jvm_error": false,
"observed_graphics_stack_methods": [
"net.minecraft.client.renderer.LevelRenderer.mixinextras$bridge$renderGroup$135",
"net.minecraft.client.renderer.LevelRenderer.wrapOperation$bio000$iris$beginTerrainLayer",
"net.minecraft.client.renderer.LevelRenderer.executeSolid",
"net.minecraft.client.renderer.LevelRenderer.lambda$addMainPass$0",
"com.mojang.blaze3d.framegraph.FrameGraphBuilder.execute",
"net.minecraft.client.renderer.LevelRenderer.render",
"net.minecraft.client.renderer.GameRenderer.mixinextras$bridge$render$86",
"net.minecraft.client.renderer.GameRenderer.wrapOperation$bjf000$iris$renderLevel"
],
"fixture": "client-graphics",
"profile": "cinematic",
"completed": false,
"timed_out": true,
"timeout_seconds": 240
}
]
},
{
"case": [
"--profile",
"cinematic",
"--backend",
"vulkan",
"--world",
"--shaders"
],
"exit_code": 1,
"failure": [
{
"exit_code": -15,
"result_count": 0,
"java_exception_types": [
"java.lang.RuntimeException"
],
"expected_demo_authentication_errors_observed": true,
"backend_attempts": [
{
"backend": "Vulkan",
"operation": "load_library",
"result": "success"
},
{
"backend": "Vulkan",
"operation": "create_device",
"result": "success"
}
],
"created_devices": [
{
"gpu": "Apple Paravirtual device",
"graphics_backend": "Vulkan",
"graphics_driver": "1.2.350 MoltenVK 1.4.2"
}
],
"client_initializer_reached": true,
"readback_requested": false,
"readback_callback_received": false,
"readback_inspections": [],
"last_waiting_state": null,
"probe_failure_categories": [],
"vulkan_error_codes": [],
"fatal_jvm_error": false,
"observed_graphics_stack_methods": [],
"fixture": "client-graphics",
"profile": "cinematic",
"completed": false,
"timed_out": true,
"timeout_seconds": 240
}
]
}
]
}
}
@@ -1,160 +0,0 @@
{
"schema": 1,
"purpose": "Functional software identity capture, not a performance comparison",
"minecraft": "26.3",
"platform": "Linux x86_64 software OpenGL",
"source_commit": "110c75d712ed4827ae5e72c613f834bcc4e97da2",
"original_mod_sha256": "98f8db7ca8962a71625eef835f57d25c8afb802f2cf1b7c4c832fc070757e011",
"results": [
{
"kind": "frames",
"elapsed_seconds": 15.335704769,
"java_vendor": "Ubuntu",
"java_vm_name": "OpenJDK 64-Bit Server VM",
"java_runtime_version": "25.0.4.1+1-1-26.04.4-Ubuntu",
"mods": [
"[email protected]",
"[email protected]",
"[email protected]+38c7a2d55d",
"[email protected]+fcdff87f02",
"[email protected]+3434d6d902",
"[email protected]+26.3",
"[email protected]+74ed1ea502",
"[email protected]+0ae6f91102",
"[email protected]+3434d6d902",
"[email protected]+4be74c3f02",
"[email protected]+fcdff87f02",
"[email protected]+74ed1ea55d",
"[email protected]+6b5b47fd5d",
"[email protected]+fcdff87f02",
"[email protected]+fcdff87f02",
"[email protected]+3434d6d902",
"[email protected]+427eab975d",
"[email protected]+3434d6d902",
"[email protected]+47f74c9802",
"[email protected]+3434d6d902",
"[email protected]+3434d6d902",
"[email protected]+3434d6d902",
"[email protected]+cf6bc2db5d",
"[email protected]+3434d6d902",
"[email protected]+ffef5f6702",
"[email protected]+4068fd645d",
"[email protected]+ed66f0a35d",
"[email protected]+3434d6d902",
"[email protected]+fcdff87f5d",
"[email protected]+fcdff87f02",
"[email protected]+3434d6d902",
"[email protected]+3434d6d902",
"[email protected]+fcdff87f02",
"[email protected]+fcdff87f02",
"[email protected]+fcdff87f02",
"[email protected]+79385d0b5d",
"[email protected]+b9d63e335d",
"[email protected]+3434d6d902",
"[email protected]+901a437c02",
"[email protected]+3434d6d902",
"[email protected]+4fc5413f02",
"[email protected]+fcdff87f02",
"[email protected]+48607d035d",
"[email protected]+74ed1ea502",
"[email protected]+3434d6d902",
"[email protected]+fcdff87f02",
"[email protected]+fcdff87f02",
"[email protected]+52268a0e02",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]+26.3",
"java@25",
"[email protected]+mc26.3",
"[email protected]",
"[email protected]",
"[email protected]+mc26.3",
"[email protected]",
"[email protected]"
],
"excluded_frames": 0,
"dropped_samples": 0,
"samples": 38,
"csv_count_matched": true
},
{
"kind": "ticks",
"elapsed_seconds": 15.009787535,
"java_vendor": "Ubuntu",
"java_vm_name": "OpenJDK 64-Bit Server VM",
"java_runtime_version": "25.0.4.1+1-1-26.04.4-Ubuntu",
"mods": [
"[email protected]",
"[email protected]",
"[email protected]+38c7a2d55d",
"[email protected]+fcdff87f02",
"[email protected]+3434d6d902",
"[email protected]+26.3",
"[email protected]+74ed1ea502",
"[email protected]+0ae6f91102",
"[email protected]+3434d6d902",
"[email protected]+4be74c3f02",
"[email protected]+fcdff87f02",
"[email protected]+74ed1ea55d",
"[email protected]+6b5b47fd5d",
"[email protected]+fcdff87f02",
"[email protected]+fcdff87f02",
"[email protected]+3434d6d902",
"[email protected]+427eab975d",
"[email protected]+3434d6d902",
"[email protected]+47f74c9802",
"[email protected]+3434d6d902",
"[email protected]+3434d6d902",
"[email protected]+3434d6d902",
"[email protected]+cf6bc2db5d",
"[email protected]+3434d6d902",
"[email protected]+ffef5f6702",
"[email protected]+4068fd645d",
"[email protected]+ed66f0a35d",
"[email protected]+3434d6d902",
"[email protected]+fcdff87f5d",
"[email protected]+fcdff87f02",
"[email protected]+3434d6d902",
"[email protected]+3434d6d902",
"[email protected]+fcdff87f02",
"[email protected]+fcdff87f02",
"[email protected]+fcdff87f02",
"[email protected]+79385d0b5d",
"[email protected]+b9d63e335d",
"[email protected]+3434d6d902",
"[email protected]+901a437c02",
"[email protected]+3434d6d902",
"[email protected]+4fc5413f02",
"[email protected]+fcdff87f02",
"[email protected]+48607d035d",
"[email protected]+74ed1ea502",
"[email protected]+3434d6d902",
"[email protected]+fcdff87f02",
"[email protected]+fcdff87f02",
"[email protected]+52268a0e02",
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]+26.3",
"java@25",
"[email protected]+mc26.3",
"[email protected]",
"[email protected]",
"[email protected]+mc26.3",
"[email protected]",
"[email protected]"
],
"excluded_frames": 0,
"dropped_samples": 0,
"samples": 301,
"csv_count_matched": true
}
],
"notes": [
"Actual frame and integrated-server tick reports contain identical Java identity and 59 loaded mod versions, captured before each recording starts.",
"The short 15-second recording validates metadata and file output only; it is not a valid performance comparison or a Mac result.",
"The actual old/new report pair loads in the offline viewer with matching CSV timelines, an explicit Horizon mod-version difference and unknown legacy Java implementation warnings.",
"Synthetic changed versions, reordered mod lists, missing legacy identity, escaped mod names and expanded lists at 390px pass offline checks."
]
}
@@ -1,274 +0,0 @@
{
"schema": 1,
"original_mod_sha256": "7e0ffb16fbda2117ce3cfe9fc6249ff3c06c63be764207963ba331871ed6fabd",
"groups": [
{
"label": "initial",
"initial_warmup_checks": 1000000,
"per_observation_warmup_checks": 0,
"observations": 1,
"compiler_diagnostics": false,
"compilation_waits": false,
"results": [
{
"enabled": false,
"applied_hook_checked": true,
"owners": 30,
"queries": 491520,
"nonzero": 327049,
"lookup_digest": "c9745cc2e7cf6c486a92f87635c87590db61127063970c8a8c7bfb2ef5282cca",
"data_fingerprint": -5590987990034711991,
"data_unchanged": true,
"measured_checks": 2000000,
"checksum": 274877907204874744,
"allocated_bytes": 400,
"cpu_ns": 120024838,
"wall_ns": 161908976
},
{
"enabled": true,
"applied_hook_checked": true,
"owners": 30,
"queries": 491520,
"nonzero": 327049,
"lookup_digest": "c9745cc2e7cf6c486a92f87635c87590db61127063970c8a8c7bfb2ef5282cca",
"data_fingerprint": -5590987990034711991,
"data_unchanged": true,
"measured_checks": 2000000,
"checksum": 274877907204874744,
"allocated_bytes": 400,
"cpu_ns": 225290712,
"wall_ns": 296105327
}
]
},
{
"label": "compiler-diagnostic",
"initial_warmup_checks": 1000000,
"per_observation_warmup_checks": 4000000,
"observations": 3,
"compiler_diagnostics": true,
"compilation_waits": false,
"results": [
{
"enabled": false,
"applied_hook_checked": true,
"owners": 30,
"queries": 491520,
"nonzero": 327049,
"lookup_digest": "c9745cc2e7cf6c486a92f87635c87590db61127063970c8a8c7bfb2ef5282cca",
"data_fingerprint": -5590987990034711991,
"data_unchanged": true,
"measured_checks": 6000000,
"checksum": 274877907204874744,
"allocated_bytes": 400,
"cpu_ns": 338028221,
"wall_ns": 414836219,
"observations": [
{
"cpu_ns": 116948835,
"wall_ns": 177862175,
"allocated_bytes": 400
},
{
"cpu_ns": 118223124,
"wall_ns": 134092410,
"allocated_bytes": 0
},
{
"cpu_ns": 102856262,
"wall_ns": 102881634,
"allocated_bytes": 0
}
]
},
{
"enabled": true,
"applied_hook_checked": true,
"owners": 30,
"queries": 491520,
"nonzero": 327049,
"lookup_digest": "c9745cc2e7cf6c486a92f87635c87590db61127063970c8a8c7bfb2ef5282cca",
"data_fingerprint": -5590987990034711991,
"data_unchanged": true,
"measured_checks": 6000000,
"checksum": 274877907204874744,
"allocated_bytes": 400,
"cpu_ns": 277210100,
"wall_ns": 346114782,
"observations": [
{
"cpu_ns": 98829230,
"wall_ns": 109874899,
"allocated_bytes": 400
},
{
"cpu_ns": 99766363,
"wall_ns": 120221997,
"allocated_bytes": 0
},
{
"cpu_ns": 78614507,
"wall_ns": 116017886,
"allocated_bytes": 0
}
]
}
]
},
{
"label": "normal-early",
"initial_warmup_checks": 1000000,
"per_observation_warmup_checks": 4000000,
"observations": 3,
"compiler_diagnostics": false,
"compilation_waits": false,
"results": [
{
"enabled": false,
"applied_hook_checked": true,
"owners": 30,
"queries": 491520,
"nonzero": 327049,
"lookup_digest": "c9745cc2e7cf6c486a92f87635c87590db61127063970c8a8c7bfb2ef5282cca",
"data_fingerprint": -5590987990034711991,
"data_unchanged": true,
"measured_checks": 6000000,
"checksum": 274877907204874744,
"allocated_bytes": 400,
"cpu_ns": 250273130,
"wall_ns": 250904773,
"observations": [
{
"cpu_ns": 96863757,
"wall_ns": 97499670,
"allocated_bytes": 400
},
{
"cpu_ns": 76736599,
"wall_ns": 76731887,
"allocated_bytes": 0
},
{
"cpu_ns": 76672774,
"wall_ns": 76673216,
"allocated_bytes": 0
}
]
},
{
"enabled": true,
"applied_hook_checked": true,
"owners": 30,
"queries": 491520,
"nonzero": 327049,
"lookup_digest": "c9745cc2e7cf6c486a92f87635c87590db61127063970c8a8c7bfb2ef5282cca",
"data_fingerprint": -5590987990034711991,
"data_unchanged": true,
"measured_checks": 6000000,
"checksum": 274877907204874744,
"allocated_bytes": 400,
"cpu_ns": 260828228,
"wall_ns": 292619474,
"observations": [
{
"cpu_ns": 100375163,
"wall_ns": 120697389,
"allocated_bytes": 400
},
{
"cpu_ns": 97211084,
"wall_ns": 108680199,
"allocated_bytes": 0
},
{
"cpu_ns": 63241981,
"wall_ns": 63241886,
"allocated_bytes": 0
}
]
}
]
},
{
"label": "normal-long-warmup",
"initial_warmup_checks": 10000000,
"per_observation_warmup_checks": 4000000,
"observations": 3,
"compiler_diagnostics": false,
"compilation_waits": true,
"results": [
{
"enabled": false,
"applied_hook_checked": true,
"owners": 30,
"queries": 491520,
"nonzero": 327049,
"lookup_digest": "c9745cc2e7cf6c486a92f87635c87590db61127063970c8a8c7bfb2ef5282cca",
"data_fingerprint": -5590987990034711991,
"data_unchanged": true,
"measured_checks": 6000000,
"checksum": 274877907204874744,
"allocated_bytes": 400,
"cpu_ns": 331478729,
"wall_ns": 331596880,
"observations": [
{
"cpu_ns": 111403835,
"wall_ns": 111532068,
"allocated_bytes": 400
},
{
"cpu_ns": 108573471,
"wall_ns": 108571667,
"allocated_bytes": 0
},
{
"cpu_ns": 111501423,
"wall_ns": 111493145,
"allocated_bytes": 0
}
]
},
{
"enabled": true,
"applied_hook_checked": true,
"owners": 30,
"queries": 491520,
"nonzero": 327049,
"lookup_digest": "c9745cc2e7cf6c486a92f87635c87590db61127063970c8a8c7bfb2ef5282cca",
"data_fingerprint": -5590987990034711991,
"data_unchanged": true,
"measured_checks": 6000000,
"checksum": 274877907204874744,
"allocated_bytes": 400,
"cpu_ns": 260347437,
"wall_ns": 260362090,
"observations": [
{
"cpu_ns": 74253874,
"wall_ns": 74284701,
"allocated_bytes": 400
},
{
"cpu_ns": 96313457,
"wall_ns": 96305444,
"allocated_bytes": 0
},
{
"cpu_ns": 89780106,
"wall_ns": 89771945,
"allocated_bytes": 0
}
]
}
]
}
],
"notes": [
"Exploratory fixed-order single forks. Earlier fixture protocols were not committed; warmup and diagnostics differ between groups.",
"Current production arithmetic is the same binary in all groups. Only the final protocol is reproducible from source commit c6ec0b5.",
"Retains favorable and unfavorable observations; do not combine different protocols into a statistical speedup estimate.",
"Not game FPS/RAM, Mac GPU, retained-memory or cross-hardware performance evidence."
]
}
@@ -1,88 +0,0 @@
{
"schema": 1,
"platform": "Linux-6.17.0-1022-azure-x86_64-with-glibc2.39",
"architecture": "x86_64",
"minecraft": "26.3",
"distant_horizons": "3.3.4",
"original_mod_sha256": "7e0ffb16fbda2117ce3cfe9fc6249ff3c06c63be764207963ba331871ed6fabd",
"results": [
{
"enabled": false,
"applied_hook_checked": true,
"owners": 30,
"queries": 491520,
"nonzero": 327049,
"lookup_digest": "c9745cc2e7cf6c486a92f87635c87590db61127063970c8a8c7bfb2ef5282cca",
"data_fingerprint": -5590987990034711991,
"data_unchanged": true,
"measured_checks": 6000000,
"checksum": 274877907204874744,
"allocated_bytes": 400,
"cpu_ns": 164904484,
"wall_ns": 164901169,
"observations": [
{
"cpu_ns": 59683623,
"wall_ns": 59686627,
"allocated_bytes": 400
},
{
"cpu_ns": 52733305,
"wall_ns": 52727455,
"allocated_bytes": 0
},
{
"cpu_ns": 52487556,
"wall_ns": 52487087,
"allocated_bytes": 0
}
]
},
{
"enabled": true,
"applied_hook_checked": true,
"owners": 30,
"queries": 491520,
"nonzero": 327049,
"lookup_digest": "c9745cc2e7cf6c486a92f87635c87590db61127063970c8a8c7bfb2ef5282cca",
"data_fingerprint": -5590987990034711991,
"data_unchanged": true,
"measured_checks": 6000000,
"checksum": 274877907204874744,
"allocated_bytes": 400,
"cpu_ns": 151660192,
"wall_ns": 151647654,
"observations": [
{
"cpu_ns": 56070222,
"wall_ns": 56068070,
"allocated_bytes": 400
},
{
"cpu_ns": 47850398,
"wall_ns": 47843978,
"allocated_bytes": 0
},
{
"cpu_ns": 47739572,
"wall_ns": 47735606,
"allocated_bytes": 0
}
]
}
],
"notes": [
"Actual public full-data lookup inside Fabric with generated numeric column data.",
"Thirty owners span positive/negative origins and six detail levels; output digests and source fingerprints match.",
"The actual redirect method is checked in each mode; source column data remains unchanged.",
"Three sequential warmed caller-loop observations are not independent forks; JIT compilation can vary.",
"Not whole-game FPS/RAM, rendered-pixel equivalence or a Mac GPU benchmark."
],
"provenance": {
"source_commit": "c6ec0b5e14d2ea3546fb8858be4a655634a93387",
"workflow_run": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37171062262",
"job": "portable-mod (ubuntu-latest)",
"artifact": "horizon-ubuntu-latest",
"command": "python tools/test_terrain_position.py"
}
}
@@ -1,126 +0,0 @@
{
"schema": 1,
"minecraft": "26.3",
"distant_horizons": "3.3.4",
"original_mod_sha256": "7e0ffb16fbda2117ce3cfe9fc6249ff3c06c63be764207963ba331871ed6fabd",
"platform": "Linux x86_64",
"graphics": "llvmpipe software OpenGL",
"settings": {
"heap_bytes": 3221225472,
"gc": "G1",
"compact_headers": true,
"render_distance": 12,
"simulation_distance": 12,
"lod_radius_chunks": 128,
"lod_quality": "MEDIUM/MEDIUM/BLOCK",
"terrain_workers": 2,
"runtime_ratio": 0.5,
"world_difficulty": "PEACEFUL"
},
"results": [
{
"profile": "m2-balanced",
"position_enabled": false,
"elapsed_seconds": 120.557552272,
"frame_samples": 221,
"tick_samples": 2401,
"excluded_frames": 0,
"dropped_samples": 0,
"visual_settings_changed": [],
"frame_stats": {
"count": 221,
"meanMs": 539.3068458597285,
"p50Ms": 512.140615,
"p95Ms": 731.515105,
"p99Ms": 811.750394,
"maxMs": 995.181191,
"meanRate": 1.8542319788391781,
"lowOnePercentRate": 1.1163478251626853,
"over16Ms": 221,
"over33Ms": 221,
"over50Ms": 221,
"over100Ms": 221
},
"tick_stats": {
"count": 2401,
"meanMs": 9.190547997917534,
"p50Ms": 8.84372,
"p95Ms": 16.100883,
"p99Ms": 21.297713,
"maxMs": 50.24744,
"meanRate": 108.8074400162632,
"lowOnePercentRate": 34.084420672139515,
"over16Ms": 99,
"over33Ms": 6,
"over50Ms": 1,
"over100Ms": 0
},
"process_rss_peak_sampled_bytes": 2961256448,
"launcher_exit_code": 0
},
{
"profile": "terrain-position",
"position_enabled": true,
"elapsed_seconds": 120.41545128,
"frame_samples": 219,
"tick_samples": 2401,
"excluded_frames": 0,
"dropped_samples": 0,
"visual_settings_changed": [],
"frame_stats": {
"count": 219,
"meanMs": 543.8858950547946,
"p50Ms": 511.34048,
"p95Ms": 780.127415,
"p99Ms": 989.910492,
"maxMs": 1062.14914,
"meanRate": 1.8386209480561242,
"lowOnePercentRate": 0.9801615082035254,
"over16Ms": 219,
"over33Ms": 219,
"over50Ms": 219,
"over100Ms": 219
},
"tick_stats": {
"count": 2401,
"meanMs": 9.594661623490213,
"p50Ms": 9.152511,
"p95Ms": 17.227297,
"p99Ms": 25.78339,
"maxMs": 56.681493,
"meanRate": 104.22462398796237,
"lowOnePercentRate": 30.354925598948153,
"over16Ms": 143,
"over33Ms": 9,
"over50Ms": 1,
"over100Ms": 0
},
"process_rss_peak_sampled_bytes": 2989678592,
"launcher_exit_code": 0
}
],
"provenance": {
"source_commit": "c6ec0b5e14d2ea3546fb8858be4a655634a93387",
"workflow_run": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37171062262",
"runtime_mod_matches_linux_ci": true,
"initial_player_snapshot_sha256": "b4d11dbd6443625415a1e32aa242d0e2d09cd77ddb1becfde5d35cb6ab8d278a",
"initial_level_snapshot_sha256": "86a3c75ea993e50c4428da4dbadc5856688a9367f035c41b8bb49863a9aeb644",
"first_saved_player_position": [
-56.5,
69.0,
55.5
],
"first_saved_player_rotation": [
141.5,
16.950002670288086
]
},
"notes": [
"Fixed-order candidate then control single pair, separate copies of the same private world; approximately 307 seconds from demo-popup dismissal to capture for each. Initial player camera and both first saved camera positions matched.",
"Stationary view includes LOD terrain; both recordings have zero paused/unfocused exclusions and matching captured settings apart from the isolated hook. No statistical speed estimate is established.",
"Preceding 60-second JFR captures ran separately before the frame recording; JIT/cache/profiling effects are not eliminated.",
"Candidate saved, reloaded, saved again and quit; control saved and quit. Both foreground launchers returned 0, with no crash reports or remaining game processes.",
"Scene differs from earlier release captures, so comparisons across releases are not valid. Private test-world camera preparation is not included in the mod or release packs.",
"No FPS improvement is established. Software rendering dominates this machine; these are functional observations, not Mac, GPU or unified-memory performance results. RSS is process resident memory, not complete GPU/unified RAM."
]
}
@@ -1,98 +0,0 @@
{
"schema": 1,
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"architecture": "x86_64",
"minecraft": "26.3",
"distant_horizons": "3.3.4",
"original_mod_sha256": "7e0ffb16fbda2117ce3cfe9fc6249ff3c06c63be764207963ba331871ed6fabd",
"results": [
{
"enabled": false,
"applied_hook_checked": true,
"owners": 30,
"queries": 491520,
"nonzero": 327049,
"lookup_digest": "c9745cc2e7cf6c486a92f87635c87590db61127063970c8a8c7bfb2ef5282cca",
"data_fingerprint": -5590987990034711991,
"data_unchanged": true,
"measured_checks": 6000000,
"checksum": 274877907204874744,
"allocated_bytes": 400,
"cpu_ns": 331478729,
"wall_ns": 331596880,
"observations": [
{
"cpu_ns": 111403835,
"wall_ns": 111532068,
"allocated_bytes": 400
},
{
"cpu_ns": 108573471,
"wall_ns": 108571667,
"allocated_bytes": 0
},
{
"cpu_ns": 111501423,
"wall_ns": 111493145,
"allocated_bytes": 0
}
]
},
{
"enabled": true,
"applied_hook_checked": true,
"owners": 30,
"queries": 491520,
"nonzero": 327049,
"lookup_digest": "c9745cc2e7cf6c486a92f87635c87590db61127063970c8a8c7bfb2ef5282cca",
"data_fingerprint": -5590987990034711991,
"data_unchanged": true,
"measured_checks": 6000000,
"checksum": 274877907204874744,
"allocated_bytes": 400,
"cpu_ns": 260347437,
"wall_ns": 260362090,
"observations": [
{
"cpu_ns": 74253874,
"wall_ns": 74284701,
"allocated_bytes": 400
},
{
"cpu_ns": 96313457,
"wall_ns": 96305444,
"allocated_bytes": 0
},
{
"cpu_ns": 89780106,
"wall_ns": 89771945,
"allocated_bytes": 0
}
]
}
],
"notes": [
"Actual public full-data lookup inside Fabric with generated numeric column data.",
"Thirty owners span positive/negative origins and six detail levels; output digests and source fingerprints match.",
"The actual redirect method is checked in each mode; source column data remains unchanged.",
"Three sequential warmed caller-loop observations are not independent forks; JIT compilation can vary.",
"Not whole-game FPS/RAM, rendered-pixel equivalence or a Mac GPU benchmark."
],
"provenance": {
"source_commit": "c6ec0b5e14d2ea3546fb8858be4a655634a93387",
"command": "python tools/test_terrain_position.py",
"protocol": {
"initial_warmup_checks": 10000000,
"initial_compilation_wait_ms": 1000,
"observation_count": 3,
"per_observation_warmup_checks": 4000000,
"per_observation_compilation_wait_ms": 200,
"per_observation_measured_checks": 2000000,
"run_order": [
false,
true
],
"compiler_diagnostics": false
}
}
}
@@ -1,43 +0,0 @@
{
"schema": 1,
"platform": "Linux-6.17.0-1022-azure-x86_64-with-glibc2.39",
"architecture": "x86_64",
"minecraft": "26.3",
"distant_horizons": "3.3.4",
"original_mod_sha256": "c506982631880604513de8ef85e3b4461fbb898702e60b4a6f74ca3b3d4a687f",
"results": [
{
"enabled": false,
"applied_io_worker_checked": true,
"ordinary_join_checked": true,
"shared_future_preserved": true,
"exception_identity_checked": true,
"completed_interrupt_checked": true,
"cancelled_completion_checked": true,
"preinterrupted_pending_checked": true
},
{
"enabled": true,
"applied_io_worker_checked": true,
"ordinary_join_checked": true,
"shared_future_preserved": true,
"exception_identity_checked": true,
"completed_interrupt_checked": true,
"cancelled_completion_checked": true,
"preinterrupted_pending_checked": true
}
],
"notes": [
"Actual game IOWorker under Fabric, with controlled cached blending-read futures.",
"DH worker interruption releases only its waiter; the shared future remains consumable.",
"Ordinary callers retain join behavior; completed values, cancellation and exception identity are checked.",
"This is a shutdown correctness fixture, not an FPS or world-generation throughput benchmark."
],
"provenance": {
"source_commit": "9a1b22aa56f58a3ee39a3564be859a662d2beedc",
"workflow_run": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37166150119",
"job": "portable-mod (ubuntu-latest)",
"artifact": "horizon-ubuntu-latest",
"command": "python tools/test_terrain_read.py"
}
}
@@ -1,41 +0,0 @@
{
"schema": 1,
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"architecture": "x86_64",
"minecraft": "26.3",
"distant_horizons": "3.3.4",
"original_mod_sha256": "c506982631880604513de8ef85e3b4461fbb898702e60b4a6f74ca3b3d4a687f",
"results": [
{
"enabled": false,
"applied_io_worker_checked": true,
"ordinary_join_checked": true,
"shared_future_preserved": true,
"exception_identity_checked": true,
"completed_interrupt_checked": true,
"cancelled_completion_checked": true,
"preinterrupted_pending_checked": true
},
{
"enabled": true,
"applied_io_worker_checked": true,
"ordinary_join_checked": true,
"shared_future_preserved": true,
"exception_identity_checked": true,
"completed_interrupt_checked": true,
"cancelled_completion_checked": true,
"preinterrupted_pending_checked": true
}
],
"notes": [
"Actual game IOWorker under Fabric, with controlled cached blending-read futures.",
"DH worker interruption releases only its waiter; the shared future remains consumable.",
"Ordinary callers retain join behavior; completed values, cancellation and exception identity are checked.",
"This is a shutdown correctness fixture, not an FPS or world-generation throughput benchmark."
],
"provenance": {
"source_commit": "9a1b22aa56f58a3ee39a3564be859a662d2beedc",
"environment": "local Linux x64 software graphics; actual Fabric fixture",
"command": "python tools/test_terrain_read.py"
}
}
@@ -1,41 +0,0 @@
{
"schema": 1,
"platform": "Linux-6.17.0-1022-azure-x86_64-with-glibc2.39",
"architecture": "x86_64",
"minecraft": "26.3",
"distant_horizons": "3.3.4",
"results": [
{
"enabled": false,
"allocated_bytes": 245760208,
"cpu_ns": 423649902,
"wall_ns": 481491629,
"nodes_per_tick": 512,
"measured_ticks": 20000,
"verified_transitions": 6000,
"checksum": 10240000
},
{
"enabled": true,
"allocated_bytes": 208,
"cpu_ns": 185922780,
"wall_ns": 192151484,
"nodes_per_tick": 512,
"measured_ticks": 20000,
"verified_transitions": 6000,
"checksum": 10240000
}
],
"notes": [
"Actual publisher tick holder under Fabric, warmed with preallocated nodes and a reused action list.",
"Checks duplicate/null membership, enable/disable precedence, published iteration order and clear boundaries.",
"Only private membership checks change; action collections and traversal remain upstream.",
"CPU and allocation measure the calling thread in one isolated loop; no statistical speed claim.",
"Not a game FPS, visible terrain completion, whole-game RAM or Mac GPU benchmark."
],
"provenance": {
"source_commit": "e091816ce06686d64d0f7a181a42701aa67e5bf7",
"ci_run": "https://github.com/ludovic111/minecraft-optimization-lab/actions/runs/37162939262",
"artifact": "horizon-ubuntu-latest"
}
}
@@ -1,14 +0,0 @@
Java openjdk 25.0.4.1 2026-08-18 LTS
Platform Darwin 25.6.0 arm64; logical CPUs 3
upstream requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.346; 1643.771 ms; worker allocation 1403064 bytes
precise requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.514; 1061.526 ms; worker allocation 15456 bytes
upstream requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.466; 1238.603 ms; worker allocation 1449704 bytes
precise requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.063; 11385.730 ms; worker allocation 204024 bytes
upstream requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.703; 785.293 ms; worker allocation 1417064 bytes
precise requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.509; 1097.416 ms; worker allocation 14496 bytes
upstream requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.431; 1293.360 ms; worker allocation 1529184 bytes
precise requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.065; 10727.658 ms; worker allocation 198104 bytes
upstream requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.620; 896.747 ms; worker allocation 1490864 bytes
precise requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.518; 1062.565 ms; worker allocation 13096 bytes
upstream requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.605; 975.086 ms; worker allocation 1450064 bytes
precise requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.060; 11976.557 ms; worker allocation 196840 bytes
@@ -1,14 +0,0 @@
Java openjdk 25.0.4.1 2026-08-18 LTS
Platform Linux 6.17.0-1022-azure x86_64; logical CPUs 4
upstream requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 1.000; 578.014 ms; worker allocation 1450616 bytes
precise requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.525; 1041.454 ms; worker allocation 64976 bytes
upstream requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.976; 591.683 ms; worker allocation 1451744 bytes
precise requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.076; 10349.493 ms; worker allocation 145264 bytes
upstream requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 1.000; 577.632 ms; worker allocation 1451096 bytes
precise requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.523; 1043.863 ms; worker allocation 65120 bytes
upstream requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.977; 591.337 ms; worker allocation 1410264 bytes
precise requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.076; 10334.845 ms; worker allocation 124264 bytes
upstream requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.987; 583.777 ms; worker allocation 1490096 bytes
precise requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.524; 1038.102 ms; worker allocation 64656 bytes
upstream requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.952; 606.495 ms; worker allocation 1408464 bytes
precise requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.076; 10346.209 ms; worker allocation 165856 bytes
@@ -1,14 +0,0 @@
Java openjdk 25.0.4.1 2026-08-18 LTS
Platform Windows 2025Server AMD64; logical CPUs 4
upstream requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.952; 557.784 ms; worker allocation 1491496 bytes
precise requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.556; 1038.982 ms; worker allocation 17776 bytes
upstream requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.852; 623.419 ms; worker allocation 1410384 bytes
precise requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.078; 10247.387 ms; worker allocation 214896 bytes
upstream requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.998; 548.088 ms; worker allocation 1489616 bytes
precise requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.574; 1034.032 ms; worker allocation 15096 bytes
upstream requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.867; 630.903 ms; worker allocation 1449664 bytes
precise requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.078; 10266.232 ms; worker allocation 214904 bytes
upstream requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.996; 549.301 ms; worker allocation 1448456 bytes
precise requested ratio 0.500; 50000 tasks of 10000 ns; worker CPU/wall 0.452; 1036.321 ms; worker allocation 13776 bytes
upstream requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.971; 563.129 ms; worker allocation 1409664 bytes
precise requested ratio 0.050; 50000 tasks of 10000 ns; worker CPU/wall 0.100; 10276.324 ms; worker allocation 214744 bytes
+2
View File
@@ -22,6 +22,8 @@ serde_json = { version = "1.0.151", features = ["raw_value"] }
cpal = "0.16"
symphonia = { version = "0.5", default-features = false, features = ["ogg", "vorbis"] }
miniz_oxide = "0.8"
ab_glyph = "0.2.32"
horizon-theme = { path = "../horizon-theme" }
[features]
# Records the call sites of mob random draws (`mob_ai_probe` traces).
@@ -0,0 +1,132 @@
//! The chat screen's input for tools/test_chat_screen_parity.py: reads one
//! JSON case per line (GUI size, history, options, typed text, keys,
//! clicks, mouse), runs `horizon_client::chat::ChatScreen` on the vanilla
//! command tree and writes the input's state and the screen's GUI calls in
//! the oracle's JSON form.
//!
//! usage: chat_screen_fixture RESOURCES REGISTRIES CASES OUTPUT
use horizon_client::{
chat::{ChatAction, ChatScreen, Commands},
command::vanilla,
hud::HudAtlas,
lang,
screen_draw::Measure,
};
use serde_json::{Value, json};
use std::{fmt::Write as _, fs, path::PathBuf};
use winit::keyboard::KeyCode as K;
#[path = "pack_screen_fixture.rs"]
#[allow(dead_code)]
mod pack_screen_fixture;
#[path = "chat_screen_fixture/registries.rs"]
mod registries;
fn main() -> horizon_client::Result<()> {
let args: Vec<PathBuf> = std::env::args_os().skip(1).map(PathBuf::from).collect();
let [root, registries, inputs, output] = args.as_slice() else {
return Err("usage: chat_screen_fixture RESOURCES REGISTRIES CASES OUTPUT".into());
};
let atlas = HudAtlas::build(root)?;
lang::set(lang::Language::load(&[root], lang::DEFAULT));
let m = Measure(&atlas.font);
let reg = registries::registries(&serde_json::from_slice(&fs::read(registries)?)?, 4);
let c = Commands {
dispatcher: vanilla::release_dispatcher(),
registries: &reg,
};
let mut out = String::new();
for line in fs::read_to_string(inputs)?
.lines()
.filter(|l| !l.is_empty())
{
let case: Value = serde_json::from_str(line)?;
let int = |v: &Value| v.as_i64().unwrap_or(0) as i32;
let history: Vec<String> = case["history"]
.as_array()
.into_iter()
.flatten()
.filter_map(|s| s.as_str().map(str::to_owned))
.collect();
let (w, h) = (int(&case["width"]), int(&case["height"]));
let mut screen = ChatScreen::new(
&m,
&c,
case["initial"].as_str().unwrap_or(""),
history.len(),
w,
h,
);
screen.auto_suggestions = case["autoSuggest"] == true;
let mut closed = false;
for a in case["actions"].as_array().into_iter().flatten() {
match a["type"].as_str().unwrap_or_default() {
"type" => screen.type_text(&m, &c, a["text"].as_str().unwrap_or_default()),
"click" => {
screen.click(
&m,
&c,
a["x"].as_f64().unwrap_or(0.0),
a["y"].as_f64().unwrap_or(0.0),
);
}
"key" => {
let mut name = a["key"].as_str().unwrap_or_default();
let (mut shift, mut ctrl) = (false, false);
loop {
if let Some(n) = name.strip_prefix("shift+") {
shift = true;
name = n;
} else if let Some(n) = name.strip_prefix("ctrl+") {
ctrl = true;
name = n;
} else {
break;
}
}
let key = match name {
"backspace" => K::Backspace,
"delete" => K::Delete,
"home" => K::Home,
"end" => K::End,
"right" => K::ArrowRight,
"left" => K::ArrowLeft,
"down" => K::ArrowDown,
"up" => K::ArrowUp,
"tab" => K::Tab,
"escape" => K::Escape,
_ => K::KeyA,
};
// InputQuirks.EDIT_SHORTCUT_KEY_MODIFIER: Cmd, not Ctrl, on macOS.
let ctrl = ctrl && !cfg!(target_os = "macos");
if screen.key(&m, &c, &history, key, shift, ctrl) != ChatAction::None {
closed = true;
break;
}
}
_ => {}
}
}
if closed {
writeln!(out, "{}", json!({"closed": true}))?;
continue;
}
// Options.getBackgroundColor(Integer.MIN_VALUE).
let background = if case["chatOnly"] == true {
i32::MIN
} else {
let a = (case["opacity"].as_f64().unwrap_or(0.0) as f32 * 255.0).floor() as i32;
a << 24
};
let mouse = (int(&case["mouse"][0]), int(&case["mouse"][1]));
let draws = screen.draw(&m, mouse, case["blink"].as_u64().unwrap_or(0), background);
let input = &screen.input;
writeln!(
out,
"{}",
json!({"value": input.value, "cursor": input.cursor, "highlight": input.highlight, "display": input.display,
"draws": pack_screen_fixture::encode(&draws)})
)?;
}
fs::write(output, out)?;
Ok(())
}
@@ -0,0 +1,85 @@
//! The registries VanillaCommandParseOracle exports (`registries` mode), as
//! the command dispatcher reads them; shared by the command fixtures.
use horizon_client::command::{Registries, args::RegistryIds};
use serde_json::Value;
fn strings(v: &Value) -> Vec<String> {
v.as_array()
.map(|a| {
a.iter()
.filter_map(|x| x.as_str().map(str::to_owned))
.collect()
})
.unwrap_or_default()
}
pub fn registries(r: &Value, permission: u8) -> Registries {
let mut reg = Registries {
permission,
..Registries::default()
};
reg.items = strings(&r["items"]);
reg.item_tags = strings(&r["item_tags"]);
reg.block_tags = strings(&r["block_tags"]);
for (id, props) in r["blocks"].as_object().into_iter().flatten() {
let props = props
.as_array()
.into_iter()
.flatten()
.map(|p| (p[0].as_str().unwrap_or("").to_owned(), strings(&p[1])))
.collect();
reg.blocks.insert(id.clone(), props);
}
reg.summonable = strings(&r["summonable"]);
reg.entity_types = strings(&r["entity_types"]);
reg.effects = strings(&r["effects"]);
reg.attributes = strings(&r["attributes"]);
reg.sounds = strings(&r["sounds"]);
reg.enchantments = strings(&r["enchantments"]);
reg.structures = strings(&r["structures"]);
reg.biomes = strings(&r["biomes"]);
reg.damage_types = strings(&r["damage_types"]);
reg.clocks = strings(&r["clocks"]);
reg.timelines = strings(&r["timelines"]);
reg.dimensions = strings(&r["dimensions"]);
reg.players = strings(&r["players"]);
reg.teams = strings(&r["teams"]);
reg.objectives = strings(&r["objectives"]);
reg.tracked = strings(&r["tracked"]);
for (name, entry) in r["by_registry"].as_object().into_iter().flatten() {
reg.by_registry.insert(
name.clone(),
RegistryIds {
ids: strings(&entry["ids"]),
tags: strings(&entry["tags"]),
},
);
}
reg.block_entities = strings(&r["block_entities"]).into_iter().collect();
for (tag, members) in r["block_tag_members"].as_object().into_iter().flatten() {
reg.block_tag_members.insert(tag.clone(), strings(members));
}
reg.templates = strings(&r["templates"]);
reg.persistent_components = strings(&r["persistent_components"]);
reg.learnable_recipes = strings(&r["learnable_recipes"]);
for (clock, markers) in r["clock_time_markers"].as_object().into_iter().flatten() {
reg.clock_time_markers
.insert(clock.clone(), strings(markers));
}
for (id, criteria) in r["advancement_criteria"].as_object().into_iter().flatten() {
reg.advancement_criteria
.insert(id.clone(), strings(criteria));
}
reg.datapacks_enabled = strings(&r["datapacks_selected"]);
let enabled = reg.datapacks_enabled.clone();
reg.datapacks_disabled = strings(&r["datapacks_enableable"])
.into_iter()
.filter(|p| !enabled.contains(p))
.collect();
reg.advancements = reg.ids("minecraft:advancement").to_vec();
reg.recipes = reg.ids("minecraft:recipe").to_vec();
reg.loot_tables = reg.ids("minecraft:loot_table").to_vec();
reg.predicates = reg.ids("minecraft:predicate").to_vec();
reg.item_modifiers = reg.ids("minecraft:item_modifier").to_vec();
reg
}
@@ -0,0 +1,163 @@
//! The resource pack screen for tools/test_pack_screen_parity.py: reads one
//! JSON case per line (packs, selection, GUI size, actions, mouse), runs
//! `horizon_client::pack_screen` through the actions and writes the shown
//! screen's GUI calls in the oracle's JSON form.
//!
//! usage: pack_screen_fixture RESOURCES CASES OUTPUT
use horizon_client::{
hud::HudAtlas,
lang,
pack_screen::{Compat, PackInfo, PackScreen, Source},
packs::{self, Position},
screen_draw::{Draw, Measure},
text::Text,
};
use serde_json::{Value, json};
use std::{fmt::Write as _, fs, path::PathBuf};
/// Styled runs: [text, rgb or null, bold, italic, underlined, strikethrough, obfuscated].
pub fn runs(t: &Text) -> Value {
let mut out: Vec<(String, Option<u32>, [bool; 5])> = Vec::new();
for (c, s) in t.chars() {
let f = [
s.bold,
s.italic,
s.underlined,
s.strikethrough,
s.obfuscated,
]
.map(|b| b == Some(true));
match out.last_mut() {
Some(last) if last.1 == s.color && last.2 == f => last.0.push(c),
_ => out.push((c.to_string(), s.color, f)),
}
}
Value::Array(
out.into_iter()
.map(|(t, c, f)| json!([t, c, f[0], f[1], f[2], f[3], f[4]]))
.collect(),
)
}
pub fn encode(draws: &[Draw]) -> Value {
Value::Array(
draws
.iter()
.map(|d| match d {
Draw::Sprite { sprite, x, y, w, h, color } => {
json!({"type": "sprite", "sprite": sprite, "x": x, "y": y, "w": w, "h": h, "color": color})
}
Draw::Blit { texture, x, y, w, h, u, v, src, tex, color } => json!({"type": "blit", "texture": texture,
"x": x, "y": y, "w": w, "h": h, "u": u, "v": v, "srcW": src[0], "srcH": src[1], "texW": tex[0],
"texH": tex[1], "color": color}),
Draw::Fill { x0, y0, x1, y1, color } => {
json!({"type": "fill", "x0": x0, "y0": y0, "x1": x1, "y1": y1, "color": color})
}
Draw::Highlight { x0, y0, x1, y1 } => json!({"type": "highlight", "x0": x0, "y0": y0, "x1": x1, "y1": y1}),
Draw::Text { text, x, y, color, shadow } => {
json!({"type": "text", "runs": runs(text), "x": x, "y": y, "color": color, "shadow": shadow})
}
Draw::Scissor { x0, y0, x1, y1 } => json!({"type": "scissor", "x0": x0, "y0": y0, "x1": x1, "y1": y1}),
Draw::NoScissor => json!({"type": "noscissor"}),
Draw::Tooltip { lines, x, y } => {
json!({"type": "tooltip", "lines": lines.iter().map(runs).collect::<Vec<_>>(), "x": x, "y": y})
}
})
.collect(),
)
}
fn main() -> horizon_client::Result<()> {
let args: Vec<PathBuf> = std::env::args_os().skip(1).map(PathBuf::from).collect();
let [root, inputs, output] = args.as_slice() else {
return Err("usage: pack_screen_fixture RESOURCES CASES OUTPUT".into());
};
let atlas = HudAtlas::build(root)?;
lang::set(lang::Language::load(&[root], lang::DEFAULT));
let m = Measure(&atlas.font);
let mut out = String::new();
for line in fs::read_to_string(inputs)?
.lines()
.filter(|l| !l.is_empty())
{
let c: Value = serde_json::from_str(line)?;
let int = |v: &Value| v.as_i64().unwrap_or(0) as i32;
let packs: Vec<PackInfo> = c["packs"]
.as_array()
.into_iter()
.flatten()
.map(|p| {
let (description, description_style) = packs::component_root(&p["description"]);
PackInfo {
id: p["id"].as_str().unwrap_or_default().to_owned(),
title: packs::component_root(&p["title"]).0,
description,
description_style,
source: match p["source"].as_str() {
Some("builtin") => Source::BuiltIn,
Some("world") => Source::World,
Some("server") => Source::Server,
Some("feature") => Source::Feature,
_ => Source::Default,
},
compat: match p["compat"].as_str() {
Some("old") => Compat::TooOld,
Some("new") => Compat::TooNew,
Some("unknown") => Compat::Unknown,
_ => Compat::Compatible,
},
icon: p["icon"].as_bool().unwrap_or(false),
required: p["required"].as_bool().unwrap_or(false),
position: if p["position"] == "top" {
Position::Top
} else {
Position::Bottom
},
fixed: p["fixed"].as_bool().unwrap_or(false),
}
})
.collect();
let selected: Vec<String> = c["selected"]
.as_array()
.into_iter()
.flatten()
.filter_map(|s| s.as_str().map(str::to_owned))
.collect();
let mut screen = PackScreen::new(
&m,
int(&c["width"]),
int(&c["height"]),
c["inWorld"] == true,
packs,
&selected,
);
for a in c["actions"].as_array().into_iter().flatten() {
let f = |k: &str| a[k].as_f64().unwrap_or(0.0);
match a["type"].as_str().unwrap_or_default() {
"click" => {
screen.click(&m, f("x"), f("y"));
}
"scroll" => screen.scroll(f("x"), f("y"), f("amount")),
"type" => screen.type_text(&m, a["text"].as_str().unwrap_or_default()),
"erase" => screen.erase(&m, f("count") as isize),
_ => {}
}
if std::env::var_os("PACK_DEBUG").is_some() {
eprintln!("{a} -> {}", screen.debug());
}
}
let mouse = (int(&c["mouse"][0]), int(&c["mouse"][1]));
let draws = screen.draw(&m, mouse, c["blink"].as_u64().unwrap_or(0));
let screen_name = if screen.confirming() {
"confirm"
} else {
"packs"
};
writeln!(
out,
"{}",
json!({"screen": screen_name, "draws": encode(&draws)})
)?;
}
fs::write(output, out)?;
Ok(())
}
+478 -372
View File
@@ -3,11 +3,13 @@
//! (ChatScreen + EditBox + CommandSuggestions: history navigation, argument
//! colouring, usage hints, parse errors and tab completion).
use crate::{
command::{Dispatcher, ParseResults, Registries, Suggestion},
hud::{HudAtlas, HudBatch, rgba},
command::{
Dispatcher, ParseResults, Registries, Suggestion, SuggestionsBuilder, merge_suggestions,
},
hud::{HudAtlas, HudBatch},
hud_layout::{self, GuiDraw, PoseOp},
screen_draw::{self as d, Draw, Measure, TextField},
text::{self, Style, Text},
ui::{EditBox, char_len},
};
/// GuiMessageTag.systemSinglePlayer's indicator colour.
@@ -299,81 +301,151 @@ impl Chat {
}
}
/// CommandSuggestions.SuggestionsList.
/// `CommandSuggestions.SuggestionsList`.
#[derive(Clone, Debug)]
struct SuggestionList {
x: f32,
width: f32,
/// `rect`: x, y, width, height.
rect: [i32; 4],
original: String,
list: Vec<Suggestion>,
offset: usize,
current: usize,
original: String,
last_mouse: (i32, i32),
tab_cycles: bool,
last_mouse: (f32, f32),
}
impl SuggestionList {
fn contains(&self, x: i32, y: i32) -> bool {
let [rx, ry, w, h] = self.rect;
x >= rx && x <= rx + w && y >= ry && y <= ry + h
}
}
/// The open chat screen.
pub struct ChatScreen {
pub input: EditBox,
history_pos: usize,
history_buffer: String,
parse: Option<ParseResults>,
usage: Vec<Text>,
usage_x: f32,
suggestions: Option<SuggestionList>,
pending: Vec<Suggestion>,
pending_start: usize,
keep_suggestions: bool,
allow_suggestions: bool,
pub auto_suggestions: bool,
dirty: bool,
/// What a key did on the chat screen.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ChatAction {
None,
/// Escape: the screen closes.
Close,
/// Enter: the message is sent and the screen closes.
Submit(String),
}
const FILL: u32 = 0xD000_0000;
fn fill_color() -> u32 {
rgba(0, 0, 0, (FILL >> 24) as u8)
/// The dispatcher and registries the suggestions come from.
pub struct Commands<'a> {
pub dispatcher: &'a Dispatcher,
pub registries: &'a Registries,
}
/// The open chat screen: vanilla's `ChatScreen` with its `EditBox` and
/// `CommandSuggestions` (argument colouring, usage lines, parse errors,
/// the suggestion list, Tab completion, history).
pub struct ChatScreen {
pub input: TextField,
width: i32,
height: i32,
history_buffer: String,
history_pos: usize,
parse: Option<ParseResults>,
/// The completions at the cursor (`pendingSuggestions`): range start (bytes) and list.
pending: Option<(usize, Vec<Suggestion>)>,
suggestions: Option<SuggestionList>,
usage: Vec<Text>,
usage_position: i32,
usage_width: i32,
allow_suggestions: bool,
keep_suggestions: bool,
pub auto_suggestions: bool,
}
/// `CommandSuggestions`' fill colour.
const FILL: i32 = -805306368;
fn byte_at(s: &str, chars: usize) -> usize {
s.char_indices().nth(chars).map_or(s.len(), |(i, _)| i)
}
fn chars_to(s: &str, byte: usize) -> usize {
s[..byte.min(s.len())].chars().count()
}
/// `Mth.clamp(int)`: the minimum wins over a smaller maximum.
fn clamp(v: i32, lo: i32, hi: i32) -> i32 {
if v < lo { lo } else { v.min(hi) }
}
/// `CommandSuggestions.getLastWordIndex`: after the last whitespace run.
fn last_word_index(s: &str) -> usize {
let mut out = 0;
let mut prev_space = false;
for (i, c) in s.char_indices() {
let space = matches!(c, ' ' | '\t' | '\n' | '\u{b}' | '\u{c}' | '\r');
if prev_space && !space {
out = i;
}
prev_space = space;
}
if prev_space { s.len() } else { out }
}
impl ChatScreen {
pub fn new(initial: &str, history_len: usize, width: f32, height: f32) -> Self {
let mut input = EditBox::new(4.0, height - 12.0, width - 4.0, 12.0);
input.bordered = false;
/// `ChatScreen.init`: the input at the bottom, focused, holding `initial`.
pub fn new(
m: &Measure,
c: &Commands,
initial: &str,
history_len: usize,
width: i32,
height: i32,
) -> Self {
let mut input = TextField::new(4, height - 12, width - 4, 12);
input.max_length = 256;
input.set_value(initial);
Self {
input.bordered = false;
input.focused = true;
input.set_value(m, initial);
let mut s = Self {
input,
history_pos: history_len,
width,
height,
history_buffer: String::new(),
history_pos: history_len,
parse: None,
usage: Vec::new(),
usage_x: 0.0,
pending: None,
suggestions: None,
pending: Vec::new(),
pending_start: 0,
keep_suggestions: false,
usage: Vec::new(),
usage_position: 0,
usage_width: 0,
allow_suggestions: false,
keep_suggestions: false,
auto_suggestions: true,
dirty: true,
}
}
/// Keep the input box at the bottom when the window resizes.
pub fn resize(&mut self, width: f32, height: f32) {
self.input.x = 4.0;
self.input.y = height - 12.0;
self.input.width = width - 4.0;
};
s.update_command_info(m, c);
s
}
pub fn value(&self) -> &str {
&self.input.value
}
/// ChatScreen.onEdited.
pub fn edited(&mut self) {
self.allow_suggestions = true;
self.dirty = true;
}
/// CommandSuggestions.updateCommandInfo (run lazily before drawing/keys).
pub fn update(&mut self, atlas: &HudAtlas, d: &Dispatcher, reg: &Registries) {
if !self.dirty {
return;
/// `ChatScreen.resize`: a new screen with the current text.
pub fn resize(&mut self, m: &Measure, c: &Commands, width: i32, height: i32) {
if (width, height) != (self.width, self.height) {
let value = self.input.value.clone();
let auto = self.auto_suggestions;
*self = Self::new(m, c, &value, self.history_pos, width, height);
self.auto_suggestions = auto;
}
self.dirty = false;
}
/// `ChatScreen.onEdited`.
fn edited(&mut self, m: &Measure, c: &Commands) {
self.allow_suggestions = true;
self.update_command_info(m, c);
}
/// Typed text (`charTyped` per character).
pub fn type_text(&mut self, m: &Measure, c: &Commands, text: &str) {
for ch in text.chars() {
if ch >= ' '
&& ch != '\u{7f}'
&& ch != '§'
&& self.input.insert_text(m, &ch.to_string())
{
self.edited(m, c);
}
}
}
/// `CommandSuggestions.updateCommandInfo`.
fn update_command_info(&mut self, m: &Measure, c: &Commands) {
let command = self.input.value.clone();
if self.parse.as_ref().is_some_and(|p| p.input != command) {
self.parse = None;
@@ -383,221 +455,234 @@ impl ChatScreen {
self.suggestions = None;
}
self.usage.clear();
self.pending.clear();
let cursor_chars = self.input.cursor;
let cursor = command
.char_indices()
.nth(cursor_chars)
.map_or(command.len(), |(i, _)| i);
if !command.starts_with('/') {
return;
}
if self.parse.is_none() {
self.parse = Some(d.parse_at(&command, 1, reg));
}
let Some(parse) = &self.parse else { return };
if cursor >= 1 && (self.suggestions.is_none() || !self.keep_suggestions) {
let (range, list) = d.suggestions(parse, cursor, reg);
self.pending = list;
self.pending_start = range.0;
// CommandSuggestions.updateUsageInfo.
let mut trailing = false;
if cursor == command.len() {
if self.pending.is_empty() && !parse.errors.is_empty() {
let mut literals = 0;
for (_, e) in &parse.errors {
if e.literal_incorrect {
literals += 1;
} else {
self.usage.push(e.with_context().with_color(text::RED));
}
}
if literals > 0 {
let reader = crate::command::Reader {
string: &parse.input,
cursor: parse.cursor,
};
self.usage.push(
crate::command::CommandError::tr_at(
"command.unknown.argument",
&[],
&reader,
)
.with_context()
.with_color(text::RED),
);
}
} else if parse.can_read() {
trailing = true;
}
let cursor = self.input.cursor;
let cursor_b = byte_at(&command, cursor);
if command.starts_with('/') {
if self.parse.is_none() {
self.parse = Some(c.dispatcher.parse_at(&command, 1, c.registries));
}
let (node, start, _) = parse.context.suggestion_context(cursor);
if self.usage.is_empty() {
let mut lines: Vec<Text> = d
.smart_usage(node, reg.permission)
.into_iter()
.filter(|(n, _)| {
!matches!(d.nodes[*n].kind, crate::command::NodeKind::Literal(_))
})
.map(|(_, u)| Text::colored(u, text::GRAY))
.collect();
if lines.is_empty()
&& trailing
&& let Some(e) = parse.error()
{
lines.push(e.with_context().with_color(text::RED));
}
self.usage = lines;
}
let usage_width = self
.usage
.iter()
.map(|u| atlas.font.width_text(u))
.fold(0.0, f32::max);
let start_chars = char_len(&command[..start.min(command.len())]);
self.usage_x = if self.usage.is_empty() {
0.0
} else {
self.input.screen_x(atlas, start_chars).clamp(
0.0,
(self.input.screen_x(atlas, 0) + self.input.inner_width() - usage_width)
.max(0.0),
)
};
self.suggestions = None;
if self.allow_suggestions && self.auto_suggestions {
self.show_suggestions(atlas);
if cursor >= 1 && (self.suggestions.is_none() || !self.keep_suggestions) {
let parse = self.parse.as_ref().expect("parsed above");
let (range, list) = c.dispatcher.suggestions(parse, cursor_b, c.registries);
self.pending = Some((range.0, list));
self.update_usage_info(m, c);
}
} else if !command.chars().all(char::is_whitespace) {
let partial = &command[..cursor_b];
let mut builder = SuggestionsBuilder::new(partial, last_word_index(partial));
builder.suggest_matching(c.registries.players.iter().map(String::as_str));
let (range, list) = merge_suggestions(partial, builder.out);
self.pending = Some((range.0, list));
self.usage_width = 0;
self.usage_position = 0;
} else {
self.pending = None;
}
}
/// CommandSuggestions.showSuggestions.
fn show_suggestions(&mut self, atlas: &HudAtlas) {
if self.pending.is_empty() {
/// `CommandSuggestions.updateUsageInfo`.
fn update_usage_info(&mut self, m: &Measure, c: &Commands) {
let Some(parse) = &self.parse else { return };
let empty = self.pending.as_ref().is_none_or(|p| p.1.is_empty());
let mut trailing = false;
if self.input.cursor == self.input.value.chars().count() {
if empty && !parse.errors.is_empty() {
let mut literals = 0;
for (_, e) in &parse.errors {
if e.literal_incorrect {
literals += 1;
} else {
self.usage.push(e.with_context());
}
}
if literals > 0 {
let reader = crate::command::Reader {
string: &parse.input,
cursor: parse.cursor,
};
self.usage.push(
crate::command::CommandError::tr_at(
"command.unknown.argument",
&[],
&reader,
)
.with_context(),
);
}
} else if parse.can_read() {
trailing = true;
}
}
let cursor_b = byte_at(&self.input.value, self.input.cursor);
let (node, start, _) = parse.context.suggestion_context(cursor_b);
if self.usage.is_empty() {
let entries: Vec<Text> = c
.dispatcher
.smart_usage(node, c.registries.permission)
.into_iter()
.filter(|(n, _)| {
!matches!(
c.dispatcher.nodes[*n].kind,
crate::command::NodeKind::Literal(_)
)
})
.map(|(_, u)| Text::colored(u, text::GRAY))
.collect();
if entries.is_empty()
&& trailing
&& let Some(e) = parse.error()
{
self.usage.push(e.with_context());
}
self.usage.extend(entries);
}
self.usage_width = self.usage.iter().map(|u| m.width(u)).max().unwrap_or(0);
self.usage_position = if self.usage.is_empty() {
0
} else {
let start = chars_to(&self.input.value, start);
clamp(
self.input.screen_x(m, start),
0,
self.input.screen_x(m, 0) + self.input.inner_width() - self.usage_width,
)
};
self.suggestions = None;
if self.allow_suggestions && self.auto_suggestions {
self.show_suggestions(m);
}
}
/// `CommandSuggestions.showSuggestions`.
fn show_suggestions(&mut self, m: &Measure) {
let Some((start, list)) = self.pending.clone() else {
return;
};
if list.is_empty() {
return;
}
let width = list.iter().map(|s| m.width_str(&s.text)).max().unwrap_or(0);
let value = self.input.value.clone();
let width = self
.pending
.iter()
.map(|s| atlas.font.width(&s.text))
.fold(0.0, f32::max);
let start_chars = char_len(&value[..self.pending_start.min(value.len())]);
let x = self.input.screen_x(atlas, start_chars).clamp(
0.0,
(self.input.screen_x(atlas, 0) + self.input.inner_width() - width).max(0.0),
let x = clamp(
self.input.screen_x(m, chars_to(&value, start)),
0,
self.input.screen_x(m, 0) + self.input.inner_width() - width,
);
// Sort: suggestions starting with the last word first.
let cursor = value
.char_indices()
.nth(self.input.cursor)
.map_or(value.len(), |(i, _)| i);
let partial = &value[..cursor];
let last_word = partial.rfind(char::is_whitespace).map_or(0, |i| i + 1);
let word = partial[last_word..].to_lowercase();
let (mut first, partial_matches): (Vec<Suggestion>, Vec<Suggestion>) =
self.pending.iter().cloned().partition(|s| {
let y = self.height - 12;
// sortSuggestions: those starting with the word at the cursor first.
let partial = &value[..byte_at(&value, self.input.cursor)];
let word = partial[last_word_index(partial)..].to_lowercase();
let (mut first, rest): (Vec<Suggestion>, Vec<Suggestion>) =
list.into_iter().partition(|s| {
s.text.starts_with(&word) || s.text.starts_with(&format!("minecraft:{word}"))
});
first.extend(partial_matches);
let mut list = SuggestionList {
x: x - 1.0,
width: width + 1.0,
first.extend(rest);
let n = first.len().min(10) as i32;
let mut l = SuggestionList {
rect: [x - 1, y - 3 - n * 12, width + 1, n * 12],
original: value,
list: first,
offset: 0,
current: 0,
original: value,
last_mouse: (0, 0),
tab_cycles: false,
last_mouse: (-1.0, -1.0),
};
self.select(&mut list, 0);
self.suggestions = Some(list);
self.select(&mut l, 0);
self.suggestions = Some(l);
}
fn select(&mut self, list: &mut SuggestionList, index: isize) {
let n = list.list.len() as isize;
list.current = index.rem_euclid(n.max(1)) as usize;
let applied = list.list[list.current].apply(&list.original);
/// `SuggestionsList.select`: the grey completion after the text.
fn select(&mut self, l: &mut SuggestionList, index: isize) {
let n = l.list.len() as isize;
let mut i = index;
if i < 0 {
i += n;
}
if i >= n {
i -= n;
}
l.current = i as usize;
let applied = l.list[l.current].apply(&l.original);
self.input.suggestion = applied
.strip_prefix(self.input.value.as_str())
.filter(|s| !s.is_empty())
.map(str::to_owned);
}
fn cycle(&mut self, list: &mut SuggestionList, dir: isize) {
self.select(list, list.current as isize + dir);
let limit = 10;
let max_offset = list.list.len().saturating_sub(limit);
if list.current < list.offset {
list.offset = list.current.min(max_offset);
} else if list.current > list.offset + limit - 1 {
list.offset = (list.current + 1).saturating_sub(limit).min(max_offset);
fn cycle(&mut self, l: &mut SuggestionList, dir: isize) {
self.select(l, l.current as isize + dir);
let max = l.list.len().saturating_sub(10);
if l.current < l.offset {
l.offset = l.current.min(max);
} else if l.current > l.offset + 9 {
l.offset = (l.current as isize + 1 - 10).clamp(0, max as isize) as usize;
}
}
fn use_suggestion(&mut self, list: &mut SuggestionList) {
let s = list.list[list.current].clone();
/// `SuggestionsList.useSuggestion`.
fn use_suggestion(&mut self, m: &Measure, c: &Commands, l: &mut SuggestionList) {
let s = l.list[l.current].clone();
self.keep_suggestions = true;
let applied = s.apply(&list.original);
self.input.set_value(&applied);
let end =
char_len(&list.original[..s.range.0.min(list.original.len())]) + char_len(&s.text);
self.input.set_cursor(end, false);
self.dirty = true;
self.select(list, list.current as isize);
let value = s.apply(&l.original);
self.suggestions = Some(l.clone());
self.input.set_value(m, &value);
self.edited(m, c);
let end = chars_to(&l.original, s.range.0) + s.text.chars().count();
self.input.set_cursor_and_highlight(m, end);
self.select(l, l.current as isize);
self.keep_suggestions = false;
list.tab_cycles = true;
l.tab_cycles = true;
}
/// Suggestion-list keys (CommandSuggestions.keyPressed). Returns true if handled.
pub fn suggestion_key(
/// `ChatScreen.keyPressed`.
pub fn key(
&mut self,
atlas: &HudAtlas,
d: &Dispatcher,
reg: &Registries,
m: &Measure,
c: &Commands,
history: &[String],
key: winit::keyboard::KeyCode,
shift: bool,
) -> bool {
ctrl: bool,
) -> ChatAction {
use winit::keyboard::KeyCode as K;
self.update(atlas, d, reg);
if let Some(mut list) = self.suggestions.take() {
// CommandSuggestions.keyPressed.
if let Some(mut l) = self.suggestions.take() {
let handled = match key {
K::ArrowUp => {
self.cycle(&mut list, -1);
list.tab_cycles = false;
true
}
K::ArrowDown => {
self.cycle(&mut list, 1);
list.tab_cycles = false;
K::ArrowUp | K::ArrowDown => {
self.cycle(&mut l, if key == K::ArrowUp { -1 } else { 1 });
l.tab_cycles = false;
true
}
K::Tab => {
if list.tab_cycles {
self.cycle(&mut list, if shift { -1 } else { 1 });
if l.tab_cycles {
self.cycle(&mut l, if shift { -1 } else { 1 });
}
self.use_suggestion(&mut list);
// Keep the list across the re-parse triggered by the edit.
let keep = list.clone();
self.keep_suggestions = true;
self.update(atlas, d, reg);
self.keep_suggestions = false;
self.suggestions = Some(keep);
return true;
self.use_suggestion(m, c, &mut l);
true
}
K::Escape => {
self.input.suggestion = None;
return true;
return ChatAction::None;
}
_ => false,
};
self.suggestions = Some(list);
return handled;
self.suggestions = Some(l);
if handled {
return ChatAction::None;
}
} else if key == K::Tab {
self.show_suggestions(m);
return ChatAction::None;
}
if key == K::Tab {
self.show_suggestions(atlas);
return true;
match key {
K::Escape => return ChatAction::Close,
K::Enter | K::NumpadEnter => return ChatAction::Submit(self.normalized()),
K::ArrowUp => self.move_in_history(m, c, history, -1),
K::ArrowDown => self.move_in_history(m, c, history, 1),
_ => {
if self.input.key(m, key, shift, ctrl) == Some(true) {
self.edited(m, c);
}
}
}
false
ChatAction::None
}
/// ChatScreen.moveInHistory.
pub fn move_in_history(&mut self, recent: &[String], dir: isize) {
let max = recent.len();
/// `ChatScreen.moveInHistory`.
fn move_in_history(&mut self, m: &Measure, c: &Commands, history: &[String], dir: isize) {
let max = history.len();
let new = (self.history_pos as isize + dir).clamp(0, max as isize) as usize;
if new == self.history_pos {
return;
@@ -605,55 +690,70 @@ impl ChatScreen {
if new == max {
self.history_pos = max;
let b = self.history_buffer.clone();
self.input.set_value(&b);
self.input.set_value(m, &b);
self.edited(m, c);
} else {
if self.history_pos == max {
self.history_buffer = self.input.value.clone();
}
self.input.set_value(&recent[new]);
self.suggestions = None;
self.input.set_value(m, &history[new]);
self.edited(m, c);
self.allow_suggestions = false;
self.suggestions = None;
self.history_pos = new;
}
self.dirty = true;
}
/// Mouse wheel over the suggestion list.
pub fn scroll_suggestions(&mut self, cursor: (f32, f32), height: f32, amount: f32) -> bool {
let Some(list) = &mut self.suggestions else {
return false;
};
let n = list.list.len().min(10);
let top = height - 12.0 - 3.0 - n as f32 * 12.0;
if crate::ui::hovered(cursor, list.x, top, list.width, n as f32 * 12.0) {
let max = list.list.len().saturating_sub(10) as isize;
list.offset = (list.offset as isize - amount.signum() as isize).clamp(0, max) as usize;
return true;
}
false
}
/// Click on a suggestion row.
pub fn click(&mut self, cursor: (f32, f32), height: f32) -> bool {
let Some(mut list) = self.suggestions.take() else {
return false;
};
let n = list.list.len().min(10);
let top = height - 12.0 - 3.0 - n as f32 * 12.0;
if crate::ui::hovered(cursor, list.x, top, list.width, n as f32 * 12.0) {
let row = ((cursor.1 - top) / 12.0) as usize + list.offset;
if row < list.list.len() {
self.select(&mut list, row as isize);
self.use_suggestion(&mut list);
/// A left click (`ChatScreen.mouseClicked`): a suggestion, else the input.
pub fn click(&mut self, m: &Measure, c: &Commands, x: f64, y: f64) -> bool {
if let Some(mut l) = self.suggestions.take() {
let (xi, yi) = (x as i32, y as i32);
if l.contains(xi, yi) {
let line = (yi - l.rect[1]) / 12 + l.offset as i32;
if line >= 0 && (line as usize) < l.list.len() {
self.select(&mut l, line as isize);
self.use_suggestion(m, c, &mut l);
}
self.suggestions = Some(l);
return true;
}
self.suggestions = Some(list);
self.suggestions = Some(l);
}
if self.input.contains(x, y) {
self.input.click(m, x, false);
return true;
}
self.suggestions = Some(list);
false
}
/// CommandSuggestions.formatText: argument colours over the input.
fn formatted(&self) -> Option<Text> {
let parse = self.parse.as_ref()?;
let value = &self.input.value;
/// The mouse wheel over the suggestion list (`SuggestionsList.mouseScrolled`).
pub fn scroll(&mut self, mouse: (i32, i32), amount: f64) -> bool {
let Some(l) = &mut self.suggestions else {
return false;
};
if !l.contains(mouse.0, mouse.1) {
return false;
}
let max = l.list.len().saturating_sub(10) as i32;
l.offset = ((l.offset as f64 - amount.clamp(-1.0, 1.0)) as i32).clamp(0, max) as usize;
true
}
/// `CommandSuggestions.formatText`: argument colours over the input.
fn format(&self, value: &str, offset: usize) -> Text {
let gray = Style::color(text::GRAY);
let Some(parse) = &self.parse else {
return Text::literal(value);
};
let full = &self.input.value;
let chars = |b: usize| chars_to(full, b) as isize;
let len = value.chars().count() as isize;
let piece = |from: isize, to: isize| -> String {
value
.chars()
.skip(from as usize)
.take((to - from).max(0) as usize)
.collect()
};
let mut out = Text::empty();
let mut unformatted = 0isize;
let styles = [
text::AQUA,
text::YELLOW,
@@ -661,128 +761,134 @@ impl ChatScreen {
text::LIGHT_PURPLE,
text::GOLD,
];
let mut colors = vec![text::GRAY; value.len()];
let ctx = parse.context.last_child();
for (i, arg) in ctx.args.iter().enumerate() {
let c = styles[i % styles.len()];
for b in arg.range.0.min(value.len())..arg.range.1.min(value.len()) {
colors[b] = c;
for (i, arg) in parse.context.last_child().args.iter().enumerate() {
let start = (chars(arg.range.0) - offset as isize).max(0);
if start >= len {
break;
}
let end = (chars(arg.range.1) - offset as isize).min(len);
if end > 0 {
out.push(Text::styled(piece(unformatted, start), gray.clone()));
out.push(Text::styled(
piece(start, end),
Style::color(styles[i % styles.len()]),
));
unformatted = end;
}
}
if parse.can_read() {
for c in colors.iter_mut().skip(parse.cursor) {
*c = text::RED;
let start = (chars(parse.cursor) - offset as isize).max(0);
if start < len {
let remaining = (full.len() - parse.cursor.min(full.len())) as isize;
let end = (start + full[parse.cursor.min(full.len())..].chars().count() as isize)
.min(len);
let _ = remaining;
out.push(Text::styled(piece(unformatted, start), gray.clone()));
out.push(Text::styled(piece(start, end), Style::color(text::RED)));
unformatted = end;
}
}
let mut out = Text::empty();
for (i, ch) in value.char_indices() {
out.push(Text::styled(ch.to_string(), Style::color(colors[i])));
}
Some(out)
out.push(Text::styled(piece(unformatted, len), gray));
out
}
/// ChatScreen.extractRenderState minus the chat lines.
/// `ChatScreen.extractRenderState` without the chat lines: the input's
/// background (`background`, `Options.getBackgroundColor`), the input,
/// then the suggestion list or the usage lines.
pub fn draw(
&mut self,
batch: &mut HudBatch,
atlas: &HudAtlas,
d: &Dispatcher,
reg: &Registries,
cursor: (f32, f32),
background_opacity: f32,
) {
self.update(atlas, d, reg);
let (w, h) = (batch.width, batch.height);
batch.fill(
atlas,
2.0,
h - 14.0,
w - 4.0,
12.0,
rgba(0, 0, 0, (background_opacity * 255.0) as u8),
);
let formatted = self.formatted();
self.input.draw(batch, atlas, formatted.as_ref());
let fill = fill_color();
if let Some(mut list) = self.suggestions.take() {
let limit = list.list.len().min(10);
let top = h - 12.0 - 3.0 - limit as f32 * 12.0;
let has_prev = list.offset > 0;
let has_next = list.list.len() > list.offset + limit;
let moved = list.last_mouse != cursor;
list.last_mouse = cursor;
if has_prev || has_next {
batch.fill(atlas, list.x, top - 1.0, list.width, 1.0, fill);
batch.fill(
atlas,
list.x,
top + limit as f32 * 12.0,
list.width,
1.0,
fill,
);
for x in (0..list.width as i32).step_by(2) {
if has_prev {
batch.fill(atlas, list.x + x as f32, top - 1.0, 1.0, 1.0, u32::MAX);
}
if has_next {
batch.fill(
atlas,
list.x + x as f32,
top + limit as f32 * 12.0,
1.0,
1.0,
u32::MAX,
);
}
}
}
let mut hovered_row = None;
for i in 0..limit {
let y = top + 12.0 * i as f32;
batch.fill(atlas, list.x, y, list.width, 12.0, fill);
if cursor.0 > list.x
&& cursor.0 < list.x + list.width
&& cursor.1 > y
&& cursor.1 < y + 12.0
{
hovered_row = Some(i + list.offset);
}
}
if moved && let Some(r) = hovered_row {
self.select(&mut list, r as isize);
}
for i in 0..limit {
let s = &list.list[i + list.offset];
let color = if i + list.offset == list.current {
rgba(255, 255, 0, 255)
} else {
rgba(0xAA, 0xAA, 0xAA, 255)
};
batch.text(
atlas,
&s.text,
list.x + 1.0,
top + 2.0 + 12.0 * i as f32,
color,
true,
);
}
if hovered_row.is_some()
&& let Some(tip) = &list.list[list.current].tooltip
{
crate::ui::tooltip(batch, atlas, &[Text::literal(tip.clone())], cursor);
}
self.suggestions = Some(list);
m: &Measure,
mouse: (i32, i32),
blink_ms: u64,
background: i32,
) -> Vec<Draw> {
let (w, h) = (self.width, self.height);
let mut out = Vec::new();
d::fill(&mut out, 2, h - 14, w - 2, h - 2, background);
let format = |s: &str, o: usize| self.format(s, o);
self.input.draw(&mut out, m, blink_ms, Some(&format));
if let Some(mut l) = self.suggestions.take() {
self.draw_list(&mut out, m, &mut l, mouse);
self.suggestions = Some(l);
} else {
for (i, line) in self.usage.iter().enumerate() {
let y = h - 27.0 - 12.0 * i as f32;
let width = atlas.font.width_text(line);
batch.fill(atlas, self.usage_x - 1.0, y, width + 2.0, 12.0, fill);
batch.text_styled(atlas, line, self.usage_x, y + 2.0, u32::MAX, true);
let y = h - 27 - 12 * i as i32;
d::fill(
&mut out,
self.usage_position - 1,
y,
self.usage_position + self.usage_width + 1,
y + 12,
FILL,
);
d::text(&mut out, line.clone(), self.usage_position, y + 2, -1, true);
}
}
out
}
/// ChatScreen.normalizeChatMessage.
fn draw_list(
&mut self,
out: &mut Vec<Draw>,
m: &Measure,
l: &mut SuggestionList,
mouse: (i32, i32),
) {
let limit = l.list.len().min(10);
let [rx, ry, rw, rh] = l.rect;
let has_prev = l.offset > 0;
let has_next = l.list.len() > l.offset + limit;
let moved = l.last_mouse != mouse;
if moved {
l.last_mouse = mouse;
}
if has_prev || has_next {
d::fill(out, rx, ry - 1, rx + rw, ry, FILL);
d::fill(out, rx, ry + rh, rx + rw, ry + rh + 1, FILL);
if has_prev {
for x in (0..rw).step_by(2) {
d::fill(out, rx + x, ry - 1, rx + x + 1, ry, -1);
}
}
if has_next {
for x in (0..rw).step_by(2) {
d::fill(out, rx + x, ry + rh, rx + x + 1, ry + rh + 1, -1);
}
}
}
let mut hovered = false;
for i in 0..limit {
let y = ry + 12 * i as i32;
d::fill(out, rx, y, rx + rw, y + 12, FILL);
if mouse.0 > rx && mouse.0 < rx + rw && mouse.1 > y && mouse.1 < y + 12 {
if moved {
self.select(l, (i + l.offset) as isize);
}
hovered = true;
}
let s = &l.list[i + l.offset];
let color = if i + l.offset == l.current {
-256
} else {
-5592406
};
d::text(
out,
Text::literal(s.text.clone()),
rx + 1,
ry + 2 + 12 * i as i32,
color,
true,
);
}
if hovered && let Some(tip) = &l.list[l.current].tooltip {
out.push(Draw::Tooltip {
lines: vec![Text::literal(tip.clone())],
x: mouse.0,
y: mouse.1,
});
}
let _ = m;
}
/// `ChatScreen.normalizeChatMessage`.
pub fn normalized(&self) -> String {
let collapsed = self
.input
+987
View File
@@ -0,0 +1,987 @@
//! The front-end screens in Horizon's menu style (`ui_theme`), laid out like
//! the launcher: a 200-wide sidebar with the sliding selection (Home,
//! Singleplayer, Multiplayer, Options), content pages with a page header,
//! settings rows and 1px dividers, and the launcher's opening (the wordmark,
//! then the interface). They drive the same state as the classic layouts in
//! `title` and `multiplayer`; only drawing and hit testing differ. The pause
//! menu's Horizon layout is `pause`, below.
use crate::{
hud::{HudAtlas, HudBatch},
multiplayer::{Outcome, Ping, Screen},
title::{Action, Mode, Title, list_worlds},
ui_theme::{
self as t, BODY, CONTROL, CONTROL_LARGE, Face, Kind, SIDEBAR, SMALL, Ui, color, id,
},
};
use std::time::Instant;
const NAV: u64 = id("title.nav", 0);
const QUIT: u64 = id("title.quit", 0);
const PLAY: u64 = id("home.play", 0);
const MULTIPLAYER: u64 = id("home.multiplayer", 0);
const RESUME: u64 = id("home.resume", 0);
const BACK: u64 = id("front.back", 0);
const PLAY_WORLD: u64 = id("worlds.play", 0);
const CREATE: u64 = id("worlds.create", 0);
const WORLD: u64 = id("worlds.row", 0);
const NAME: u64 = id("create.name", 0);
const SEED: u64 = id("create.seed", 0);
const MODE: u64 = id("create.mode", 0);
const MAKE: u64 = id("create.make", 0);
const SERVER: u64 = id("mp.row", 0);
const JOIN: u64 = id("mp.join", 0);
const DIRECT: u64 = id("mp.direct", 0);
const ADD: u64 = id("mp.add", 0);
const EDIT: u64 = id("mp.edit", 0);
const DELETE: u64 = id("mp.delete", 0);
const REFRESH: u64 = id("mp.refresh", 0);
const FIELD_A: u64 = id("mp.field", 0);
const FIELD_B: u64 = id("mp.field", 1);
const DONE: u64 = id("mp.done", 0);
/// The launcher's opening (`launcher/src/main.rs`): the wordmark holds over
/// the backdrop, then the interface comes in. A click or a key skips ahead.
#[derive(Clone, Copy, Debug)]
pub struct Opening {
started: Instant,
reveal: Option<Instant>,
}
impl Opening {
pub fn new() -> Self {
Self {
started: Instant::now(),
reveal: None,
}
}
/// The reveal's progress, 0 to 1; `ready` says the backdrop is showing.
fn phase(&mut self, ready: bool) -> f32 {
let held = self.started.elapsed();
if self.reveal.is_none()
&& ((held >= horizon_theme::OPENING_HOLD && ready)
|| held >= horizon_theme::OPENING_MAX)
{
self.reveal = Some(Instant::now());
}
self.reveal.map_or(0.0, |at| {
at.elapsed().as_secs_f32() / horizon_theme::OPENING_REVEAL.as_secs_f32()
})
}
pub fn skip(&mut self) {
self.reveal.get_or_insert_with(Instant::now);
}
}
impl Default for Opening {
fn default() -> Self {
Self::new()
}
}
/// Which sidebar item a mode belongs to.
fn page(mode: &Mode) -> usize {
match mode {
Mode::Main => 0,
Mode::Select { .. } | Mode::Create { .. } => 1,
Mode::Multiplayer(_) => 2,
}
}
const PAGES: [&str; 4] = ["Home", "Singleplayer", "Multiplayer", "Options"];
impl Title {
/// Horizon's layout for every title mode. `backdrop` is how much of the
/// live backdrop is visible (0 shows the plain cold background).
pub fn draw_horizon(&self, ui: &mut Ui, backdrop: f32) {
let reveal = self.opening_phase(backdrop >= 1.0);
if backdrop < 1.0 {
ui.cold_background(1.0 - backdrop);
}
let shade = t::ease_out_cubic(reveal);
let veil = if matches!(self.mode, Mode::Main) {
0.42
} else {
0.66
};
ui.atmosphere(veil * shade, shade);
let side = t::ease_out_cubic((reveal - 0.2) / 0.7);
let main = t::ease_out_cubic((reveal - 0.35) / 0.65);
// The sidebar slides in from the left.
ui.opacity = side;
ui.offset = (-16.0 * (1.0 - side), 0.0);
if side > 0.0 {
self.sidebar(ui);
}
// The content rises; each new page fades in and rises 8 over MOVE.
let entered = self.entered();
let p = t::ease_out_quint(entered.elapsed().as_secs_f32() / t::move_());
ui.opacity = main * p;
ui.offset = (0.0, 16.0 * (1.0 - main) + 8.0 * (1.0 - p));
if main > 0.0 {
let x = SIDEBAR + 48.0;
let w = (ui.w - x - 48.0).min(760.0);
match &self.mode {
Mode::Main => self.home(ui, x, w),
Mode::Select { worlds, selected } => worlds_page(ui, x, w, worlds, *selected),
Mode::Create {
name,
seed,
creative,
focus,
} => {
let caret = (self.started.elapsed().as_millis() / 500).is_multiple_of(2);
create_page(ui, x, w, name, seed, *creative, *focus, caret);
}
Mode::Multiplayer(screen) => {
let caret = (self.started.elapsed().as_millis() / 500).is_multiple_of(2);
multiplayer_page(ui, x, w, screen, caret);
}
}
}
ui.opacity = 1.0;
ui.offset = (0.0, 0.0);
if reveal < 1.0 {
// The wordmark rises and fades as the interface comes in.
let word = 1.0 - t::ease_out_cubic(reveal / 0.6);
ui.opacity = word;
let tw = ui.measure(Face::Display, t::WORDMARK, "Horizon");
let line = (t::WORDMARK * 1.2).round();
ui.text_line(
Face::Display,
t::WORDMARK,
line,
((ui.w - tw) / 2.0).round(),
(ui.h - line) / 2.0 - 28.0 * (1.0 - word),
color::WHITE,
"Horizon",
);
ui.opacity = 1.0;
}
}
fn opening_phase(&self, ready: bool) -> f32 {
let mut opening = self.opening.get();
let phase = opening.as_mut().map_or(1.0, |o| o.phase(ready));
self.opening.set(opening.filter(|_| phase < 1.0));
phase.min(1.0)
}
/// A click or key during the opening jumps to the reveal; true if it did.
pub fn skip_opening(&self) -> bool {
let mut opening = self.opening.get();
let skipped = opening.as_mut().is_some_and(|o| {
let holding = o.reveal.is_none();
o.skip();
holding
});
self.opening.set(opening);
skipped
}
fn sidebar(&self, ui: &mut Ui) {
let h = ui.h;
ui.fill(0.0, 0.0, SIDEBAR, h, color::with_alpha(color::SIDEBAR, 0.8));
ui.vline(SIDEBAR - 1.0, 0.0, h, color::BORDER);
ui.text_line(
Face::Display,
22.0,
30.0,
22.0,
16.0,
color::TEXT,
"Horizon",
);
ui.sidebar_list(NAV, 12.0, 66.0, SIDEBAR - 24.0, &PAGES, page(&self.mode));
let qy = h - 12.0 - 18.0 - 12.0 - CONTROL;
let hover = ui.interact(QUIT, 12.0, qy, SIDEBAR - 24.0, CONTROL, true);
ui.rounded(
12.0,
qy,
SIDEBAR - 24.0,
CONTROL,
t::RADIUS,
color::with_alpha(color::HOVER, 0.7 * hover),
);
ui.text_line(
Face::Regular,
BODY,
CONTROL,
22.0,
qy,
color::mix(color::MUTED, color::TEXT, hover),
"Quit game",
);
ui.text(
Face::Regular,
SMALL,
22.0,
h - 12.0 - 18.0,
color::FAINT,
"Horizon 26.3",
);
}
/// Home: the launcher's Play page over the backdrop.
fn home(&self, ui: &mut Ui, x: f32, w: f32) {
let mut y = 36.0 + 28.0;
ui.text(
Face::Medium,
SMALL,
x,
y,
color::FAINT,
"Minecraft 26.3 · Java Edition, rewritten in Rust",
);
y += 22.0;
ui.text_line(Face::Display, t::HERO, 58.0, x, y, color::TEXT, "Horizon");
y += 58.0 + 12.0;
ui.text(
Face::Regular,
t::LARGE,
x,
y,
color::MUTED,
"The world you know, rebuilt from the ground up.",
);
y += 22.0 + 24.0;
let pw = ui.button_width("Singleplayer", true).max(120.0);
ui.button(
PLAY,
[x, y, pw, CONTROL_LARGE],
"Singleplayer",
Kind::Primary,
true,
);
let mw = ui.button_width("Multiplayer", true);
ui.button(
MULTIPLAYER,
[x + pw + 8.0, y, mw, CONTROL_LARGE],
"Multiplayer",
Kind::Secondary,
true,
);
y += CONTROL_LARGE + 24.0;
ui.divider(x, y, w);
let worlds = self.recent_worlds();
let last = worlds.first();
let value = last.map_or("None yet".to_owned(), |l| {
let secs = l
.modified
.duration_since(std::time::UNIX_EPOCH)
.map_or(0, |d| d.as_secs());
format!("{} · {}", l.name, crate::title::date_label(secs))
});
let rh = ui.row(x, y, "Last played", &value, w - t::ROW_LABEL - 120.0);
if last.is_some() {
let bw = ui.button_width("Resume", false);
ui.button(
RESUME,
[x + w - bw, y + (rh - CONTROL) / 2.0, bw, CONTROL],
"Resume",
Kind::Secondary,
true,
);
}
y += rh;
ui.divider(x, y, w);
let count = match worlds.len() {
1 => "1 world".to_owned(),
n => format!("{n} worlds"),
};
y += ui.row(x, y, "Saves", &count, w - t::ROW_LABEL - 16.0);
ui.divider(x, y, w);
let note = "Not affiliated with Mojang or Microsoft";
ui.text(
Face::Regular,
SMALL,
x,
ui.h - 12.0 - 18.0,
color::FAINT,
note,
);
}
/// A click in Horizon's layout (`x`, `y` in GUI pixels).
pub fn click_horizon(
&mut self,
atlas: &HudAtlas,
batch: &mut HudBatch,
x: f32,
y: f32,
) -> Action {
if self.skip_opening() {
return Action::None;
}
let hit = {
let mut ui = Ui::dry(atlas, batch, (x, y));
self.draw_horizon(&mut ui, 1.0);
ui.hit((x, y))
};
let Some(hit) = hit else {
if let Mode::Create { focus, .. } = &mut self.mode {
*focus = 2;
}
return Action::None;
};
let saves = self.saves.clone();
let select = |saves: &std::path::Path| Mode::Select {
worlds: list_worlds(saves),
selected: None,
};
match hit {
QUIT => return Action::Quit,
h if h == NAV => {
self.mode = Mode::Main;
return Action::None;
}
h if h == NAV + 1 => {
if !matches!(self.mode, Mode::Select { .. }) {
self.mode = select(&saves);
}
return Action::None;
}
h if h == NAV + 2 => {
if !matches!(self.mode, Mode::Multiplayer(_)) {
self.mode = Mode::Multiplayer(Screen::list(&saves));
}
return Action::None;
}
h if h == NAV + 3 => return Action::Options,
_ => {}
}
match &mut self.mode {
Mode::Main => match hit {
PLAY => self.mode = select(&saves),
MULTIPLAYER => self.mode = Mode::Multiplayer(Screen::list(&saves)),
RESUME => {
if let Some(w) = list_worlds(&saves).into_iter().next() {
return Action::Play { folder: w.folder };
}
}
_ => {}
},
Mode::Select { worlds, selected } => match hit {
PLAY_WORLD => {
if let Some(w) = selected.and_then(|i| worlds.get(i)) {
return Action::Play {
folder: w.folder.clone(),
};
}
}
CREATE => {
self.mode = Mode::Create {
name: "New World".into(),
seed: String::new(),
creative: false,
focus: 0,
}
}
h if (WORLD..WORLD + 10_000).contains(&h) => {
let i = (h - WORLD) as usize;
if *selected == Some(i) {
return Action::Play {
folder: worlds[i].folder.clone(),
};
}
*selected = Some(i);
}
_ => {}
},
Mode::Create {
creative, focus, ..
} => match hit {
BACK => self.mode = select(&saves),
NAME => *focus = 0,
SEED => *focus = 1,
h if h == MODE || h == MODE + 1 => *creative = h == MODE + 1,
MAKE => return self.create_action(),
_ => {}
},
Mode::Multiplayer(screen) => {
let id = match hit {
JOIN => Some(40),
DIRECT => Some(41),
ADD => Some(42),
EDIT => Some(43),
DELETE => Some(44),
REFRESH => Some(45),
BACK => Some(match screen {
Screen::List { .. } => 46,
Screen::Edit { .. } => 51,
Screen::Direct { .. } => 53,
Screen::Disconnected { .. } => 54,
}),
DONE => Some(match screen {
Screen::Direct { .. } => 52,
_ => 50,
}),
FIELD_A | FIELD_B => {
if let Screen::Edit { focus, .. } = screen {
*focus = u8::from(hit == FIELD_B);
}
None
}
h if (SERVER..SERVER + 10_000).contains(&h) => {
let i = (h - SERVER) as usize;
let again =
matches!(screen, Screen::List { selected, .. } if *selected == Some(i));
if again {
if let Some(address) = screen.address_of(i) {
return Action::Connect { address };
}
} else if let Screen::List { selected, .. } = screen {
*selected = Some(i);
}
None
}
_ => None,
};
if let Some(id) = id {
match screen.click(Some(id), 0.0, 0.0, (0.0, 0.0), &saves) {
Outcome::Back => self.mode = Mode::Main,
Outcome::Connect(address) => return Action::Connect { address },
Outcome::None => {}
}
}
}
}
Action::None
}
}
/// The page header plus a row of actions under it; returns the y below.
fn header(ui: &mut Ui, x: f32, title: &str, description: &str) -> f32 {
let y = 36.0;
y + ui.page_header(x, y, title, description) + 24.0
}
/// Actions laid out right to left from `right`; returns the left edge.
fn actions_right(ui: &mut Ui, right: f32, y: f32, items: &[(u64, &str, Kind, bool)]) -> f32 {
let mut rx = right;
for &(bid, label, kind, on) in items {
let large = kind == Kind::Primary;
let (bw, bh) = if large {
(ui.button_width(label, true).max(120.0), CONTROL_LARGE)
} else {
(ui.button_width(label, false), CONTROL)
};
rx -= bw;
ui.button(
bid,
[rx, y + (CONTROL_LARGE - bh) / 2.0, bw, bh],
label,
kind,
on,
);
rx -= 8.0;
}
rx
}
/// A selectable list row: the launcher's row look with a hover layer and
/// the raised selection with its 1px border. Returns the row height.
#[allow(clippy::too_many_arguments)]
fn list_row(
ui: &mut Ui,
rid: u64,
x: f32,
y: f32,
w: f32,
selected: bool,
title: &str,
meta: &str,
right: &str,
dot: Option<u32>,
) -> f32 {
let h = 60.0;
let hover = ui.interact(rid, x - 12.0, y + 2.0, w + 24.0, h - 4.0, true);
let sel = ui.tween(rid ^ 0x5e1ec7, if selected { 1.0 } else { 0.0 }, t::quick());
ui.rounded(
x - 12.0,
y + 4.0,
w + 24.0,
h - 8.0,
t::RADIUS,
color::with_alpha(color::HOVER, 0.7 * hover),
);
ui.rounded(
x - 12.0,
y + 4.0,
w + 24.0,
h - 8.0,
t::RADIUS,
color::with_alpha(color::RAISED, sel),
);
ui.border(
x - 12.0,
y + 4.0,
w + 24.0,
h - 8.0,
t::RADIUS,
color::with_alpha(color::BORDER, sel),
);
let mut tx = x;
if let Some(dot) = dot {
ui.rounded(x, y + 17.0, 6.0, 6.0, 3.0, dot);
tx += 16.0;
}
let title = ui.fit(Face::Medium, BODY, title, w - 200.0);
ui.text(Face::Medium, BODY, tx, y + 10.0, color::TEXT, &title);
let meta = ui.fit(Face::Regular, SMALL, meta, w - 200.0);
ui.text(Face::Regular, SMALL, tx, y + 31.0, color::MUTED, &meta);
ui.text_right(Face::Regular, SMALL, x + w, y + 21.0, color::FAINT, right);
ui.divider(x, y + h, w);
h
}
/// An empty list: a serif line and a hint.
fn empty(ui: &mut Ui, x: f32, y: f32, title: &str, hint: &str) {
ui.text_line(Face::Display, 22.0, 30.0, x, y + 32.0, color::TEXT, title);
ui.text(Face::Regular, BODY, x, y + 66.0, color::MUTED, hint);
}
fn worlds_page(
ui: &mut Ui,
x: f32,
w: f32,
worlds: &[crate::title::WorldEntry],
selected: Option<usize>,
) {
let count = match worlds.len() {
0 => "No worlds yet. They live in the saves folder.".to_owned(),
1 => "1 world in the saves folder.".to_owned(),
n => format!("{n} worlds in the saves folder."),
};
let mut y = header(ui, x, "Singleplayer", &count);
actions_right(
ui,
x + w,
y - 24.0 - 58.0,
&[
(PLAY_WORLD, "Play", Kind::Primary, selected.is_some()),
(CREATE, "Create world", Kind::Secondary, true),
],
);
ui.divider(x, y, w);
if worlds.is_empty() {
empty(ui, x, y, "A blank map.", "Create a world to begin.");
return;
}
let bottom = ui.h - 36.0;
for (i, world) in worlds.iter().enumerate() {
if y + 60.0 > bottom {
break;
}
let secs = world
.modified
.duration_since(std::time::UNIX_EPOCH)
.map_or(0, |d| d.as_secs());
let meta = format!("{} · {}", crate::title::date_label(secs), world.folder);
let mode = if world.creative {
"Creative"
} else {
"Survival"
};
y += list_row(
ui,
WORLD + i as u64,
x,
y,
w,
selected == Some(i),
&world.name,
&meta,
mode,
None,
);
}
}
#[allow(clippy::too_many_arguments)]
fn create_page(
ui: &mut Ui,
x: f32,
w: f32,
name: &str,
seed: &str,
creative: bool,
focus: u8,
caret: bool,
) {
let mut y = header(
ui,
x,
"Create world",
"Generated by Horizon from the seed, as vanilla would.",
);
actions_right(
ui,
x + w,
y - 24.0 - 58.0,
&[
(MAKE, "Create", Kind::Primary, true),
(BACK, "Cancel", Kind::Ghost, true),
],
);
ui.divider(x, y, w);
let fx = x + t::ROW_LABEL + 16.0;
let fw = (w - t::ROW_LABEL - 16.0).min(360.0);
for (i, label) in ["World name", "Seed", "Game mode"].iter().enumerate() {
let rh = 12.0 + CONTROL + 12.0;
ui.text_line(Face::Regular, BODY, rh, x, y, color::MUTED, label);
let r = [fx, y + 12.0, fw, CONTROL];
match i {
0 => ui.field(NAME, r, name, "New World", focus == 0, caret),
1 => ui.field(SEED, r, seed, "Random", focus == 1, caret),
_ => {
ui.segmented(
MODE,
fx,
y + 12.0,
&["Survival", "Creative"],
usize::from(creative),
);
}
}
y += rh;
ui.divider(x, y, w);
}
}
fn multiplayer_page(ui: &mut Ui, x: f32, w: f32, screen: &Screen, caret: bool) {
match screen {
Screen::List {
servers,
selected,
pings,
lan,
} => {
let games = lan.games();
let sub = match servers.len() {
0 => "No saved servers. Worlds opened to LAN show up here too.".to_owned(),
1 => "1 saved server, and worlds opened to LAN.".to_owned(),
n => format!("{n} saved servers, and worlds opened to LAN."),
};
let mut y = header(ui, x, "Multiplayer", &sub);
let has = selected.is_some();
let saved = selected.is_some_and(|i| i < servers.len());
let mut items = vec![
(JOIN, "Join", Kind::Primary, has),
(ADD, "Add server", Kind::Secondary, true),
(DIRECT, "Direct connect", Kind::Secondary, true),
(REFRESH, "Refresh", Kind::Ghost, true),
];
if saved {
items.push((EDIT, "Edit", Kind::Ghost, true));
items.push((DELETE, "Delete", Kind::Danger, true));
}
actions_right(ui, x + w, y - 24.0 - 58.0, &items);
ui.divider(x, y, w);
let pings = pings.lock().map(|p| p.clone()).unwrap_or_default();
let mut rows: Vec<(String, String, String, u32)> = servers
.iter()
.map(|s| {
let (line, right, dot) = match pings.get(&s.ip) {
Some(Ping::Ok {
motd, players, ms, ..
}) => (
motd.lines().next().unwrap_or("").trim().to_owned(),
format!("{players} · {ms} ms"),
color::ACCENT,
),
Some(Ping::Failed(_)) => (
"Can't reach the server".to_owned(),
String::new(),
color::DANGER,
),
_ => ("Pinging…".to_owned(), String::new(), color::FAINT),
};
(s.name.clone(), format!("{line} · {}", s.ip), right, dot)
})
.collect();
rows.extend(games.iter().map(|g| {
(
"LAN world".to_owned(),
format!("{} · {}", g.motd, g.address),
"On your network".to_owned(),
color::ACCENT,
)
}));
if rows.is_empty() {
empty(
ui,
x,
y,
"Nobody here yet.",
"Add a server, connect directly, or open a world to LAN.",
);
return;
}
let bottom = ui.h - 36.0;
for (i, (name, meta, right, dot)) in rows.iter().enumerate() {
if y + 60.0 > bottom {
break;
}
y += list_row(
ui,
SERVER + i as u64,
x,
y,
w,
*selected == Some(i),
name,
meta,
right,
Some(*dot),
);
}
}
Screen::Edit {
index,
name,
address,
focus,
} => {
let title = if index.is_some() {
"Edit server"
} else {
"Add server"
};
let mut y = header(
ui,
x,
title,
"Saved to servers.dat, like vanilla's server list.",
);
let ok = horizon_protocol::servers::parse_address(address).is_some();
actions_right(
ui,
x + w,
y - 24.0 - 58.0,
&[
(DONE, "Save", Kind::Primary, ok),
(BACK, "Cancel", Kind::Ghost, true),
],
);
ui.divider(x, y, w);
let fx = x + t::ROW_LABEL + 16.0;
let fw = (w - t::ROW_LABEL - 16.0).min(360.0);
for (i, (label, value, hint)) in [
("Name", name, "Minecraft Server"),
("Address", address, "play.example.net"),
]
.iter()
.enumerate()
{
let rh = 12.0 + CONTROL + 12.0;
ui.text_line(Face::Regular, BODY, rh, x, y, color::MUTED, label);
let fid = if i == 0 { FIELD_A } else { FIELD_B };
ui.field(
fid,
[fx, y + 12.0, fw, CONTROL],
value,
hint,
usize::from(*focus) == i,
caret,
);
y += rh;
ui.divider(x, y, w);
}
}
Screen::Direct { address } => {
let y = header(
ui,
x,
"Direct connect",
"Join a server once without saving it.",
);
let ok = horizon_protocol::servers::parse_address(address).is_some();
actions_right(
ui,
x + w,
y - 24.0 - 58.0,
&[
(DONE, "Join", Kind::Primary, ok),
(BACK, "Cancel", Kind::Ghost, true),
],
);
ui.divider(x, y, w);
let rh = 12.0 + CONTROL + 12.0;
ui.text_line(Face::Regular, BODY, rh, x, y, color::MUTED, "Address");
let fx = x + t::ROW_LABEL + 16.0;
ui.field(
FIELD_A,
[fx, y + 12.0, (w - t::ROW_LABEL - 16.0).min(360.0), CONTROL],
address,
"host:port",
true,
caret,
);
ui.divider(x, y + rh, w);
}
Screen::Disconnected { reason } => {
let mut y = header(
ui,
x,
"Connection lost",
"The server closed the connection.",
);
ui.divider(x, y, w);
y += 16.0;
// The launcher's error note: a danger dot beside the message.
let lines = wrap(ui, reason, w - 40.0);
let box_h = 24.0 + lines.len() as f32 * 19.0;
ui.rounded(x, y, w, box_h, t::RADIUS, color::RAISED);
ui.border(x, y, w, box_h, t::RADIUS, color::BORDER);
ui.rounded(x + 12.0, y + 18.0, 6.0, 6.0, 3.0, color::DANGER);
for (i, line) in lines.iter().enumerate() {
ui.text_line(
Face::Regular,
BODY,
19.0,
x + 28.0,
y + 12.0 + i as f32 * 19.0,
color::TEXT,
line,
);
}
y += box_h + 16.0;
let bw = ui.button_width("Back to servers", false);
ui.button(
BACK,
[x, y, bw, CONTROL],
"Back to servers",
Kind::Secondary,
true,
);
}
}
}
/// Greedy word wrap in dp.
pub fn wrap(ui: &Ui, text: &str, width: f32) -> Vec<String> {
let mut lines = Vec::new();
for para in text.lines() {
let mut line = String::new();
for word in para.split_whitespace() {
let next = if line.is_empty() {
word.to_owned()
} else {
format!("{line} {word}")
};
if !line.is_empty() && ui.measure(Face::Regular, BODY, &next) > width {
lines.push(std::mem::replace(&mut line, word.to_owned()));
} else {
line = next;
}
}
lines.push(line);
}
lines
}
/// The pause menu in Horizon's style: the launcher's sidebar over the
/// blurred world, with the game's actions as a page. Ids match
/// `game/screens.rs`'s PauseScreen actions: 0 back to game, 1 options,
/// 2 save and quit, 3 statistics, 4 advancements, 9 world options.
pub mod pause {
use super::*;
fn act(a: u8) -> u64 {
id("pause", u64::from(a))
}
pub fn draw(ui: &mut Ui, world: &str, quit_label: &str, opened: Instant) {
let (w, h) = (ui.w, ui.h);
let p = t::ease_out_quint(opened.elapsed().as_secs_f32() / t::move_());
ui.opacity = p;
ui.atmosphere(0.35, 1.0);
ui.offset = (-16.0 * (1.0 - p), 0.0);
ui.fill(0.0, 0.0, SIDEBAR, h, color::with_alpha(color::SIDEBAR, 0.8));
ui.vline(SIDEBAR - 1.0, 0.0, h, color::BORDER);
ui.text_line(
Face::Display,
22.0,
30.0,
22.0,
16.0,
color::TEXT,
"Horizon",
);
ui.sidebar_list(
id("pause.nav", 0),
12.0,
66.0,
SIDEBAR - 24.0,
&["Game", "Advancements", "Statistics", "Options"],
0,
);
ui.text(
Face::Regular,
SMALL,
22.0,
h - 12.0 - 18.0,
color::FAINT,
"Horizon 26.3",
);
ui.offset = (0.0, 8.0 * (1.0 - p));
let x = SIDEBAR + 48.0;
let cw = (w - x - 48.0).min(760.0);
let mut y = 36.0;
ui.text(Face::Medium, SMALL, x, y, color::FAINT, "Game paused");
y += 22.0;
let title = ui.fit(Face::Display, t::HERO, world, cw);
ui.text_line(Face::Display, t::HERO, 58.0, x, y, color::TEXT, &title);
y += 58.0 + 24.0;
let bw = ui.button_width("Back to game", true).max(120.0);
ui.button(
act(0),
[x, y, bw, CONTROL_LARGE],
"Back to game",
Kind::Primary,
true,
);
let lw = ui.button_width("Open to LAN", true);
ui.button(
act(9),
[x + bw + 8.0, y, lw, CONTROL_LARGE],
"Open to LAN",
Kind::Secondary,
true,
);
y += CONTROL_LARGE + 24.0;
ui.divider(x, y, cw);
let rh = ui.row(
x,
y,
"Leave",
"Saves the world, then returns to the title.",
cw - t::ROW_LABEL - 220.0,
);
let qw = ui.button_width(quit_label, false);
ui.button(
act(2),
[x + cw - qw, y + (rh - CONTROL) / 2.0, qw, CONTROL],
quit_label,
Kind::Danger,
true,
);
y += rh;
ui.divider(x, y, cw);
ui.opacity = 1.0;
ui.offset = (0.0, 0.0);
}
/// The PauseScreen action under a click, if any.
pub fn click(
atlas: &HudAtlas,
batch: &mut HudBatch,
x: f32,
y: f32,
world: &str,
quit_label: &str,
) -> Option<u8> {
let mut ui = Ui::dry(atlas, batch, (x, y));
draw(
&mut ui,
world,
quit_label,
Instant::now() - std::time::Duration::from_secs(5),
);
let hit = ui.hit((x, y))?;
let nav = id("pause.nav", 0);
match hit {
h if h == nav => Some(0),
h if h == nav + 1 => Some(4),
h if h == nav + 2 => Some(3),
h if h == nav + 3 => Some(1),
h => [0u8, 1, 2, 3, 4, 9].into_iter().find(|&a| act(a) == h),
}
}
}
+83 -11
View File
@@ -4,6 +4,7 @@ mod advancements;
mod advancements_screen;
mod allays;
mod armor_stands;
mod backdrop;
mod banners;
mod beacon;
mod block_entity_anims;
@@ -694,6 +695,10 @@ struct Game<'a> {
settings: Settings,
/// Where the options screen returns: true = title, false = pause menu.
options_from_title: bool,
/// The live title backdrop (game/backdrop.rs).
backdrop: backdrop::Backdrop,
/// When the pause menu opened (Horizon style's entrance).
pause_since: Option<Instant>,
dragging: bool,
/// `ClientAvatarState`: walked distance and view bob.
avatar: horizon_client::camera::AvatarBob,
@@ -2969,7 +2974,15 @@ impl Game<'_> {
return batch;
}
if let Some(title) = &self.title {
title.draw(&self.res.atlas, &mut batch, self.cursor);
if horizon_client::ui_theme::horizon() {
let fade = self.backdrop_fade();
let mut ui =
horizon_client::ui_theme::Ui::new(&self.res.atlas, &mut batch, self.cursor);
title.draw_horizon(&mut ui, fade);
ui.finish();
} else {
title.draw(&self.res.atlas, &mut batch, self.cursor);
}
return batch;
}
let atlas_ptr: *const HudAtlas = &self.res.atlas;
@@ -2994,7 +3007,8 @@ impl Game<'_> {
// the sleep overlay, debug screen and open screens still draw.
let spectator = self.spectator();
let (wi, hi) = (w as i32, h as i32);
if !self.ui.hide_gui {
// Horizon's pause menu sits over the blurred world alone.
if !self.ui.hide_gui && !self.horizon_pause() {
self.draw_spyglass(&mut batch);
// Hud.extractCrosshair / extractItemHotbar / extractPlayerHealth /
// extractVehicleHealth and the experience bar, laid out by hud_layout.
@@ -7150,7 +7164,13 @@ impl Game<'_> {
return Ok(false);
};
let alpha = self.clock.fraction();
let (camera, underwater, view_yaw, view_pitch) = match self.camera_view(alpha as f32) {
let live = self.backdrop_live();
let view = if live {
self.backdrop_view()
} else {
self.camera_view(alpha as f32)
};
let (camera, underwater, view_yaw, view_pitch) = match view {
Some((c, yaw, pitch)) => {
let s =
self.world
@@ -7236,7 +7256,7 @@ impl Game<'_> {
entities.extend(dragon);
}
}
let celestial = if title {
let celestial = if title && !live {
self.panorama_geometry()
} else if self.dim == Dim::Overworld
&& self.potions.effects.get("darkness").is_none()
@@ -7262,12 +7282,14 @@ impl Game<'_> {
if !title {
self.end_geometry(camera, &mut entities);
}
if !title && self.dim == Dim::Overworld {
if (!title || live) && self.dim == Dim::Overworld {
self.cloud_geometry(&sky, camera, alpha, &mut entities);
self.weather_geometry(camera, alpha, &mut entities);
}
// PanoramaRenderer: the title cube spins at 0.1 degrees per tick, pitched 10 degrees.
let (yaw, pitch) = if title {
let (yaw, pitch) = if live {
(view_yaw, view_pitch)
} else if title {
(-(self.started.elapsed().as_secs_f32() * 2.0) % 360.0, 10.0)
} else {
(view_yaw, view_pitch)
@@ -7287,7 +7309,9 @@ impl Game<'_> {
camera,
yaw,
pitch,
fov_degrees: if title {
fov_degrees: if live {
72.0
} else if title {
85.0
} else {
self.fov_degrees(alpha as f32, camera.to_array())
@@ -7300,7 +7324,7 @@ impl Game<'_> {
sky,
distance: (self.streaming.radius * 16) as f32,
underwater,
title,
title: title && !live,
skybox: self.dim == Dim::Overworld,
end_sky: self.dim == Dim::End,
environment_fog: (self.dim == Dim::Nether).then_some((sky.fog_start, sky.fog_end)),
@@ -7334,6 +7358,13 @@ impl Game<'_> {
darkness: self.darkness_lighting(alpha as f32),
night_vision: self.night_vision_intensity(),
block_flicker: self.res.fog.state.block_light_flicker,
post: if live {
Some(horizon_client::post::PostGrade::FROST)
} else if self.horizon_pause() {
Some(horizon_client::post::PostGrade::PAUSE)
} else {
None
},
};
self.renderer.as_mut().ok_or("renderer")?.render(&frame)
}
@@ -7627,6 +7658,15 @@ impl ApplicationHandler for Game<'_> {
) {
self.last_input = Instant::now();
}
if let WindowEvent::MouseInput {
state,
button: MouseButton::Left,
..
} = &event
{
// The press state of Horizon-style buttons.
horizon_client::ui_theme::set_pressed(*state == ElementState::Pressed);
}
let result: Result<()> = (|| {
match event {
WindowEvent::CloseRequested => {
@@ -7752,9 +7792,14 @@ impl ApplicationHandler for Game<'_> {
.as_ref()
.map(|r| [r.config.width, r.config.height])
.unwrap_or([1, 1]);
let b = HudBatch::new(size);
let mut b = HudBatch::new(size);
let atlas = &self.res.atlas;
let action = self.title.as_mut().map_or(Action::None, |t| {
t.click(self.cursor.0, self.cursor.1, (b.width, b.height))
if horizon_client::ui_theme::horizon() {
t.click_horizon(atlas, &mut b, self.cursor.0, self.cursor.1)
} else {
t.click(self.cursor.0, self.cursor.1, (b.width, b.height))
}
});
match action {
Action::Quit => event_loop.exit(),
@@ -7920,6 +7965,7 @@ impl ApplicationHandler for Game<'_> {
WindowEvent::KeyboardInput { event, .. } if self.title.is_some() => {
if event.state == ElementState::Pressed
&& let Some(title) = self.title.as_mut()
&& !title.skip_opening()
{
match event.physical_key {
PhysicalKey::Code(KeyCode::Backspace) => title.backspace(),
@@ -8001,6 +8047,11 @@ impl ApplicationHandler for Game<'_> {
self.pitch = (self.pitch
+ (turn(KeyCode::ArrowDown) - turn(KeyCode::ArrowUp)) * 90.0 * secs)
.clamp(-90.0, 90.0);
self.update_backdrop()?;
horizon_client::ui_theme::set_backdrop(self.backdrop_fade());
if self.screen != Screen::Paused {
self.pause_since = None;
}
if self.title.is_none() {
self.update_world();
self.spawn_player()?;
@@ -8013,6 +8064,8 @@ impl ApplicationHandler for Game<'_> {
self.tick()?;
self.tick_ambience();
self.tick_fov();
} else if self.title.is_some() {
self.tick_backdrop();
}
self.tick_music();
self.tick_sound_engine();
@@ -8246,6 +8299,14 @@ pub fn run() -> Result<()> {
let now = Instant::now();
let game_root = options.resources.clone();
let mut settings = Settings::load(&std::env::current_dir()?.join("options.txt"));
horizon_client::ui_theme::load_preferences(&std::env::current_dir()?);
// Scripted and frame-limited runs (the parity harnesses) see vanilla's
// screens unless HORIZON_MENU_STYLE asks otherwise.
if (options.frames.is_some() || options.control.is_some())
&& std::env::var_os("HORIZON_MENU_STYLE").is_none()
{
horizon_client::ui_theme::set_style(horizon_client::ui_theme::MenuStyle::Classic);
}
if let Some(d) = options.distance_override {
settings.render_distance = d;
}
@@ -8363,6 +8424,8 @@ pub fn run() -> Result<()> {
hand_item: None,
settings,
options_from_title: false,
backdrop: Default::default(),
pause_since: None,
dragging: false,
avatar: Default::default(),
flash: 0,
@@ -8493,7 +8556,16 @@ pub fn run() -> Result<()> {
let (seed, creative) = (game.options.seed, game.options.creative);
game.open_world(&folder, None, Some(seed), creative)?;
}
None => game.title = Some(Title::new(std::env::current_dir()?.join("saves"))),
None => {
let title = Title::new(std::env::current_dir()?.join("saves"));
// The launcher's opening, once per session and only in Horizon's style.
if horizon_client::ui_theme::horizon() && game.options.frames.is_none() {
title
.opening
.set(Some(horizon_client::front::Opening::new()));
}
game.title = Some(title);
}
}
if let (Some(script), Some(output)) = (
std::env::var_os("HORIZON_COMMAND_SCRIPT"),
+245
View File
@@ -0,0 +1,245 @@
//! The live title backdrop (Menu style: Horizon): a frozen landscape that
//! Horizon generates and renders itself behind the title screens, seen
//! through a slow orbiting camera, falling snow, an overcast sky and the cold
//! blur and grade of `gfx::PostGrade`. Nothing is bundled: the chunks come
//! from the vanilla generator for a fixed seed and are cached in
//! `saves/.horizon-title/backdrop` (no level.dat, so no world list entry).
//! The ice-spikes spot is found once with `/locate biome`'s search and kept
//! in `spot.txt` there.
use super::Game;
use horizon_client::{
Result,
save::{Persistent, SaveDir},
streaming::Streaming,
vanillagen::VanillaTerrain,
world::{Weather, World},
};
use horizon_core::biome::{BiomeZoom, obfuscate_seed};
use std::{
sync::{Arc, Mutex},
time::Instant,
};
/// The world the backdrop is cut from (HORIZON_BACKDROP_SEED overrides it).
const SEED: i64 = 2_026_031_337;
/// The biome the camera looks for.
const BIOME: &str = "minecraft:ice_spikes";
/// Late morning: the snow reads clearly; the grade (`PostGrade::FROST`) makes it cold.
const DAY_TIME: i64 = 4_000;
#[derive(Default)]
pub(super) struct Backdrop {
pub active: bool,
/// The search for the spot, then the spot (block x, z).
spot: Arc<Mutex<Option<Option<(i32, i32)>>>>,
centred: bool,
/// Camera position once the ground under it has loaded.
pub camera: Option<glam::DVec3>,
pub ready: Option<Instant>,
pub started: Option<Instant>,
}
fn seed() -> i64 {
std::env::var("HORIZON_BACKDROP_SEED")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(SEED)
}
impl Game<'_> {
/// How visible the live backdrop is (0 until its first chunks are drawn).
pub(super) fn backdrop_fade(&self) -> f32 {
let Some(at) = self.backdrop.ready else {
return 0.0;
};
let x = (at.elapsed().as_secs_f32() / 1.6).clamp(0.0, 1.0);
x * x * (3.0 - 2.0 * x)
}
/// Whether the frame should draw the backdrop world instead of the panorama.
pub(super) fn backdrop_live(&self) -> bool {
self.title.is_some() && self.backdrop.active && self.backdrop.camera.is_some()
}
/// The orbiting camera: position, yaw and pitch.
pub(super) fn backdrop_view(&self) -> Option<(glam::DVec3, f32, f32)> {
let c = self.backdrop.camera?;
let t = self
.backdrop
.started
.map_or(0.0, |s| s.elapsed().as_secs_f32());
// A full turn in about six minutes.
let yaw = (200.0 + t * 1.0) % 360.0;
let pitch = 6.0 + (t * 0.05).sin() * 2.0;
Some((c, yaw, pitch))
}
/// Called every frame while the title is up.
pub(super) fn update_backdrop(&mut self) -> Result<()> {
let wanted = self.title.is_some()
&& horizon_client::ui_theme::horizon()
&& self.renderer.is_some()
&& self.options.frames.is_none();
if !wanted {
if self.backdrop.active && self.title.is_some() {
self.stop_backdrop();
}
if self.title.is_none() && self.backdrop.active {
// open_world / connect_server replaced the world and streaming.
self.backdrop = Backdrop::default();
}
return Ok(());
}
if !self.backdrop.active {
self.start_backdrop()?;
}
let found = *self.backdrop.spot.lock().unwrap_or_else(|e| e.into_inner());
let Some(Some((x, z))) = found else {
return Ok(());
};
if !self.backdrop.centred {
self.backdrop.centred = true;
self.streaming.center = (x >> 4, z >> 4);
self.streaming.paused = false;
}
self.update_world();
if self.backdrop.camera.is_none()
&& (-2..=2)
.all(|dz| (-2..=2).all(|dx| self.streaming.is_lit((x >> 4) + dx, (z >> 4) + dz)))
{
// Above the tallest block nearby, so no spike pokes through the lens.
let mut top = 64;
for dz in (-12..=12).step_by(3) {
for dx in (-12..=12).step_by(3) {
if let Some(y) = self.surface_y(x + dx, z + dz) {
top = top.max(y);
}
}
}
let ground = self.surface_y(x, z).unwrap_or(top);
let y = (ground + 22).max(top + 4);
self.backdrop.camera = Some(glam::DVec3::new(
f64::from(x) + 0.5,
f64::from(y),
f64::from(z) + 0.5,
));
}
if self.backdrop.camera.is_some()
&& self.backdrop.ready.is_none()
&& self
.renderer
.as_ref()
.is_some_and(|r| r.section_count() > 40)
{
self.backdrop.ready = Some(Instant::now());
}
Ok(())
}
/// The world tick of the backdrop: time passes for clouds and snow only.
pub(super) fn tick_backdrop(&mut self) {
if self.backdrop.active {
self.world.game_time += 1;
// The snow's fall follows the client tick counter.
self.ticks += 1;
}
}
fn surface_y(&self, x: i32, z: i32) -> Option<i32> {
let air = self.res.facts.air;
(-60..320).rev().find(|&y| self.world.block(x, y, z) != air)
}
fn start_backdrop(&mut self) -> Result<()> {
let seed = seed();
let root = std::env::current_dir()?
.join("saves")
.join(".horizon-title")
.join("backdrop");
std::fs::create_dir_all(&root)?;
let save = Arc::new(SaveDir::new(root.join(format!("{seed}"))));
let res = &*self.res;
let inner = Arc::new(
VanillaTerrain::new(
&self.options.resources.join("worldgen"),
res.assets.registry,
&res.biomes,
seed,
)
.map_err(|e| format!("title backdrop: {e}"))?,
);
let mut streaming = Streaming::new(
Arc::new(Persistent {
inner: inner.clone(),
save: save.clone(),
registry: res.assets.clone(),
biomes: res.biomes.clone(),
}),
res.context.clone(),
res.threads.min(6),
);
streaming.radius = self.settings.render_distance.clamp(4, 10);
streaming.biome_blend = self.settings.biome_blend;
streaming.smooth_lighting = self.settings.smooth_lighting;
streaming.cutout_leaves = self.settings.cutout_leaves;
streaming.biome_zoom = BiomeZoom::new(obfuscate_seed(seed));
streaming.paused = true;
self.streaming = streaming;
self.save = save;
let mut world = World::new(self.res.facts.air, seed);
world.day_time = DAY_TIME;
world.game_time = 6000;
// Light snow: the weather renders as snow in frozen biomes.
world.weather = Weather {
clear_time: 0,
rain_time: i32::MAX / 2,
thunder_time: i32::MAX / 2,
raining: true,
thundering: false,
rain_level: (0.35, 0.35),
thunder_level: (0.0, 0.0),
};
self.world = world;
self.dim = super::Dim::Overworld;
if let Some(r) = self.renderer.as_mut() {
r.clear_sections();
}
self.backdrop = Backdrop {
active: true,
started: Some(Instant::now()),
..Default::default()
};
// Find (or recall) the spot off the main thread.
let spot = self.backdrop.spot.clone();
std::fs::create_dir_all(root.join(format!("{seed}")))?;
let cache = root.join(format!("{seed}")).join("spot.txt");
std::thread::Builder::new()
.name("horizon-backdrop".into())
.spawn(move || {
let known = std::fs::read_to_string(&cache).ok().and_then(|t| {
let mut it = t.split_whitespace().map(|v| v.parse::<i32>().ok());
Some((it.next()??, it.next()??))
});
let found = known.or_else(|| {
let allowed = |name: &str| name == BIOME;
let search = horizon_world::worldgen::generator::BiomeSearch {
allowed: &allowed,
origin: [0, 64, 0],
radius: 6400,
horizontal: 32,
vertical: 64,
min_y: -64,
max_y: 320,
};
let found = inner.find_closest_biome(&search);
eprintln!("Horizon: title backdrop: {BIOME} at {found:?}");
let (_, p) = found?;
let _ = std::fs::write(&cache, format!("{} {}\n", p[0], p[2]));
Some((p[0], p[2]))
});
*spot.lock().unwrap_or_else(|e| e.into_inner()) =
Some(Some(found.unwrap_or((0, 0))));
})?;
Ok(())
}
fn stop_backdrop(&mut self) {
self.streaming.paused = true;
self.world = World::new(self.res.facts.air, 0);
if let Some(r) = self.renderer.as_mut() {
r.clear_sections();
}
self.backdrop = Backdrop::default();
}
}
+99 -69
View File
@@ -2,10 +2,11 @@
//! (game rules, the world clock, difficulty), bound to the game.
use super::{Dim, Game, Screen};
use horizon_client::{
chat::{Chat, ChatScreen, SYSTEM_INDICATOR},
chat::{Chat, ChatAction, ChatScreen, Commands, SYSTEM_INDICATOR},
command::{Registries, vanilla},
gamerules::GameRules,
hud::{HudBatch, rgba},
screen_draw::Measure,
text::Text,
};
use std::collections::BTreeMap;
@@ -63,6 +64,8 @@ impl TimeMarker {
pub struct UiState {
pub chat: Chat,
pub chat_screen: Option<ChatScreen>,
/// When the chat screen opened (its input took the focus: the cursor blink).
pub chat_opened: Option<std::time::Instant>,
pub registries: Registries,
pub rules: GameRules,
pub clock: WorldClock,
@@ -368,9 +371,22 @@ impl Game<'_> {
.as_ref()
.map_or([1280, 720], |r| [r.config.width, r.config.height]);
let b = HudBatch::new(size);
let mut screen = ChatScreen::new(initial, self.ui.chat.recent.len(), b.width, b.height);
screen.auto_suggestions = true;
let m = Measure(&self.res.atlas.font);
let c = Commands {
dispatcher: vanilla::game_dispatcher(),
registries: &self.ui.registries,
};
let mut screen = ChatScreen::new(
&m,
&c,
initial,
self.ui.chat.recent.len(),
b.width as i32,
b.height as i32,
);
screen.auto_suggestions = self.settings.auto_suggestions;
self.ui.chat_screen = Some(screen);
self.ui.chat_opened = Some(std::time::Instant::now());
self.screen = Screen::Chat;
self.keys.clear();
self.left = false;
@@ -409,67 +425,68 @@ impl Game<'_> {
}
/// A key (and the text it typed) while the chat screen is open.
pub(super) fn chat_key_code(&mut self, key: KeyCode, typed_text: Option<&str>) {
let ctrl =
self.keys.contains(&KeyCode::ControlLeft) || self.keys.contains(&KeyCode::ControlRight);
// InputQuirks.EDIT_SHORTCUT_KEY_MODIFIER: Cmd on macOS, Ctrl elsewhere.
let (left, right) = if cfg!(target_os = "macos") {
(KeyCode::SuperLeft, KeyCode::SuperRight)
} else {
(KeyCode::ControlLeft, KeyCode::ControlRight)
};
let ctrl = self.keys.contains(&left) || self.keys.contains(&right);
let shift =
self.keys.contains(&KeyCode::ShiftLeft) || self.keys.contains(&KeyCode::ShiftRight);
match key {
// ChatScreen.keyPressed: the chat scrolls a page.
KeyCode::PageUp | KeyCode::PageDown
if !self
.ui
.chat_screen
.as_ref()
.is_some_and(|s| s.suggestions_visible()) =>
{
let n = self.ui.chat.lines_per_page(true) as i32 - 1;
self.ui
.chat
.scroll_by(if key == KeyCode::PageUp { n } else { -n }, true);
return;
}
_ => {}
}
let Some(mut screen) = self.ui.chat_screen.take() else {
return;
};
let atlas = &self.res.atlas;
let d = vanilla::game_dispatcher();
if screen.suggestion_key(atlas, d, &self.ui.registries, key, shift) {
self.ui.chat_screen = Some(screen);
return;
}
let mut close = false;
let mut submit = None;
match key {
KeyCode::Escape => close = true,
KeyCode::Enter | KeyCode::NumpadEnter => {
submit = Some(screen.normalized());
close = true;
}
KeyCode::ArrowUp => screen.move_in_history(&self.ui.chat.recent, -1),
KeyCode::ArrowDown => screen.move_in_history(&self.ui.chat.recent, 1),
KeyCode::PageUp => {
let n = self.ui.chat.lines_per_page(true) as i32 - 1;
self.ui.chat.scroll_by(n, true);
}
KeyCode::PageDown => {
let n = self.ui.chat.lines_per_page(true) as i32 - 1;
self.ui.chat.scroll_by(-n, true);
}
_ => {
if screen.input.key(key, ctrl, shift) {
screen.edited();
} else if let Some(text) = typed_text
&& !ctrl
{
let typed: String = text.chars().filter(|c| !c.is_control()).collect();
if !typed.is_empty() {
screen.input.insert_text(&typed);
screen.edited();
}
let m = Measure(&self.res.atlas.font);
let c = Commands {
dispatcher: vanilla::game_dispatcher(),
registries: &self.ui.registries,
};
match screen.key(&m, &c, &self.ui.chat.recent, key, shift, ctrl) {
ChatAction::Close => self.close_chat(),
ChatAction::Submit(message) => {
self.close_chat();
if !message.is_empty() {
self.handle_chat_input(&message);
}
}
}
if close {
self.close_chat();
} else {
self.ui.chat_screen = Some(screen);
}
if let Some(message) = submit
&& !message.is_empty()
{
self.handle_chat_input(&message);
ChatAction::None => {
// charTyped: the text the key typed.
if let Some(text) = typed_text
&& !ctrl
{
screen.type_text(&m, &c, text);
}
self.ui.chat_screen = Some(screen);
}
}
}
/// Text typed into the chat box (control socket `chat`).
pub(super) fn chat_type(&mut self, text: &str) {
let m = Measure(&self.res.atlas.font);
let c = Commands {
dispatcher: vanilla::game_dispatcher(),
registries: &self.ui.registries,
};
if let Some(screen) = self.ui.chat_screen.as_mut() {
screen.input.insert_text(text);
screen.edited();
screen.type_text(&m, &c, text);
}
}
/// ChatScreen.handleChatInput: history, then a command or a chat line.
@@ -494,8 +511,10 @@ impl Game<'_> {
let height = self.renderer.as_ref().map_or(720.0, |r| {
HudBatch::new([r.config.width, r.config.height]).height
});
let _ = height;
let mouse = (cursor.0.floor() as i32, cursor.1.floor() as i32);
if let Some(screen) = self.ui.chat_screen.as_mut()
&& screen.scroll_suggestions(cursor, height, amount)
&& screen.scroll(mouse, amount as f64)
{
return;
}
@@ -508,12 +527,14 @@ impl Game<'_> {
let height = self.renderer.as_ref().map_or(720.0, |r| {
HudBatch::new([r.config.width, r.config.height]).height
});
if let Some(screen) = self.ui.chat_screen.as_mut()
&& !screen.click(cursor, height)
&& screen.input.y <= cursor.1
{
let i = screen.input.index_at(&self.res.atlas, cursor.0);
screen.input.set_cursor(i, false);
let _ = height;
let m = Measure(&self.res.atlas.font);
let c = Commands {
dispatcher: vanilla::game_dispatcher(),
registries: &self.ui.registries,
};
if let Some(screen) = self.ui.chat_screen.as_mut() {
screen.click(&m, &c, cursor.0 as f64, cursor.1 as f64);
}
}
/// Chat lines over the HUD (focused while the chat screen is open).
@@ -530,16 +551,25 @@ impl Game<'_> {
let Some(mut screen) = self.ui.chat_screen.take() else {
return;
};
screen.resize(batch.width, batch.height);
let bg = self.ui.chat.options.background_opacity as f32;
screen.draw(
batch,
&self.res.atlas,
vanilla::game_dispatcher(),
&self.ui.registries,
self.cursor,
bg,
);
let m = Measure(&self.res.atlas.font);
let c = Commands {
dispatcher: vanilla::game_dispatcher(),
registries: &self.ui.registries,
};
screen.resize(&m, &c, batch.width as i32, batch.height as i32);
// Options.getBackgroundColor(Integer.MIN_VALUE).
let background = if self.settings.file.bool("backgroundForChatOnly") {
i32::MIN
} else {
self.settings.text_background(0.0) as i32
};
let mouse = (self.cursor.0.floor() as i32, self.cursor.1.floor() as i32);
let blink = self
.ui
.chat_opened
.map_or(0, |t| t.elapsed().as_millis() as u64);
let draws = screen.draw(&m, mouse, blink, background);
horizon_client::screen_draw::paint(batch, &self.res.atlas, &draws);
self.ui.chat_screen = Some(screen);
}
/// Advance the overworld clock (ServerClockManager.tick) when
+1 -1
View File
@@ -140,7 +140,7 @@ impl Game<'_> {
if self.command_source.is_some_and(|s| s.silent) {
return;
}
self.system_message(message.with_color(text::RED));
self.system_message(Text::empty().append(message).with_color(text::RED));
}
/// sendSuccess honouring `send_command_feedback`.
pub(super) fn feedback(&mut self, message: Text) {
+1 -1
View File
@@ -299,7 +299,7 @@ impl Game<'_> {
}
match self.screen {
Screen::Chat => self.chat_type(text),
Screen::Options => self.ui.options.type_text(text),
Screen::Options => self.ui.options.type_text(&self.res.atlas, text),
Screen::Inventory if self.recipe_search_focused() => {
self.recipe_text(Some(text), false)
}
@@ -544,14 +544,14 @@ impl Game<'_> {
.take()
.unwrap_or_default()
.iter()
.map(horizon_client::text::Text::plain)
.collect::<Vec<String>>()
.map(|t| horizon_client::lan::data::component_nbt(&t.component()))
.collect::<Vec<_>>()
});
for line in lines.unwrap_or_default() {
for content in lines.unwrap_or_default() {
host.hub.send_to(
conn,
&C::SystemChat(play::SystemChat {
content: literal(&line),
content,
overlay: false,
}),
);
+2 -2
View File
@@ -77,12 +77,12 @@ impl Game<'_> {
}
pub(super) fn options_key(&mut self, key: KeyCode, text: Option<&str>) -> Result<()> {
let mut ui = std::mem::take(&mut self.ui.options);
let events = ui.key(&mut self.settings, key, text);
let events = ui.key(&mut self.settings, &self.res.atlas, key, text);
self.ui.options = ui;
self.handle_option_events(events)
}
pub(super) fn options_scroll(&mut self, amount: f32) {
self.ui.options.scroll(amount);
self.ui.options.scroll_at(self.cursor, amount);
}
/// Mouse buttons pressed while a key is being bound.
pub(super) fn options_waiting_for_key(&self) -> bool {
+33 -23
View File
@@ -5,9 +5,9 @@ use super::Game;
use horizon_client::{
hud::HudAtlas,
lang,
options_ui::PackEntry,
packs::{self, Pack},
text::Text,
pack_screen::{Compat, PackInfo, Source as PackSource},
packs::{self, Pack, Position},
text::{Style, Text},
};
use std::path::{Path, PathBuf};
@@ -28,22 +28,38 @@ pub fn startup_root(vanilla: &Path, selected: &[String]) -> PathBuf {
let enabled = packs::enabled(&all, selected);
packs::resource_root(vanilla, &enabled, &cache_dir())
}
fn entry(p: &Pack) -> PackEntry {
PackEntry {
fn info(p: &Pack) -> PackInfo {
let built_in = !p.id.starts_with("file/");
PackInfo {
id: p.id.clone(),
title: p.title.clone(),
description: p.description.clone(),
compatible: p.compatible,
description: p.raw_description.clone(),
description_style: p.description_style.clone(),
source: if built_in {
PackSource::BuiltIn
} else {
PackSource::Default
},
compat: p.compatibility,
icon: p.icon,
required: false,
position: Position::Top,
fixed: false,
}
}
fn vanilla_entry() -> PackEntry {
PackEntry {
/// The vanilla pack: required, at the bottom (`BuiltInPackSource`).
fn vanilla_info() -> PackInfo {
PackInfo {
id: "vanilla".into(),
title: Text::translate("resourcePack.vanilla.name", &[]),
description: Text::translate("resourcePack.vanilla.description", &[]),
compatible: true,
description_style: Style::default(),
source: PackSource::BuiltIn,
compat: Compat::Compatible,
icon: true,
required: true,
position: Position::Bottom,
fixed: false,
}
}
impl Game<'_> {
@@ -54,22 +70,16 @@ impl Game<'_> {
self.ui.vanilla_root.clone()
}
}
/// PackSelectionModel: available (unselected) and selected (top first).
/// The packs the pack screen offers and the current selection
/// (`PackSelectionScreen` makes its `PackSelectionModel` from them).
pub(super) fn refresh_pack_lists(&mut self) {
let all = packs::discover(&self.vanilla_root(), &packs_dir());
let mut choices = vec![packs::Selectable::vanilla()];
choices.extend(
all.iter()
.map(|p| packs::Selectable::optional(&p.id, p.compatible)),
);
let model = packs::SelectionModel::new(choices, &self.settings.resource_packs);
let mut entries: Vec<PackEntry> = all.iter().map(entry).collect();
entries.push(vanilla_entry());
let mut infos: Vec<PackInfo> = all.iter().map(info).collect();
infos.push(vanilla_info());
let o = &mut self.ui.options;
o.available = entries;
o.selected = Vec::new();
o.pack_model = model;
o.sync_pack_lists();
o.pack_infos = infos;
o.pack_selection = self.settings.resource_packs.clone();
o.pack_screen = None;
}
/// Rebuild the overlay and reload what can change while running.
pub(super) fn reload_packs(&mut self) {
+46 -4
View File
@@ -52,7 +52,32 @@ fn death_buttons(w: f32, h: f32) -> [(f32, f32, &'static str, u8); 2] {
]
}
impl Game<'_> {
/// Whether the pause menu is drawn in Horizon's style (over a blurred world).
pub(super) fn horizon_pause(&self) -> bool {
self.screen == Screen::Paused && self.title.is_none() && horizon_client::ui_theme::horizon()
}
fn pause_labels(&self) -> (String, &'static str) {
let world = if self.remote.is_some() {
"Multiplayer".to_owned()
} else {
self.level.name.clone()
};
let quit = if self.remote.is_some() {
"Disconnect"
} else {
"Save and quit"
};
(world, quit)
}
pub(super) fn draw_pause_menu(&mut self, batch: &mut HudBatch) {
if horizon_client::ui_theme::horizon() {
let opened = *self.pause_since.get_or_insert_with(std::time::Instant::now);
let (world, quit) = self.pause_labels();
let mut ui = horizon_client::ui_theme::Ui::new(&self.res.atlas, batch, self.cursor);
horizon_client::front::pause::draw(&mut ui, &world, quit, opened);
ui.finish();
return;
}
let atlas = &self.res.atlas;
let (w, h) = (batch.width, batch.height);
ui::menu_background(batch, atlas, 0.0, 0.0, w, h, true);
@@ -102,10 +127,27 @@ impl Game<'_> {
let b = HudBatch::new(size);
(b.width, b.height)
};
let hit = pause_buttons(w, h)
.into_iter()
.find(|b| b.5 && ui::hovered(self.cursor, b.0, b.1, b.2, 20.0))
.map(|b| b.4);
let hit = if horizon_client::ui_theme::horizon() {
let size = self
.renderer
.as_ref()
.map_or([1, 1], |r| [r.config.width, r.config.height]);
let mut b = HudBatch::new(size);
let (world, quit) = self.pause_labels();
horizon_client::front::pause::click(
&self.res.atlas,
&mut b,
self.cursor.0,
self.cursor.1,
&world,
quit,
)
} else {
pause_buttons(w, h)
.into_iter()
.find(|b| b.5 && ui::hovered(self.cursor, b.0, b.1, b.2, 20.0))
.map(|b| b.4)
};
match hit {
Some(0) => {
self.screen = Screen::Playing;
+22
View File
@@ -96,6 +96,8 @@ pub struct Frame<'a> {
pub night_vision: f32,
/// Torch flicker added to the block light factor of 1.4.
pub block_flicker: f32,
/// Blur and grade the frame under a Horizon-style menu (`post`).
pub post: Option<crate::post::PostGrade>,
}
/// One frame of the world border wall (`WorldBorderRenderer.render`).
#[derive(Clone, Debug)]
@@ -162,6 +164,8 @@ pub struct Renderer {
reachable_from: Option<SectionKey>,
visibility_dirty: bool,
pub hud: HudRenderer,
/// The menus' backdrop blur, made on first use.
post: Option<crate::post::Post>,
pub info: wgpu::AdapterInfo,
pub suspended: bool,
pub drawn_sections: usize,
@@ -1086,6 +1090,7 @@ impl Renderer {
reachable_from: None,
visibility_dirty: true,
hud,
post: None,
info,
suspended: size.width == 0 || size.height == 0,
drawn_sections: 0,
@@ -1853,6 +1858,23 @@ impl Renderer {
pass.draw_indexed(0..6, (i * 4) as i32, 0..1);
}
}
if let Some(grade) = &frame.post
&& self.config.usage.contains(wgpu::TextureUsages::COPY_SRC)
{
let format = self.config.format;
let device = &self.device;
self.post
.get_or_insert_with(|| crate::post::Post::new(device, format))
.apply(
&self.device,
&self.queue,
&mut encoder,
&surface_frame.texture,
&view_target,
[self.config.width, self.config.height],
grade,
);
}
self.hud.draw(
&self.device,
&self.queue,
+7
View File
@@ -204,6 +204,13 @@ impl HudAtlas {
for i in 0..SKIN_SLOTS {
images.push((format!("horizon/skin{i}"), 64, 64, vec![0; 64 * 64 * 4]));
}
// Horizon-style menu text and corner masks (ui_theme), rasterized at run time.
images.push((
"horizon/ui-text".into(),
2048,
1024,
vec![0; 2048 * 1024 * 4],
));
images.sort_by(|a, b| b.2.cmp(&a.2).then(b.1.cmp(&a.1)));
let width = 4096u32;
let mut placements = Vec::with_capacity(images.len());
@@ -0,0 +1,304 @@
//! A player's advancements on a server (PlayerAdvancements): on the
//! player's first tick the `minecraft:tick` criteria are met, the
//! advancements they complete grant their recipes (ServerRecipeBook.addRecipes:
//! ClientboundRecipeBookAddPacket) and the advancements the player may see go
//! out in ClientboundUpdateAdvancementsPacket (PlayerAdvancements.flushDirty).
use super::data::{SyncData, json_to_nbt};
use crate::{advancements::Tree, recipe_book::RecipeIndex};
use horizon_protocol::buf::Writer;
use serde_json::Value;
use std::{
collections::{BTreeMap, HashMap},
path::Path,
};
pub struct ServerAdvancements {
tree: Tree,
kids: Vec<Vec<usize>>,
layout: Vec<Option<(i32, f32)>>,
/// Recipe files by id.
recipes: BTreeMap<String, Value>,
displays: RecipeIndex,
/// RecipeManager.unpackRecipeInfo's group numbers.
groups: HashMap<String, i32>,
}
/// What the first tick sends: ClientboundRecipeBookAddPacket's payload (when
/// recipes were unlocked) and ClientboundUpdateAdvancementsPacket's.
pub struct FirstTick {
pub recipe_book_add: Option<Vec<u8>>,
pub update_advancements: Vec<u8>,
}
impl ServerAdvancements {
pub fn load(resources: &Path) -> Self {
let tree = Tree::load(&resources.join("data"));
let kids = tree.children();
let layout = tree.layout();
let mut recipes = BTreeMap::new();
super::recipes::recipes(&resources.join("data/minecraft/recipe"), "", &mut recipes);
let mut groups = HashMap::new();
for r in recipes.values() {
if let Some(g) = r["group"].as_str().filter(|g| !g.is_empty()) {
let next = groups.len() as i32;
groups.entry(g.to_owned()).or_insert(next);
}
}
Self {
tree,
kids,
layout,
recipes,
displays: RecipeIndex::load(resources),
groups,
}
}
/// The first tick of a player without advancements.
pub fn first_tick(&self, sync: &SyncData, now_millis: i64) -> FirstTick {
// CriteriaTriggers.TICK: the criteria it meets, and what they complete.
let mut obtained: Vec<Vec<&str>> = vec![Vec::new(); self.tree.list.len()];
for (i, a) in self.tree.list.iter().enumerate() {
for c in &a.criteria {
if c.trigger == "minecraft:tick" && c.conditions.is_null() {
obtained[i].push(&c.name);
}
}
}
let done: Vec<bool> = self
.tree
.list
.iter()
.zip(&obtained)
.map(|(a, got)| {
!a.requirements.is_empty()
&& a.requirements
.iter()
.all(|group| group.iter().any(|c| got.contains(&c.as_str())))
})
.collect();
// AdvancementRewards.grant: the recipes, in the advancements' order.
let mut entries = Vec::new();
for (i, a) in self.tree.list.iter().enumerate() {
if !done[i] {
continue;
}
for id in &a.rewards.recipes {
entries.extend(self.book_entries(id, sync));
}
}
let recipe_book_add = (!entries.is_empty()).then(|| {
let mut w = Writer::new();
w.varint(entries.len() as i32);
for e in entries {
w.data.extend(e);
}
w.bool(false); // not a replacement
w.data
});
// flushDirty: every advancement the player may see, and its progress.
let visible = self.tree.visible(&self.kids, |i| done[i]);
let shown: Vec<usize> = (0..self.tree.list.len()).filter(|i| visible[*i]).collect();
let mut w = Writer::new();
w.bool(true); // the first packet resets the client's advancements
w.varint(shown.len() as i32);
for &i in &shown {
let a = &self.tree.list[i];
w.string(&a.id);
w.bool(a.parent.is_some());
if let Some(p) = &a.parent {
w.string(p);
}
w.bool(a.display.is_some());
if let Some(d) = &a.display {
w.nbt(&json_to_nbt(&d.title));
w.nbt(&json_to_nbt(&d.description));
w.varint(sync.id("minecraft:item", &d.icon).unwrap_or(0));
w.varint(1);
w.varint(0);
w.varint(0);
w.varint(match d.frame {
crate::advancements::Frame::Task => 0,
crate::advancements::Frame::Challenge => 1,
crate::advancements::Frame::Goal => 2,
});
w.i32(
i32::from(d.background.is_some())
| i32::from(d.show_toast) << 1
| i32::from(d.hidden) << 2,
);
if let Some(b) = &d.background {
w.string(b);
}
}
w.varint(a.requirements.len() as i32);
for group in &a.requirements {
w.varint(group.len() as i32);
for c in group {
w.string(c);
}
}
w.bool(false); // sends_telemetry_event
let (x, y) = self.layout[i].unwrap_or((0, 0.0));
w.f32(x as f32);
w.f32(y);
}
w.varint(0); // nothing removed
w.varint(shown.len() as i32);
for &i in &shown {
let a = &self.tree.list[i];
w.string(&a.id);
w.varint(a.criteria.len() as i32);
for c in &a.criteria {
w.string(&c.name);
let got = obtained[i].contains(&c.name.as_str());
w.bool(got);
if got {
w.i64(now_millis);
}
}
}
w.bool(true); // show the advancements
FirstTick {
recipe_book_add,
update_advancements: w.data,
}
}
/// ClientboundRecipeBookAddPacket.Entry for each display of a recipe:
/// highlighted, and with a notification unless the recipe turns it off.
fn book_entries(&self, id: &str, sync: &SyncData) -> Vec<Vec<u8>> {
let Some(r) = self.recipes.get(id) else {
return Vec::new();
};
let ids = self.displays.display_ids(id);
if ids.len() != 1 {
// Special recipes have no display; transmutations aren't unlocked on joining.
return Vec::new();
}
let kind = r["type"].as_str().unwrap_or("");
let item = |n: &str| sync.id("minecraft:item", n).unwrap_or(0);
let slot = |n: &str| sync.id("minecraft:slot_display", n).unwrap_or(0);
let mut w = Writer::new();
w.varint(ids.start);
let (ingredients, category): (Vec<Option<&Value>>, &str) = match kind {
"minecraft:crafting_shaped" => {
let pattern = shrink(r["pattern"].as_array().map_or(&[][..], |p| p));
let (width, height) = (pattern.first().map_or(0, Vec::len), pattern.len());
w.varint(sync.id("minecraft:recipe_display", kind).unwrap_or(0));
w.varint(width as i32);
w.varint(height as i32);
let cells: Vec<Option<&Value>> = pattern
.iter()
.flatten()
.map(|c| (*c != ' ').then(|| &r["key"][c.to_string()]))
.collect();
(cells, "misc")
}
"minecraft:crafting_shapeless" => {
w.varint(sync.id("minecraft:recipe_display", kind).unwrap_or(0));
let cells = r["ingredients"]
.as_array()
.map_or(Vec::new(), |a| a.iter().map(Some).collect());
(cells, "misc")
}
_ => return Vec::new(),
};
// ShapedCraftingRecipeDisplay / ShapelessCraftingRecipeDisplay:
// the ingredients' TagSlotDisplays, the result, the crafting table.
w.varint(ingredients.len() as i32);
for cell in &ingredients {
match cell {
Some(v) => {
w.varint(slot("minecraft:tag"));
holder_set(&mut w, v, &item);
}
None => w.varint(slot("minecraft:empty")),
}
}
w.varint(slot("minecraft:item_stack"));
w.varint(item(r["result"]["id"].as_str().unwrap_or("minecraft:air")));
w.varint(r["result"]["count"].as_i64().unwrap_or(1) as i32);
w.varint(0);
w.varint(0);
w.varint(slot("minecraft:item"));
w.varint(item("minecraft:crafting_table"));
// The group, the recipe book category and the placement's ingredients.
match r["group"].as_str().and_then(|g| self.groups.get(g)) {
Some(g) => w.varint(g + 1),
None => w.varint(0),
}
let category = format!(
"minecraft:crafting_{}",
match r["category"].as_str().unwrap_or(category) {
"building" => "building_blocks",
c => c,
}
);
w.varint(
sync.id("minecraft:recipe_book_category", &category)
.unwrap_or(0),
);
let placed: Vec<&Value> = ingredients.iter().flatten().copied().collect();
w.bool(true);
w.varint(placed.len() as i32);
for v in placed {
holder_set(&mut w, v, &item);
}
let notify = r["show_notification"].as_bool().unwrap_or(true);
w.i8(i8::from(notify) | 2);
vec![w.data]
}
}
/// ShapedRecipePattern.shrink: the pattern without blank border rows and columns.
fn shrink(rows: &[Value]) -> Vec<Vec<char>> {
let rows: Vec<Vec<char>> = rows
.iter()
.map(|r| r.as_str().unwrap_or("").chars().collect())
.collect();
let used = |r: &Vec<char>| r.iter().any(|c| *c != ' ');
let (Some(top), Some(bottom)) = (rows.iter().position(used), rows.iter().rposition(used))
else {
return Vec::new();
};
let rows = &rows[top..=bottom];
let left = rows
.iter()
.filter_map(|r| r.iter().position(|c| *c != ' '))
.min()
.unwrap_or(0);
let right = rows
.iter()
.filter_map(|r| r.iter().rposition(|c| *c != ' '))
.max()
.unwrap_or(0);
rows.iter()
.map(|r| {
(left..=right)
.map(|x| r.get(x).copied().unwrap_or(' '))
.collect()
})
.collect()
}
/// ByteBufCodecs.holderSet for an ingredient: a tag by name, or the items.
fn holder_set(w: &mut Writer, v: &Value, item: &dyn Fn(&str) -> i32) {
match v {
Value::String(s) if s.starts_with('#') => {
w.varint(0);
w.string(&s[1..]);
}
Value::String(s) => {
w.varint(2);
w.varint(item(s));
}
Value::Array(a) => {
w.varint(a.len() as i32 + 1);
for s in a {
w.varint(item(s.as_str().unwrap_or("")));
}
}
_ => w.varint(1),
}
}
@@ -0,0 +1,892 @@
//! The order of the children of each node of vanilla's command tree
//! (path of node names from the root, children in registration order),
//! for nodes with several children. Generated by
//! tools/generate_lan_command_order.py; do not edit by hand.
pub const ORDER: &[(&str, &str)] = &[
(
"",
"advancement attribute execute bossbar clear clone compute damage data datapack debug defaultgamemode dialog difficulty effect me enchant experience xp fill fillbiome forceload function gamemode gamerule give help item kick kill list locate loot msg tell w swing particle place playsound posteffect random reload recipe fetchprofile return ride rotate say schedule scoreboard seed version setblock spawnpoint setworldspawn spectate spreadplayers stopsound stopwatch summon tag team teammsg tm teleport tp tellraw test tick time title trigger waypoint weather worldborder jfr ban-ip banlist ban deop op pardon pardon-ip perf save-all save-off save-on setidletimeout stop transfer whitelist publish unpublish",
),
("advancement", "grant revoke"),
(
"advancement grant targets",
"only from until through everything",
),
(
"advancement revoke targets",
"only from until through everything",
),
("attribute target attribute", "get base modifier"),
("attribute target attribute base", "set get reset"),
("attribute target attribute modifier", "add remove value"),
(
"attribute target attribute modifier add id value",
"add_value add_multiplied_base add_multiplied_total",
),
(
"execute",
"run if unless as at store positioned rotated facing align anchored in summon on",
),
(
"execute if",
"block biome loaded dimension score blocks entity predicate function stopwatch data items slots",
),
(
"execute if score target targetObjective",
"= < <= > >= matches",
),
("execute if blocks start end destination", "all masked"),
("execute if data", "entity block storage"),
("execute if items", "entity block"),
("execute if slots", "entity block"),
(
"execute unless",
"block biome loaded dimension score blocks entity predicate function stopwatch data items slots",
),
(
"execute unless score target targetObjective",
"= < <= > >= matches",
),
("execute unless blocks start end destination", "all masked"),
("execute unless data", "entity block storage"),
("execute unless items", "entity block"),
("execute unless slots", "entity block"),
("execute store", "result success"),
("execute store result", "score bossbar entity block storage"),
("execute store result bossbar id", "value max"),
(
"execute store result entity target path",
"int float short long double byte",
),
(
"execute store result block target path",
"int float short long double byte",
),
(
"execute store result storage target path",
"int float short long double byte",
),
(
"execute store success",
"score bossbar entity block storage",
),
("execute store success bossbar id", "value max"),
(
"execute store success entity target path",
"int float short long double byte",
),
(
"execute store success block target path",
"int float short long double byte",
),
(
"execute store success storage target path",
"int float short long double byte",
),
("execute positioned", "pos as over"),
("execute rotated", "rot as"),
("execute facing", "entity pos"),
(
"execute on",
"owner leasher target attacker vehicle controller origin passengers",
),
("bossbar", "add remove list set get"),
(
"bossbar set id",
"name color style value max visible players",
),
(
"bossbar set id color",
"pink blue red green yellow purple white",
),
(
"bossbar set id style",
"progress notched_6 notched_10 notched_12 notched_20",
),
("bossbar get id", "value max visible players"),
("clone", "begin from"),
("clone begin end", "destination to"),
(
"clone begin end destination",
"replace masked filtered strict",
),
("clone begin end destination replace", "force move normal"),
("clone begin end destination masked", "force move normal"),
(
"clone begin end destination filtered filter",
"force move normal",
),
(
"clone begin end destination strict",
"replace masked filtered",
),
(
"clone begin end destination strict replace",
"force move normal",
),
(
"clone begin end destination strict masked",
"force move normal",
),
(
"clone begin end destination strict filtered filter",
"force move normal",
),
(
"clone begin end to targetDimension destination",
"replace masked filtered strict",
),
(
"clone begin end to targetDimension destination replace",
"force move normal",
),
(
"clone begin end to targetDimension destination masked",
"force move normal",
),
(
"clone begin end to targetDimension destination filtered filter",
"force move normal",
),
(
"clone begin end to targetDimension destination strict",
"replace masked filtered",
),
(
"clone begin end to targetDimension destination strict replace",
"force move normal",
),
(
"clone begin end to targetDimension destination strict masked",
"force move normal",
),
(
"clone begin end to targetDimension destination strict filtered filter",
"force move normal",
),
("clone from sourceDimension begin end", "destination to"),
(
"clone from sourceDimension begin end destination",
"replace masked filtered strict",
),
(
"clone from sourceDimension begin end destination replace",
"force move normal",
),
(
"clone from sourceDimension begin end destination masked",
"force move normal",
),
(
"clone from sourceDimension begin end destination filtered filter",
"force move normal",
),
(
"clone from sourceDimension begin end destination strict",
"replace masked filtered",
),
(
"clone from sourceDimension begin end destination strict replace",
"force move normal",
),
(
"clone from sourceDimension begin end destination strict masked",
"force move normal",
),
(
"clone from sourceDimension begin end destination strict filtered filter",
"force move normal",
),
(
"clone from sourceDimension begin end to targetDimension destination",
"replace masked filtered strict",
),
(
"clone from sourceDimension begin end to targetDimension destination replace",
"force move normal",
),
(
"clone from sourceDimension begin end to targetDimension destination masked",
"force move normal",
),
(
"clone from sourceDimension begin end to targetDimension destination filtered filter",
"force move normal",
),
(
"clone from sourceDimension begin end to targetDimension destination strict",
"replace masked filtered",
),
(
"clone from sourceDimension begin end to targetDimension destination strict replace",
"force move normal",
),
(
"clone from sourceDimension begin end to targetDimension destination strict masked",
"force move normal",
),
(
"clone from sourceDimension begin end to targetDimension destination strict filtered filter",
"force move normal",
),
("compute", "default block entity"),
("compute default", "float integer"),
("compute block computePos", "float integer"),
("compute entity computeTarget", "float integer"),
("damage target amount damageType", "at by"),
("data", "merge get remove modify"),
("data merge", "entity block storage"),
("data get", "entity block storage"),
("data remove", "entity block storage"),
("data modify", "entity block storage"),
(
"data modify entity target targetPath",
"insert prepend append set merge",
),
(
"data modify entity target targetPath insert index",
"from string compute value",
),
(
"data modify entity target targetPath insert index from",
"entity block storage",
),
(
"data modify entity target targetPath insert index string",
"entity block storage",
),
(
"data modify entity target targetPath insert index compute",
"default block entity",
),
(
"data modify entity target targetPath insert index compute default",
"float integer",
),
(
"data modify entity target targetPath insert index compute block computePos",
"float integer",
),
(
"data modify entity target targetPath insert index compute entity computeTarget",
"float integer",
),
(
"data modify entity target targetPath prepend",
"from string compute value",
),
(
"data modify entity target targetPath prepend from",
"entity block storage",
),
(
"data modify entity target targetPath prepend string",
"entity block storage",
),
(
"data modify entity target targetPath prepend compute",
"default block entity",
),
(
"data modify entity target targetPath prepend compute default",
"float integer",
),
(
"data modify entity target targetPath prepend compute block computePos",
"float integer",
),
(
"data modify entity target targetPath prepend compute entity computeTarget",
"float integer",
),
(
"data modify entity target targetPath append",
"from string compute value",
),
(
"data modify entity target targetPath append from",
"entity block storage",
),
(
"data modify entity target targetPath append string",
"entity block storage",
),
(
"data modify entity target targetPath append compute",
"default block entity",
),
(
"data modify entity target targetPath append compute default",
"float integer",
),
(
"data modify entity target targetPath append compute block computePos",
"float integer",
),
(
"data modify entity target targetPath append compute entity computeTarget",
"float integer",
),
(
"data modify entity target targetPath set",
"from string compute value",
),
(
"data modify entity target targetPath set from",
"entity block storage",
),
(
"data modify entity target targetPath set string",
"entity block storage",
),
(
"data modify entity target targetPath set compute",
"default block entity",
),
(
"data modify entity target targetPath set compute default",
"float integer",
),
(
"data modify entity target targetPath set compute block computePos",
"float integer",
),
(
"data modify entity target targetPath set compute entity computeTarget",
"float integer",
),
(
"data modify entity target targetPath merge",
"from string compute value",
),
(
"data modify entity target targetPath merge from",
"entity block storage",
),
(
"data modify entity target targetPath merge string",
"entity block storage",
),
(
"data modify entity target targetPath merge compute",
"default block entity",
),
(
"data modify entity target targetPath merge compute default",
"float integer",
),
(
"data modify entity target targetPath merge compute block computePos",
"float integer",
),
(
"data modify entity target targetPath merge compute entity computeTarget",
"float integer",
),
(
"data modify block target targetPath",
"insert prepend append set merge",
),
(
"data modify block target targetPath insert index",
"from string compute value",
),
(
"data modify block target targetPath insert index from",
"entity block storage",
),
(
"data modify block target targetPath insert index string",
"entity block storage",
),
(
"data modify block target targetPath insert index compute",
"default block entity",
),
(
"data modify block target targetPath insert index compute default",
"float integer",
),
(
"data modify block target targetPath insert index compute block computePos",
"float integer",
),
(
"data modify block target targetPath insert index compute entity computeTarget",
"float integer",
),
(
"data modify block target targetPath prepend",
"from string compute value",
),
(
"data modify block target targetPath prepend from",
"entity block storage",
),
(
"data modify block target targetPath prepend string",
"entity block storage",
),
(
"data modify block target targetPath prepend compute",
"default block entity",
),
(
"data modify block target targetPath prepend compute default",
"float integer",
),
(
"data modify block target targetPath prepend compute block computePos",
"float integer",
),
(
"data modify block target targetPath prepend compute entity computeTarget",
"float integer",
),
(
"data modify block target targetPath append",
"from string compute value",
),
(
"data modify block target targetPath append from",
"entity block storage",
),
(
"data modify block target targetPath append string",
"entity block storage",
),
(
"data modify block target targetPath append compute",
"default block entity",
),
(
"data modify block target targetPath append compute default",
"float integer",
),
(
"data modify block target targetPath append compute block computePos",
"float integer",
),
(
"data modify block target targetPath append compute entity computeTarget",
"float integer",
),
(
"data modify block target targetPath set",
"from string compute value",
),
(
"data modify block target targetPath set from",
"entity block storage",
),
(
"data modify block target targetPath set string",
"entity block storage",
),
(
"data modify block target targetPath set compute",
"default block entity",
),
(
"data modify block target targetPath set compute default",
"float integer",
),
(
"data modify block target targetPath set compute block computePos",
"float integer",
),
(
"data modify block target targetPath set compute entity computeTarget",
"float integer",
),
(
"data modify block target targetPath merge",
"from string compute value",
),
(
"data modify block target targetPath merge from",
"entity block storage",
),
(
"data modify block target targetPath merge string",
"entity block storage",
),
(
"data modify block target targetPath merge compute",
"default block entity",
),
(
"data modify block target targetPath merge compute default",
"float integer",
),
(
"data modify block target targetPath merge compute block computePos",
"float integer",
),
(
"data modify block target targetPath merge compute entity computeTarget",
"float integer",
),
(
"data modify storage target targetPath",
"insert prepend append set merge",
),
(
"data modify storage target targetPath insert index",
"from string compute value",
),
(
"data modify storage target targetPath insert index from",
"entity block storage",
),
(
"data modify storage target targetPath insert index string",
"entity block storage",
),
(
"data modify storage target targetPath insert index compute",
"default block entity",
),
(
"data modify storage target targetPath insert index compute default",
"float integer",
),
(
"data modify storage target targetPath insert index compute block computePos",
"float integer",
),
(
"data modify storage target targetPath insert index compute entity computeTarget",
"float integer",
),
(
"data modify storage target targetPath prepend",
"from string compute value",
),
(
"data modify storage target targetPath prepend from",
"entity block storage",
),
(
"data modify storage target targetPath prepend string",
"entity block storage",
),
(
"data modify storage target targetPath prepend compute",
"default block entity",
),
(
"data modify storage target targetPath prepend compute default",
"float integer",
),
(
"data modify storage target targetPath prepend compute block computePos",
"float integer",
),
(
"data modify storage target targetPath prepend compute entity computeTarget",
"float integer",
),
(
"data modify storage target targetPath append",
"from string compute value",
),
(
"data modify storage target targetPath append from",
"entity block storage",
),
(
"data modify storage target targetPath append string",
"entity block storage",
),
(
"data modify storage target targetPath append compute",
"default block entity",
),
(
"data modify storage target targetPath append compute default",
"float integer",
),
(
"data modify storage target targetPath append compute block computePos",
"float integer",
),
(
"data modify storage target targetPath append compute entity computeTarget",
"float integer",
),
(
"data modify storage target targetPath set",
"from string compute value",
),
(
"data modify storage target targetPath set from",
"entity block storage",
),
(
"data modify storage target targetPath set string",
"entity block storage",
),
(
"data modify storage target targetPath set compute",
"default block entity",
),
(
"data modify storage target targetPath set compute default",
"float integer",
),
(
"data modify storage target targetPath set compute block computePos",
"float integer",
),
(
"data modify storage target targetPath set compute entity computeTarget",
"float integer",
),
(
"data modify storage target targetPath merge",
"from string compute value",
),
(
"data modify storage target targetPath merge from",
"entity block storage",
),
(
"data modify storage target targetPath merge string",
"entity block storage",
),
(
"data modify storage target targetPath merge compute",
"default block entity",
),
(
"data modify storage target targetPath merge compute default",
"float integer",
),
(
"data modify storage target targetPath merge compute block computePos",
"float integer",
),
(
"data modify storage target targetPath merge compute entity computeTarget",
"float integer",
),
("datapack", "enable disable list create"),
("datapack enable name", "after before last first"),
("datapack list", "available enabled"),
("debug", "start stop function"),
("dialog", "show clear"),
("difficulty", "peaceful easy normal hard"),
("effect", "clear give"),
("effect give targets effect", "seconds infinite"),
("experience", "add set query"),
("experience add target amount", "points levels"),
("experience set target amount", "points levels"),
("experience query target", "points levels"),
(
"fill from to block",
"outline hollow destroy strict replace keep",
),
(
"fill from to block replace filter",
"outline hollow destroy strict",
),
("forceload", "add remove query"),
("forceload remove", "from all"),
("function name", "arguments with"),
("function name with", "entity block storage"),
("item", "replace fill override modify"),
("item replace", "entity block"),
("item replace entity target slots", "from with"),
("item replace entity target slots from", "entity block"),
("item replace block target slots", "from with"),
("item replace block target slots from", "entity block"),
("item fill", "entity block"),
("item fill entity target slots", "from with"),
("item fill entity target slots from", "entity block"),
("item fill block target slots", "from with"),
("item fill block target slots from", "entity block"),
("item override", "entity block"),
("item override entity target slots", "from with"),
("item override entity target slots from", "entity block"),
("item override block target slots", "from with"),
("item override block target slots from", "entity block"),
("item modify", "entity block"),
("locate", "structure biome poi"),
("loot", "replace insert give spawn"),
("loot replace", "entity block"),
(
"loot replace entity entities slot",
"fish loot kill mine count",
),
(
"loot replace entity entities slot fish loot_table pos",
"tool mainhand offhand",
),
(
"loot replace entity entities slot mine pos",
"tool mainhand offhand",
),
(
"loot replace entity entities slot count",
"fish loot kill mine",
),
(
"loot replace entity entities slot count fish loot_table pos",
"tool mainhand offhand",
),
(
"loot replace entity entities slot count mine pos",
"tool mainhand offhand",
),
(
"loot replace block targetPos slot",
"fish loot kill mine count",
),
(
"loot replace block targetPos slot fish loot_table pos",
"tool mainhand offhand",
),
(
"loot replace block targetPos slot mine pos",
"tool mainhand offhand",
),
(
"loot replace block targetPos slot count",
"fish loot kill mine",
),
(
"loot replace block targetPos slot count fish loot_table pos",
"tool mainhand offhand",
),
(
"loot replace block targetPos slot count mine pos",
"tool mainhand offhand",
),
("loot insert targetPos", "fish loot kill mine"),
(
"loot insert targetPos fish loot_table pos",
"tool mainhand offhand",
),
("loot insert targetPos mine pos", "tool mainhand offhand"),
("loot give players", "fish loot kill mine"),
(
"loot give players fish loot_table pos",
"tool mainhand offhand",
),
("loot give players mine pos", "tool mainhand offhand"),
("loot spawn targetPos", "fish loot kill mine"),
(
"loot spawn targetPos fish loot_table pos",
"tool mainhand offhand",
),
("loot spawn targetPos mine pos", "tool mainhand offhand"),
("swing targets", "mainhand offhand"),
("particle name pos delta speed count", "force normal"),
("place", "feature jigsaw structure template"),
(
"playsound sound",
"master music record weather block hostile neutral player ambient voice ui",
),
("posteffect", "add clear list remove"),
("random", "value roll reset"),
("random reset", "* sequence"),
("recipe", "give take"),
("recipe give targets", "recipe *"),
("recipe take targets", "recipe *"),
("fetchprofile", "name id entity"),
("return", "value fail run"),
("ride target", "mount dismount"),
("rotate target", "rotation facing"),
("rotate target facing", "entity facingLocation"),
("schedule", "function clear"),
("schedule function function time", "append replace"),
("scoreboard", "objectives players"),
("scoreboard objectives", "list add modify remove setdisplay"),
(
"scoreboard objectives modify objective",
"displayname rendertype displayautoupdate numberformat",
),
(
"scoreboard objectives modify objective rendertype",
"integer hearts",
),
(
"scoreboard objectives modify objective numberformat",
"blank fixed styled",
),
(
"scoreboard players",
"list set get add remove reset enable display operation",
),
("scoreboard players display", "name numberformat"),
(
"scoreboard players display numberformat targets objective",
"blank fixed styled",
),
("setblock pos block", "destroy keep replace strict"),
(
"spreadplayers center spreadDistance maxRange",
"respectTeams under",
),
(
"stopsound targets",
"* master music record weather block hostile neutral player ambient voice ui",
),
("stopwatch", "create query restart remove"),
("tag targets", "add remove list"),
("team", "list add remove empty join leave modify"),
(
"team modify team",
"displayName color friendlyFire seeFriendlyInvisibles nametagVisibility deathMessageVisibility collisionRule prefix suffix",
),
("team modify team color", "reset value"),
(
"team modify team nametagVisibility",
"never hideForOtherTeams hideForOwnTeam always",
),
(
"team modify team deathMessageVisibility",
"never hideForOtherTeams hideForOwnTeam always",
),
(
"team modify team collisionRule",
"never pushOwnTeam pushOtherTeams always",
),
("teleport", "location destination targets"),
("teleport targets", "location destination"),
("teleport targets location", "rotation facing"),
("teleport targets location facing", "entity facingLocation"),
(
"test",
"run runmultiple runthese runclosest runthat runfailed verify locate resetclosest resetthese resetthat clearthat clearthese clearall stop pos create",
),
("test runfailed", "onlyRequiredTests numberOfTimes"),
("tick", "query rate step sprint unfreeze freeze"),
("tick step", "stop time"),
("tick sprint", "stop time"),
("time", "set add pause resume rate query of"),
("time set", "time timemarker"),
("time query", "time timeline gametime"),
("time of clock", "set add pause resume rate query"),
("time of clock set", "time timemarker"),
("time of clock query", "time timeline"),
(
"title targets",
"clear reset title subtitle actionbar times",
),
("trigger objective", "add set"),
("waypoint", "list modify"),
("waypoint modify waypoint", "color style"),
("waypoint modify waypoint color", "color hex reset"),
("waypoint modify waypoint style", "reset set"),
("weather", "clear rain thunder"),
("worldborder", "add set center damage get warning"),
("worldborder damage", "amount buffer"),
("worldborder warning", "distance time"),
("jfr", "start stop"),
("banlist", "ips players"),
("perf", "start stop"),
("whitelist", "on off list add remove reload"),
];
+21 -5
View File
@@ -4,8 +4,10 @@
//! use and the commands of the server kind (dedicated servers have `op`,
//! `ban`, `stop` ...; an integrated server `publish`), numbered breadth first
//! as vanilla does, with the argument parsers' network properties and the
//! custom suggestion providers (`command_suggestions`).
use super::command_suggestions::SUGGESTIONS;
//! custom suggestion providers (`command_suggestions`). The report sorts each
//! node's children; the tree keeps vanilla's registration order
//! (`command_order`).
use super::{command_order::ORDER, command_suggestions::SUGGESTIONS};
use horizon_protocol::{
buf::Writer,
packets::play::{CommandNode, Commands},
@@ -15,6 +17,7 @@ use serde_json::Value;
use std::{
collections::{HashMap, VecDeque},
path::Path,
sync::OnceLock,
};
/// Commands.CommandSelection: registered only on dedicated servers.
@@ -107,7 +110,7 @@ impl CommandTree {
&mut paths,
);
// enumerateNodes: breadth first from the root, each node's children
// (in name order) then its redirect target.
// (in registration order) then its redirect target.
let mut ids = vec![None; nodes.len()];
let mut order = Vec::new();
let mut queue = VecDeque::from([0usize]);
@@ -170,6 +173,18 @@ fn fill(
};
let mut names: Vec<&String> = children.keys().collect();
names.sort();
// Vanilla's registration order; names it doesn't list (the game rules,
// registered in an identity-hashed order) keep the report's.
static ORDERS: OnceLock<HashMap<&str, Vec<&str>>> = OnceLock::new();
let orders = ORDERS.get_or_init(|| {
ORDER
.iter()
.map(|(path, names)| (*path, names.split(' ').collect()))
.collect()
});
if let Some(order) = orders.get(path.join(" ").as_str()) {
names.sort_by_key(|n| order.iter().position(|o| o == n).unwrap_or(order.len()));
}
for name in names {
let child = &children[name];
let required =
@@ -343,10 +358,11 @@ mod tests {
assert_eq!(guest.nodes[2].redirect, Some(1));
let op = tree.packet(2, true, &builtin);
let names: Vec<_> = op.nodes.iter().map(|n| n.name.as_str()).collect();
// The root's children in vanilla's registration order.
assert_eq!(
names,
["", "me", "say", "stop", "tell", "action", "message"]
["", "me", "tell", "say", "stop", "action", "message"]
);
assert!(op.nodes[2].restricted);
assert!(op.nodes[3].restricted);
}
}
+32 -2
View File
@@ -66,6 +66,9 @@ pub struct SyncData {
pub features: Vec<String>,
/// Vanilla's command tree (the commands report), when found.
pub commands: Option<super::commands::CommandTree>,
/// ClientboundUpdateRecipesPacket's payload.
pub recipes: Vec<u8>,
pub advancements: super::advancements::ServerAdvancements,
}
/// Every `*.json` under `dir`, as (path without extension relative to dir, value), sorted.
@@ -106,6 +109,29 @@ pub fn json_to_nbt(v: &Value) -> Tag {
}
}
/// A component's JSON as NbtOps writes it: a list whose elements differ in
/// type (translation arguments mixing numbers and components) holds each
/// element that isn't a compound wrapped in one under the empty key.
pub fn component_nbt(v: &Value) -> Tag {
match v {
Value::Array(a) => {
let kind = |v: &Value| std::mem::discriminant(&json_to_nbt(v));
let mixed = a.windows(2).any(|w| kind(&w[0]) != kind(&w[1]));
Tag::List(
a.iter()
.map(|e| match component_nbt(e) {
t @ Tag::Compound(_) => t,
t if mixed => Tag::compound([("", t)]),
t => t,
})
.collect(),
)
}
Value::Object(o) => Tag::compound(o.iter().map(|(k, v)| (k.as_str(), component_nbt(v)))),
other => json_to_nbt(other),
}
}
impl SyncData {
pub fn load(resources: &Path) -> Result<Self, String> {
let builtin = Builtin::find(resources)
@@ -129,14 +155,18 @@ impl SyncData {
registries.push(((*key).to_owned(), Entries { names, json }));
}
let tags = Self::load_tags(&root, &builtin, &dynamic);
Ok(Self {
let mut sync = Self {
builtin,
dynamic,
registries,
tags,
features: vec!["minecraft:vanilla".to_owned()],
commands: super::commands::CommandTree::load(resources),
})
recipes: Vec::new(),
advancements: super::advancements::ServerAdvancements::load(resources),
};
sync.recipes = super::recipes::update_recipes(resources, &sync);
Ok(sync)
}
/// The id of a name in a built-in or synchronized registry.
+11 -6
View File
@@ -104,8 +104,6 @@ pub struct Hub {
last_rate: f32,
ticking: (f32, bool),
weather: (bool, f32, f32),
/// ClientboundUpdateRecipesPacket, when the game provides it.
pub recipes: Option<Vec<u8>>,
/// Operators and their permission levels (dedicated servers).
pub ops: std::collections::HashMap<u128, u8>,
chat_type: i32,
@@ -193,7 +191,6 @@ impl Hub {
last_clock: i64::MIN,
last_rate: 0.0,
ticking: (20.0, false),
recipes: None,
ops: Default::default(),
weather: (false, 0.0, 0.0),
chat_type,
@@ -494,9 +491,8 @@ impl Hub {
g.send(&C::SetHeldSlot(play::SetHeldSlot {
slot: g.selected as i32,
}));
if let Some(recipes) = &self.recipes {
g.sender.send(recipes.clone());
}
// PlayerList.placeNewPlayer: ClientboundUpdateRecipesPacket.
g.send(&raw(ids::UPDATE_RECIPES, self.sync.recipes.clone()));
// PlayerList.sendPlayerPermissionLevel, then the recipe book.
self.send_permission_level(i);
let g = &self.guests[i];
@@ -1285,6 +1281,15 @@ impl Hub {
id: g.entity_id,
values: vec![(9, serializer::FLOAT, Value::Float(g.health))],
}));
// ServerPlayer.tick's CriteriaTriggers.TICK, then flushDirty.
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map_or(0, |d| d.as_millis() as i64);
let first = self.sync.advancements.first_tick(&self.sync, now);
if let Some(add) = first.recipe_book_add {
g.send(&raw(ids::RECIPE_BOOK_ADD, add));
}
g.send(&raw(ids::UPDATE_ADVANCEMENTS, first.update_advancements));
}
let health = {
let g = &self.guests[i];
+3
View File
@@ -4,7 +4,9 @@
//! (`data`). The play state is driven by the game thread (`hub`), which only
//! ever exchanges decoded packets with these threads through channels, so a
//! world that is not open to the network pays nothing.
mod advancements;
pub mod chunks;
mod command_order;
pub mod command_suggestions;
pub mod commands;
pub mod conn;
@@ -16,6 +18,7 @@ pub mod guest;
pub mod hub;
pub mod menu;
pub mod playerdata;
mod recipes;
pub mod tracking;
pub use conn::PlayerSender;
+148
View File
@@ -0,0 +1,148 @@
//! ClientboundUpdateRecipesPacket: what RecipeManager.finalizeRecipeLoading
//! synchronizes, the recipe property sets (the items each furnace, smithing
//! table slot and brewing stand slot accepts) and the stonecutter's recipes,
//! read from the data pack's recipe files.
use super::data::SyncData;
use horizon_protocol::buf::Writer;
use serde_json::Value;
use std::{
collections::{BTreeMap, BTreeSet},
path::Path,
};
/// RecipeManager.RECIPE_PROPERTY_SETS: each set and the ingredients it takes
/// from a recipe of the given type.
const PROPERTY_SETS: &[(&str, &str, &[&str])] = &[
("smithing_addition", "smithing", &["addition"]),
("smithing_base", "smithing", &["base"]),
("smithing_template", "smithing", &["template"]),
("furnace_input", "minecraft:smelting", &["ingredient"]),
("blast_furnace_input", "minecraft:blasting", &["ingredient"]),
("smoker_input", "minecraft:smoking", &["ingredient"]),
(
"campfire_input",
"minecraft:campfire_cooking",
&["ingredient"],
),
("brewing_input", "minecraft:brewing", &["input"]),
("brewing_reagent", "minecraft:brewing", &["reagent"]),
];
/// An ingredient as its HolderSet: a tag, or the items listed.
enum Ingredient {
Tag(String),
Items(Vec<String>),
}
fn ingredient(v: &Value) -> Option<Ingredient> {
match v {
Value::String(s) => Some(match s.strip_prefix('#') {
Some(tag) => Ingredient::Tag(tag.to_owned()),
None => Ingredient::Items(vec![s.clone()]),
}),
Value::Array(a) => Some(Ingredient::Items(
a.iter()
.filter_map(|s| s.as_str().map(str::to_owned))
.collect(),
)),
// A brewing slot: the item predicate's `item` ingredient.
Value::Object(o) => ingredient(o.get("item")?),
_ => None,
}
}
/// Every recipe file, by recipe id (the registry's order).
pub(super) fn recipes(dir: &Path, prefix: &str, out: &mut BTreeMap<String, Value>) {
for entry in std::fs::read_dir(dir).into_iter().flatten().flatten() {
let path = entry.path();
let name = entry.file_name().to_string_lossy().into_owned();
if path.is_dir() {
recipes(&path, &format!("{prefix}{name}/"), out);
} else if let Some(stem) = name.strip_suffix(".json")
&& let Ok(v) = serde_json::from_slice(&std::fs::read(&path).unwrap_or_default())
{
out.insert(format!("minecraft:{prefix}{stem}"), v);
}
}
}
/// The packet's payload for the vanilla data pack in `resources`.
pub fn update_recipes(resources: &Path, sync: &SyncData) -> Vec<u8> {
let mut all = BTreeMap::new();
recipes(&resources.join("data/minecraft/recipe"), "", &mut all);
let tags: BTreeMap<&str, &[i32]> = sync
.tags
.registries
.iter()
.filter(|r| r.registry == "minecraft:item")
.flat_map(|r| r.tags.iter())
.map(|t| (t.name.trim_start_matches("minecraft:"), t.ids.as_slice()))
.collect();
let item = |name: &str| sync.id("minecraft:item", name).unwrap_or(0);
let items = |i: &Ingredient| -> Vec<i32> {
match i {
Ingredient::Tag(t) => tags
.get(t.trim_start_matches("minecraft:"))
.map(|ids| ids.to_vec())
.unwrap_or_default(),
Ingredient::Items(list) => list.iter().map(|n| item(n)).collect(),
}
};
let mut w = Writer::new();
w.varint(PROPERTY_SETS.len() as i32);
for (key, kind, fields) in PROPERTY_SETS {
let mut set = BTreeSet::new();
for recipe in all.values() {
let t = recipe["type"].as_str().unwrap_or("");
let matches = if *kind == "smithing" {
t.starts_with("minecraft:smithing_")
} else {
t == *kind
};
if matches {
for field in *fields {
if let Some(i) = ingredient(&recipe[*field]) {
set.extend(items(&i));
}
}
}
}
w.string(&format!("minecraft:{key}"));
w.varint(set.len() as i32);
for id in set {
w.varint(id);
}
}
// SelectableRecipe.SingleInputSet: each stonecutting recipe's input and
// its result as an ItemStackSlotDisplay.
let stonecutting: Vec<&Value> = all
.values()
.filter(|r| r["type"] == "minecraft:stonecutting")
.collect();
let item_stack = sync
.id("minecraft:slot_display", "minecraft:item_stack")
.unwrap_or(0);
w.varint(stonecutting.len() as i32);
for r in stonecutting {
match ingredient(&r["ingredient"]) {
Some(Ingredient::Tag(t)) => {
w.varint(0);
w.string(&t);
}
Some(i) => {
let ids = items(&i);
w.varint(ids.len() as i32 + 1);
for id in ids {
w.varint(id);
}
}
None => w.varint(1),
}
w.varint(item_stack);
w.varint(item(r["result"]["id"].as_str().unwrap_or("minecraft:air")));
w.varint(r["result"]["count"].as_i64().unwrap_or(1) as i32);
w.varint(0); // no components added
w.varint(0); // nor removed
}
w.data
}
+6
View File
@@ -44,6 +44,7 @@ pub mod fastutil_order;
pub mod flatgen;
pub mod fog;
pub mod font;
pub mod front;
pub mod gamerules;
pub mod gfx;
pub mod gossip;
@@ -79,11 +80,14 @@ pub mod nbt_path;
pub mod net;
pub mod options_file;
pub mod options_fixes;
pub mod options_horizon;
pub mod options_ui;
pub mod pack_screen;
pub mod packs;
pub mod particles;
pub mod patrol;
pub mod pose;
pub mod post;
pub mod projectiles;
pub mod raid;
pub mod random_sequences;
@@ -92,6 +96,7 @@ pub mod recipe_book_screen;
pub mod save;
pub mod scoreboard;
pub mod scoreboard_cmd;
pub mod screen_draw;
pub mod screen_effects;
pub mod screen_layout;
pub mod sculk;
@@ -114,6 +119,7 @@ pub mod testgen;
pub mod text;
pub mod title;
pub mod ui;
pub mod ui_theme;
pub mod vanillagen;
pub mod window;
pub mod world;
+7
View File
@@ -108,6 +108,13 @@ fn entry_address(servers: &[ServerEntry], lan: &Scanner, index: usize) -> Option
}
impl Screen {
/// The address of list row `row` (saved servers, then LAN games).
pub fn address_of(&self, row: usize) -> Option<String> {
match self {
Self::List { servers, lan, .. } => entry_address(servers, lan, row),
_ => None,
}
}
pub fn list(saves: &Path) -> Self {
let servers = servers::load(&servers_file(saves));
let pings: Pings = Arc::default();
@@ -0,0 +1,518 @@
//! The options screen in Horizon's menu style, laid out like the launcher's
//! Settings page: a sidebar with the sliding selection (one item per
//! section), then the section's page header and settings rows (label column,
//! value, control on the right) between 1px dividers.
//!
//! Adding settings (for example the Simple/Advanced graphics menu): add rows
//! to a section in [`SECTIONS`], or a new section. A row is an [`HRow`]: an
//! existing option (`Opt`, drawn as a switch, a slider or a value button from
//! its kind), a header, or a button opening one of vanilla's pages. New kinds
//! of control belong in `ui_theme` so the launcher-matching look stays in one
//! place. Everything else (sliders dragging, scrolling, Done) is handled here.
use crate::{
hud::{HudAtlas, HudBatch},
options_ui::{Event, Kind, Opt, OptionsUi, Page, apply_preset},
settings::{SOUND_SOURCES, Settings},
ui_theme::{
self as t, CONTROL, Face, Kind as Button, MenuStyle, ROW_LABEL, SIDEBAR, SMALL, Ui, color,
id,
},
};
/// One row of a section.
#[derive(Clone, Copy, Debug)]
pub enum HRow {
Header(&'static str),
Opt(Opt),
/// A label, a value and a button opening one of vanilla's pages.
Page(&'static str, &'static str, Page),
/// Menu style: Horizon / Classic.
Style,
}
/// A sidebar section: name, description, rows.
pub struct Section {
pub name: &'static str,
pub blurb: &'static str,
pub rows: fn(&Settings) -> Vec<HRow>,
}
pub const SECTIONS: &[Section] = &[
Section {
name: "Video",
blurb: "Display, quality and how the world is drawn.",
rows: |_| {
let mut r = vec![HRow::Header("Display")];
r.extend(
[
Opt::Fullscreen,
Opt::Vsync,
Opt::MaxFps,
Opt::InactivityFps,
Opt::GuiScale,
Opt::Gamma,
]
.map(HRow::Opt),
);
r.push(HRow::Header("Quality"));
r.extend(
[
Opt::Preset,
Opt::RenderDistance,
Opt::SimulationDistance,
Opt::SmoothLighting,
Opt::Clouds,
Opt::CloudRange,
Opt::Particles,
Opt::Mipmaps,
Opt::EntityShadows,
Opt::EntityDistance,
Opt::BiomeBlend,
Opt::CutoutLeaves,
Opt::ImprovedTransparency,
Opt::WeatherRadius,
Opt::ChunkBuilder,
]
.map(HRow::Opt),
);
r.push(HRow::Header("Preferences"));
r.extend(
[
Opt::Fov,
Opt::ViewBobbing,
Opt::Autosave,
Opt::Vignette,
Opt::AttackIndicator,
Opt::ChunkFade,
]
.map(HRow::Opt),
);
r
},
},
Section {
name: "Audio",
blurb: "Volume for every kind of sound, and subtitles.",
rows: |_| {
let mut r: Vec<HRow> = (0..SOUND_SOURCES.len())
.map(|i| HRow::Opt(Opt::Volume(i)))
.collect();
r.push(HRow::Opt(Opt::ShowSubtitles));
r
},
},
Section {
name: "Controls",
blurb: "Keys, the mouse and how movement keys behave.",
rows: |_| {
let mut r = vec![HRow::Page(
"Key binds",
"Every action and its key",
Page::KeyBinds,
)];
r.push(HRow::Header("Mouse"));
r.extend(
[
Opt::Sensitivity,
Opt::WheelSensitivity,
Opt::InvertY,
Opt::DiscreteScroll,
]
.map(HRow::Opt),
);
r.push(HRow::Header("Movement"));
r.extend([Opt::ToggleCrouch, Opt::ToggleSprint, Opt::AutoJump].map(HRow::Opt));
r
},
},
Section {
name: "Accessibility",
blurb: "Contrast, motion, text backgrounds and notifications.",
rows: |_| {
[
Opt::HighContrast,
Opt::MenuBlur,
Opt::TextBackgroundOpacity,
Opt::NotificationDisplayTime,
Opt::ShowSubtitles,
Opt::ViewBobbing,
Opt::ChatLineSpacing,
]
.map(HRow::Opt)
.to_vec()
},
},
Section {
name: "Language",
blurb: "The game's language and its font.",
rows: |_| {
vec![
HRow::Page("Language", "", Page::Language),
HRow::Opt(Opt::ForceUnicode),
HRow::Opt(Opt::JapaneseGlyphs),
]
},
},
Section {
name: "Chat",
blurb: "What chat shows and how it looks.",
rows: |_| {
[
Opt::ChatVisibility,
Opt::ChatColors,
Opt::ChatLinks,
Opt::ChatOpacity,
Opt::ChatScale,
Opt::ChatWidth,
Opt::ChatHeightFocused,
Opt::ChatHeightUnfocused,
Opt::AutoSuggestions,
Opt::ReducedDebugInfo,
]
.map(HRow::Opt)
.to_vec()
},
},
Section {
name: "Interface",
blurb: "Menus and resource packs.",
rows: |_| {
vec![
HRow::Style,
HRow::Page("Resource packs", "Textures, sounds and fonts", Page::Packs),
]
},
},
];
const NAV: u64 = id("options.nav", 0);
const DONE: u64 = id("options.done", 0);
const ROW: u64 = id("options.row", 0);
const STYLE: u64 = id("options.style", 0);
const ROW_H: f32 = 12.0 + CONTROL + 12.0;
const HEADER_H: f32 = 40.0;
/// Whether an option is an on/off switch, and its value.
fn switch_value(opt: Opt, s: &Settings) -> Option<bool> {
Some(match opt {
Opt::InvertY => s.invert_y,
Opt::DiscreteScroll => s.discrete_scroll,
Opt::ViewBobbing => s.view_bobbing,
Opt::Vsync => s.vsync,
Opt::Fullscreen => s.fullscreen,
Opt::SmoothLighting => s.smooth_lighting,
Opt::EntityShadows => s.entity_shadows,
Opt::Vignette => s.vignette,
Opt::Autosave => s.autosave_indicator,
Opt::CutoutLeaves => s.cutout_leaves,
Opt::ImprovedTransparency => s.improved_transparency,
Opt::AutoJump => s.auto_jump,
Opt::ChatColors => s.chat_colors,
Opt::ChatLinks => s.chat_links,
Opt::AutoSuggestions => s.auto_suggestions,
Opt::ReducedDebugInfo => s.reduced_debug_info,
Opt::HighContrast => s.high_contrast,
Opt::ShowSubtitles => s.show_subtitles,
Opt::ForceUnicode => s.force_unicode,
Opt::JapaneseGlyphs => s.japanese_glyphs,
_ => return None,
})
}
/// The option's caption and value text, from its vanilla label
/// ("Caption: Value") and its caption key.
fn caption_value(opt: Opt, s: &Settings) -> (String, String) {
let label = opt.label(s).plain();
let caption = crate::text::Text::translate(opt.caption(), &[]).plain();
if let Some(rest) = label.strip_prefix(&caption) {
return (caption, rest.trim_start_matches([':', ' ']).to_owned());
}
match label.split_once(": ") {
Some((c, v)) => (c.to_owned(), v.to_owned()),
None => (caption, label),
}
}
/// What a click hit.
enum Target {
Nav(usize),
Done,
Row(usize),
Slider(Opt, f32),
Style(usize),
}
impl OptionsUi {
/// Lay out (and draw, on a real frame) the Horizon options shell.
/// Returns the sliders' tracks (option, x, width) for dragging.
fn horizon_layout(&mut self, s: &Settings, ui: &mut Ui, backdrop: f32) -> Vec<(Opt, f32, f32)> {
let (w, h) = (ui.w, ui.h);
if self.in_world {
ui.atmosphere(0.45, 1.0);
} else {
if backdrop < 1.0 {
ui.cold_background(1.0 - backdrop);
}
ui.atmosphere(0.66, 1.0);
}
let section = self.section.min(SECTIONS.len() - 1);
// The sidebar.
ui.fill(0.0, 0.0, SIDEBAR, h, color::with_alpha(color::SIDEBAR, 0.8));
ui.vline(SIDEBAR - 1.0, 0.0, h, color::BORDER);
ui.text_line(
Face::Display,
22.0,
30.0,
22.0,
16.0,
color::TEXT,
"Options",
);
let names: Vec<&str> = SECTIONS.iter().map(|s| s.name).collect();
ui.sidebar_list(NAV, 12.0, 66.0, SIDEBAR - 24.0, &names, section);
let dy = h - 12.0 - CONTROL;
ui.button(
DONE,
[12.0, dy, SIDEBAR - 24.0, CONTROL],
"Done",
Button::Secondary,
true,
);
// The page fades in and rises 8 when the section changes.
let p = ui.tween(id("options.page", section as u64), 1.0, t::move_());
if self.section_shown != Some(section) {
self.section_shown = Some(section);
ui.restart(id("options.page", section as u64), 0.0, 1.0, t::move_());
}
let x = SIDEBAR + 48.0;
let cw = (w - x - 48.0).min(760.0);
ui.opacity = p;
ui.offset = (0.0, 8.0 * (1.0 - p));
let sec = &SECTIONS[section];
let mut y = 36.0;
y += ui.page_header(x, y, sec.name, sec.blurb) + 24.0;
let top = y;
let rows = (sec.rows)(s);
let content: f32 = rows
.iter()
.map(|r| {
if matches!(r, HRow::Header(_)) {
HEADER_H
} else {
ROW_H
}
})
.sum();
let bottom = h - 24.0;
let max = (content - (bottom - top)).max(0.0);
self.hscroll = self.hscroll.clamp(0.0, max);
y -= self.hscroll;
let vstart = ui.batch.vertices.len();
let hstart = ui.hits.len();
let mut sliders = Vec::new();
ui.divider(x, y, cw);
let control_x = x + cw;
for (i, row) in rows.iter().enumerate() {
match *row {
HRow::Header(label) => {
ui.text(Face::Medium, SMALL, x, y + 18.0, color::FAINT, label);
y += HEADER_H;
ui.divider(x, y, cw);
continue;
}
HRow::Opt(opt) => {
let (caption, value) = caption_value(opt, s);
let cy = y + ROW_H / 2.0;
if let Some(on) = switch_value(opt, s) {
ui.row(x, y, &caption, "", 0.0);
ui.switch(ROW + i as u64, control_x, cy, on);
} else if let Kind::Slider(v) = opt.kind(s) {
let sw = 220.0_f32.min(cw - ROW_LABEL - 200.0).max(80.0);
ui.row(x, y, &caption, &value, cw - ROW_LABEL - 16.0 - sw - 24.0);
let sx = control_x - sw - 8.0;
ui.slider(ROW + i as u64, sx, cy, sw, v);
sliders.push((opt, sx, sw));
} else {
ui.row(x, y, &caption, "", 0.0);
let bw = ui.button_width(&value, false).max(96.0);
ui.button(
ROW + i as u64,
[control_x - bw, y + 12.0, bw, CONTROL],
&value,
Button::Secondary,
true,
);
}
}
HRow::Page(label, value, _) => {
let value = if value.is_empty() {
self.languages
.iter()
.find(|l| l.code == s.language)
.map_or_else(|| s.language.clone(), |l| l.label())
} else {
value.to_owned()
};
ui.row(x, y, label, &value, cw - ROW_LABEL - 140.0);
let bw = ui.button_width("Change…", false);
let open = if label == "Language" {
"Change…"
} else {
"Open…"
};
let bw = bw.max(ui.button_width(open, false));
ui.button(
ROW + i as u64,
[control_x - bw, y + 12.0, bw, CONTROL],
open,
Button::Secondary,
true,
);
}
HRow::Style => {
ui.row(x, y, "Menu style", "", 0.0);
let labels = ["Horizon", "Classic"];
let probe = ui.segmented(STYLE, -10_000.0, -10_000.0, &labels, 0);
let selected = usize::from(t::style() == MenuStyle::Classic);
ui.segmented(STYLE, control_x - probe, y + 12.0 - 3.0, &labels, selected);
}
}
y += ROW_H;
ui.divider(x, y, cw);
}
// Clip the rows to the page below the header, like the launcher's scroll view.
let (ox, oy) = ui.offset;
let scale = ui.batch.scale;
let k = ui.density / scale;
let (y0, y1) = ((top - 1.0 + oy) * k, (bottom + oy) * k);
ui.batch.clip_since(vstart, 0.0, y0, ui.batch.width, y1);
let (cy0, cy1) = (top - 1.0 + oy, bottom + oy);
let kept: Vec<_> = ui
.hits
.drain(hstart..)
.filter(|h| h.rect[1] >= cy0 && h.rect[3] <= cy1)
.collect();
ui.hits.extend(kept);
if max > 0.0 {
// A thin scroll indicator.
let track = bottom - top;
let bar = (track * track / (track + max)).max(24.0);
let by = top + (track - bar) * (self.hscroll / max);
ui.rounded(
x + cw + 16.0,
by,
3.0,
bar,
1.5,
color::with_alpha(color::MUTED, 0.35),
);
}
let _ = ox;
ui.opacity = 1.0;
ui.offset = (0.0, 0.0);
sliders
}
pub(crate) fn draw_horizon(
&mut self,
s: &Settings,
batch: &mut HudBatch,
atlas: &HudAtlas,
cursor: (f32, f32),
) {
let mut ui = Ui::new(atlas, batch, cursor);
let backdrop = t::backdrop();
self.horizon_layout(s, &mut ui, backdrop);
ui.finish();
}
fn horizon_target(&mut self, s: &Settings, atlas: &HudAtlas, x: f32, y: f32) -> Option<Target> {
let mut batch = t::scratch_batch();
let mut ui = Ui::dry(atlas, &mut batch, (x, y));
let sliders = self.horizon_layout(s, &mut ui, 1.0);
let hit = ui.hit((x, y))?;
let section = self.section.min(SECTIONS.len() - 1);
if (NAV..NAV + SECTIONS.len() as u64).contains(&hit) {
return Some(Target::Nav((hit - NAV) as usize));
}
if hit == DONE {
return Some(Target::Done);
}
if hit == STYLE || hit == STYLE + 1 {
return Some(Target::Style((hit - STYLE) as usize));
}
let i = hit.checked_sub(ROW)? as usize;
let rows = (SECTIONS[section].rows)(s);
if let Some(HRow::Opt(opt)) = rows.get(i)
&& let Some(&(_, sx, sw)) = sliders.iter().find(|(o, ..)| o == opt)
{
let v = t::slider_value(&ui, sx, sw, x);
return Some(Target::Slider(*opt, v));
}
(i < rows.len()).then_some(Target::Row(i))
}
/// A click (or a drag with the button held) on the Horizon shell.
pub(crate) fn click_horizon(
&mut self,
s: &mut Settings,
atlas: &HudAtlas,
x: f32,
y: f32,
drag: bool,
right: bool,
) -> Vec<Event> {
let mut events = Vec::new();
if drag {
if let Some(opt) = self.dragging {
let mut batch = t::scratch_batch();
let mut ui = Ui::dry(atlas, &mut batch, (x, y));
let sliders = self.horizon_layout(s, &mut ui, 1.0);
if let Some(&(_, sx, sw)) = sliders.iter().find(|(o, ..)| *o == opt) {
opt.set_slider(s, t::slider_value(&ui, sx, sw, x));
if opt == Opt::Preset {
apply_preset(s);
}
events.push(Event::Changed);
}
}
return events;
}
match self.horizon_target(s, atlas, x, y) {
Some(Target::Nav(i)) => {
self.section = i;
self.hscroll = 0.0;
}
Some(Target::Done) => events.extend(self.back(s)),
Some(Target::Style(i)) => {
t::set_style(if i == 1 {
MenuStyle::Classic
} else {
MenuStyle::Horizon
});
if let Ok(dir) = std::env::current_dir() {
t::save_preferences(&dir);
}
}
Some(Target::Slider(opt, v)) => {
self.dragging = Some(opt);
opt.set_slider(s, v);
if opt == Opt::Preset {
apply_preset(s);
}
events.push(Event::Changed);
}
Some(Target::Row(i)) => {
let section = self.section.min(SECTIONS.len() - 1);
match (SECTIONS[section].rows)(s).get(i) {
Some(HRow::Opt(opt)) => {
opt.cycle(s, right);
if *opt == Opt::Preset {
apply_preset(s);
}
events.push(Event::Changed);
}
Some(HRow::Page(_, _, page)) => self.open_page(*page),
_ => {}
}
}
None => {}
}
events
}
pub(crate) fn scroll_horizon(&mut self, amount: f32) {
self.hscroll -= amount * 40.0;
}
}
+136 -261
View File
@@ -92,13 +92,13 @@ fn chat_px(caption: &str, px: f32) -> Text {
&[tr(caption), Text::literal((px as i32).to_string())],
)
}
enum Kind {
pub(crate) enum Kind {
/// Slider position 0..1.
Slider(f32),
Cycle,
}
impl Opt {
fn caption(self) -> &'static str {
pub(crate) fn caption(self) -> &'static str {
match self {
Opt::Fov => "options.fov",
Opt::RenderDistance => "options.renderDistance",
@@ -155,7 +155,7 @@ impl Opt {
Opt::JapaneseGlyphs => "options.japaneseGlyphVariants",
}
}
fn kind(self, s: &Settings) -> Kind {
pub(crate) fn kind(self, s: &Settings) -> Kind {
let unit = |v: f32, lo: f32, hi: f32| Kind::Slider(((v - lo) / (hi - lo)).clamp(0.0, 1.0));
match self {
Opt::Fov => unit(s.fov, 30.0, 110.0),
@@ -519,17 +519,6 @@ pub fn apply_preset(s: &mut Settings) {
}
}
/// A resource pack entry for the pack screen.
#[derive(Clone, Debug, PartialEq)]
pub struct PackEntry {
pub id: String,
pub title: Text,
pub description: Text,
pub compatible: bool,
/// Built-in packs that cannot be removed (vanilla).
pub required: bool,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Page {
Main,
@@ -553,7 +542,6 @@ enum Act {
Key(&'static str),
ResetKey(&'static str),
ResetKeys,
OpenPackFolder,
}
enum WKind {
Button {
@@ -576,12 +564,6 @@ enum WKind {
selected: bool,
code: String,
},
PackRow {
pack: PackEntry,
selected: bool,
index: usize,
count: usize,
},
}
struct Widget {
x: f32,
@@ -608,18 +590,24 @@ pub enum Event {
pub struct OptionsUi {
pub stack: Vec<Page>,
scroll: f32,
dragging: Option<Opt>,
pub(crate) dragging: Option<Opt>,
/// Horizon style: the selected sidebar section, the one last drawn and
/// the rows' scroll in dp (`options_horizon`).
pub section: usize,
pub(crate) section_shown: Option<usize>,
pub(crate) hscroll: f32,
/// Key Binds: the mapping waiting for a key.
pub selected_key: Option<&'static str>,
pub languages: Vec<LanguageInfo>,
language_choice: Option<String>,
language_search: ui::EditBox,
/// Packs: (available, selected top-first).
pub available: Vec<PackEntry>,
pub selected: Vec<PackEntry>,
/// The selection logic behind the two lists (`PackSelectionModel`).
pub pack_model: crate::packs::SelectionModel,
packs_changed: bool,
/// Packs: the packs found and the selection the screen opens with.
pub pack_infos: Vec<crate::pack_screen::PackInfo>,
pub pack_selection: Vec<String>,
/// The open pack screen, made at its first frame.
pub pack_screen: Option<crate::pack_screen::PackScreen>,
/// When the pack screen's search box took the focus (its cursor blink).
pack_focus: std::time::Instant,
pub in_world: bool,
/// Scroll the selected language into the middle on the next layout.
center_language: bool,
@@ -632,14 +620,17 @@ impl Default for OptionsUi {
stack: vec![Page::Main],
scroll: 0.0,
dragging: None,
section: 0,
section_shown: None,
hscroll: 0.0,
selected_key: None,
languages: Vec::new(),
language_choice: None,
language_search: search,
available: Vec::new(),
selected: Vec::new(),
pack_model: Default::default(),
packs_changed: false,
pack_infos: Vec::new(),
pack_selection: Vec::new(),
pack_screen: None,
pack_focus: std::time::Instant::now(),
in_world: false,
center_language: false,
}
@@ -710,6 +701,10 @@ impl OptionsUi {
self.in_world = in_world;
self.selected_key = None;
}
/// Open one of vanilla's pages over the current one.
pub(crate) fn open_page(&mut self, page: Page) {
self.push(page);
}
fn push(&mut self, page: Page) {
self.stack.push(page);
self.scroll = 0.0;
@@ -719,7 +714,7 @@ impl OptionsUi {
self.center_language = true;
}
if page == Page::Packs {
self.packs_changed = false;
self.pack_screen = None;
}
}
fn title(page: Page) -> &'static str {
@@ -1104,92 +1099,8 @@ impl OptionsUi {
));
out.push(button(cx + 4.0, h - 28.0, 150.0, tr("gui.done"), Act::Done));
}
Page::Packs => {
top = 47.0;
bottom = h - 33.0;
out.push(Widget {
x: 0.0,
y: 8.0,
w,
h: 9.0,
kind: WKind::Text {
text: tr("resourcePack.title"),
color: u32::MAX,
centered: true,
},
list: false,
});
out.push(Widget {
x: 0.0,
y: 20.0,
w,
h: 9.0,
kind: WKind::Text {
text: tr("pack.dropInfo").with_color(text::GRAY),
color: u32::MAX,
centered: true,
},
list: false,
});
let lists = [(false, cx - 4.0 - 200.0), (true, cx + 4.0)];
let list_start = out.len();
for (selected, lx) in lists {
let entries = if selected {
&self.selected
} else {
&self.available
};
let header = tr(if selected {
"pack.selected.title"
} else {
"pack.available.title"
})
.with_style(&Style {
bold: Some(true),
underlined: Some(true),
..Style::default()
});
out.push(Widget {
x: lx,
y: top + 4.0,
w: 200.0,
h: 9.0,
kind: WKind::Text {
text: header,
color: u32::MAX,
centered: true,
},
list: false,
});
let mut y = top + 17.0 - self.scroll;
for (i, p) in entries.iter().enumerate() {
out.push(Widget {
x: lx,
y,
w: 200.0,
h: 36.0,
kind: WKind::PackRow {
pack: p.clone(),
selected,
index: i,
count: entries.len(),
},
list: false,
});
y += 36.0;
}
content = f32::max(content, y + self.scroll - top + 4.0);
}
out[list_start..].iter_mut().for_each(|w| w.list = true);
out.push(button(
cx - 154.0,
h - 27.0,
150.0,
tr("pack.openFolder"),
Act::OpenPackFolder,
));
out.push(button(cx + 4.0, h - 27.0, 150.0, tr("gui.done"), Act::Done));
}
// Drawn by `pack_screen`.
Page::Packs => {}
_ => {
out.push(Widget {
x: 0.0,
@@ -1276,6 +1187,19 @@ impl OptionsUi {
cursor: (f32, f32),
) {
let (w, h) = (batch.width, batch.height);
if crate::ui_theme::horizon() && self.page() == Page::Main {
self.draw_horizon(s, batch, atlas, cursor);
return;
}
if self.page() == Page::Packs {
ui::menu_background(batch, atlas, 0.0, 0.0, w, h, self.in_world);
let blink = self.pack_focus.elapsed().as_millis() as u64;
let m = crate::screen_draw::Measure(&atlas.font);
let mouse = (cursor.0.floor() as i32, cursor.1.floor() as i32);
let draws = self.packs(atlas, (w, h)).draw(&m, mouse, blink);
crate::screen_draw::paint(batch, atlas, &draws);
return;
}
let (widgets, top, bottom, content) = self.layout(s, atlas, w, h);
self.clamp_scroll(top, bottom, content);
let in_world = self.in_world;
@@ -1375,102 +1299,6 @@ impl OptionsUi {
true,
);
}
WKind::PackRow {
pack,
selected,
index,
count,
} => {
if hover {
batch.fill(atlas, wd.x, wd.y, wd.w, wd.h, rgba(255, 255, 255, 255));
batch.fill(
atlas,
wd.x + 1.0,
wd.y + 1.0,
wd.w - 2.0,
wd.h - 2.0,
rgba(0, 0, 0, 255),
);
}
batch.sprite_scaled(
atlas,
"misc/unknown_pack",
wd.x + 2.0,
wd.y + 2.0,
32.0,
32.0,
u32::MAX,
);
let title_color = if pack.compatible {
u32::MAX
} else {
rgba(255, 85, 85, 255)
};
batch.text_styled(
atlas,
&pack.title,
wd.x + 36.0,
wd.y + 3.0,
title_color,
true,
);
for (i, line) in atlas
.font
.split(&pack.description, 157.0)
.iter()
.take(2)
.enumerate()
{
batch.text_styled(
atlas,
line,
wd.x + 36.0,
wd.y + 14.0 + i as f32 * 9.0,
rgba(128, 128, 128, 255),
true,
);
}
if hover && cursor.0 < wd.x + 34.0 {
// TransferableSelectionList arrows over the icon.
batch.fill(
atlas,
wd.x + 2.0,
wd.y + 2.0,
32.0,
32.0,
rgba(160, 160, 160, 136),
);
let sprite_dir = if *selected { "unselect" } else { "select" };
let left = cursor.0 < wd.x + 18.0;
let name = format!(
"gui/sprites/transferable_list/{sprite_dir}{}",
if left || !*selected {
"_highlighted"
} else {
""
}
);
batch.sprite(atlas, &name, wd.x + 2.0, wd.y + 2.0);
if *selected {
if *index > 0 {
batch.sprite(
atlas,
"gui/sprites/transferable_list/move_up",
wd.x + 2.0,
wd.y + 2.0,
);
}
if index + 1 < *count {
batch.sprite(
atlas,
"gui/sprites/transferable_list/move_down",
wd.x + 2.0,
wd.y + 2.0,
);
}
}
}
}
}
}
if list {
@@ -1512,6 +1340,28 @@ impl OptionsUi {
drag: bool,
right: bool,
) -> Vec<Event> {
if crate::ui_theme::horizon() && self.page() == Page::Main {
return self.click_horizon(s, atlas, x, y, drag, right);
}
if self.page() == Page::Packs {
let mut events = Vec::new();
if drag || right {
return events;
}
let m = crate::screen_draw::Measure(&atlas.font);
let p = self.packs(atlas, size);
let before = p.search_focused();
let action = p.click(&m, x as f64, y as f64);
if !before && p.search_focused() {
self.pack_focus = std::time::Instant::now();
}
match action {
crate::pack_screen::Action::OpenFolder => events.push(Event::OpenPackFolder),
crate::pack_screen::Action::Done => events.extend(self.back(s)),
crate::pack_screen::Action::None => {}
}
return events;
}
let (widgets, top, bottom, _) = self.layout(s, atlas, size.0, size.1);
let mut events = Vec::new();
if drag {
@@ -1565,7 +1415,6 @@ impl OptionsUi {
s.keys.reset_all();
events.push(Event::Changed);
}
Act::OpenPackFolder => events.push(Event::OpenPackFolder),
Act::None => {}
},
WKind::Slider { opt, .. } => {
@@ -1583,57 +1432,55 @@ impl OptionsUi {
self.language_choice = Some(code);
}
}
WKind::PackRow {
pack,
selected,
index,
..
} => {
let _ = pack;
// TransferableSelectionList.PackEntry.mouseClicked: the
// right quarters of a selected pack's icon move it, the
// icon otherwise selects or unselects it.
let on_icon = x < wd.x + 34.0;
let m = &mut self.pack_model;
let changed = if selected && on_icon && x >= wd.x + 18.0 {
m.move_by(true, index, y < wd.y + 18.0)
} else {
// No confirmation screen yet: an incompatible pack
// is selected as if its warning were accepted.
m.activate(selected, index, true)
};
if changed {
self.sync_pack_lists();
self.packs_changed = true;
}
}
_ => {}
}
break;
}
events
}
/// Orders the two entry lists as the selection model has them.
pub fn sync_pack_lists(&mut self) {
let all: Vec<PackEntry> = self
.available
.drain(..)
.chain(self.selected.drain(..))
.collect();
let pick = |ids: &[crate::packs::Selectable]| -> Vec<PackEntry> {
ids.iter()
.filter_map(|s| all.iter().find(|e| e.id == s.id).cloned())
.collect()
};
self.available = pick(&self.pack_model.unselected);
self.selected = pick(&self.pack_model.selected);
}
pub fn release(&mut self) {
self.dragging = None;
}
pub fn scroll(&mut self, amount: f32) {
self.scroll -= amount * 18.0;
}
/// The mouse wheel at the cursor.
pub fn scroll_at(&mut self, cursor: (f32, f32), amount: f32) {
if crate::ui_theme::horizon() && self.page() == Page::Main {
self.scroll_horizon(amount);
return;
}
match &mut self.pack_screen {
Some(p) if self.stack.last() == Some(&Page::Packs) => {
p.scroll(cursor.0 as f64, cursor.1 as f64, amount as f64)
}
_ => self.scroll(amount),
}
}
/// The pack screen at this GUI size, made on first use.
fn packs(&mut self, atlas: &HudAtlas, size: (f32, f32)) -> &mut crate::pack_screen::PackScreen {
let m = crate::screen_draw::Measure(&atlas.font);
let (w, h) = (size.0 as i32, size.1 as i32);
match &mut self.pack_screen {
Some(p) => {
if p.width != w || p.height != h {
p.resize(&m, w, h);
}
}
None => {
self.pack_focus = std::time::Instant::now();
self.pack_screen = Some(crate::pack_screen::PackScreen::new(
&m,
w,
h,
self.in_world,
self.pack_infos.clone(),
&self.pack_selection,
));
}
}
self.pack_screen.as_mut().expect("made above")
}
/// Escape or Done: leave the current page, applying page results.
pub fn back(&mut self, s: &mut Settings) -> Vec<Event> {
let mut events = Vec::new();
@@ -1650,11 +1497,15 @@ impl OptionsUi {
events.push(Event::Language(code));
}
}
Page::Packs if self.packs_changed => {
// PackSelectionModel.commit: bottom first, required packs kept.
let ids = self.pack_model.commit();
s.resource_packs = ids.clone();
events.push(Event::Packs(ids));
Page::Packs => {
// PackSelectionScreen.onClose: PackSelectionModel.commit.
if let Some(p) = self.pack_screen.take()
&& p.changed
{
let ids = p.commit();
s.resource_packs = ids.clone();
events.push(Event::Packs(ids));
}
}
_ => {}
}
@@ -1665,7 +1516,13 @@ impl OptionsUi {
events
}
/// Typed text (the language search box).
pub fn type_text(&mut self, text: &str) {
pub fn type_text(&mut self, atlas: &HudAtlas, text: &str) {
if self.page() == Page::Packs
&& let Some(p) = &mut self.pack_screen
{
p.type_text(&crate::screen_draw::Measure(&atlas.font), text);
return;
}
if self.page() == Page::Language {
self.language_search.insert_text(text);
self.scroll = 0.0;
@@ -1676,10 +1533,28 @@ impl OptionsUi {
pub fn key(
&mut self,
s: &mut Settings,
atlas: &HudAtlas,
key: winit::keyboard::KeyCode,
text: Option<&str>,
) -> Vec<Event> {
use winit::keyboard::KeyCode as K;
if self.page() == Page::Packs
&& let Some(p) = &mut self.pack_screen
{
let m = crate::screen_draw::Measure(&atlas.font);
match key {
// ConfirmScreen.keyPressed: Escape answers no.
K::Escape if p.confirming() => {
p.cancel_confirm(&m);
return Vec::new();
}
K::Backspace => {
p.erase(&m, 1);
return Vec::new();
}
_ => {}
}
}
if let Some(name) = self.selected_key.take() {
// KeyBindsScreen.keyPressed: Escape unbinds.
let value = if key == K::Escape {
+915
View File
@@ -0,0 +1,915 @@
//! The resource pack screen (`PackSelectionScreen` with its two
//! `TransferableSelectionList`s, search box and buttons) and the
//! `ConfirmScreen` an incompatible pack opens, as vanilla's state machine:
//! clicks, the mouse wheel and typing change the selection model, the lists'
//! entries, scroll, selection and focus as the vanilla widgets do, and
//! [`PackScreen::draw`] gives the screen's GUI calls. The game shows it;
//! tools/test_pack_screen_parity.py compares it with vanilla.
use crate::{
packs::{Position, Selectable, SelectionModel},
screen_draw::{self as d, Draw, Measure, TextField},
text::{Style, Text},
};
/// `PackCompatibility`.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Compat {
Compatible,
TooOld,
TooNew,
Unknown,
}
impl Compat {
fn key(self) -> &'static str {
match self {
Compat::TooOld => "old",
Compat::TooNew => "new",
Compat::Unknown => "unknown",
Compat::Compatible => "compatible",
}
}
}
/// `PackSource`: how the description is decorated.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Source {
Default,
BuiltIn,
Feature,
World,
Server,
}
/// A pack as the screen shows it.
#[derive(Clone, Debug)]
pub struct PackInfo {
pub id: String,
pub title: Text,
pub description: Text,
/// The description component's own (root) style.
pub description_style: Style,
pub source: Source,
pub compat: Compat,
/// Whether the pack has a `pack.png`.
pub icon: bool,
pub required: bool,
pub position: Position,
pub fixed: bool,
}
impl PackInfo {
pub fn selectable(&self) -> Selectable {
Selectable {
id: self.id.clone(),
required: self.required,
position: self.position,
fixed: self.fixed,
compatible: self.compat == Compat::Compatible,
}
}
/// `PackSource.decorate` merged with the entry's grey
/// (`getExtendedDescription`, `ComponentUtils.mergeStyles`), and the style of
/// its root, which the ellipsis of a cut description takes.
fn extended_description(&self) -> (Text, Style) {
let gray = Style::color(0x808080);
let key = match self.source {
Source::Default => {
let mut root = self.description_style.clone();
root.inherit(&gray);
return (self.description.clone().with_style(&gray), root);
}
Source::BuiltIn => "pack.source.builtin",
Source::Feature => "pack.source.feature",
Source::World => "pack.source.world",
Source::Server => "pack.source.server",
};
let t = Text::translate(
"pack.nameAndSource",
&[self.description.clone(), Text::translate(key, &[])],
)
.with_color(d::GRAY);
(t, Style::color(d::GRAY))
}
}
/// `PackSelectionScreen.loadPackIcon`'s texture for a pack with an icon.
pub fn icon_texture(id: &str) -> String {
let sanitized: String = id
.to_lowercase()
.chars()
.map(|c| {
if c.is_ascii_lowercase() || c.is_ascii_digit() || "_-./".contains(c) {
c
} else {
'_'
}
})
.collect();
let bytes: Vec<u8> = id.encode_utf16().flat_map(u16::to_le_bytes).collect();
let hash: String = crate::skins::sha1(&bytes)
.iter()
.map(|b| format!("{b:02x}"))
.collect();
format!("pack/{sanitized}/{hash}/icon")
}
#[derive(Clone, Debug, PartialEq)]
enum Row {
Header,
Pack(String),
}
#[derive(Clone, Debug)]
struct Entry {
row: Row,
y: i32,
height: i32,
}
/// A `TransferableSelectionList`.
#[derive(Clone, Debug)]
struct List {
selected_side: bool,
x: i32,
y: i32,
width: i32,
height: i32,
scroll: f64,
entries: Vec<Entry>,
/// `getSelected`, an index into `entries`.
selected: Option<usize>,
/// The list has a focused child (possibly an entry it no longer holds).
focused: bool,
}
impl List {
fn new(selected_side: bool, height: i32) -> Self {
Self {
selected_side,
x: 0,
y: 33,
width: 200,
height,
scroll: 0.0,
entries: Vec::new(),
selected: None,
focused: false,
}
}
fn bottom(&self) -> i32 {
self.y + self.height
}
fn row_left(&self) -> i32 {
self.x + self.width / 2 - self.row_width() / 2
}
fn row_width(&self) -> i32 {
self.width - 4
}
fn content_height(&self) -> i32 {
self.entries.iter().map(|e| e.height).sum::<i32>() + 4
}
fn max_scroll(&self) -> i32 {
(self.content_height() - self.height).max(0)
}
fn scrollable(&self) -> bool {
self.max_scroll() > 0
}
/// `TransferableSelectionList.Entry.getWidth`.
fn entry_width(&self) -> i32 {
self.row_width() - if self.scrollable() { 6 } else { 0 }
}
fn next_y(&self) -> i32 {
self.y + 2 - self.scroll as i32 + self.entries.iter().map(|e| e.height).sum::<i32>()
}
fn add(&mut self, row: Row, height: i32) {
let y = self.next_y();
self.entries.push(Entry { row, y, height });
}
fn reposition(&mut self) {
let mut y = self.y + 2 - self.scroll as i32;
for e in &mut self.entries {
e.y = y;
y += e.height;
}
}
fn set_scroll(&mut self, v: f64) {
self.scroll = v.clamp(0.0, self.max_scroll() as f64);
self.reposition();
}
fn scroll_to(&mut self, i: usize) {
let e = &self.entries[i];
let top = e.y - self.y - 2;
if top < 0 {
self.set_scroll(self.scroll + top as f64);
}
let e = &self.entries[i];
let bottom = self.bottom() - e.y - e.height - 2;
if bottom < 0 {
self.set_scroll(self.scroll - bottom as f64);
}
}
fn set_selected(&mut self, i: Option<usize>) {
self.selected = i;
if let Some(i) = i {
let e = &self.entries[i];
let top = e.y + 2 < self.y;
let bottom = e.y + 2 + e.height - 4 > self.bottom();
if top || bottom {
self.scroll_to(i);
}
}
}
fn update_size(&mut self, width: i32, height: i32, x: i32, y: i32) {
self.width = width;
self.height = height;
self.x = x;
self.y = y;
self.reposition();
if let Some(i) = self.selected {
self.scroll_to(i);
}
self.set_scroll(self.scroll);
}
fn is_over(&self, x: f64, y: f64) -> bool {
x >= self.x as f64
&& y >= self.y as f64
&& x < (self.x + self.width) as f64
&& y < self.bottom() as f64
}
/// `getEntryAtPosition`.
fn entry_at(&self, x: i32, y: i32) -> Option<usize> {
let (left, w) = (self.row_left(), self.entry_width());
self.entries
.iter()
.position(|e| x >= left && x < left + w && y >= e.y && y < e.y + e.height)
}
fn scroll_bar_x(&self) -> i32 {
self.x + self.width - 6
}
fn scroller_height(&self) -> i32 {
((self.height * self.height) as f32 / self.content_height() as f32) as i32
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum Focus {
None,
Search,
List(usize),
/// Open Pack Folder (0) or Done (1).
Button(usize),
}
/// The open `ConfirmScreen` for an incompatible pack.
#[derive(Clone, Debug)]
struct Confirm {
id: String,
title: Text,
message: Text,
}
/// What a click on the screen asks the game to do.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Action {
None,
/// The Open Pack Folder button.
OpenFolder,
/// The Done button (`onClose`: commit).
Done,
}
/// The pack screen and its state.
#[derive(Clone, Debug)]
pub struct PackScreen {
pub width: i32,
pub height: i32,
pub in_world: bool,
pub packs: Vec<PackInfo>,
pub model: SelectionModel,
search: TextField,
focus: Focus,
/// 0: available, 1: selected.
lists: [List; 2],
confirm: Option<Confirm>,
/// The selection changed since the screen opened.
pub changed: bool,
}
fn tr(key: &str) -> Text {
Text::translate(key, &[])
}
impl PackScreen {
/// `PackSelectionScreen.init`: the lists filled, the search box focused.
pub fn new(
m: &Measure,
width: i32,
height: i32,
in_world: bool,
packs: Vec<PackInfo>,
selected: &[String],
) -> Self {
let model = SelectionModel::new(packs.iter().map(PackInfo::selectable).collect(), selected);
let mut search = TextField::new(0, 0, 200, 15);
search.hint = Some(tr("gui.packSelection.search").with_style(&Style {
color: Some(d::GRAY),
italic: Some(true),
..Style::default()
}));
let mut s = Self {
width,
height,
in_world,
packs,
model,
search,
focus: Focus::None,
lists: [List::new(false, height - 66), List::new(true, height - 66)],
confirm: None,
changed: false,
};
s.reposition(m);
s.populate(None);
s.set_focus(Focus::Search);
s
}
fn info(&self, id: &str) -> Option<&PackInfo> {
self.packs.iter().find(|p| p.id == id)
}
/// The header layout: title, drop info and search box, centred.
fn header(&self, m: &Measure) -> [(i32, i32); 3] {
let tw = m.width(&tr("resourcePack.title"));
let dw = m.width(&tr("pack.dropInfo"));
let col = tw.max(dw).max(200);
let frame = self.width.max(col);
let lx = (0.5 * (frame - col) as f32) as i32;
let cell = |w: i32| lx + (0.5 * (col - w) as f32) as i32;
[(cell(tw), 4), (cell(dw), 17), (cell(200), 30)]
}
/// The footer's two buttons.
fn footer(&self) -> [(i32, i32); 2] {
let frame = self.width.max(308);
let x = (0.5 * (frame - 308) as f32) as i32;
let y = self.height - 33 + (0.5f32 * 13.0).round() as i32;
[(x, y), (x + 158, y)]
}
/// `repositionElements`.
fn reposition(&mut self, m: &Measure) {
let (sx, sy) = self.header(m)[2];
self.search.x = sx;
self.search.y = sy;
let content = self.height - 49 - 33;
let w = self.width;
self.lists[0].update_size(200, content, w / 2 - 15 - 200, 49);
self.lists[1].update_size(200, content, w / 2 + 15, 49);
}
/// `AbstractContainerEventHandler.setFocused` on the screen.
fn set_focus(&mut self, f: Focus) {
if self.focus == f {
return;
}
match self.focus {
Focus::Search => self.search.focused = false,
Focus::List(i) => self.lists[i].focused = false,
Focus::None | Focus::Button(_) => {}
}
if f == Focus::Search {
self.search.focused = true;
}
self.focus = f;
}
fn shown(&self, side: usize) -> Vec<String> {
let value = self.search.value.to_lowercase();
let blank = self.search.value.trim().is_empty()
&& self.search.value.chars().all(char::is_whitespace);
let list = if side == 1 {
&self.model.selected
} else {
&self.model.unselected
};
list.iter()
.filter(|p| {
blank
|| p.id.to_lowercase().contains(&value)
|| self.info(&p.id).is_some_and(|i| {
i.title.plain().to_lowercase().contains(&value)
|| i.description.plain().to_lowercase().contains(&value)
})
})
.map(|p| p.id.clone())
.collect()
}
/// `TransferableSelectionList.updateList`.
fn update_list(&mut self, side: usize, ids: Vec<String>, transferred: Option<&str>) {
let l = &mut self.lists[side];
l.entries.clear();
l.selected = None;
l.add(Row::Header, 13);
l.set_selected(None);
for id in ids {
let hit = transferred == Some(id.as_str());
self.lists[side].add(Row::Pack(id), 36);
if hit {
self.set_focus(Focus::List(side));
let l = &mut self.lists[side];
l.focused = true;
let i = l.entries.len() - 1;
l.set_selected(Some(i));
}
}
let l = &mut self.lists[side];
l.set_scroll(l.scroll);
}
/// `populateLists`: both lists, then again through the search filter.
fn populate(&mut self, transferred: Option<&str>) {
let all = |m: &SelectionModel, side: bool| -> Vec<String> {
(if side { &m.selected } else { &m.unselected })
.iter()
.map(|p| p.id.clone())
.collect()
};
self.update_list(1, all(&self.model, true), transferred);
self.update_list(0, all(&self.model, false), transferred);
self.filter(transferred);
}
/// `updateFilteredEntries`.
fn filter(&mut self, transferred: Option<&str>) {
let (sel, avail) = (self.shown(1), self.shown(0));
self.update_list(1, sel, transferred);
self.update_list(0, avail, transferred);
}
/// The pack's index in its model list.
fn model_index(&self, side: usize, id: &str) -> Option<usize> {
let list = if side == 1 {
&self.model.selected
} else {
&self.model.unselected
};
list.iter().position(|p| p.id == id)
}
fn flags(&self, side: usize, id: &str) -> (bool, bool, bool, bool) {
let Some(i) = self.model_index(side, id) else {
return (false, false, false, false);
};
let s = side == 1;
(
self.model.can_select(s, i),
self.model.can_unselect(s, i),
self.model.can_move_up(s, i),
self.model.can_move_down(s, i),
)
}
fn overlay(&self, id: &str) -> bool {
self.info(id).is_none_or(|p| !p.fixed || !p.required)
}
/// A left click (`Screen.mouseClicked`).
pub fn click(&mut self, m: &Measure, x: f64, y: f64) -> Action {
if self.confirm.is_some() {
return self.confirm_click(m, x, y);
}
if self.search.contains(x, y) {
self.search.click(m, x, false);
self.set_focus(Focus::Search);
return Action::None;
}
for side in 0..2 {
if !self.lists[side].is_over(x, y) {
continue;
}
let l = &self.lists[side];
let scrolling = l.scrollable()
&& x >= l.scroll_bar_x() as f64
&& x <= (l.scroll_bar_x() + 6) as f64
&& y >= l.y as f64
&& y < l.bottom() as f64;
let hit = l.entry_at(x as i32, y as i32);
let mut took = false;
if let Some(i) = hit {
took = true;
match l.entries[i].row.clone() {
Row::Header => {
let l = &mut self.lists[side];
l.focused = true;
l.set_selected(Some(i));
}
Row::Pack(id) => {
let current = self.entry_click(m, side, i, &id, x as i32, y as i32);
if self.lists[side]
.entries
.iter()
.any(|e| e.row == Row::Pack(id.clone()))
{
let l = &mut self.lists[side];
l.focused = true;
if current {
l.set_selected(Some(i));
}
}
}
}
}
if took || scrolling {
self.set_focus(Focus::List(side));
}
return Action::None;
}
for (i, (bx, by)) in self.footer().into_iter().enumerate() {
if x >= bx as f64 && y >= by as f64 && x < (bx + 150) as f64 && y < (by + 20) as f64 {
self.set_focus(Focus::Button(i));
return if i == 0 {
Action::OpenFolder
} else {
Action::Done
};
}
}
Action::None
}
/// `PackEntry.mouseClicked`; true when the entry clicked is still the
/// list's own (nothing was repopulated).
fn entry_click(
&mut self,
m: &Measure,
side: usize,
i: usize,
id: &str,
x: i32,
y: i32,
) -> bool {
if !self.overlay(id) {
return true;
}
let e = &self.lists[side].entries[i];
let (cx, cy) = (self.lists[side].row_left() + 2, e.y + 2);
let (rx, ry) = (x - cx, y - cy);
let (sel, unsel, up, down) = self.flags(side, id);
let icon = (0..32).contains(&rx) && (0..32).contains(&ry);
let left = (0..16).contains(&rx) && (0..32).contains(&ry);
let top_right = (16..32).contains(&rx) && (0..16).contains(&ry);
let bottom_right = (16..32).contains(&rx) && (16..32).contains(&ry);
let index = self.model_index(side, id).unwrap_or(0);
let s = side == 1;
if sel && icon {
if self
.info(id)
.is_some_and(|p| p.compat != Compat::Compatible)
{
self.open_confirm(id);
return true;
}
self.model.activate(s, index, true);
} else if unsel && left {
self.model.activate(s, index, false);
} else if up && top_right {
self.model.move_by(s, index, true);
} else if down && bottom_right {
self.model.move_by(s, index, false);
} else {
return true;
}
self.changed = true;
self.populate(Some(id));
let _ = m;
false
}
/// `handlePackSelection` of an incompatible pack: the ConfirmScreen
/// (the pack screen loses its focus as `Gui.setScreen` clears it).
fn open_confirm(&mut self, id: &str) {
let compat = self.info(id).map_or(Compat::Unknown, |p| p.compat);
self.set_focus(Focus::None);
for l in &mut self.lists {
l.focused = false;
}
self.confirm = Some(Confirm {
id: id.to_owned(),
title: tr("pack.incompatible.confirm.title"),
message: tr(&format!("pack.incompatible.confirm.{}", compat.key())),
});
}
/// The ConfirmScreen's layout: title, message lines and the two buttons.
fn confirm_layout(
&self,
m: &Measure,
c: &Confirm,
) -> ((i32, i32), (Vec<(Text, i32)>, i32, i32), [(i32, i32); 2]) {
let max = self.width - 50;
let lines = d::label_lines(m, &c.message, max, 15, &Style::default());
let mw = d::label_width(&lines, max);
let mh = lines.len() as i32 * 9;
let tw = m.width(&c.title);
let col = tw.max(mw).max(304);
let total = 9 + 8 + mh + 8 + 36;
let lx = (0.5 * (self.width - col) as f32) as i32;
let ly = (0.5 * (self.height - total) as f32) as i32;
let cell = |w: i32| lx + (0.5 * (col - w) as f32) as i32;
let by = ly + 9 + 8 + mh + 8 + 16;
let bx = cell(304);
(
(cell(tw), ly),
(lines, cell(mw), ly + 17),
[(bx, by), (bx + 154, by)],
)
}
fn confirm_click(&mut self, m: &Measure, x: f64, y: f64) -> Action {
let Some(c) = self.confirm.clone() else {
return Action::None;
};
let (_, _, buttons) = self.confirm_layout(m, &c);
for (i, (bx, by)) in buttons.into_iter().enumerate() {
if x >= bx as f64 && y >= by as f64 && x < (bx + 150) as f64 && y < (by + 20) as f64 {
// The callback: back to the pack screen (repositioned), then select.
self.confirm = None;
self.reposition(m);
if i == 0
&& let Some(index) = self.model_index(0, &c.id)
{
self.model.activate(false, index, true);
self.changed = true;
self.populate(Some(&c.id));
}
return Action::None;
}
}
Action::None
}
/// The focus, the lists' rows, scroll and selection (for debugging).
pub fn debug(&self) -> String {
format!(
"{:?} {:?}",
self.focus,
self.lists
.iter()
.map(|l| (
l.scroll,
l.selected,
l.focused,
l.entries.iter().map(|e| e.y).collect::<Vec<_>>()
))
.collect::<Vec<_>>()
)
}
/// Whether the confirmation screen is shown.
pub fn confirming(&self) -> bool {
self.confirm.is_some()
}
/// Escape on the confirmation screen answers no.
pub fn cancel_confirm(&mut self, m: &Measure) -> bool {
if self.confirm.take().is_some() {
self.reposition(m);
return true;
}
false
}
/// The mouse wheel (`AbstractScrollArea.mouseScrolled`).
pub fn scroll(&mut self, x: f64, y: f64, amount: f64) {
if self.confirm.is_some() || self.search.contains(x, y) {
return;
}
for l in &mut self.lists {
if l.is_over(x, y) {
l.set_scroll(l.scroll - amount * 18.0);
return;
}
}
}
/// Typed text, when the search box has the focus.
pub fn type_text(&mut self, m: &Measure, s: &str) {
if self.confirm.is_none() && self.focus == Focus::Search && self.search.insert_text(m, s) {
self.filter(None);
}
}
/// Backspace in the search box.
pub fn erase(&mut self, m: &Measure, count: isize) {
if self.confirm.is_none()
&& self.focus == Focus::Search
&& self.search.delete_chars(m, -count)
{
self.filter(None);
}
}
pub fn search_focused(&self) -> bool {
self.confirm.is_none() && self.focus == Focus::Search
}
/// Resize (`Screen.init` on a new size: `repositionElements`).
pub fn resize(&mut self, m: &Measure, width: i32, height: i32) {
self.width = width;
self.height = height;
self.reposition(m);
}
/// `PackSelectionModel.commit`: the selection as options.txt stores it.
pub fn commit(&self) -> Vec<String> {
self.model.commit()
}
/// The shown screen's calls (`Screen.extractRenderState`); `blink_ms`
/// is the time since the search box took the focus.
pub fn draw(&self, m: &Measure, mouse: (i32, i32), blink_ms: u64) -> Vec<Draw> {
let mut out = Vec::new();
if let Some(c) = &self.confirm {
let ((tx, ty), (lines, mx, my), buttons) = self.confirm_layout(m, c);
d::string_widget(&mut out, m, &c.title, tx, ty, 0);
d::label(&mut out, &lines, mx, my, self.width - 50, true);
for ((bx, by), key) in buttons.into_iter().zip(["gui.yes", "gui.no"]) {
let hover = d::inside(mouse, bx, by, 150, 20);
d::button(&mut out, m, &tr(key), bx, by, 150, 20, true, hover);
}
return out;
}
let [(tx, ty), (dx, dy), _] = self.header(m);
d::string_widget(&mut out, m, &tr("resourcePack.title"), tx, ty, 0);
d::string_widget(
&mut out,
m,
&tr("pack.dropInfo").with_color(d::GRAY),
dx,
dy,
0,
);
self.search.draw(&mut out, m, blink_ms, None);
for side in 0..2 {
self.draw_list(&mut out, m, side, mouse);
}
for (i, (bx, by)) in self.footer().into_iter().enumerate() {
let hover = d::inside(mouse, bx, by, 150, 20);
let label = tr(if i == 0 {
"pack.openFolder"
} else {
"gui.done"
});
d::button(
&mut out,
m,
&label,
bx,
by,
150,
20,
true,
hover || self.focus == Focus::Button(i),
);
if i == 0 && hover {
d::tooltip(&mut out, m, &tr("pack.folderInfo"), mouse);
}
}
out
}
fn draw_list(&self, out: &mut Vec<Draw>, m: &Measure, side: usize, mouse: (i32, i32)) {
let l = &self.lists[side];
let hovered = if l.is_over(mouse.0 as f64, mouse.1 as f64) {
l.entry_at(mouse.0, mouse.1)
} else {
None
};
let prefix = if self.in_world { "inworld_" } else { "" };
let right = l.x + l.width;
d::blit(
out,
&format!("textures/gui/{prefix}menu_list_background.png"),
l.x,
l.y,
(right as f32, (l.bottom() + l.scroll as i32) as f32),
l.width,
l.height,
[32, 32],
);
out.push(Draw::Scissor {
x0: l.x.clamp(0, self.width),
y0: l.y.clamp(0, self.height),
x1: right.clamp(0, self.width),
y1: l.bottom().clamp(0, self.height),
});
let (left, w) = (l.row_left(), l.entry_width());
let narrow = if l.scrollable() { 6 } else { 0 };
for (i, e) in l.entries.iter().enumerate() {
if e.y + e.height < l.y || e.y > l.bottom() {
continue;
}
if l.selected == Some(i) {
let color = if l.focused { -1 } else { -8355712 };
d::fill(out, left, e.y, left + w, e.y + e.height, color);
d::fill(
out,
left + 1,
e.y + 1,
left + w - 1,
e.y + e.height - 1,
-16777216,
);
}
let (cx, cy) = (left + 2, e.y + 2);
match &e.row {
Row::Header => {
let key = if l.selected_side {
"pack.selected.title"
} else {
"pack.available.title"
};
let t = tr(key).with_style(&Style {
underlined: Some(true),
bold: Some(true),
..Style::default()
});
let tw = m.width(&t);
d::text(
out,
t,
left + w / 2 - tw / 2,
cy + (e.height - 4) / 2 - 4,
-1,
true,
);
}
Row::Pack(id) => {
let Some(p) = self.info(id) else { continue };
if p.compat != Compat::Compatible {
d::fill(
out,
cx - 1,
cy - 1,
cx + w - 4 + 1,
cy + e.height - 4 + 1,
-8978432,
);
}
let icon = if p.icon {
icon_texture(id)
} else {
"textures/misc/unknown_pack.png".into()
};
d::blit(out, &icon, cx, cy, (0.0, 0.0), 32, 32, [32, 32]);
let (mut name, (mut desc, mut desc_style)) =
(p.title.clone(), p.extended_description());
let focus_hover = l.selected == Some(i) && l.focused;
if self.overlay(id) && (hovered == Some(i) || focus_hover) {
d::fill(out, cx, cy, cx + 32, cy + 32, -1601138544);
let (rx, ry) = (mouse.0 - cx, mouse.1 - cy);
if p.compat != Compat::Compatible {
name = tr("pack.incompatible");
desc = tr(&format!("pack.incompatible.{}", p.compat.key()))
.with_color(d::GRAY);
desc_style = Style::color(d::GRAY);
}
let (sel, unsel, up, down) = self.flags(side, id);
let quarter = |x0: i32, x1: i32, y0: i32, y1: i32| {
(x0..x1).contains(&rx) && (y0..y1).contains(&ry)
};
let mut arrow = |name: &str, on: bool| {
let s = if on {
format!("transferable_list/{name}_highlighted")
} else {
format!("transferable_list/{name}")
};
d::sprite(out, &s, cx, cy, 32, 32);
};
if sel {
arrow("select", quarter(0, 32, 0, 32));
} else {
if unsel {
arrow("unselect", quarter(0, 16, 0, 32));
}
if up {
arrow("move_up", quarter(16, 32, 0, 16));
}
if down {
arrow("move_down", quarter(16, 32, 16, 32));
}
}
}
let max = 157 - narrow;
d::string_widget(out, m, &name, cx + 34, cy + 1, max);
let lines = d::label_lines(m, &desc, max, 2, &desc_style);
d::label(out, &lines, cx + 34, cy + 12, max, false);
}
}
}
out.push(Draw::NoScissor);
d::blit(
out,
&format!("textures/gui/{prefix}header_separator.png"),
l.x,
l.y - 2,
(0.0, 0.0),
l.width,
2,
[32, 2],
);
d::blit(
out,
&format!("textures/gui/{prefix}footer_separator.png"),
l.x,
l.bottom(),
(0.0, 0.0),
l.width,
2,
[32, 2],
);
if l.scrollable() {
let sh = l.scroller_height().clamp(32, l.height - 8);
let sy = (l.scroll as i32 * (l.height - sh) / l.max_scroll() + l.y).max(l.y);
d::sprite(
out,
"widget/scroller_background",
l.scroll_bar_x(),
l.y,
6,
l.height,
);
d::sprite(out, "widget/scroller", l.scroll_bar_x(), sy, 6, sh);
}
}
}
+113 -26
View File
@@ -4,6 +4,7 @@
//! and an overlay resource root that layers the enabled packs over the
//! vanilla resources (later packs win), so every loader sees one tree.
pub mod pattern;
use crate::text::Style;
use crate::{text::Text, zip::Zip};
use pattern::Pattern;
use std::{
@@ -27,7 +28,13 @@ pub struct Pack {
pub source: Source,
pub title: Text,
pub description: Text,
/// The description with its legacy codes, and its root style (the pack screen's).
pub raw_description: Text,
pub description_style: Style,
pub compatible: bool,
pub compatibility: crate::pack_screen::Compat,
/// The pack has a `pack.png`.
pub icon: bool,
/// Overlay directories active for this game version, in `pack.mcmeta` order.
pub overlays: Vec<String>,
/// `filter.block` entries (namespace and path patterns) hiding resources
@@ -53,47 +60,90 @@ impl Filter {
&& self.path.as_ref().is_none_or(|p| p.is_match(path))
}
}
/// A minimal text component from JSON (strings, `text`, `translate`, arrays).
/// A text component from JSON (strings, `text`, `translate`, arrays, `extra`
/// and the style fields), legacy `§` codes resolved as the font does.
pub fn component(v: &serde_json::Value) -> Text {
component_root(v).0.resolve_legacy()
}
/// The component, its legacy codes left in place (each span is a
/// component's contents and style), and its root style (`Component.getStyle`).
pub fn component_root(v: &serde_json::Value) -> (Text, Style) {
let mut out = Text::empty();
let root = build(v, &Style::default(), &mut out);
(out, root)
}
fn style_of(o: &serde_json::Map<String, serde_json::Value>) -> Style {
let flag = |k: &str| o.get(k).and_then(|b| b.as_bool());
Style {
color: o.get("color").and_then(|c| c.as_str()).and_then(|c| {
crate::text::named_color(c).or_else(|| {
c.strip_prefix('#')
.and_then(|h| u32::from_str_radix(h, 16).ok())
})
}),
bold: flag("bold"),
italic: flag("italic"),
underlined: flag("underlined"),
strikethrough: flag("strikethrough"),
obfuscated: flag("obfuscated"),
..Style::default()
}
}
/// Appends `v` under `parent`'s style; returns the component's own style.
fn build(v: &serde_json::Value, parent: &Style, out: &mut Text) -> Style {
match v {
serde_json::Value::String(s) => Text::legacy(s),
serde_json::Value::Array(a) => {
let mut t = Text::empty();
for e in a {
t.push(component(e));
let Some(first) = a.first() else {
return Style::default();
};
let own = build(first, parent, out);
let mut style = own.clone();
style.inherit(parent);
for e in &a[1..] {
build(e, &style, out);
}
t
own
}
serde_json::Value::Object(o) => {
let mut t = if let Some(s) = o.get("text").and_then(|s| s.as_str()) {
Text::legacy(s)
let own = style_of(o);
let mut style = own.clone();
style.inherit(parent);
if let Some(s) = o.get("text").and_then(|s| s.as_str()) {
out.push(Text::styled(s, style.clone()));
} else if let Some(k) = o.get("translate").and_then(|s| s.as_str()) {
let args: Vec<Text> = o
.get("with")
.and_then(|w| w.as_array())
.map(|a| a.iter().map(component).collect())
.unwrap_or_default();
Text::translate(k, &args)
} else {
Text::empty()
};
if let Some(extra) = o.get("extra") {
t.push(component(extra));
out.push(Text::translate(k, &args).with_style(&style));
}
if let Some(c) = o.get("color").and_then(|c| c.as_str()) {
let rgb = crate::text::named_color(c).or_else(|| {
c.strip_prefix('#')
.and_then(|h| u32::from_str_radix(h, 16).ok())
});
if let Some(rgb) = rgb {
t = t.with_color(rgb);
match o.get("extra") {
Some(serde_json::Value::Array(extra)) => {
for e in extra {
build(e, &style, out);
}
}
Some(e) => {
build(e, &style, out);
}
None => {}
}
t
own
}
serde_json::Value::Number(n) => Text::literal(n.to_string()),
serde_json::Value::Bool(b) => Text::literal(b.to_string()),
serde_json::Value::Null => Text::empty(),
serde_json::Value::String(s) => {
out.push(Text::styled(s.as_str(), parent.clone()));
Style::default()
}
serde_json::Value::Number(n) => {
out.push(Text::styled(n.to_string(), parent.clone()));
Style::default()
}
serde_json::Value::Bool(b) => {
out.push(Text::styled(b.to_string(), parent.clone()));
Style::default()
}
serde_json::Value::Null => Style::default(),
}
}
fn format_of(v: &serde_json::Value) -> Option<(i64, i64)> {
@@ -128,6 +178,34 @@ pub fn compatible(meta: &serde_json::Value) -> bool {
}
format_of(&pack["pack_format"]).is_some_and(|f| f.0 == current.0)
}
/// `PackCompatibility.forVersion`: too old, too new, compatible, or unknown
/// when the metadata names no format.
pub fn compatibility(meta: &serde_json::Value) -> crate::pack_screen::Compat {
use crate::pack_screen::Compat;
let pack = &meta["pack"];
let current = RESOURCE_FORMAT;
let range = if let (Some(min), Some(max)) = (
format_of(&pack["min_format"]),
format_of(&pack["max_format"]),
) {
Some((min, (max.0, if max.1 == 0 { i64::MAX } else { max.1 })))
} else if let Some(r) = pack["supported_formats"].as_array()
&& let (Some(lo), Some(hi)) = (
r.first().and_then(|v| v.as_i64()),
r.get(1).and_then(|v| v.as_i64()),
)
{
Some(((lo, 0), (hi, i64::MAX)))
} else {
format_of(&pack["pack_format"]).map(|f| ((f.0, 0), (f.0, i64::MAX)))
};
match range {
None => Compat::Unknown,
Some((_, max)) if max < current => Compat::TooOld,
Some((min, _)) if current < min => Compat::TooNew,
_ => Compat::Compatible,
}
}
/// Whether an `overlays.entries[]` item applies to the current format
/// (OverlayMetadataSection: `formats` as an int, `[min, max]` or
/// `{min_inclusive, max_inclusive}`, or `min_format`/`max_format`).
@@ -189,11 +267,20 @@ fn read_meta(source: &Source) -> Option<serde_json::Value> {
}
fn pack(id: String, title: Text, source: Source) -> Option<Pack> {
let meta = read_meta(&source)?;
let (raw_description, description_style) = component_root(&meta["pack"]["description"]);
let icon = match &source {
Source::Dir(d) => d.join("pack.png").is_file(),
Source::Zip(z) => Zip::open(z).is_ok_and(|z| z.read("pack.png").is_ok()),
};
Some(Pack {
id,
title,
description: component(&meta["pack"]["description"]),
description: raw_description.resolve_legacy(),
raw_description,
description_style,
compatible: compatible(&meta),
compatibility: compatibility(&meta),
icon,
overlays: overlays_of(&meta),
filter: filter_of(&meta),
source,
+273
View File
@@ -0,0 +1,273 @@
//! The menus' backdrop treatment (`ui_theme`'s Horizon style): the finished
//! world frame is blurred (dual Kawase: three halvings down, back up) and
//! colour graded before the HUD is drawn over it. Needs a swapchain that can
//! be copied from; without one the frame is left as it is.
/// How the frame under a Horizon-style menu is treated.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct PostGrade {
/// Colour multiplier and lift (`c * tint + lift`).
pub tint: [f32; 3],
pub lift: [f32; 3],
/// Toward grey, 0..1.
pub desaturate: f32,
/// Darkening toward the corners, 0..1.
pub vignette: f32,
}
impl PostGrade {
/// The title backdrop: icy, slightly lifted shadows.
pub const FROST: Self = Self {
tint: [0.62, 0.78, 1.0],
lift: [0.0, 0.01, 0.035],
desaturate: 0.45,
vignette: 0.5,
};
/// Behind the pause menu: the world stays recognisable.
pub const PAUSE: Self = Self {
tint: [0.8, 0.86, 0.98],
lift: [0.0, 0.004, 0.012],
desaturate: 0.25,
vignette: 0.3,
};
}
#[repr(C)]
#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
struct Uniform {
texel: [f32; 4],
tint: [f32; 4],
lift: [f32; 4],
params: [f32; 4],
}
const LEVELS: usize = 3;
pub struct Post {
layout: wgpu::BindGroupLayout,
down: wgpu::RenderPipeline,
up: wgpu::RenderPipeline,
finish: wgpu::RenderPipeline,
sampler: wgpu::Sampler,
/// The copied frame, then the halvings.
levels: Vec<(wgpu::Texture, wgpu::TextureView, [u32; 2])>,
uniforms: Vec<wgpu::Buffer>,
size: [u32; 2],
format: wgpu::TextureFormat,
}
impl Post {
pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Self {
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("Menu backdrop"),
source: wgpu::ShaderSource::Wgsl(include_str!("post.wgsl").into()),
});
let layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: Some("Menu backdrop bindings"),
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
sample_type: wgpu::TextureSampleType::Float { filterable: true },
view_dimension: wgpu::TextureViewDimension::D2,
multisampled: false,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
},
],
});
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("Menu backdrop"),
bind_group_layouts: &[Some(&layout)],
..Default::default()
});
let pipeline = |entry: &str| {
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("Menu backdrop pass"),
layout: Some(&pipeline_layout),
vertex: wgpu::VertexState {
module: &shader,
entry_point: Some("vs_main"),
buffers: &[],
compilation_options: Default::default(),
},
fragment: Some(wgpu::FragmentState {
module: &shader,
entry_point: Some(entry),
targets: &[Some(wgpu::ColorTargetState {
format,
blend: None,
write_mask: wgpu::ColorWrites::ALL,
})],
compilation_options: Default::default(),
}),
primitive: Default::default(),
depth_stencil: None,
multisample: Default::default(),
multiview_mask: None,
cache: None,
})
};
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
label: Some("Menu backdrop"),
mag_filter: wgpu::FilterMode::Linear,
min_filter: wgpu::FilterMode::Linear,
address_mode_u: wgpu::AddressMode::ClampToEdge,
address_mode_v: wgpu::AddressMode::ClampToEdge,
..Default::default()
});
let uniforms = (0..LEVELS * 2 + 1)
.map(|_| {
device.create_buffer(&wgpu::BufferDescriptor {
label: Some("Menu backdrop pass"),
size: std::mem::size_of::<Uniform>() as u64,
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false,
})
})
.collect();
Self {
down: pipeline("fs_down"),
up: pipeline("fs_up"),
finish: pipeline("fs_final"),
layout,
sampler,
levels: Vec::new(),
uniforms,
size: [0, 0],
format,
}
}
fn ensure(&mut self, device: &wgpu::Device, size: [u32; 2]) {
if self.size == size && !self.levels.is_empty() {
return;
}
self.size = size;
self.levels = (0..=LEVELS)
.map(|i| {
let s = [(size[0] >> i).max(1), (size[1] >> i).max(1)];
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("Menu backdrop level"),
size: wgpu::Extent3d {
width: s[0],
height: s[1],
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: self.format,
usage: wgpu::TextureUsages::TEXTURE_BINDING
| wgpu::TextureUsages::RENDER_ATTACHMENT
| wgpu::TextureUsages::COPY_DST,
view_formats: &[],
});
let view = texture.create_view(&Default::default());
(texture, view, s)
})
.collect();
}
fn pass(
&self,
device: &wgpu::Device,
queue: &wgpu::Queue,
encoder: &mut wgpu::CommandEncoder,
pipeline: &wgpu::RenderPipeline,
(from, uniform): (usize, usize),
target: &wgpu::TextureView,
data: Uniform,
) {
let (_, view, s) = &self.levels[from];
let mut data = data;
data.texel = [0.5 / s[0] as f32, 0.5 / s[1] as f32, 0.0, 0.0];
queue.write_buffer(&self.uniforms[uniform], 0, bytemuck::bytes_of(&data));
let group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("Menu backdrop pass"),
layout: &self.layout,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::TextureView(view),
},
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Sampler(&self.sampler),
},
wgpu::BindGroupEntry {
binding: 2,
resource: self.uniforms[uniform].as_entire_binding(),
},
],
});
let attachments = [Some(wgpu::RenderPassColorAttachment {
view: target,
resolve_target: None,
depth_slice: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
store: wgpu::StoreOp::Store,
},
})];
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Menu backdrop pass"),
color_attachments: &attachments,
..Default::default()
});
pass.set_pipeline(pipeline);
pass.set_bind_group(0, &group, &[]);
pass.draw(0..3, 0..1);
}
/// Blur and grade `frame` (the swapchain texture) into `target`.
#[allow(clippy::too_many_arguments)]
pub fn apply(
&mut self,
device: &wgpu::Device,
queue: &wgpu::Queue,
encoder: &mut wgpu::CommandEncoder,
frame: &wgpu::Texture,
target: &wgpu::TextureView,
size: [u32; 2],
grade: &PostGrade,
) {
self.ensure(device, size);
encoder.copy_texture_to_texture(
frame.as_image_copy(),
self.levels[0].0.as_image_copy(),
wgpu::Extent3d {
width: size[0],
height: size[1],
depth_or_array_layers: 1,
},
);
let data = Uniform {
texel: [0.0; 4],
tint: [grade.tint[0], grade.tint[1], grade.tint[2], 1.0],
lift: [grade.lift[0], grade.lift[1], grade.lift[2], 0.0],
params: [grade.desaturate, grade.vignette, 0.0, 0.0],
};
let mut u = 0;
for i in 1..=LEVELS {
let target = &self.levels[i].1;
self.pass(device, queue, encoder, &self.down, (i - 1, u), target, data);
u += 1;
}
for i in (1..LEVELS).rev() {
let target = &self.levels[i].1;
self.pass(device, queue, encoder, &self.up, (i + 1, u), target, data);
u += 1;
}
self.pass(device, queue, encoder, &self.finish, (1, u), target, data);
}
}
+51
View File
@@ -0,0 +1,51 @@
// Menu backdrop: dual-Kawase blur (down and up passes) and a cold colour grade.
struct Post {
// Half a source texel (u, v), unused, unused.
texel: vec4<f32>,
// Multiplier and lift of the grade.
tint: vec4<f32>,
lift: vec4<f32>,
// Desaturation, vignette, unused, unused.
params: vec4<f32>,
}
@group(0) @binding(0) var src: texture_2d<f32>;
@group(0) @binding(1) var samp: sampler;
@group(0) @binding(2) var<uniform> post: Post;
struct Out {
@builtin(position) clip: vec4<f32>,
@location(0) uv: vec2<f32>,
}
@vertex fn vs_main(@builtin(vertex_index) i: u32) -> Out {
let p = vec2<f32>(f32((i << 1u) & 2u), f32(i & 2u));
var out: Out;
out.clip = vec4(p * 2.0 - 1.0, 0.0, 1.0);
out.uv = vec2(p.x, 1.0 - p.y);
return out;
}
fn s(uv: vec2<f32>) -> vec3<f32> {
return textureSampleLevel(src, samp, uv, 0.0).rgb;
}
@fragment fn fs_down(in: Out) -> @location(0) vec4<f32> {
let h = post.texel.xy;
let c = s(in.uv) * 4.0 + s(in.uv - h) + s(in.uv + h) + s(in.uv + vec2(h.x, -h.y)) + s(in.uv - vec2(h.x, -h.y));
return vec4(c / 8.0, 1.0);
}
fn up(uv: vec2<f32>) -> vec3<f32> {
let h = post.texel.xy;
var c = s(uv + vec2(-h.x * 2.0, 0.0)) + s(uv + vec2(h.x * 2.0, 0.0));
c += s(uv + vec2(0.0, -h.y * 2.0)) + s(uv + vec2(0.0, h.y * 2.0));
c += (s(uv + vec2(-h.x, h.y)) + s(uv + vec2(h.x, h.y)) + s(uv + vec2(-h.x, -h.y)) + s(uv + vec2(h.x, -h.y))) * 2.0;
return c / 12.0;
}
@fragment fn fs_up(in: Out) -> @location(0) vec4<f32> {
return vec4(up(in.uv), 1.0);
}
@fragment fn fs_final(in: Out) -> @location(0) vec4<f32> {
var c = up(in.uv);
let l = dot(c, vec3(0.2126, 0.7152, 0.0722));
c = mix(c, vec3(l), post.params.x);
c = c * post.tint.rgb + post.lift.rgb;
let d = length((in.uv - 0.5) * vec2(1.25, 1.0));
c *= 1.0 - post.params.y * smoothstep(0.35, 0.95, d);
return vec4(clamp(c, vec3(0.0), vec3(1.0)), 1.0);
}
+921
View File
@@ -0,0 +1,921 @@
//! Menu screens as the `GuiGraphicsExtractor` calls vanilla's widgets make
//! (sprites, texture blits, fills, text highlight, text, scissor and the
//! tooltip), with ports of the widgets that make them: `StringWidget`,
//! `MultiLineTextWidget`, `Button`, `EditBox` (a font-aware port, scrolling
//! included) and the label layouts. The screen layouts built on them
//! (`pack_screen`) are compared with vanilla's calls by the parity harnesses;
//! [`paint`] draws them with the HUD batch.
use crate::{
font::Font,
hud::{HudAtlas, HudBatch},
text::{Style, Text},
};
/// One GUI call.
#[derive(Clone, Debug, PartialEq)]
pub enum Draw {
/// `blitSprite`, the id without its namespace.
Sprite {
sprite: String,
x: i32,
y: i32,
w: i32,
h: i32,
color: i32,
},
/// `blit` of a texture region; `texture` is the full path (`textures/…png`).
Blit {
texture: String,
x: i32,
y: i32,
w: i32,
h: i32,
u: f32,
v: f32,
src: [i32; 2],
tex: [i32; 2],
color: i32,
},
/// `fill`, corners sorted.
Fill {
x0: i32,
y0: i32,
x1: i32,
y1: i32,
color: i32,
},
/// `textHighlight`.
Highlight {
x0: i32,
y0: i32,
x1: i32,
y1: i32,
},
Text {
text: Text,
x: i32,
y: i32,
color: i32,
shadow: bool,
},
/// `enableScissor`, `disableScissor`.
Scissor {
x0: i32,
y0: i32,
x1: i32,
y1: i32,
},
NoScissor,
/// `setTooltipForNextFrame`: the split lines and the mouse.
Tooltip {
lines: Vec<Text>,
x: i32,
y: i32,
},
}
pub const WHITE: i32 = -1;
pub const GRAY: u32 = 0xAAAAAA;
pub const DARK_GRAY: u32 = 0x555555;
pub fn fill(out: &mut Vec<Draw>, x0: i32, y0: i32, x1: i32, y1: i32, color: i32) {
out.push(Draw::Fill {
x0: x0.min(x1),
y0: y0.min(y1),
x1: x0.max(x1),
y1: y0.max(y1),
color,
});
}
pub fn sprite(out: &mut Vec<Draw>, sprite: &str, x: i32, y: i32, w: i32, h: i32) {
out.push(Draw::Sprite {
sprite: sprite.to_owned(),
x,
y,
w,
h,
color: WHITE,
});
}
/// `blit(pipeline, texture, x, y, u, v, w, h, texW, texH)`.
pub fn blit(
out: &mut Vec<Draw>,
texture: &str,
x: i32,
y: i32,
uv: (f32, f32),
w: i32,
h: i32,
tex: [i32; 2],
) {
out.push(Draw::Blit {
texture: texture.to_owned(),
x,
y,
w,
h,
u: uv.0,
v: uv.1,
src: [w, h],
tex,
color: WHITE,
});
}
/// `graphics.text`: dropped when fully transparent; legacy codes resolved.
pub fn text(out: &mut Vec<Draw>, text: Text, x: i32, y: i32, color: i32, shadow: bool) {
if (color as u32) >> 24 != 0 {
out.push(Draw::Text {
text: text.resolve_legacy(),
x,
y,
color,
shadow,
});
}
}
/// `StringDecomposer.iterateFormatted`: the drawn characters of `contents`,
/// with their index in it and their style; legacy `§` codes restyle what
/// follows them, `§r` returns to `reset`.
pub fn formatted(contents: &str, current: &Style, reset: &Style) -> Vec<(usize, char, Style)> {
let chars: Vec<char> = contents.chars().collect();
let mut style = current.clone();
let mut out = Vec::new();
let mut i = 0;
while i < chars.len() {
let c = chars[i];
if c == '§' {
let Some(code) = chars.get(i + 1) else { break };
let code = code.to_ascii_lowercase();
if let Some(c) = crate::text::COLORS.iter().find(|c| c.0 == code) {
style = Style {
color: Some(c.2),
bold: Some(false),
italic: Some(false),
underlined: Some(false),
strikethrough: Some(false),
obfuscated: Some(false),
..style
};
} else {
match code {
'k' => style.obfuscated = Some(true),
'l' => style.bold = Some(true),
'm' => style.strikethrough = Some(true),
'n' => style.underlined = Some(true),
'o' => style.italic = Some(true),
'r' => style = reset.clone(),
_ => {}
}
}
i += 2;
continue;
}
out.push((i, c, style.clone()));
i += 1;
}
out
}
/// Text measurement as vanilla's `Font` and `StringSplitter` do it, on
/// text whose spans may hold legacy `§` codes (each span is a component's
/// contents and style).
pub struct Measure<'a>(pub &'a Font);
impl Measure<'_> {
/// `Font.width`.
pub fn width(&self, t: &Text) -> i32 {
self.0.width_text(&t.resolve_legacy()) as i32
}
pub fn width_str(&self, s: &str) -> i32 {
self.0.width(s) as i32
}
/// `StringSplitter.headByWidth`: the leading characters whose widths sum to at most `max`.
pub fn head(&self, t: &Text, max: i32) -> Text {
let mut left = max as f32;
let mut out = Text::empty();
for span in &t.spans {
let mut end = None;
let mut position = 0;
for (i, c, style) in formatted(&span.text, &span.style, &span.style) {
left -= self.0.advance(c, &style);
if left >= 0.0 {
position = i + 1;
} else {
end = Some(position);
break;
}
}
match end {
Some(p) => {
out.push(Text::styled(
span.text.chars().take(p).collect::<String>(),
span.style.clone(),
));
return out;
}
None => out.push(Text::styled(span.text.clone(), span.style.clone())),
}
}
t.clone()
}
/// `Font.plainSubstrByWidth`, from the start or (`tail`) the end, in characters.
pub fn plain(&self, s: &str, max: i32, tail: bool) -> usize {
if tail {
self.0.fit_reverse(s, max as f32)
} else {
self.0.fit(s, max as f32)
}
}
/// `StringSplitter.splitLines` (`Font.split`): breaks at a newline, or
/// at the last space (else the character) once the width is exceeded;
/// the rest of a broken part takes the style found at the break, legacy
/// codes counted from the root style.
pub fn split(&self, t: &Text, max: i32) -> Vec<Text> {
let max = (max as f32).max(1.0);
let mut parts: Vec<(Vec<char>, Style)> = t
.spans
.iter()
.filter(|s| !s.text.is_empty())
.map(|s| (s.text.chars().collect(), s.style.clone()))
.collect();
let mut lines = Vec::new();
let mut force_new_line = false;
let root = Style::default();
'restart: loop {
let (mut width, mut had_visible) = (0.0f32, false);
let (mut last_space, mut last_space_style) = (None::<usize>, Style::default());
let mut offset = 0;
for (pi, (contents, style)) in parts.iter().enumerate() {
let s: String = contents.iter().collect();
for (i, c, st) in formatted(&s, style, &root) {
let at = i + offset;
let brk = if c == '\n' {
Some((at, st.clone()))
} else {
if c == ' ' {
last_space = Some(at);
last_space_style = st.clone();
}
let w = self.0.advance(c, &st);
width += w;
if !had_visible || width <= max {
had_visible |= w != 0.0;
None
} else {
Some(match last_space {
Some(p) => (p, last_space_style.clone()),
None => (at, st.clone()),
})
}
};
if let Some((at, split_style)) = brk {
let flat: Vec<char> =
parts.iter().flat_map(|p| p.0.iter().copied()).collect();
let first = flat.get(at).copied().unwrap_or(' ');
let new_line = first == '\n';
let skip = usize::from(new_line || first == ' ');
force_new_line = new_line;
// FlatComponents.splitAt.
let mut line = Text::empty();
let mut position = at;
let mut rest = Vec::new();
let mut in_skip = false;
let mut done = false;
for (contents, style) in parts.drain(..) {
if done {
rest.push((contents, style));
continue;
}
let size = contents.len();
if !in_skip {
if position > size {
line.push(Text::styled(
contents.iter().collect::<String>(),
style,
));
position -= size;
continue;
}
let before: String = contents[..position].iter().collect();
if !before.is_empty() {
line.push(Text::styled(before, style.clone()));
}
position += skip;
in_skip = true;
}
if position <= size {
if position < size {
rest.push((contents[position..].to_vec(), split_style.clone()));
}
done = true;
continue;
}
position -= size;
}
let _ = pi;
parts = rest;
lines.push(line);
continue 'restart;
}
}
offset += contents.len();
}
break;
}
if !parts.is_empty() {
let mut line = Text::empty();
for (contents, style) in parts {
line.push(Text::styled(contents.iter().collect::<String>(), style));
}
lines.push(line);
} else if force_new_line {
lines.push(Text::empty());
}
lines
}
}
/// `TextAlignment.CENTER.calculateLeft`.
pub fn center_left(anchor: i32, width: i32) -> i32 {
anchor - width / 2
}
/// `ComponentRenderUtils.clipText`: as much as fits before an unstyled "...".
pub fn clip(m: &Measure, t: &Text, width: i32) -> Text {
m.head(t, width - m.width_str("..."))
.append(Text::literal("..."))
}
/// `StringWidget` (CLAMPED) at its position: its single line, clipped when wider than `max_width`.
pub fn string_widget(
out: &mut Vec<Draw>,
m: &Measure,
message: &Text,
x: i32,
y: i32,
max_width: i32,
) {
let w = m.width(message);
let max = if max_width > 0 { max_width } else { w };
let line = if w > max {
clip(m, message, max)
} else {
message.clone()
};
text(out, line, x, y, WHITE, true);
}
/// `MultiLineLabel.create(font, maxWidth, maxRows, message)`: the lines and their widths;
/// the last kept line gets "..." in `ellipsis` (the message's own style) when rows were cut.
pub fn label_lines(
m: &Measure,
message: &Text,
max_width: i32,
max_rows: usize,
ellipsis: &Style,
) -> Vec<(Text, i32)> {
let split = m.split(message, max_width);
let n = split.len().min(max_rows);
let mut out = Vec::new();
for (i, line) in split.iter().take(n).enumerate() {
if i == n - 1 && n == max_rows && n != split.len() {
let clipped = m.head(line, m.width(line) - m.width_str("..."));
let with = clipped.append(Text::styled("...", ellipsis.clone()));
let w = m.width(&with);
out.push((with, w));
} else {
out.push((line.clone(), m.width(line)));
}
}
out
}
/// `MultiLineTextWidget.getWidth`.
pub fn label_width(lines: &[(Text, i32)], max_width: i32) -> i32 {
lines.iter().map(|l| l.1).max().unwrap_or(0).min(max_width)
}
/// `MultiLineTextWidget.visitLines`.
pub fn label(
out: &mut Vec<Draw>,
lines: &[(Text, i32)],
x: i32,
y: i32,
max_width: i32,
centered: bool,
) {
let mid = x + label_width(lines, max_width) / 2;
for (i, (line, w)) in lines.iter().enumerate() {
let left = if centered { center_left(mid, *w) } else { x };
text(out, line.clone(), left, y + 9 * i as i32, WHITE, true);
}
}
/// `Button` (`extractDefaultSprite` and the label over its contents, which
/// must fit: scrolling labels depend on the clock).
pub fn button(
out: &mut Vec<Draw>,
m: &Measure,
label: &Text,
x: i32,
y: i32,
w: i32,
h: i32,
active: bool,
highlighted: bool,
) {
let sprite_id = if !active {
"widget/button_disabled"
} else if highlighted {
"widget/button_highlighted"
} else {
"widget/button"
};
sprite(out, sprite_id, x, y, w, h);
let (left, right) = (x + 2, x + w - 2);
let lw = m.width(label);
let top = (y + y + h - 9) / 2 + 1;
let cx = ((left + right) / 2).clamp(left + lw / 2, right - lw / 2);
text(out, label.clone(), center_left(cx, lw), top, WHITE, true);
}
/// `Tooltip.splitTooltip` of a widget's tooltip, shown under the mouse.
pub fn tooltip(out: &mut Vec<Draw>, m: &Measure, message: &Text, mouse: (i32, i32)) {
out.push(Draw::Tooltip {
lines: m.split(message, 170),
x: mouse.0,
y: mouse.1,
});
}
/// `AbstractWidget.areCoordinatesInRectangle`.
pub fn inside(mouse: (i32, i32), x: i32, y: i32, w: i32, h: i32) -> bool {
mouse.0 >= x && mouse.1 >= y && mouse.0 < x + w && mouse.1 < y + h
}
/// Vanilla's `EditBox`: value, cursor, selection and the first shown
/// character, which follows the cursor as `scrollTo` moves it. Positions
/// are in characters.
#[derive(Clone, Debug)]
pub struct TextField {
pub value: String,
pub cursor: usize,
pub highlight: usize,
pub display: usize,
pub max_length: usize,
pub bordered: bool,
pub x: i32,
pub y: i32,
pub width: i32,
pub height: i32,
pub focused: bool,
pub text_color: i32,
pub text_shadow: bool,
pub hint: Option<Text>,
pub suggestion: Option<String>,
}
fn chars(s: &str) -> usize {
s.chars().count()
}
fn sub(s: &str, from: usize, to: usize) -> String {
s.chars().skip(from).take(to.saturating_sub(from)).collect()
}
impl TextField {
pub fn new(x: i32, y: i32, width: i32, height: i32) -> Self {
Self {
value: String::new(),
cursor: 0,
highlight: 0,
display: 0,
max_length: 32,
bordered: true,
x,
y,
width,
height,
focused: false,
text_color: -2039584,
text_shadow: true,
hint: None,
suggestion: None,
}
}
pub fn inner_width(&self) -> i32 {
if self.bordered {
self.width - 8
} else {
self.width
}
}
fn text_x(&self) -> i32 {
self.x + if self.bordered { 4 } else { 0 }
}
fn text_y(&self) -> i32 {
if self.bordered {
self.y + (self.height - 8) / 2
} else {
self.y
}
}
/// `setValue`.
pub fn set_value(&mut self, m: &Measure, value: &str) {
self.value = value.chars().take(self.max_length).collect();
self.move_cursor_to(m, chars(&self.value), false);
self.set_highlight(m, self.cursor);
}
/// `insertText`: replaces the selection within the maximum length. True
/// when the value changed (its responder runs).
pub fn insert_text(&mut self, m: &Measure, input: &str) -> bool {
let (start, end) = (
self.cursor.min(self.highlight),
self.cursor.max(self.highlight),
);
let room = self.max_length as isize - chars(&self.value) as isize + (end - start) as isize;
if room <= 0 {
return false;
}
let filtered: String = input
.chars()
.filter(|c| *c >= ' ' && *c != '\u{7f}' && *c != '§')
.collect();
let insert: String = filtered.chars().take(room as usize).collect();
let n = chars(&insert);
self.value = format!(
"{}{}{}",
sub(&self.value, 0, start),
insert,
sub(&self.value, end, chars(&self.value))
);
self.set_cursor(m, start + n);
self.set_highlight(m, self.cursor);
true
}
/// `deleteChars(dir)`: the selection, or `dir` characters from the cursor.
pub fn delete_chars(&mut self, m: &Measure, dir: isize) -> bool {
if self.value.is_empty() {
return false;
}
if self.highlight != self.cursor {
return self.insert_text(m, "");
}
let pos = (self.cursor as isize + dir).clamp(0, chars(&self.value) as isize) as usize;
let (start, end) = (pos.min(self.cursor), pos.max(self.cursor));
if start == end {
return false;
}
self.value = format!(
"{}{}",
sub(&self.value, 0, start),
sub(&self.value, end, chars(&self.value))
);
self.set_cursor(m, start);
self.move_cursor_to(m, start, false);
true
}
pub fn move_cursor_to(&mut self, m: &Measure, pos: usize, extend: bool) {
self.set_cursor(m, pos);
if !extend {
self.set_highlight(m, self.cursor);
}
}
fn set_cursor(&mut self, m: &Measure, pos: usize) {
self.cursor = pos.min(chars(&self.value));
self.scroll_to(m, self.cursor);
}
fn set_highlight(&mut self, m: &Measure, pos: usize) {
self.highlight = pos.min(chars(&self.value));
self.scroll_to(m, self.highlight);
}
fn scroll_to(&mut self, m: &Measure, pos: usize) {
let len = chars(&self.value);
self.display = self.display.min(len);
let inner = self.inner_width();
let rest = sub(&self.value, self.display, len);
let last = m.plain(&rest, inner, false) + self.display;
let mut display = self.display as isize;
if pos == self.display {
display -= m.plain(&self.value, inner, true) as isize;
}
if pos > last {
display += (pos - last) as isize;
} else if pos as isize <= display {
display = pos as isize;
}
self.display = display.clamp(0, len as isize) as usize;
}
/// `getWordPosition(dir, from)`: past the next space run, or back to the
/// start of the word.
pub fn word_position(&self, dir: isize, from: usize) -> usize {
let v: Vec<char> = self.value.chars().collect();
let mut at = from;
if dir > 0 {
at = v
.iter()
.skip(at)
.position(|c| *c == ' ')
.map_or(v.len(), |p| p + at);
while at < v.len() && v[at] == ' ' {
at += 1;
}
} else {
while at > 0 && v[at - 1] == ' ' {
at -= 1;
}
while at > 0 && v[at - 1] != ' ' {
at -= 1;
}
}
at
}
/// `keyPressed` of a focused, editable box: `Some(changed)` when handled.
pub fn key(
&mut self,
m: &Measure,
key: winit::keyboard::KeyCode,
shift: bool,
ctrl: bool,
) -> Option<bool> {
use winit::keyboard::KeyCode as K;
let len = chars(&self.value);
match key {
K::Backspace | K::Delete => {
let dir = if key == K::Backspace { -1 } else { 1 };
if !ctrl {
return Some(self.delete_chars(m, dir));
}
// deleteWords.
if self.value.is_empty() {
return Some(false);
}
if self.highlight != self.cursor {
return Some(self.insert_text(m, ""));
}
let to = self.word_position(dir, self.cursor);
return Some(self.delete_chars(m, to as isize - self.cursor as isize));
}
K::Home => self.move_cursor_to(m, 0, shift),
K::End => self.move_cursor_to(m, len, shift),
K::ArrowRight | K::ArrowLeft => {
let dir = if key == K::ArrowRight { 1 } else { -1 };
let to = if ctrl {
self.word_position(dir, self.cursor)
} else {
(self.cursor as isize + dir).clamp(0, len as isize) as usize
};
self.move_cursor_to(m, to, shift);
}
K::KeyA if ctrl && !shift => {
self.move_cursor_to(m, len, false);
self.set_highlight(m, 0);
}
_ => return None,
}
Some(false)
}
/// `getScreenX`: where a character index is drawn, from the box's left.
pub fn screen_x(&self, m: &Measure, index: usize) -> i32 {
if index > chars(&self.value) {
return self.x;
}
self.x + m.width_str(&sub(&self.value, 0, index))
}
/// `setCursorPosition` then `setHighlightPos`.
pub fn set_cursor_and_highlight(&mut self, m: &Measure, pos: usize) {
self.set_cursor(m, pos);
self.set_highlight(m, pos);
}
/// `onClick`: the cursor where the mouse is (`findClickedPositionInText`).
pub fn click(&mut self, m: &Measure, x: f64, extend: bool) {
let pos = (x.floor() as i32 - self.text_x()).min(self.inner_width());
let rest = sub(&self.value, self.display, chars(&self.value));
let at = self.display + m.plain(&rest, pos, false);
self.move_cursor_to(m, at, extend);
}
pub fn contains(&self, x: f64, y: f64) -> bool {
x >= self.x as f64
&& y >= self.y as f64
&& x < (self.x + self.width) as f64
&& y < (self.y + self.height) as f64
}
/// `extractWidgetRenderState`; `blink_ms` is the time since the field
/// was focused, `format` styles a substring starting at a character index.
pub fn draw(
&self,
out: &mut Vec<Draw>,
m: &Measure,
blink_ms: u64,
format: Option<&dyn Fn(&str, usize) -> Text>,
) {
if self.bordered {
let s = if self.focused {
"widget/text_field_highlighted"
} else {
"widget/text_field"
};
sprite(out, s, self.x, self.y, self.width, self.height);
}
let color = self.text_color;
let len = chars(&self.value);
let rest = sub(&self.value, self.display, len);
let shown_len = m.plain(&rest, self.inner_width(), false);
let displayed = sub(&rest, 0, shown_len);
let rel_cursor = self.cursor as isize - self.display as isize;
let on_screen = rel_cursor >= 0 && rel_cursor <= shown_len as isize;
let show_cursor = self.focused && (blink_ms / 300).is_multiple_of(2) && on_screen;
let (tx, ty) = (self.text_x(), self.text_y());
let mut draw_x = tx;
let rel_highlight =
(self.highlight as isize - self.display as isize).clamp(0, shown_len as isize) as usize;
let styled = |s: String, offset: usize| match format {
Some(f) => f(&s, offset),
None => Text::literal(s),
};
if !displayed.is_empty() {
let half = if on_screen {
sub(&displayed, 0, rel_cursor as usize)
} else {
displayed.clone()
};
let t = styled(half, self.display);
let w = m.width(&t);
text(out, t, draw_x, ty, color, self.text_shadow);
draw_x += w + 1;
}
let insert = self.cursor < len || len >= self.max_length;
let mut cursor_x = draw_x;
if !on_screen {
cursor_x = if rel_cursor > 0 { tx + self.width } else { tx };
} else if insert {
cursor_x -= 1;
draw_x -= 1;
}
if !displayed.is_empty() && on_screen && (rel_cursor as usize) < shown_len {
let t = styled(sub(&displayed, rel_cursor as usize, shown_len), self.cursor);
text(out, t, draw_x, ty, color, self.text_shadow);
}
if let Some(hint) = &self.hint
&& displayed.is_empty()
&& !self.focused
{
text(out, hint.clone(), draw_x, ty, color, true);
}
if !insert && let Some(s) = &self.suggestion {
text(
out,
Text::literal(s.clone()),
cursor_x - 1,
ty,
-8355712,
self.text_shadow,
);
}
if rel_highlight as isize != rel_cursor {
let hx = tx + m.width_str(&sub(&displayed, 0, rel_highlight));
let right = self.x + self.width;
out.push(Draw::Highlight {
x0: cursor_x.min(right),
y0: ty - 1,
x1: (hx - 1).min(right),
y1: ty + 1 + 9,
});
}
if show_cursor {
if insert {
fill(out, cursor_x, ty - 1, cursor_x + 1, ty + 10, color);
} else {
text(
out,
Text::literal("_"),
cursor_x,
ty,
color,
self.text_shadow,
);
}
}
}
}
/// Draws the calls with the HUD batch: sprites nine-sliced, textures from
/// the atlas (`textures/gui/x.png` is `gui/x`; tiled textures from their
/// corner), scissor clipping, and the tooltip at the mouse.
pub fn paint(batch: &mut HudBatch, atlas: &HudAtlas, draws: &[Draw]) {
let mut clip: Option<(usize, [i32; 4])> = None;
let mut tooltip = None;
for d in draws {
match d {
Draw::Sprite {
sprite,
x,
y,
w,
h,
color,
} => crate::ui::nine_slice(
batch,
atlas,
&format!("gui/sprites/{sprite}"),
*x as f32,
*y as f32,
*w as f32,
*h as f32,
crate::hud_layout::abgr(*color as u32),
),
Draw::Blit {
texture,
x,
y,
w,
h,
u,
v,
src,
tex,
color,
} => {
let key = texture
.trim_start_matches("textures/")
.trim_end_matches(".png");
let key = if atlas.sprites.contains_key(key) {
key
} else {
"misc/unknown_pack"
};
let color = crate::hud_layout::abgr(*color as u32);
if src[0] == tex[0] && src[1] == tex[1]
|| (*u == 0.0 && *v == 0.0 && src[0] <= tex[0] && src[1] <= tex[1])
{
if let Some(mut r) = atlas.sprites.get(key).copied() {
let (du, dv) = (r.u1 - r.u0, r.v1 - r.v0);
r.u1 = r.u0 + du * src[0] as f32 / tex[0] as f32;
r.v1 = r.v0 + dv * src[1] as f32 / tex[1] as f32;
batch.rect_uv(*x as f32, *y as f32, *w as f32, *h as f32, r, color);
}
} else {
crate::ui::tiled(
batch,
atlas,
key,
*x as f32,
*y as f32,
*w as f32,
*h as f32,
tex[0] as f32,
color,
);
}
}
Draw::Fill {
x0,
y0,
x1,
y1,
color,
} => batch.fill(
atlas,
*x0 as f32,
*y0 as f32,
(x1 - x0) as f32,
(y1 - y0) as f32,
crate::hud_layout::abgr(*color as u32),
),
Draw::Highlight { x0, y0, x1, y1 } => {
let (a, b) = ((*x0).min(*x1), (*x0).max(*x1));
batch.fill(
atlas,
a as f32,
*y0 as f32,
(b - a) as f32,
(y1 - y0) as f32,
crate::hud::rgba(0, 0, 255, 128),
);
}
Draw::Text {
text,
x,
y,
color,
shadow,
} => {
batch.text_styled(
atlas,
text,
*x as f32,
*y as f32,
crate::hud_layout::abgr(*color as u32),
*shadow,
);
}
Draw::Scissor { x0, y0, x1, y1 } => {
clip = Some((batch.vertices.len(), [*x0, *y0, *x1, *y1]))
}
Draw::NoScissor => {
if let Some((start, [x0, y0, x1, y1])) = clip.take() {
batch.clip_since(start, x0 as f32, y0 as f32, x1 as f32, y1 as f32);
}
}
Draw::Tooltip { lines, x, y } => {
tooltip = Some((lines.clone(), (*x as f32, *y as f32)))
}
}
}
if let Some((lines, at)) = tooltip {
crate::ui::tooltip(batch, atlas, &lines, at);
}
}
+133 -10
View File
@@ -2,6 +2,7 @@
//! and decorations, translatable messages formatted like
//! `TranslatableContents` (`%s`, `%1$s`, `%%`), and legacy `§` codes.
use crate::lang;
use serde_json::{Map, Value, json};
/// ChatFormatting colours by legacy code index 0..=15.
pub const COLORS: [(char, &str, u32); 16] = [
@@ -86,11 +87,20 @@ pub struct Span {
pub text: String,
pub style: Style,
}
/// A run of styled spans.
#[derive(Clone, Debug, Default, PartialEq, Eq)]
/// A run of styled spans, and the `Component` they came from (its JSON form)
/// when it was built through the constructors below, for sending to vanilla
/// clients. Equality compares the spans only.
#[derive(Clone, Debug, Default)]
pub struct Text {
pub spans: Vec<Span>,
source: Option<std::sync::Arc<Value>>,
}
impl PartialEq for Text {
fn eq(&self, other: &Self) -> bool {
self.spans == other.spans
}
}
impl Eq for Text {}
impl From<&str> for Text {
fn from(s: &str) -> Self {
Text::literal(s)
@@ -111,6 +121,7 @@ impl Text {
return Self::default();
}
Self {
source: Some(json!({ "text": text }).into()),
spans: vec![Span {
text,
style: Style::default(),
@@ -118,18 +129,21 @@ impl Text {
}
}
pub fn styled(s: impl Into<String>, style: Style) -> Self {
let mut t = Self::literal(s);
for span in &mut t.spans {
span.style = style.clone();
}
t
Self::literal(s).with_style(&style)
}
pub fn colored(s: impl Into<String>, color: u32) -> Self {
Self::styled(s, Style::color(color))
}
/// Component.translatable(key, args) in the current language.
pub fn translate(key: &str, args: &[Text]) -> Self {
format_translation(&lang::get(key), args)
let mut t = format_translation(&lang::get(key), args);
let mut c = Map::new();
c.insert("translate".into(), key.into());
if !args.is_empty() {
c.insert("with".into(), args.iter().map(Text::argument).collect());
}
t.source = Some(Value::Object(c).into());
t
}
/// A translatable message whose arguments are plain strings.
pub fn tr(key: &str, args: &[&dyn std::fmt::Display]) -> Self {
@@ -137,19 +151,81 @@ impl Text {
Self::translate(key, &args)
}
pub fn append(mut self, other: impl Into<Text>) -> Self {
self.spans.extend(other.into().spans);
self.push(other);
self
}
/// MutableComponent.append: `other` becomes a sibling. A styled text is
/// wrapped first, as its style doesn't reach what is appended here.
pub fn push(&mut self, other: impl Into<Text>) {
self.spans.extend(other.into().spans);
let other = other.into();
let sibling = other.component();
let mut root = if self.spans.is_empty() && self.source.is_none() {
json!({ "text": "" })
} else {
let c = self.component();
if STYLE_KEYS.iter().any(|k| c.get(*k).is_some()) {
json!({ "text": "", "extra": [c] })
} else {
c
}
};
if let Value::Object(o) = &mut root {
match o.get_mut("extra") {
Some(Value::Array(a)) => a.push(sibling),
_ => {
o.insert("extra".into(), Value::Array(vec![sibling]));
}
}
}
self.source = Some(root.into());
self.spans.extend(other.spans);
}
/// Apply `style` underneath every span (MutableComponent.withStyle on a parent).
pub fn with_style(mut self, style: &Style) -> Self {
for span in &mut self.spans {
span.style.inherit(style);
}
let mut c = self.component();
if let Value::Object(o) = &mut c {
for (k, v) in style_json(style) {
o.entry(k).or_insert(v);
}
}
self.source = Some(c.into());
self
}
/// The `Component` as vanilla's JSON (ComponentSerialization): the one
/// built through the constructors, else the spans as literal siblings.
pub fn component(&self) -> Value {
if let Some(c) = &self.source {
return (**c).clone();
}
let span = |s: &Span| {
let mut o = Map::new();
o.insert("text".into(), s.text.clone().into());
o.extend(style_json(&s.style));
Value::Object(o)
};
match self.spans.as_slice() {
[] => json!({ "text": "" }),
[one] => span(one),
many => json!({ "text": "", "extra": many.iter().map(span).collect::<Vec<_>>() }),
}
}
/// A translation argument: vanilla passes numbers as numbers, which
/// Horizon formats into unstyled literals.
fn argument(&self) -> Value {
let c = self.component();
match c
.as_object()
.and_then(|o| o.get("text").filter(|_| o.len() == 1))
{
Some(Value::String(s)) if s.parse::<i64>().is_ok_and(|n| n.to_string() == *s) => {
s.parse::<i64>().map_or(c.clone(), Value::from)
}
_ => c,
}
}
pub fn with_color(self, color: u32) -> Self {
self.with_style(&Style::color(color))
}
@@ -315,6 +391,53 @@ impl Text {
}
}
/// The style fields of a component's JSON.
const STYLE_KEYS: [&str; 8] = [
"color",
"bold",
"italic",
"underlined",
"strikethrough",
"obfuscated",
"click_event",
"hover_event",
];
/// Style.Serializer: the fields a style sets.
fn style_json(style: &Style) -> Vec<(String, Value)> {
let mut out = Vec::new();
if let Some(c) = style.color {
let name = COLORS
.iter()
.find(|n| n.2 == c)
.map_or_else(|| format!("#{c:06X}"), |n| n.1.to_owned());
out.push(("color".to_owned(), name.into()));
}
for (key, flag) in [
("bold", style.bold),
("italic", style.italic),
("underlined", style.underlined),
("strikethrough", style.strikethrough),
("obfuscated", style.obfuscated),
] {
if let Some(f) = flag {
out.push((key.to_owned(), f.into()));
}
}
if let Some(command) = &style.suggest {
out.push((
"click_event".to_owned(),
json!({ "action": "suggest_command", "command": command }),
));
}
if let Some(hover) = &style.hover {
out.push((
"hover_event".to_owned(),
json!({ "action": "show_text", "value": hover.component() }),
));
}
out
}
/// TranslatableContents.decomposeTemplate: `%s` takes the next argument,
/// `%n$s` a numbered one and `%%` is a percent sign. Malformed templates are
/// shown verbatim.
+83 -40
View File
@@ -50,6 +50,12 @@ pub struct Title {
pub mode: Mode,
pub saves: PathBuf,
pub started: std::time::Instant,
/// The mode last drawn and when it appeared (Horizon's screen fades).
shown: std::cell::Cell<(std::mem::Discriminant<Mode>, std::time::Instant)>,
/// The launcher-style opening (Horizon style, first title of the session).
pub opening: std::cell::Cell<Option<crate::front::Opening>>,
/// The saves listed for Home, re-read every couple of seconds.
recent: std::cell::RefCell<Option<(std::time::Instant, Vec<WorldEntry>)>>,
}
struct Button {
x: f32,
@@ -96,10 +102,78 @@ pub fn list_worlds(saves: &Path) -> Vec<WorldEntry> {
}
impl Title {
pub fn new(saves: PathBuf) -> Self {
let mode = Mode::Main;
let now = std::time::Instant::now();
Self {
mode: Mode::Main,
shown: std::cell::Cell::new((std::mem::discriminant(&mode), now)),
mode,
saves,
started: std::time::Instant::now(),
started: now,
opening: std::cell::Cell::new(None),
recent: std::cell::RefCell::new(None),
}
}
/// The worlds, newest first, cached for two seconds (drawn every frame).
pub fn recent_worlds(&self) -> Vec<WorldEntry> {
let mut recent = self.recent.borrow_mut();
match &*recent {
Some((at, worlds)) if at.elapsed().as_secs() < 2 => worlds.clone(),
_ => {
let worlds = list_worlds(&self.saves);
*recent = Some((std::time::Instant::now(), worlds.clone()));
worlds
}
}
}
/// When the current mode first appeared.
pub fn entered(&self) -> std::time::Instant {
let now = std::mem::discriminant(&self.mode);
let (mode, at) = self.shown.get();
if mode == now {
return at;
}
let at = std::time::Instant::now();
self.shown.set((now, at));
at
}
/// Create New World: the folder name and options (FileUtil.findAvailableName).
pub fn create_action(&self) -> Action {
let Mode::Create {
name,
seed,
creative,
..
} = &self.mode
else {
return Action::None;
};
let base: String = name
.chars()
.map(|c| {
if c.is_alphanumeric() || c == ' ' || c == '-' || c == '_' {
c
} else {
'_'
}
})
.collect();
let base = if base.trim().is_empty() {
"World".to_owned()
} else {
base.trim().to_owned()
};
// FileUtil.findAvailableName: append (n) until unused.
let mut folder = base.clone();
let mut n = 1;
while self.saves.join(&folder).exists() {
folder = format!("{base} ({n})");
n += 1;
}
Action::Create {
folder,
name: name.clone(),
seed: parse_seed(seed),
creative: *creative,
}
}
fn buttons(&self, w: f32, h: f32) -> Vec<Button> {
@@ -446,44 +520,7 @@ impl Title {
*creative = !*creative;
Action::None
}
(
Mode::Create {
name,
seed,
creative,
..
},
Some(21),
) => {
let base: String = name
.chars()
.map(|c| {
if c.is_alphanumeric() || c == ' ' || c == '-' || c == '_' {
c
} else {
'_'
}
})
.collect();
let base = if base.trim().is_empty() {
"World".to_owned()
} else {
base.trim().to_owned()
};
// FileUtil.findAvailableName: append (n) until unused.
let mut folder = base.clone();
let mut n = 1;
while self.saves.join(&folder).exists() {
folder = format!("{base} ({n})");
n += 1;
}
Action::Create {
folder,
name: name.clone(),
seed: parse_seed(seed),
creative: *creative,
}
}
(Mode::Create { .. }, Some(21)) => self.create_action(),
(Mode::Create { .. }, Some(22)) => {
self.mode = Mode::Select {
worlds: list_worlds(&self.saves),
@@ -510,6 +547,7 @@ impl Title {
if let Mode::Create {
name, seed, focus, ..
} = &mut self.mode
&& *focus < 2
{
let field = if *focus == 0 { name } else { seed };
for c in text.chars().filter(|c| !c.is_control()) {
@@ -526,6 +564,7 @@ impl Title {
if let Mode::Create {
name, seed, focus, ..
} = &mut self.mode
&& *focus < 2
{
let field = if *focus == 0 { name } else { seed };
field.pop();
@@ -554,6 +593,10 @@ impl Title {
};
}
}
/// `yyyy/MM/dd HH:mm` (UTC) for a modification time in Unix seconds.
pub fn date_label(secs: u64) -> String {
date_string(secs)
}
fn date_string(secs: u64) -> String {
// Civil date from Unix time (days-from-civil inverse), UTC.
let days = (secs / 86400) as i64;
File diff suppressed because it is too large. Load diff
+8
View File
@@ -0,0 +1,8 @@
[package]
name = "horizon-theme"
version = "0.1.0"
edition = "2021"
license = "MIT"
description = "Horizon's design tokens and fonts, shared by the launcher and the game's menus"
[dependencies]
Binary file not shown.
Loaded 100 of 175 files, more files were not shown because too many files have changed in this diff. Show more