Tools read the pinned Minecraft version from research-lock.json

lab.VERSION, lab.GAME (.local/minecraft/<version>) and lab.RESOURCES
(.local/horizon-client/<version>) come from the lock, and lab.version_info()
reads the pinned client jar's version.json. Every harness, generator and
tool that named 26.3 (resource folders, jar and source paths, result
records, the vanilla client's --version and asset index, the bare login
client's protocol, the benchmark's options.txt data version, the packet id
table's header) uses them, so a candidate worktree pinned to another version
runs them unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Ludovic MarieandClaude Opus 5.5 committed 2026-10-21 12:22:20 +02:00
1 parent ef8b045d79
commit ce87bfb8c7
62 files changed
+238 -89

No files matched your search

+7 -2
View File
@@ -32,6 +32,11 @@ import tempfile
import time
from pathlib import Path
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parents[1]
LAVAPIPE = Path('/run/opengl-driver/share/vulkan/icd.d/lvp_icd.x86_64.json')
LOG_KINDS = ['oak_log', 'birch_log', 'spruce_log', 'jungle_log', 'acacia_log', 'dark_oak_log',
@@ -431,7 +436,7 @@ def run(mode, ctl, out, resources, which='survival'):
work = Path(tempfile.mkdtemp(prefix=f'hzac-{mode}-'))
(work / '.local').mkdir()
(work / '.local/horizon-client').mkdir()
os.symlink(resources, work / '.local/horizon-client/26.3')
os.symlink(resources, work / '.local/horizon-client' / lab.VERSION)
socket = work / 'c.sock'
env = game_env(os.environ.get('VSCREEN', 'agent-control'))
driver = (Cli if mode == 'cli' else Mcp)(ctl, socket, work, env)
@@ -472,7 +477,7 @@ def main():
meta = json.loads(subprocess.run(['cargo', 'metadata', '--format-version', '1', '--no-deps'], cwd=ROOT,
capture_output=True, text=True, check=True).stdout)
bins = Path(meta['target_directory']) / 'fast'
resources = (ROOT / '.local/horizon-client/26.3').resolve()
resources = (lab.RESOURCES).resolve()
if not (resources / 'horizon-resources.json').exists():
sys.exit(f'no prepared resources in {resources}')
out = Path(args.out)
+1 -1
View File
@@ -18,7 +18,7 @@ try:
except ImportError:
import lab, test_rust_parity as base, test_model_baking_parity as baking
RESOURCES = lab.LOCAL / 'horizon-client/26.3'
RESOURCES = lab.RESOURCES
COMMON_SOURCES = [
lab.ROOT / 'tools/audio_harness.py',
lab.ROOT / 'tools/test_rust_parity.py',
+6 -1
View File
@@ -10,6 +10,11 @@ import os
from pathlib import Path
import subprocess
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parents[1]
@@ -31,7 +36,7 @@ def main():
mode.add_argument('--test', action='store_true', help='run extracted production upload tests')
mode.add_argument('--build-only', action='store_true', help='build without measuring')
parser.add_argument('--label', default='candidate')
parser.add_argument('--resources', type=Path, default=ROOT / '.local/horizon-client/26.3')
parser.add_argument('--resources', type=Path, default=lab.RESOURCES)
args = parser.parse_args()
path = 'crates/horizon-client/src/gfx.rs'
source = (subprocess.check_output(['git', 'show', f'{args.ref}:{path}'], cwd=ROOT, text=True)
+2 -2
View File
@@ -21,8 +21,8 @@ def wanted(name):
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--target', type=Path, default=lab.LOCAL / 'horizon-client/26.3',
help='prepared resource directory (default: .local/horizon-client/26.3)')
parser.add_argument('--target', type=Path, default=lab.RESOURCES,
help='prepared resource directory (default: .local/horizon-client/<pinned version>)')
parser.add_argument('--minecraft-dir', type=Path,
help="official launcher game directory (default: the launcher's own)")
args = parser.parse_args()
+8 -3
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""Convert vanilla's BlockStateData.java into a plain data file.
Reads .local/minecraft/26.3/sources/server/net/minecraft/util/datafix/fixes/BlockStateData.java
Reads .local/minecraft/<pinned version>/sources/server/net/minecraft/util/datafix/fixes/BlockStateData.java
Writes crates/horizon-world/src/datafix/block_state_data.txt
Output: UTF-8, '#' header lines, then one line per register() call, in the order the
@@ -20,8 +20,13 @@ import re
import sys
from pathlib import Path
try:
from . import lab
except ImportError:
import lab
REPO = Path(__file__).resolve().parent.parent
DEFAULT_JAVA = REPO / ".local/minecraft/26.3/sources/server/net/minecraft/util/datafix/fixes/BlockStateData.java"
DEFAULT_JAVA = lab.GAME / "sources/server/net/minecraft/util/datafix/fixes/BlockStateData.java"
DEFAULT_OUT = REPO / "crates/horizon-world/src/datafix/block_state_data.txt"
TOKEN_RE = re.compile(
@@ -305,7 +310,7 @@ def main():
raise SystemExit(f"create count mismatch: textual {textual_create}, parsed {total_create}")
header = [
"# Generated by tools/gen_block_state_data.py from vanilla 26.3 BlockStateData.java. Do not edit.",
f"# Generated by tools/gen_block_state_data.py from vanilla {lab.VERSION} BlockStateData.java. Do not edit.",
"# One line per register(ID, new, legacy...) call, in execution order of the static initializer",
"# (bootstrap0, 1, 2, 3_1, 3_2, 4 .. 9, A .. F).",
"# Format (tab separated): ID <TAB> newName <TAB> newProps [<TAB> legacyName <TAB> legacyProps]...",
+6 -1
View File
@@ -11,8 +11,13 @@ import subprocess
import sys
from pathlib import Path
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parent.parent
FIXES = ROOT / '.local' / 'minecraft' / '26.3' / 'sources' / 'server' / 'net' / 'minecraft' / 'util' / 'datafix' / 'fixes'
FIXES = lab.GAME / 'sources' / 'server' / 'net' / 'minecraft' / 'util' / 'datafix' / 'fixes'
OUT = ROOT / 'crates' / 'horizon-world' / 'src' / 'datafix' / 'flat_tables.rs'
STR = r'"((?:[^"\\]|\\.)*)"'
+7 -2
View File
@@ -5,12 +5,17 @@ trackDeltas, which ChunkMap.TrackedEntity and ServerEntity use to decide who
sees an entity and how often its movement is sent), read from the decompiled
EntityTypes.java.
generate_entity_tracking.py [--sources .local/minecraft/26.3/sources/client]
generate_entity_tracking.py [--sources .local/minecraft/<pinned version>/sources/client]
"""
import argparse
import re
from pathlib import Path
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parents[1]
INT_MAX = 2147483647
@@ -34,7 +39,7 @@ def parse(sources):
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--sources", type=Path, default=ROOT / ".local/minecraft/26.3/sources/client")
parser.add_argument("--sources", type=Path, default=lab.GAME / "sources/client")
parser.add_argument("--out", type=Path, default=ROOT / "crates/horizon-client/src/lan/tracking.rs")
args = parser.parse_args()
rows = parse(args.sources)
+7 -1
View File
@@ -10,6 +10,11 @@ import argparse
import json
from pathlib import Path
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parents[1]
STATES = ["handshake", "status", "login", "configuration", "play"]
DIRECTIONS = ["clientbound", "serverbound"]
@@ -25,8 +30,9 @@ def main():
parser.add_argument("--out", type=Path, default=ROOT / "crates/horizon-protocol/src/ids.rs")
args = parser.parse_args()
report = json.loads(args.report.read_text())
info = lab.version_info()
lines = [
"//! Packet ids per connection state and direction for protocol 777 (26.3).",
f"//! Packet ids per connection state and direction for protocol {info['protocol_version']} ({info['name']}).",
"//! Generated by tools/generate_packet_ids.py from the data generator's",
"//! packets report; do not edit by hand.",
"#![allow(missing_docs)]",
+6 -1
View File
@@ -25,6 +25,11 @@ import sys
import time
from pathlib import Path
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parent.parent
SEED = "1234"
WORLD = "GraphicsBench"
@@ -153,7 +158,7 @@ def main():
p.add_argument("--seconds", type=float, default=12.0, help="flight duration per scene")
p.add_argument("--settle", type=float, default=2.0, help="seconds to wait before each flight")
p.add_argument("--offscreen", action="store_true", help="render offscreen on the discrete GPU")
p.add_argument("--resources", default=str(ROOT / ".local/horizon-client/26.3"))
p.add_argument("--resources", default=str(lab.RESOURCES))
p.add_argument("--build", default=str(ROOT / "target/release"))
p.add_argument("--out", help="JSON file (default benchmarks/graphics/<label>.json)")
p.add_argument("--compare", nargs=2, metavar=("BEFORE", "AFTER"),
+1 -1
View File
@@ -12,7 +12,7 @@ except ImportError:
import lab
import test_rust_parity as base
RESOURCES = lab.LOCAL / 'horizon-client' / '26.3'
RESOURCES = lab.RESOURCES
PARITY = lab.ROOT / 'mods/horizon/src/test/java/dev/horizonlab/parity'
+23 -4
View File
@@ -24,6 +24,28 @@ LOCAL = ROOT / ".local"
LOCK = ROOT / "research-lock.json"
def pinned_version():
"""The Minecraft version research-lock.json pins: every tool reads it from there, never by hand."""
version = json.loads(LOCK.read_text(encoding="utf-8"))["minecraft"]["version"]
if not re.fullmatch(r"[A-Za-z0-9_.-]+", version) or version in {".", ".."}:
raise ValueError("Unsafe version identifier in lock file")
return version
VERSION = pinned_version()
# The pinned version's imported jars, libraries and sources (tools/lab.py prepare), and the resources
# horizon-prepare made from them.
GAME = LOCAL / "minecraft" / VERSION
RESOURCES = LOCAL / "horizon-client" / VERSION
def version_info(client_jar=None):
"""What the pinned client jar states about itself in its version.json (protocol_version, world_version,
pack_version, java_version...)."""
with zipfile.ZipFile(client_jar or GAME / "jars" / "client.jar") as archive:
return json.loads(archive.read("version.json"))
def cargo_target():
"""Cargo's target directory, honouring CARGO_TARGET_DIR (tools/parity.py sets it)."""
return ROOT / os.environ.get("CARGO_TARGET_DIR", "target")
@@ -260,10 +282,7 @@ def launcher_object(assets, checksum):
def config():
lock = json.loads(LOCK.read_text(encoding="utf-8"))
version = lock["minecraft"]["version"]
if not re.fullmatch(r"[A-Za-z0-9_.-]+", version) or version in {".", ".."}:
raise ValueError("Unsafe version identifier in lock file")
return lock, LOCAL / "minecraft" / version
return lock, LOCAL / "minecraft" / pinned_version()
def bundle_entries(archive, name):
+7 -2
View File
@@ -22,6 +22,11 @@ import sys
import tempfile
from pathlib import Path
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parents[1]
TAG = 'v2099.1.1'
@@ -98,7 +103,7 @@ def main():
parser.add_argument('--out', default=str(ROOT / '.local/launcher-mcp-e2e'), help='the screenshot goes here')
args = parser.parse_args()
bins = Path(args.bin_dir).resolve()
resources = (ROOT / '.local/horizon-client/26.3').resolve()
resources = (lab.RESOURCES).resolve()
if not (resources / 'horizon-resources.json').exists():
sys.exit(f'no prepared resources in {resources}')
out = Path(args.out)
@@ -108,7 +113,7 @@ def main():
(version / '.local/horizon-client').mkdir(parents=True)
for name in ['horizon-client', 'horizon-ctl']:
os.symlink(bins / name, version / name)
os.symlink(resources, version / '.local/horizon-client/26.3')
os.symlink(resources, version / '.local/horizon-client' / lab.VERSION)
(version / '.installed').write_text('')
env = dict(os.environ, HORIZON_LAUNCHER_HOME=str(work / 'launcher'), HORIZON_HOME=str(work / 'home'),
HORIZON_NO_AUDIO='1')
+8 -3
View File
@@ -15,6 +15,11 @@ import subprocess
import tarfile
from pathlib import Path
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parent.parent
LOCAL = ROOT / '.local'
# Inputs of the exporters, not read by the game at runtime.
@@ -31,7 +36,7 @@ if [ "$1" = "--install" ]; then
[Desktop Entry]
Type=Application
Name=Horizon
Comment=Minecraft Java Edition 26.3 in Rust
Comment=Minecraft Java Edition @MINECRAFT@ in Rust
Exec="$here/horizon.sh"
Icon=$here/horizon.png
Terminal=false
@@ -73,7 +78,7 @@ def add_bytes(tar, name, data, mode=0o644):
def main():
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('--binary', type=Path, help='built horizon-client (default: cargo release target)')
parser.add_argument('--resources', type=Path, default=LOCAL / 'horizon-client/26.3')
parser.add_argument('--resources', type=Path, default=lab.RESOURCES)
parser.add_argument('--out', type=Path, default=LOCAL / 'dist')
args = parser.parse_args()
@@ -107,7 +112,7 @@ def main():
ctl = args.binary.with_name('horizon-ctl') # built with --bins: scripts and agents play through it
if ctl.is_file():
tar.add(ctl, 'horizon/horizon-ctl')
add_bytes(tar, 'horizon/horizon.sh', LAUNCHER.encode(), 0o755)
add_bytes(tar, 'horizon/horizon.sh', LAUNCHER.replace('@MINECRAFT@', lab.VERSION).encode(), 0o755)
tar.add(ROOT / 'docs/media/icon-256.png', 'horizon/horizon.png')
add_bytes(tar, 'horizon/README.txt', README.format(version=version, commit=commit, platform=plat).encode())
for path in sorted(args.resources.iterdir()):
+7 -6
View File
@@ -63,7 +63,7 @@ except ImportError:
ROOT = lab.ROOT
WORK = ROOT / ".local/perf-bench"
VANILLA = ROOT / ".local/minecraft/26.3"
VANILLA = lab.GAME
SEED = 1234
WORLD = "PerfBench"
# (name, from xyz, to xyz, pitch): straight 192-block flights over fixed
@@ -81,7 +81,7 @@ SCENES = [
# minimized turns off the 30 FPS limit both games apply after a minute without
# input. Everything not listed stays at vanilla's default.
OPTIONS = {
"version": "5023",
"version": "{data_version}",
"graphicsPreset": '"custom"',
"renderDistance": "{distance}",
"simulationDistance": "12",
@@ -249,8 +249,9 @@ def nvidia_memory_mb(pid):
def write_options(game_dir, distance, version=None):
game_dir.mkdir(parents=True, exist_ok=True)
data_version = lab.version_info()["world_version"]
options = dict(OPTIONS, version=version) if version else OPTIONS
text = "".join(f"{k}:{v.format(distance=distance)}\n" for k, v in options.items())
text = "".join(f"{k}:{v.format(distance=distance, data_version=data_version)}\n" for k, v in options.items())
(game_dir / "options.txt").write_text(text)
return text
@@ -543,7 +544,7 @@ def run_vanilla(args, distance):
"-cp", os.pathsep.join(map(str, game_jars + fabric)),
"net.fabricmc.loader.impl.launch.knot.KnotClient",
"--username", "Bench", "--uuid", "00000000000000000000000000000000", "--accessToken", "0",
"--offlineDeveloperMode", "--version", "26.3", "--gameDir", str(game_dir),
"--offlineDeveloperMode", "--version", lab.VERSION, "--gameDir", str(game_dir),
"--assetsDir", str(assets), "--assetIndex", manifest["assetIndex"]["id"],
"--width", str(args.width), "--height", str(args.height)]
env = dict(os.environ, ALSOFT_DRIVERS="null")
@@ -784,7 +785,7 @@ def main():
p.add_argument("--heap", default="2G", help="vanilla -Xmx (the official launcher's default is 2G)")
p.add_argument("--offscreen", action="store_true",
help="Horizon renders into a texture and does not wait for the window (locked macOS sessions)")
p.add_argument("--resources", default=str(ROOT / ".local/horizon-client/26.3"))
p.add_argument("--resources", default=str(lab.RESOURCES))
p.add_argument("--build", default=str(ROOT / "target/release"))
p.add_argument("--repeats", type=int, default=3, help="games per render distance; the report gives means and 95%% CIs")
p.add_argument("--port-work", help="horizon: also load the mods carried over in this horizon-port-pack work folder")
@@ -830,7 +831,7 @@ def app(args):
mods = [{"name": "fabric-loader", "version": lock["fabric_loader"]}]
if args.game == "vanilla-mods":
mods += [{"name": n, "version": lock["projects"][n]["version"]} for n in PERF_MODS]
return {"name": "minecraft", "version": "26.3", "mods": mods}
return {"name": "minecraft", "version": lab.VERSION, "mods": mods}
if __name__ == "__main__":
+1 -1
View File
@@ -261,7 +261,7 @@ def main():
libraries = baking.client_libraries()
build = lab.LOCAL / 'rust-block-entity-anim-parity'
build.mkdir(parents=True, exist_ok=True)
resources = lab.LOCAL / 'horizon-client' / '26.3'
resources = lab.RESOURCES
chosen = [c for c in cases() if args.filter in c['name']]
inputs = build / 'inputs.jsonl'
inputs.write_text(''.join(json.dumps(c) + '\n' for c in chosen))
+1 -1
View File
@@ -285,7 +285,7 @@ def main():
lock, jars, _ = base.verify_artifacts()
libraries = baking.client_libraries()
build = lab.LOCAL / 'rust-block-entity-render-parity'; build.mkdir(parents=True, exist_ok=True)
resources = lab.LOCAL / 'horizon-client' / '26.3'
resources = lab.RESOURCES
chosen = [c for c in cases() if args.filter in c['block']]
inputs = build / 'inputs.jsonl'; inputs.write_text(''.join(json.dumps(c) + '\n' for c in chosen))
classes = build / 'classes'; classes.mkdir(exist_ok=True)
+1 -1
View File
@@ -10,7 +10,7 @@ except ImportError:
def main():
lock, jars, _ = base.verify_artifacts()
resources = lab.LOCAL / "horizon-client/26.3"
resources = lab.RESOURCES
build = lab.LOCAL / "block-particles-parity"
build.mkdir(exist_ok=True)
paths = [lab.ROOT / p for p in ["tools/test_block_particles_parity.py", "tools/test_breaking_model_parity.py", "tools/oracle_harness.py", "tools/lab.py", "crates/horizon-client/src/particles.rs", "crates/horizon-client/src/game.rs", "crates/horizon-client/src/blocks.rs", "crates/horizon-client/src/mesher.rs", "crates/horizon-client/examples/block_particles_fixture.rs", "mods/horizon/src/test/java/dev/horizonlab/parity/VanillaBlockParticlesOracle.java", "crates/horizon-core/src/random.rs", "Cargo.lock", "mods/horizon/src/test/java/dev/horizonlab/parity/VanillaGameplayFactsExporter.java"]]
+1 -1
View File
@@ -28,7 +28,7 @@ def canonical(quads):
def main():
lock,jars,_=base.verify_artifacts();libraries=baking.client_libraries()
resources=lab.LOCAL/"horizon-client/26.3";build=lab.LOCAL/"breaking-model-parity";build.mkdir(exist_ok=True)
resources=lab.RESOURCES;build=lab.LOCAL/"breaking-model-parity";build.mkdir(exist_ok=True)
paths=[lab.ROOT/"tools/test_breaking_model_parity.py",lab.ROOT/"crates/horizon-client/src/breaking.rs",lab.ROOT/"crates/horizon-client/src/game.rs",lab.ROOT/"crates/horizon-client/src/gfx.rs",lab.ROOT/"crates/horizon-client/src/entity.wgsl",lab.ROOT/"crates/horizon-client/src/models/catalog.rs",lab.ROOT/"crates/horizon-client/src/mesher.rs",lab.ROOT/"crates/horizon-client/src/camera.rs",lab.ROOT/"crates/horizon-client/examples/breaking_fixture.rs",lab.ROOT/"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaBreakingModelOracle.java",lab.ROOT/"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaSectionMeshOracle.java",lab.ROOT/"Cargo.lock"]
tested=base.source_hashes(paths)
rows=[dict(case=i,**row) for i,row in enumerate(cases(resources))]
+1 -1
View File
@@ -40,7 +40,7 @@ SEEDS = [12345, -7046029254386353131, 987654321987, 4242, -1, 0x5DEECE66D, 20260
REGRESSIONS = [
(-1860902098141295193, 'the_nether', '-1,6,3,9', 'bastion_remnant across 20 chunks (#249)'),
]
RESOURCES = lab.LOCAL / 'horizon-client/26.3'
RESOURCES = lab.RESOURCES
ORACLE = lab.ROOT / 'mods/horizon/src/test/java/dev/horizonlab/parity/VanillaChunkGenerationOracle.java'
+6 -1
View File
@@ -10,6 +10,11 @@ import re
import shutil
import sys
try:
from . import lab
except ImportError:
import lab
try:
from . import build_mod, build_pack
from .test_culling_rays import FixtureTimeout, run_fixture
@@ -179,7 +184,7 @@ def main():
print(json.dumps(report), flush=True)
output = root / 'dist/client-graphics-smoke.json'
output.write_text(json.dumps({'schema': 1, 'platform': platform.platform(),
'architecture': platform.machine(), 'minecraft': '26.3',
'architecture': platform.machine(), 'minecraft': lab.VERSION,
'original_mod_sha256': original_hash, 'results': results,
'limits': ['Short scene startup and nonuniform framebuffer readback only.',
'World mode uses the ordinary limited demo; world files remain private.',
+1 -1
View File
@@ -83,7 +83,7 @@ def main():
shutil.rmtree(rust_dir, ignore_errors=True)
rust_dir.mkdir()
env = dict(os.environ, HORIZON_NO_AUDIO='1', HORIZON_COMMAND_SCRIPT=str(script_path), HORIZON_COMMAND_OUTPUT=str(build / 'rust.jsonl'))
run([binary, '--resources', lab.LOCAL / 'horizon-client/26.3', '--world', 'harness', '--seed', SEED, '--radius', 4], 'rust', cwd=rust_dir, env=env)
run([binary, '--resources', lab.RESOURCES, '--world', 'harness', '--seed', SEED, '--radius', 4], 'rust', cwd=rust_dir, env=env)
vanilla = [json.loads(l) for l in (build / 'vanilla.jsonl').open(encoding='utf-8')]
rust = [json.loads(l) for l in (build / 'rust.jsonl').open(encoding='utf-8')]
+1 -1
View File
@@ -67,7 +67,7 @@ def main():
run(['cargo', 'build', '--release', '-p', 'horizon-client', '--example', 'command_parse_fixture'], 'compile-rust')
metadata = json.loads(subprocess.check_output(['cargo', 'metadata', '--no-deps', '--format-version', '1'], cwd=lab.ROOT, text=True))
binary = Path(metadata['target_directory']) / 'release/examples' / ('command_parse_fixture.exe' if os.name == 'nt' else 'command_parse_fixture')
resources = lab.LOCAL / 'horizon-client/26.3'
resources = lab.RESOURCES
total_failures = 0
summary = []
for permission in args.permission:
+6 -1
View File
@@ -9,6 +9,11 @@ import shutil
import subprocess
import sys
try:
from . import lab
except ImportError:
import lab
try:
from . import build_mod, build_pack
except ImportError:
@@ -50,7 +55,7 @@ def main():
raise AssertionError("Empty shortcut did not apply to actual methods")
output = root / "dist/culling-empty-integration.json"
output.write_text(json.dumps({"schema": 1, "platform": platform.platform(), "architecture": platform.machine(),
"minecraft": "26.3", "entity_culling": "1.11.2", "results": results,
"minecraft": lab.VERSION, "entity_culling": "1.11.2", "results": results,
"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.",
+6 -1
View File
@@ -11,6 +11,11 @@ import signal
import subprocess
import sys
try:
from . import lab
except ImportError:
import lab
try:
from . import build_mod, build_pack
except ImportError:
@@ -86,7 +91,7 @@ def main():
raise AssertionError(f"Scratch redirect changed upstream geometry: {key}")
output = root / "dist/culling-rays-integration.json"
output.write_text(json.dumps({"schema": 1, "platform": platform.platform(), "architecture": platform.machine(),
"minecraft": "26.3", "entity_culling": "1.11.2", "original_mod_sha256": original_sha256, "results": results,
"minecraft": lab.VERSION, "entity_culling": "1.11.2", "original_mod_sha256": original_sha256, "results": results,
"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.",
+2 -2
View File
@@ -342,7 +342,7 @@ def horizon_client_joins(vanilla_server, binary, world, build, reference):
server.wait_for(r'Done \(')
env = dict(os.environ, HORIZON_NO_AUDIO='1', HORIZON_NET_REPORT=str(report))
with (build / 'horizon-client-run.log').open('w') as log:
subprocess.run([str(c) for c in [binary, '--resources', lab.LOCAL / 'horizon-client/26.3', '--render-distance', 2,
subprocess.run([str(c) for c in [binary, '--resources', lab.RESOURCES, '--render-distance', 2,
'--server', f'127.0.0.1:{port}', '--name', PLAYER]],
cwd=client_dir, env=env, stdout=log, stderr=subprocess.STDOUT, timeout=300, check=True)
server.wait_for(r'left the game', timeout=30)
@@ -394,7 +394,7 @@ def main():
cwd=lab.ROOT, text=True))
binary = Path(metadata['target_directory']) / 'release' / ('horizon-client.exe' if os.name == 'nt' else 'horizon-client')
vanilla_server = ['java', '-Xmx2g', '-Duser.timezone=UTC', '-cp', dependencies, 'net.minecraft.server.Main', 'nogui']
horizon_server = [binary, '--resources', lab.LOCAL / 'horizon-client/26.3', '--dedicated', '--nogui']
horizon_server = [binary, '--resources', lab.RESOURCES, '--dedicated', '--nogui']
# The world, generated once by vanilla.
generate = build / 'generate'
+6 -1
View File
@@ -11,6 +11,11 @@ import shutil
import subprocess
import sys
try:
from . import lab
except ImportError:
import lab
try:
from . import build_mod, build_pack
from .test_culling_rays import run_fixture
@@ -69,7 +74,7 @@ def main():
print(json.dumps(report), flush=True)
output = root / "dist/dispatch-integration.json"
output.write_text(json.dumps({"schema": 1, "platform": platform.platform(), "architecture": platform.machine(),
"minecraft": "26.3", "distant_horizons": "3.3.4", "results": results,
"minecraft": lab.VERSION, "distant_horizons": "3.3.4", "results": results,
"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.",
+1 -1
View File
@@ -38,7 +38,7 @@ def main():
if args.prepare:
lab.prepare()
lock, jars, libraries = base.verify_artifacts()
resources = lab.LOCAL / 'horizon-client/26.3'
resources = lab.RESOURCES
catalog = json.loads((resources / 'items.json').read_text())
items = sorted(k for k, v in catalog.items() if 'minecraft:enchantable' in v)
oracle = lab.ROOT / 'mods/horizon/src/test/java/dev/horizonlab/parity/VanillaEnchantingOracle.java'
+2 -2
View File
@@ -19,7 +19,7 @@ SPECIES = ('wolf', 'cat', 'frog', 'pig', 'cow', 'chicken')
def predicates():
"""Every criterion's entity predicate, plus the components alone and
with the wrong type."""
folder = lab.LOCAL / 'horizon-client/26.3/data/minecraft/advancement/husbandry'
folder = lab.RESOURCES / 'data/minecraft/advancement/husbandry'
out = []
for name in ADVANCEMENTS:
data = json.loads((folder / f'{name}.json').read_text())
@@ -33,7 +33,7 @@ def predicates():
def variants(species):
folder = lab.LOCAL / f'horizon-client/26.3/data/minecraft/{species}_variant'
folder = lab.RESOURCES / f'data/minecraft/{species}_variant'
return sorted('minecraft:' + p.stem for p in folder.glob('*.json'))
+1 -1
View File
@@ -118,7 +118,7 @@ def main():
if args.prepare:
lab.prepare()
lock, jars, libraries = base.verify_artifacts()
resources = lab.LOCAL / 'horizon-client/26.3'
resources = lab.RESOURCES
tables = resources / 'data/minecraft/loot_table/entities'
types = sorted('minecraft:' + p.stem for p in tables.glob('*.json') if p.stem not in SKIPPED)
oracle = lab.ROOT / 'mods/horizon/src/test/java/dev/horizonlab/parity/VanillaEntityDeathLootOracle.java'
+2 -2
View File
@@ -36,7 +36,7 @@ try:
except ImportError:
import lab, test_rust_parity as base, test_model_baking_parity as baking
CLIENT = lab.LOCAL / 'minecraft' / '26.3' / 'sources' / 'client' / 'net' / 'minecraft' / 'client'
CLIENT = lab.GAME / 'sources' / 'client' / 'net' / 'minecraft' / 'client'
# Models that no renderer builds with a plain `new Model(context.bakeLayer(CONSTANT))`.
EXTRAS = [
@@ -341,7 +341,7 @@ def main():
lock, jars, _ = base.verify_artifacts()
libraries = baking.client_libraries()
build = lab.LOCAL / 'rust-entity-model-parity'; build.mkdir(parents=True, exist_ok=True)
resources = lab.LOCAL / 'horizon-client' / '26.3'
resources = lab.RESOURCES
models = json.loads((resources / 'entity-models.json').read_text())
chosen = {k: v for k, v in layers(models).items() if args.filter in k}
extra_cases = json.loads((Path(__file__).with_suffix('.cases.json')).read_text()) \
+1 -1
View File
@@ -51,7 +51,7 @@ def main():
args = parser.parse_args()
lock, jars, libraries = base.verify_artifacts()
build = lab.LOCAL / 'rust-environment-parity'; build.mkdir(parents=True, exist_ok=True)
resources = lab.LOCAL / 'horizon-client' / '26.3'
resources = lab.RESOURCES
inputs = build / 'inputs.txt'; inputs.write_text('\n'.join(cases(resources)) + '\n')
classes = build / 'classes'; classes.mkdir(exist_ok=True)
oracle = lab.ROOT / 'mods/horizon/src/test/java/dev/horizonlab/parity/VanillaEnvironmentOracle.java'
+1 -1
View File
@@ -116,7 +116,7 @@ def main():
if args.prepare:
lab.prepare()
lock, jars, libraries = base.verify_artifacts()
resources = lab.LOCAL / 'horizon-client/26.3'
resources = lab.RESOURCES
oracle = lab.ROOT / 'mods/horizon/src/test/java/dev/horizonlab/parity/VanillaFinalizeSpawnOracle.java'
sources = [oracle, Path(__file__), lab.ROOT / 'crates/horizon-client/examples/finalize_spawn_fixture.rs',
lab.ROOT / 'crates/horizon-client/src/mobs/finalize.rs']
+6 -1
View File
@@ -31,6 +31,11 @@ import tempfile
import time
import urllib.request
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parents[1]
@@ -330,7 +335,7 @@ def main():
parser.add_argument('--client', type=Path, required=True)
parser.add_argument('--relay', type=Path, help='horizon-relay binary (started on a free local port)')
parser.add_argument('--relay-url', help='--role: a relay already running elsewhere, HOST:PORT')
parser.add_argument('--resources', type=Path, default=ROOT / '.local/horizon-client/26.3')
parser.add_argument('--resources', type=Path, default=lab.RESOURCES)
parser.add_argument('--role', choices=['host', 'guest'])
parser.add_argument('--code')
parser.add_argument('--path', choices=['relay', 'direct'])
+1 -1
View File
@@ -99,7 +99,7 @@ def main():
lock, jars, _ = base.verify_artifacts()
libraries = baking.client_libraries()
build = lab.LOCAL / 'rust-hud-parity'; build.mkdir(parents=True, exist_ok=True)
resources = lab.LOCAL / 'horizon-client' / '26.3'
resources = lab.RESOURCES
chosen = cases(args.count, kinds)
inputs = build / 'inputs.jsonl'; inputs.write_text(''.join(json.dumps(c) + '\n' for c in chosen))
classes = build / 'classes'; classes.mkdir(exist_ok=True)
+6 -1
View File
@@ -16,6 +16,11 @@ import subprocess
import tempfile
import time
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parents[1]
GROUP = '224.0.2.60'
DISCOVERY_PORT = 4445
@@ -145,7 +150,7 @@ def guest_names(endpoint, port, guests):
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--client', type=Path, required=True)
parser.add_argument('--resources', type=Path, default=ROOT / '.local/horizon-client/26.3')
parser.add_argument('--resources', type=Path, default=lab.RESOURCES)
args = parser.parse_args()
client, resources = args.client.resolve(), args.resources.resolve()
with tempfile.TemporaryDirectory(prefix='horizon-lan-') as directory:
+7 -2
View File
@@ -16,10 +16,15 @@ import subprocess
import sys
from pathlib import Path
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parent.parent
LOCAL = ROOT / '.local'
RESOURCES = LOCAL / 'horizon-client' / '26.3'
SERVER = LOCAL / 'minecraft' / '26.3' / 'jars' / 'server.jar'
RESOURCES = lab.RESOURCES
SERVER = lab.GAME / 'jars' / 'server.jar'
# Absolute coordinates well above the terrain, inside force-loaded chunks.
SCENE = [
+1 -1
View File
@@ -26,7 +26,7 @@ def size(png):
def make_input(build):
root = oh.lab.LOCAL / 'horizon-client' / '26.3'
root = oh.lab.RESOURCES
textures = root / 'assets/minecraft/textures'
names = []
for folder, every in (('block', 1), ('item', 7)):
+1 -1
View File
@@ -469,7 +469,7 @@ def main():
CARGO_PROFILE_RELEASE_LTO='false', CARGO_PROFILE_RELEASE_CODEGEN_UNITS='16')
oracle_harness.run_logged(command, build, 'compile-rust', env=env)
binary = target / 'release/examples/mob_ai_probe'
oracle_harness.run_logged([binary, lab.ROOT / '.local/horizon-client/26.3', inputs, build / 'horizon.txt'], build, 'horizon')
oracle_harness.run_logged([binary, lab.RESOURCES, inputs, build / 'horizon.txt'], build, 'horizon')
if args.java_only:
return
names = {s[0] for _, s in chosen}
+1 -1
View File
@@ -64,7 +64,7 @@ def main():
run(['java', '-Xmx1G', '-cp', os.pathsep.join([str(classes), str(jars['server']), deps]), 'dev.horizonlab.parity.VanillaMobAttributesOracle', build / 'vanilla.txt'], 'java')
run(['cargo', 'build', '--release', '-p', 'horizon-client', '--example', 'mob_attributes_fixture'], 'compile-rust')
binary = lab.cargo_target() / 'release/examples/mob_attributes_fixture'
resources = lab.ROOT / '.local/horizon-client/26.3'
resources = lab.RESOURCES
run([binary, resources, build / 'rust.txt'], 'rust')
vanilla, rust = parse(build / 'vanilla.txt'), parse(build / 'rust.txt')
problems = []
+4 -4
View File
@@ -43,7 +43,7 @@ def main():
root.mkdir(parents=True, exist_ok=True)
report = root / 'startup-smoke.json'
report.unlink(missing_ok=True)
resources = resource_fingerprint(root / '26.3')
resources = resource_fingerprint(root / lab.VERSION)
sources = [lab.ROOT / 'Cargo.toml', lab.ROOT / 'Cargo.lock', Path(__file__).resolve(),
lab.ROOT / 'crates/horizon-client/Cargo.toml', lab.ROOT / 'crates/horizon-assets/Cargo.toml',
*sorted((lab.ROOT / 'crates/horizon-client/src').rglob('*')),
@@ -91,7 +91,7 @@ def main():
'-d', str(classes), str(oracle), str(helper), str(heightmap)], cwd=lab.ROOT, check=True,
stdout=log, stderr=subprocess.STDOUT, timeout=3600)
subprocess.run(['java', '-Xmx512M', '-cp', str(classes)+os.pathsep+dependencies,
'dev.horizonlab.parity.VanillaGallerySelectionOracle', str(report), str(native), str(root/'26.3')],
'dev.horizonlab.parity.VanillaGallerySelectionOracle', str(report), str(native), str(root / lab.VERSION)],
cwd=lab.ROOT, check=True, stdout=log, stderr=subprocess.STDOUT, timeout=3600)
native_result = json.loads(native.read_text())
selections = native_result['gallery']
@@ -103,12 +103,12 @@ def main():
'client_jar_sha256': lab.digest(jars['client'], 'sha256'),
'output_sha256': lab.digest(native, 'sha256'),
'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.'}
if resource_fingerprint(root / '26.3') != resources:
if resource_fingerprint(root / lab.VERSION) != resources:
raise RuntimeError('Resources changed during native client verification')
result['resource_files'] = resources
result['executable_sha256'] = lab.digest(executable, 'sha256')
result['resource_manifest_sha256'] = lab.digest(
root / '26.3/horizon-resources.json', 'sha256')
root / lab.VERSION / 'horizon-resources.json', 'sha256')
actual_sources = {str(path.relative_to(lab.ROOT)): lab.digest(path, 'sha256') for path in sources if path.is_file()}
if actual_sources != tested_sources:
raise RuntimeError('Sources changed during native client verification')
+1 -1
View File
@@ -548,7 +548,7 @@ def main():
if args.prepare:
lab.prepare()
lock, jars, libraries = base.verify_artifacts()
resources = lab.LOCAL / 'horizon-client/26.3'
resources = lab.RESOURCES
oracle = lab.ROOT / 'mods/horizon/src/test/java/dev/horizonlab/parity/VanillaNaturalSpawnOracle.java'
sources = [oracle, Path(__file__), lab.ROOT / 'crates/horizon-client/examples/natural_spawn_fixture.rs',
lab.ROOT / 'crates/horizon-client/src/mobs/spawn_selection.rs',
+1 -1
View File
@@ -180,7 +180,7 @@ def run_client(binary, build, port, label, token, discovery):
directory.mkdir()
report = directory / 'report.json'
env = dict(os.environ, HORIZON_NO_AUDIO='1', HORIZON_NET_REPORT=str(report), HORIZON_API_DISCOVERY=discovery)
command = [binary, '--resources', lab.LOCAL / 'horizon-client/26.3', '--render-distance', 2,
command = [binary, '--resources', lab.RESOURCES, '--render-distance', 2,
'--server', f'127.0.0.1:{port}', '--name', PLAYER]
if token:
command += ['--session-file', session_file(directory, token)]
+6 -1
View File
@@ -10,6 +10,11 @@ import shutil
import subprocess
import sys
try:
from . import lab
except ImportError:
import lab
try:
from . import build_mod, build_pack
except ImportError:
@@ -59,7 +64,7 @@ def main():
raise AssertionError(f"Quad reuse changed upstream geometry: {key}")
output = root / "dist/quad-reuse-integration.json"
output.write_text(json.dumps({"schema": 1, "platform": platform.platform(), "architecture": platform.machine(),
"minecraft": "26.3", "distant_horizons": "3.3.4", "original_mod_sha256": original_sha256, "results": results,
"minecraft": lab.VERSION, "distant_horizons": "3.3.4", "original_mod_sha256": original_sha256, "results": results,
"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.",
+6 -1
View File
@@ -11,6 +11,11 @@ import subprocess
import sys
import zipfile
try:
from . import lab
except ImportError:
import lab
try:
from . import build_mod, build_pack
from .test_culling_rays import run_fixture
@@ -79,7 +84,7 @@ def main():
"additional_builder_and_scratch_bytes": candidate["builder_shallow_bytes"] - control["builder_shallow_bytes"] + candidate["pending_scratch_shallow_bytes"]})
output = root / "dist/quad-size-integration.json"
output.write_text(json.dumps({"schema": 1, "platform": platform.platform(), "architecture": platform.machine(),
"minecraft": "26.3", "distant_horizons": "3.3.4", "original_mod_sha256": mod_hash,
"minecraft": lab.VERSION, "distant_horizons": "3.3.4", "original_mod_sha256": mod_hash,
"results": results, "differences": differences,
"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.",
+1 -1
View File
@@ -314,7 +314,7 @@ def main():
if args.prepare:
lab.prepare()
lock, jars, libraries = base.verify_artifacts()
resources = lab.LOCAL / 'horizon-client/26.3'
resources = lab.RESOURCES
oracle = lab.ROOT / 'mods/horizon/src/test/java/dev/horizonlab/parity/VanillaRaidOracle.java'
sources = [oracle, Path(__file__), lab.ROOT / 'crates/horizon-client/examples/raid_fixture.rs',
lab.ROOT / 'crates/horizon-client/src/raid.rs', lab.ROOT / 'crates/horizon-client/src/patrol.rs']
+1 -1
View File
@@ -119,7 +119,7 @@ def main():
def make(build, selection=selection):
folder = build / "resourcepacks"
packs(folder)
vanilla = lab.LOCAL / "horizon-client" / "26.3"
vanilla = lab.RESOURCES
path = build / "inputs.txt"
path.write_text(f"root {vanilla} {folder} {' '.join(selection)}".rstrip() + "\n"
+ "".join(q + "\n" for q in QUERIES))
+7 -2
View File
@@ -41,10 +41,15 @@ sys.path.insert(0, str(Path(__file__).resolve().parent))
import anvil_dump # noqa: E402
import save_roundtrip_scene as scene # noqa: E402
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parent.parent
LOCAL = ROOT / '.local'
RESOURCES = LOCAL / 'horizon-client' / '26.3'
SERVER = LOCAL / 'minecraft' / '26.3' / 'jars' / 'server.jar'
RESOURCES = lab.RESOURCES
SERVER = lab.GAME / 'jars' / 'server.jar'
RUN = LOCAL / 'save-roundtrip' / 'run'
# Game rules Horizon's player changes before saving: rule -> (vanilla's value, Horizon's).
+1 -1
View File
@@ -29,7 +29,7 @@ except ImportError:
import test_model_baking_parity as baking
BUILD = lab.ROOT / 'target/section-mesh-parity'
RESOURCES = lab.LOCAL / 'horizon-client' / '26.3'
RESOURCES = lab.RESOURCES
SECTION_Y = 0
COLORS = {'grass': 0x91BD59, 'foliage': 0x77AB2F, 'dry_foliage': 0xA88B5E, 'water': 0x3F76E4}
POSITION_TOLERANCE = 1e-4
+6 -1
View File
@@ -8,6 +8,11 @@ import platform
import shutil
import sys
try:
from . import lab
except ImportError:
import lab
try:
from . import build_mod, build_pack
from .test_culling_rays import run_fixture
@@ -57,7 +62,7 @@ def main():
if not (instance / 'saves/Demo_World/level.dat').is_file():
raise AssertionError('Disposable world was not saved')
report = {'schema': 1, 'platform': platform.platform(), 'architecture': platform.machine(),
'minecraft': '26.3', 'original_mod_sha256': digest, 'launcher_exit_code': run.returncode,
'minecraft': lab.VERSION, 'original_mod_sha256': digest, 'launcher_exit_code': run.returncode,
'requested_backend': args.backend or 'pack_default', 'result': result, 'limits': ['Short report-context check, not FPS or physical M2 performance.',
'Graphics context is captured at recording start, not continuously monitored.',
'World files and full logs remain private.']}
+1 -1
View File
@@ -134,7 +134,7 @@ def main():
if args.prepare:
lab.prepare()
lock, jars, libraries = base.verify_artifacts()
resources = lab.LOCAL / 'horizon-client/26.3'
resources = lab.RESOURCES
entity_types = json.loads((resources / 'entity-types.json').read_text())
types = sorted(t for t, v in entity_types.items() if 'attributes' in v and t.split(':')[1] not in SKIPPED)
oracle = lab.ROOT / 'mods/horizon/src/test/java/dev/horizonlab/parity/VanillaSpawnRulesOracle.java'
+1 -1
View File
@@ -228,7 +228,7 @@ def main():
if args.prepare:
lab.prepare()
lock, jars, libraries = base.verify_artifacts()
resources = lab.LOCAL / 'horizon-client/26.3'
resources = lab.RESOURCES
oracle = lab.ROOT / 'mods/horizon/src/test/java/dev/horizonlab/parity/VanillaNaturalSpawnOracle.java'
sources = [oracle, Path(__file__), lab.ROOT / 'crates/horizon-client/examples/natural_spawn_fixture.rs',
lab.ROOT / 'crates/horizon-client/src/mobs/spawner.rs',
+1 -1
View File
@@ -112,7 +112,7 @@ def main():
args = parser.parse_args()
lock, jars, _ = base.verify_artifacts()
libraries = baking.client_libraries()
resources = lab.LOCAL / 'horizon-client' / '26.3'
resources = lab.RESOURCES
build = lab.LOCAL / 'subtitle-parity'
build.mkdir(parents=True, exist_ok=True)
classes = build / 'classes'
+1 -1
View File
@@ -226,7 +226,7 @@ def main():
lock, jars, _ = base.verify_artifacts()
libraries = baking.client_libraries()
build = lab.LOCAL / 'rust-tab-list-parity'; build.mkdir(parents=True, exist_ok=True)
resources = lab.LOCAL / 'horizon-client' / '26.3'
resources = lab.RESOURCES
chosen = cases(args.count)
inputs = build / 'inputs.jsonl'; inputs.write_text(''.join(json.dumps(c) + '\n' for c in chosen))
classes = build / 'classes'; classes.mkdir(exist_ok=True)
+6 -1
View File
@@ -10,6 +10,11 @@ import shutil
import subprocess
import sys
try:
from . import lab
except ImportError:
import lab
try:
from . import build_mod, build_pack
except ImportError:
@@ -59,7 +64,7 @@ def main():
raise AssertionError(f"Position redirect changed upstream lookup: {key}")
output = root / "dist/terrain-position-integration.json"
output.write_text(json.dumps({"schema": 1, "platform": platform.platform(), "architecture": platform.machine(),
"minecraft": "26.3", "distant_horizons": "3.3.4", "original_mod_sha256": original_sha256, "results": results,
"minecraft": lab.VERSION, "distant_horizons": "3.3.4", "original_mod_sha256": original_sha256, "results": results,
"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.",
+6 -1
View File
@@ -10,6 +10,11 @@ import shutil
import subprocess
import sys
try:
from . import lab
except ImportError:
import lab
try:
from . import build_mod, build_pack
except ImportError:
@@ -54,7 +59,7 @@ def main():
print(json.dumps(report), flush=True)
output = root / "dist/terrain-read-integration.json"
output.write_text(json.dumps({"schema": 1, "platform": platform.platform(), "architecture": platform.machine(),
"minecraft": "26.3", "distant_horizons": "3.3.4", "original_mod_sha256": original_sha256, "results": results,
"minecraft": lab.VERSION, "distant_horizons": "3.3.4", "original_mod_sha256": original_sha256, "results": results,
"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.",
+6 -1
View File
@@ -9,6 +9,11 @@ import shutil
import subprocess
import sys
try:
from . import lab
except ImportError:
import lab
try:
from . import build_mod, build_pack
except ImportError:
@@ -50,7 +55,7 @@ def main():
raise AssertionError("Membership hook did not remove repeated entry allocation")
output = root / "dist/tick-dedup-integration.json"
output.write_text(json.dumps({"schema": 1, "platform": platform.platform(), "architecture": platform.machine(),
"minecraft": "26.3", "distant_horizons": "3.3.4", "results": results,
"minecraft": lab.VERSION, "distant_horizons": "3.3.4", "results": results,
"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.",
+1 -1
View File
@@ -182,7 +182,7 @@ def main():
if args.prepare:
lab.prepare()
lock, jars, libraries = base.verify_artifacts()
resources = lab.LOCAL / 'horizon-client/26.3'
resources = lab.RESOURCES
oracle = lab.ROOT / 'mods/horizon/src/test/java/dev/horizonlab/parity/VanillaTradingOracle.java'
sources = [oracle, Path(__file__), lab.ROOT / 'crates/horizon-client/examples/trading_fixture.rs',
lab.ROOT / 'crates/horizon-client/src/merchant.rs', lab.ROOT / 'crates/horizon-client/src/menu.rs']
+1 -1
View File
@@ -192,7 +192,7 @@ def main():
if args.prepare:
lab.prepare()
lock, jars, libraries = base.verify_artifacts()
resources = lab.LOCAL / 'horizon-client/26.3'
resources = lab.RESOURCES
oracle = lab.ROOT / 'mods/horizon/src/test/java/dev/horizonlab/parity/VanillaNaturalSpawnOracle.java'
sources = [oracle, Path(__file__), lab.ROOT / 'crates/horizon-client/examples/natural_spawn_fixture.rs',
lab.ROOT / 'crates/horizon-client/src/mobs/trial_spawner.rs',
+1 -1
View File
@@ -56,7 +56,7 @@ NAME = 'world-spawn-parity'
REPORT = 1891623539983467248
RETRIES = 3
SEEDS = [REPORT, 12345, -7046029254386353131, 987654321987, 4242, -1, 0x5DEECE66D, 20260607, 777, 0]
RESOURCES = lab.LOCAL / 'horizon-client/26.3'
RESOURCES = lab.RESOURCES
def seeds(count):
+6 -1
View File
@@ -15,8 +15,13 @@ import sys
import tempfile
from pathlib import Path
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parent.parent
SERVER = ROOT / '.local' / 'minecraft' / '26.3' / 'jars' / 'server.jar'
SERVER = lab.GAME / 'jars' / 'server.jar'
def free_port():
+8 -3
View File
@@ -23,8 +23,13 @@ import uuid
import zipfile
from pathlib import Path
try:
from . import lab
except ImportError:
import lab
ROOT = Path(__file__).resolve().parents[1]
GAME = ROOT / ".local/minecraft/26.3"
GAME = lab.GAME
MAC = sys.platform == "darwin"
# The natives of this machine's platform, and the shared libraries in them.
NATIVES, LIBRARY_SUFFIX = ("natives-macos-arm64.jar", ".dylib") if MAC else ("natives-linux.jar", ".so")
@@ -124,8 +129,8 @@ def command(args):
"-cp", os.pathsep.join(map(str, jars)), "net.minecraft.client.main.Main",
"--username", args.name, "--uuid", offline_uuid(args.name).hex,
"--accessToken", "0", "--offlineDeveloperMode",
"--version", "26.3", "--gameDir", str(args.game_dir),
"--assetsDir", str(assets), "--assetIndex", "34",
"--version", lab.VERSION, "--gameDir", str(args.game_dir),
"--assetsDir", str(assets), "--assetIndex", json.loads((GAME / "manifest.json").read_text())["assetIndex"]["id"],
"--width", str(args.width), "--height", str(args.height)]
if args.join:
cmd += ["--quickPlayMultiplayer", args.join]
+5 -2
View File
@@ -19,7 +19,10 @@ import time
import uuid
import zlib
PROTOCOL = 777 # 26.3
try:
from . import lab
except ImportError:
import lab
def offline_uuid(name):
@@ -101,7 +104,7 @@ def parse_varint(data, pos):
def join(host, port, name, seconds):
c = Connection(host, port)
c.send(0, varint(PROTOCOL) + string(host) + struct.pack('>H', port) + varint(2))
c.send(0, varint(lab.version_info()['protocol_version']) + string(host) + struct.pack('>H', port) + varint(2))
c.send(0, string(name) + offline_uuid(name).bytes)
# Login: compression, then login finished.
while True: