Files
shacraft-core/scripts/measure_lighting.py
Emil c7e86663d8
MVP checks / mvp (push) Waiting to run
Expand voxel gameplay, lighting, full-height streaming and world imports
Add shared Rust/WASM physics, worker meshing and diagnostics, 64-chunk full-height streaming, atlas texture support, and baseline world import. Document the current implementation and include the supplied in-game lobby screenshot.
2026-09-17 02:10:53 +03:00

89 lines
4.4 KiB
Python

#!/usr/bin/env python3
"""Measure Java 26.2 light properties using the verified local catalog cache."""
from pathlib import Path
import argparse
import hashlib
import json
import os
import subprocess
import zipfile
ROOT = Path(__file__).resolve().parents[1]
SOURCE_SHA1 = "823e2250d24b3ddac457a60c92a6a941943fcd6a"
def digest(path, algorithm="sha256"):
with path.open("rb") as source:
return hashlib.file_digest(source, algorithm).hexdigest()
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--java", type=Path, required=True)
parser.add_argument("--cache", type=Path, default=ROOT / "artifacts/catalog-cache")
parser.add_argument("--output", type=Path, default=ROOT / "artifacts/lighting/reference.json")
parser.add_argument("--runtime-output", type=Path, default=ROOT / "client/light-properties.json")
parser.add_argument("--fixture-output", type=Path, default=ROOT / "client/tests/fixtures/lighting-java26.2.json")
args = parser.parse_args()
cache = args.cache.resolve()
source = cache / "server.jar"
if digest(source, "sha1") != SOURCE_SHA1:
raise SystemExit("The official source JAR does not match pinned Java 26.2")
executable = cache / "versions/26.2/server-26.2.jar"
with zipfile.ZipFile(source) as bundle:
with bundle.open("META-INF/versions/26.2/server-26.2.jar") as embedded:
expected = hashlib.file_digest(embedded, "sha256").hexdigest()
if digest(executable) != expected:
raise SystemExit("The cached executable differs from the verified official bundle")
classpath = os.pathsep.join(map(str, [executable, *sorted((cache / "libraries").rglob("*.jar"))]))
java = args.java.resolve()
script = ROOT / "scripts/lighting_reference.java"
measured = cache / "lighting-measurements.json"
commands = [
[str(java.with_name("javac")), "-cp", classpath, "-d", str(cache), str(script)],
[str(java), "-Xmx1G", "-cp", str(cache) + os.pathsep + classpath, "lighting_reference", str(measured)],
]
with (cache / "lighting-measurements.log").open("w") as log:
for command in commands:
result = subprocess.run(command, cwd=cache, stdout=log, stderr=subprocess.STDOUT)
if result.returncode:
raise SystemExit(f"Reference probe failed. Read {cache / 'lighting-measurements.log'}")
reference = json.loads(measured.read_text())
reference["provenance"] = {
"source_url": f"https://piston-data.mojang.com/v1/objects/{SOURCE_SHA1}/server.jar",
"source_sha1": SOURCE_SHA1,
"source_sha256": digest(source),
"executable_sha256": digest(executable),
"probe_sha256": digest(script),
"command": "python3 scripts/measure_lighting.py --java /path/to/java25/bin/java",
}
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(json.dumps(reference, separators=(",", ":")) + "\n")
print(f"Wrote {args.output}: {len(reference['states'])} states, {len(reference['shapes'])} shapes, {args.output.stat().st_size} bytes")
codes = []
for state in reference["states"]:
state_id, dampening, shape_id = state[:3]
assert state_id == len(codes), "Minecraft state IDs must be contiguous"
assert 0 <= dampening <= 15 and 0 <= shape_id < len(reference["shapes"])
codes.append(dampening + 16 * shape_id)
runtime = {
"version": reference["version"],
"encoding": "codes[minecraft_id] = light_dampening + 16 * occlusion_shape_index; blocks[name] = [first_state_id, default_state_id, schema_index]",
"codes": codes,
"shapes": reference["shapes"],
"blocks": reference["blocks"],
"schemas": reference["schemas"],
"provenance": reference["provenance"],
}
args.runtime_output.parent.mkdir(parents=True, exist_ok=True)
args.runtime_output.write_text(json.dumps(runtime, separators=(",", ":")) + "\n")
print(f"Wrote {args.runtime_output}: {args.runtime_output.stat().st_size} bytes")
fixture = {key: reference[key] for key in ("version", "examples", "crossings", "measurement_scope", "provenance")}
args.fixture_output.parent.mkdir(parents=True, exist_ok=True)
args.fixture_output.write_text(json.dumps(fixture, indent=2) + "\n")
print(f"Wrote {args.fixture_output}: {len(fixture['crossings'])} original directional crossings")
if __name__ == "__main__":
main()