Port LightEngine.shapeOccludes / getFaceOcclusionShape (occlusion.nbt) so
slabs, stairs, snow layers, paths etc. block light directionally, and use
ChunkSkyLightSources.isEdgeOccluded for sky sources. Block light now rises
into the section above the highest occupied one.
Block edits on lit chunks are relit in place with vanilla's decrease and
increase passes instead of recomputing the 3x3 chunks (and remeshing every
section of them); edits that race a chunk light job are replayed onto it.
examples/light_parity compares Horizon light with the SkyLight/BlockLight
arrays of worlds saved by the vanilla 26.3 server (0 differences on
villages, outposts and a slab/stair/snow scene; 181 of 113M sky values
differ where vanilla's worldgen light is stale) and checks incremental
relighting against full relights. tools/vanilla_world_check.py runs the
vanilla server headless; tools/anvil_dump.py prints NBT and region chunks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>