minecraft-renderer 0.1.107 → 0.1.108

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/lightOwnerWorker.js +9 -0
  2. package/dist/lightOwnerWorker.js.map +7 -0
  3. package/dist/mesher.js +1 -1
  4. package/dist/mesher.js.map +2 -2
  5. package/dist/mesherWasm.js +222 -222
  6. package/dist/minecraft-renderer.js +80 -80
  7. package/dist/minecraft-renderer.js.meta.json +1 -1
  8. package/dist/threeWorker.js +513 -513
  9. package/package.json +1 -1
  10. package/src/bundler/bundlePrepare.test.ts +25 -0
  11. package/src/bundler/bundlePrepare.ts +1 -1
  12. package/src/graphicsBackend/appViewer.ts +15 -0
  13. package/src/graphicsBackend/config.ts +5 -0
  14. package/src/graphicsBackend/rendererDefaultOptions.test.ts +51 -0
  15. package/src/graphicsBackend/rendererDefaultOptions.ts +13 -1
  16. package/src/graphicsBackend/rendererOptionsSync.ts +3 -3
  17. package/src/lib/blockEntityLightRegistry.ts +4 -0
  18. package/src/lib/worldrendererCommon.lightOwner.test.ts +916 -0
  19. package/src/lib/worldrendererCommon.removeColumn.test.ts +16 -0
  20. package/src/lib/worldrendererCommon.ts +329 -67
  21. package/src/lighting/cache/rendererLightCache.test.ts +158 -0
  22. package/src/lighting/cache/rendererLightCache.ts +248 -0
  23. package/src/lighting/coordinator/clientLightCoordinator.test.ts +102 -0
  24. package/src/lighting/coordinator/clientLightCoordinator.ts +574 -0
  25. package/src/lighting/debug/clientLightProbe.test.ts +24 -0
  26. package/src/lighting/debug/clientLightProbe.ts +20 -0
  27. package/src/lighting/debug/clientLightTrace.test.ts +271 -0
  28. package/src/lighting/debug/clientLightTrace.ts +335 -0
  29. package/src/lighting/entity/entityLightController.test.ts +216 -0
  30. package/src/lighting/entity/entityLightController.ts +322 -0
  31. package/src/lighting/owner/clientLightOwner.test.ts +467 -0
  32. package/src/lighting/owner/clientLightOwner.ts +523 -0
  33. package/src/lighting/owner/lightOwnerHost.test.ts +78 -0
  34. package/src/lighting/owner/lightOwnerHost.ts +202 -0
  35. package/src/lighting/owner/lightOwnerWorker.ts +154 -0
  36. package/src/lighting/owner/updateLight1171OwnerPath.test.ts +68 -0
  37. package/src/lighting/owner/updateLightToOwnerEvents.ts +49 -0
  38. package/src/lighting/tables/lightTables1171.generated.json +10 -0
  39. package/src/lighting/tables/lightTables1171.test.ts +168 -0
  40. package/src/lighting/tables/lightTables1171.ts +59 -0
  41. package/src/lighting/versioning/clientLightVersions.test.ts +241 -0
  42. package/src/lighting/versioning/clientLightVersions.ts +203 -0
  43. package/src/lighting/versioning/pendingSectionFlush.test.ts +214 -0
  44. package/src/lighting/versioning/pendingSectionFlush.ts +123 -0
  45. package/src/mesher-shared/lightNibblePack.ts +26 -0
  46. package/src/mesher-shared/mcDataWorkerShim.cjs +9 -7
  47. package/src/mesher-shared/modelsGeometryCommon.test.ts +6 -1
  48. package/src/mesher-shared/shared.ts +48 -1
  49. package/src/three/chunkMeshManager.ts +26 -0
  50. package/src/three/entities.ts +77 -11
  51. package/src/three/entity/EntityMesh.ts +1 -0
  52. package/src/three/entity/legWalkAnimation.test.ts +11 -2
  53. package/src/three/entity/legWalkAnimation.ts +1 -9
  54. package/src/three/globalBlockBuffer.ts +94 -2
  55. package/src/three/globalLegacyBuffer.ts +94 -2
  56. package/src/three/graphicsBackendBase.ts +2 -9
  57. package/src/three/tests/globalBlockBuffer.test.ts +98 -0
  58. package/src/three/tests/globalLegacyBuffer.test.ts +108 -0
  59. package/src/three/worldRendererThree.ts +75 -34
  60. package/src/wasm-mesher/bridge/render-from-wasm.ts +46 -1
  61. package/src/wasm-mesher/runtime-build/wasm_mesher.d.ts +31 -5
  62. package/src/wasm-mesher/runtime-build/wasm_mesher.js +180 -5
  63. package/src/wasm-mesher/runtime-build/wasm_mesher_bg.wasm +0 -0
  64. package/src/wasm-mesher/runtime-build/wasm_mesher_bg.wasm.d.ts +11 -0
  65. package/src/wasm-mesher/tests/mesherLightDependencies.test.ts +83 -0
  66. package/src/wasm-mesher/tests/mesherWasmColumnTickSelect.test.ts +39 -0
  67. package/src/wasm-mesher/tests/mesherWasmConversionCache.test.ts +30 -1
  68. package/src/wasm-mesher/tests/mesherWasmTickParseCache.test.ts +73 -0
  69. package/src/wasm-mesher/tests/mesherWasmTickSchedule.test.ts +51 -0
  70. package/src/wasm-mesher/tests/mesherWasmTopologyPostCache.test.ts +78 -0
  71. package/src/wasm-mesher/worker/clientLightDarkPublication.probe.test.ts +32 -0
  72. package/src/wasm-mesher/worker/mesherLightDependencies.ts +43 -0
  73. package/src/wasm-mesher/worker/mesherWasm.ownerLightSync.test.ts +198 -0
  74. package/src/wasm-mesher/worker/mesherWasm.ts +506 -96
  75. package/src/wasm-mesher/worker/mesherWasmChunkBuffer.ts +1 -0
  76. package/src/wasm-mesher/worker/mesherWasmColumnTickSelect.ts +47 -0
  77. package/src/wasm-mesher/worker/mesherWasmConversionCache.ts +16 -5
  78. package/src/wasm-mesher/worker/mesherWasmLightDirty.test.ts +17 -1
  79. package/src/wasm-mesher/worker/mesherWasmLightDirty.ts +10 -0
  80. package/src/wasm-mesher/worker/mesherWasmLightMerge.test.ts +208 -0
  81. package/src/wasm-mesher/worker/mesherWasmLightMerge.ts +228 -0
  82. package/src/wasm-mesher/worker/mesherWasmOwnerLight.test.ts +161 -0
  83. package/src/wasm-mesher/worker/mesherWasmOwnerLight.ts +112 -0
  84. package/src/wasm-mesher/worker/mesherWasmTickParseCache.ts +45 -0
  85. package/src/wasm-mesher/worker/mesherWasmTickSchedule.ts +44 -0
  86. package/src/wasm-mesher/worker/mesherWasmTopologyPostCache.ts +63 -0
  87. package/src/worldView/types.ts +1 -0
  88. package/src/worldView/worldView.geometryReload.test.ts +68 -0
  89. package/src/worldView/worldView.spiral.test.ts +1 -1
  90. package/src/worldView/worldView.ts +46 -1
@@ -40,6 +40,9 @@ import { FireworksManager } from './fireworks'
40
40
  import { SceneOrigin } from './sceneOrigin'
41
41
  import { downloadWorldGeometry } from './worldGeometryExport'
42
42
  import { ChunkMeshManager } from './chunkMeshManager'
43
+ import { selectReadySectionFlushes } from '../lighting/versioning/pendingSectionFlush'
44
+ import { isClientLightTraceEnabled, recordClientLightTrace } from '../lighting/debug/clientLightTrace'
45
+ import { EntityLightController } from '../lighting/entity/entityLightController'
43
46
  import { raycastVoxelSolid } from './thirdPersonVoxelRaycast'
44
47
  import type { RendererModuleManifest, RegisteredModule, RendererModuleController } from './rendererModuleSystem'
45
48
  import { BUILTIN_MODULES } from './modules/index'
@@ -89,6 +92,7 @@ export class WorldRendererThree extends WorldRendererCommon {
89
92
  ambientLight = new THREE.AmbientLight(0xcc_cc_cc, WorldRendererThree.LEGACY_TO_PHYSICAL_LIGHT)
90
93
  directionalLight = new THREE.DirectionalLight(0xff_ff_ff, 0.5 * WorldRendererThree.LEGACY_TO_PHYSICAL_LIGHT)
91
94
  entities = new Entities(this, (globalThis as any).mcData)
95
+ entityLightController?: EntityLightController
92
96
  performanceMonitor!: PerformanceMonitor
93
97
  cameraGroupVr?: THREE.Object3D
94
98
  material = new THREE.MeshBasicMaterial({ vertexColors: true, transparent: true, alphaTest: 0.1 })
@@ -204,6 +208,14 @@ export class WorldRendererThree extends WorldRendererCommon {
204
208
 
205
209
  // Initialize chunk mesh manager
206
210
  this.chunkMeshManager = new ChunkMeshManager(this, this.scene, this.material, this.worldSizeParams.worldHeight, this.viewDistance)
211
+ this.entityLightController = new EntityLightController({
212
+ getLight: (x, y, z) => this.rendererLightCache.getLight(x, y, z),
213
+ getSkyLevel: () => this.chunkMeshManager.getSkyLevel(),
214
+ getLightmapParams: () => this.chunkMeshManager.getLightmapParams(),
215
+ getColumnRevision: (cx, cz) => this.rendererLightCache.getColumnRevision(cx, cz),
216
+ getGlobalRevision: () => this.rendererLightCache.getGlobalRevision(),
217
+ lightingEnabled: () => this.worldRendererConfig.enableLighting !== false
218
+ })
207
219
  this.onRenderDistanceChanged = viewDistance => {
208
220
  this.chunkMeshManager.updateViewDistance(viewDistance)
209
221
  }
@@ -563,6 +575,9 @@ export class WorldRendererThree extends WorldRendererCommon {
563
575
  this.cursorBlock.setHighlightCursorBlock(value ? new Vec3(value.x, value.y, value.z) : null, value?.shapes)
564
576
  })
565
577
  this.onReactivePlayerStateUpdated('diggingBlock', value => {
578
+ if (value && (value.stage == null || value.stage === 0) && isClientLightTraceEnabled()) {
579
+ recordClientLightTrace({ phase: 'inputClick', sectionKey: `${value.x},${value.y},${value.z}` })
580
+ }
566
581
  this.cursorBlock.updateBreakAnimation(value ? { x: value.x, y: value.y, z: value.z } : undefined, value?.stage ?? null, value?.mergedShape)
567
582
  })
568
583
  this.onReactivePlayerStateUpdated('perspective', value => {
@@ -594,6 +609,13 @@ export class WorldRendererThree extends WorldRendererCommon {
594
609
  this.onReactiveConfigUpdated('futuristicReveal', () => {
595
610
  this.updateModulesFromConfig()
596
611
  })
612
+ this.onReactiveConfigUpdated(
613
+ 'enableLighting',
614
+ () => {
615
+ this.rerenderAllChunks()
616
+ },
617
+ false
618
+ )
597
619
  this.onReactiveDebugUpdated('disableEntities', () => {
598
620
  this.entities.syncSceneAttachment()
599
621
  })
@@ -830,6 +852,10 @@ export class WorldRendererThree extends WorldRendererCommon {
830
852
  if (camCollisionBytes > 0) {
831
853
  text += `CAM: ${formatCompact(camCollisionBytes)}b `
832
854
  }
855
+ const entityLightBytes = this.rendererLightCache.getAllocatedBytes()
856
+ if (entityLightBytes > 0) {
857
+ text += `ELIGHT: ${formatCompact(entityLightBytes)}b `
858
+ }
833
859
  const pf = formatPerformanceFactorsDebug(this.reactiveState.world.instabilityFactors)
834
860
  if (pf) text += `PF: ${pf} `
835
861
  // entities can be seen in F3
@@ -884,45 +910,37 @@ export class WorldRendererThree extends WorldRendererCommon {
884
910
  if (this.pendingSectionUpdates.size === 0) return
885
911
 
886
912
  const now = performance.now()
887
- const sectionHeight = this.getSectionHeight()
888
- const ready: string[] = []
889
-
890
- for (const key of this.pendingSectionUpdates.keys()) {
891
- const startedAt = this.pendingSectionBufferStartTimes.get(key) ?? now
892
- const sinceFirst = now - startedAt
893
-
894
- if (sinceFirst < WorldRendererThree.MAX_SECTION_UPDATE_BUFFER_MS) {
895
- // Still within this section's grace window — wait if any neighbor is
896
- // currently being re-meshed so we don't briefly expose a hole between
897
- // the just-updated section and a stale neighbor (sky-flicker bug).
898
- const [sx, sy, sz] = key.split(',').map(Number)
899
- const neighborKeys = [
900
- `${sx - 16},${sy},${sz}`,
901
- `${sx + 16},${sy},${sz}`,
902
- `${sx},${sy - sectionHeight},${sz}`,
903
- `${sx},${sy + sectionHeight},${sz}`,
904
- `${sx},${sy},${sz - 16}`,
905
- `${sx},${sy},${sz + 16}`
906
- ]
907
- let neighborBusy = false
908
- for (const neighborKey of neighborKeys) {
909
- if (this.sectionsWaiting.has(neighborKey) && !this.pendingSectionUpdates.has(neighborKey) && this.sectionObjects[neighborKey]) {
910
- neighborBusy = true
911
- break
913
+ // Face-adjacent buffered sections are installed as one group: a lone
914
+ // install would show the neighbour's faces still culled against the old
915
+ // block state, i.e. a see-through hole (sky flash) on dig/place.
916
+ const ready = selectReadySectionFlushes({
917
+ pendingKeys: this.pendingSectionUpdates.keys(),
918
+ startedAt: key => this.pendingSectionBufferStartTimes.get(key),
919
+ now,
920
+ maxBufferMs: WorldRendererThree.MAX_SECTION_UPDATE_BUFFER_MS,
921
+ sectionHeight: this.getSectionHeight(),
922
+ isOutstanding: key => this.sectionsWaiting.has(key) && !this.pendingSectionUpdates.has(key),
923
+ ...(this.lightCoordinator.isSessionLive()
924
+ ? {
925
+ isTopologyOutstanding: (key: string) => this.lightCoordinator.pendingTopologyBySection.has(key) && !this.pendingSectionUpdates.has(key)
912
926
  }
913
- }
914
- if (neighborBusy) continue
915
- }
916
-
917
- ready.push(key)
918
- }
927
+ : {}),
928
+ hasSectionObject: key => !!this.sectionObjects[key]
929
+ })
919
930
 
920
931
  if (ready.length === 0) return
921
932
 
922
- for (const key of ready) {
933
+ for (const { key, reason } of ready) {
923
934
  const update = this.pendingSectionUpdates.get(key)!
924
935
  this.pendingSectionUpdates.delete(key)
925
936
  this.pendingSectionBufferStartTimes.delete(key)
937
+ if (isClientLightTraceEnabled()) {
938
+ recordClientLightTrace({
939
+ phase: 'flush',
940
+ sectionKey: key,
941
+ flushReason: reason
942
+ })
943
+ }
926
944
 
927
945
  const chunkCoords = update.key.split(',')
928
946
  const chunkKey = `${chunkCoords[0]},${chunkCoords[2]}`
@@ -932,6 +950,14 @@ export class WorldRendererThree extends WorldRendererCommon {
932
950
  continue
933
951
  }
934
952
 
953
+ const decision = this.lightCoordinator.evaluateOwnerGeometry(update)
954
+ if (!decision.accepted || update.geometry?.hadErrors) {
955
+ this.lightCoordinator.noteRejectedOwnerGeometry(update.key, undefined, { expectLaterFinished: false })
956
+ continue
957
+ }
958
+ this.lightCoordinator.acknowledgeAcceptedTopology(update)
959
+ if (decision.keepCovering) this.lightCoordinator.maybeDispatchCoveringRemesh(update.key)
960
+
935
961
  if (!this.chunkMeshManager.sectionHasRenderableContent(update.geometry)) {
936
962
  this.chunkMeshManager.releaseSection(update.key)
937
963
  continue
@@ -966,6 +992,14 @@ export class WorldRendererThree extends WorldRendererCommon {
966
992
  return
967
993
  }
968
994
 
995
+ const decision = this.lightCoordinator.evaluateOwnerGeometry(data)
996
+ if (!decision.accepted || data.geometry?.hadErrors) {
997
+ this.lightCoordinator.noteRejectedOwnerGeometry(data.key, undefined, { expectLaterFinished: true })
998
+ return
999
+ }
1000
+ this.lightCoordinator.acknowledgeAcceptedTopology(data)
1001
+ if (decision.keepCovering) this.lightCoordinator.maybeDispatchCoveringRemesh(data.key)
1002
+
969
1003
  if (this.sectionObjects[data.key]) {
970
1004
  this.pendingSectionUpdates.set(data.key, data)
971
1005
  // Per-section deadline: only set if we don't already have one, so
@@ -973,6 +1007,13 @@ export class WorldRendererThree extends WorldRendererCommon {
973
1007
  if (!this.pendingSectionBufferStartTimes.has(data.key)) {
974
1008
  this.pendingSectionBufferStartTimes.set(data.key, performance.now())
975
1009
  }
1010
+ if (isClientLightTraceEnabled()) {
1011
+ recordClientLightTrace({
1012
+ phase: 'pending',
1013
+ sectionKey: data.key,
1014
+ queueDepth: this.pendingSectionUpdates.size
1015
+ })
1016
+ }
976
1017
  return
977
1018
  }
978
1019
 
@@ -1552,8 +1593,8 @@ export class WorldRendererThree extends WorldRendererCommon {
1552
1593
  }
1553
1594
  }
1554
1595
 
1555
- removeColumn(x, z) {
1556
- super.removeColumn(x, z)
1596
+ removeColumn(x, z, opts?: { preserveClientLight?: boolean }) {
1597
+ super.removeColumn(x, z, opts)
1557
1598
 
1558
1599
  this.clearPendingSectionUpdatesForChunk(x, z)
1559
1600
  const sectionHeight = this.getSectionHeight()
@@ -3,6 +3,7 @@
3
3
  // This file takes WASM output and generates full Three.js buffer geometry
4
4
 
5
5
  import * as THREE from 'three'
6
+ import { isClientLightProbeBlock } from '../../lighting/debug/clientLightProbe'
6
7
  import worldBlockProviderModule, { WorldBlockProvider } from 'mc-assets/dist/worldBlockProvider'
7
8
  import blocksAtlasesJson from 'mc-assets/dist/blocksAtlases.json'
8
9
  import blockStatesModels from 'mc-assets/dist/blockStatesModels.json'
@@ -692,7 +693,26 @@ export function renderWasmOutputToGeometry(
692
693
  },
693
694
  shaderWordBuffer
694
695
  )
695
- if (emitted) continue
696
+ if (emitted) {
697
+ if (isClientLightProbeBlock(bx, by, bz)) {
698
+ console.log('[lightProbe:shaderCube]', {
699
+ time: Date.now(),
700
+ position: [bx, by, bz],
701
+ blockStateId,
702
+ name: prismBlock.name,
703
+ useModelLighting: false,
704
+ wasmSky: block.sky_light_data?.map(values => [...values]),
705
+ visibleFaces: block.visible_faces,
706
+ jsNeighborSky: Object.fromEntries(
707
+ Object.entries(elemFaces).map(([face, info]) => [
708
+ face,
709
+ world?.getChannelLightNorm(new Vec3(bx, by, bz).offset(info.dir[0], info.dir[1], info.dir[2])).sky
710
+ ])
711
+ )
712
+ })
713
+ }
714
+ continue
715
+ }
696
716
  }
697
717
  }
698
718
 
@@ -842,6 +862,20 @@ export function renderWasmOutputToGeometry(
842
862
  const tint = getTint(matchingEFace, cachedModel.blockName, cachedModel.blockProps, biome, world)
843
863
 
844
864
  const useModelLighting = (!cachedModel.isCube || globalMatrix != null) && world
865
+ if (isClientLightProbeBlock(bx, by, bz)) {
866
+ console.log('[lightProbe:face]', {
867
+ time: Date.now(),
868
+ position: [bx, by, bz],
869
+ faceName,
870
+ blockStateId,
871
+ name: prismBlock.name,
872
+ isCube: cachedModel.isCube,
873
+ rotated: globalMatrix != null,
874
+ useModelLighting: Boolean(useModelLighting),
875
+ wasmSky: skyValuesRaw ? [...skyValuesRaw] : null,
876
+ jsNeighborSky: world?.getChannelLightNorm(new Vec3(bx, by, bz).offset(...transformedDirI)).sky
877
+ })
878
+ }
845
879
  const baseChannels = useModelLighting
846
880
  ? world.getChannelLightNorm(new Vec3(bx, by, bz).offset(transformedDirI[0], transformedDirI[1], transformedDirI[2]))
847
881
  : null
@@ -921,6 +955,17 @@ export function renderWasmOutputToGeometry(
921
955
  tgtCol.push(tintAo[0], tintAo[1], tintAo[2])
922
956
  tgtSky.push(skyLightNorm)
923
957
  tgtBlock.push(blockLightNorm)
958
+ if (isClientLightProbeBlock(bx, by, bz)) {
959
+ console.log('[lightProbe:vertex]', {
960
+ time: Date.now(),
961
+ position: [bx, by, bz],
962
+ faceName,
963
+ cornerIdx,
964
+ useModelLighting: Boolean(useModelLighting),
965
+ skyLightNorm,
966
+ blockLightNorm
967
+ })
968
+ }
924
969
 
925
970
  const baseu = (pos[3] - 0.5) * uvcs - (pos[4] - 0.5) * uvsn + 0.5
926
971
  const basev = (pos[3] - 0.5) * uvsn + (pos[4] - 0.5) * uvcs + 0.5
@@ -2,6 +2,21 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
 
5
+ export class JsLightEngine {
6
+ free(): void;
7
+ [Symbol.dispose](): void;
8
+ pushEvent(event: any): void;
9
+ getSkyLight(x: number, y: number, z: number): number;
10
+ getBlockLight(x: number, y: number, z: number): number;
11
+ setLightTables(emission: Uint8Array, opacity: Uint8Array): void;
12
+ setOcclusionTable(occupancy: Uint8Array): void;
13
+ setSkyLightEnabled(enabled: boolean): void;
14
+ pollCompletedPublication(): any;
15
+ step(budget_ms: number): boolean;
16
+ constructor(world_min_y: number, world_height: number);
17
+ readonly fallbackRelights: number;
18
+ }
19
+
5
20
  /**
6
21
  * Compute wireframe edge positions from a triangle mesh.
7
22
  *
@@ -210,11 +225,11 @@ export function parseMapChunkV18Plus(raw_packet: Uint8Array, num_sections: numbe
210
225
  * `raw_packet` includes the leading packet-id varint (we skip it).
211
226
  * `num_sections` should match the column the light is for (16 in 1.17).
212
227
  *
213
- * Returns `{ x, z, skyLight: Uint8Array(num_sections * 4096),
214
- * blockLight: Uint8Array(num_sections * 4096), bytesRead }`.
215
- * Layout matches the existing 1.18+ light arrays
216
- * (`x + z*16 + y_abs*256`); the JS-side worker reorders into per-section
217
- * stack via the same path used for 1.18+ raw map_chunk parsing.
228
+ * Returns `{ x, z, trustEdges, skyLight, blockLight, skyLightMask,
229
+ * emptySkyLightMask, blockLightMask, emptyBlockLightMask,
230
+ * skyBelow?, skyAbove?, blockBelow?, blockAbove?, bytesRead }`.
231
+ * World arrays are `num_sections * 4096` (`x + z*16 + y_abs*256`).
232
+ * Omitted sections are left 0 and are not authoritative — use the masks.
218
233
  */
219
234
  export function parseUpdateLightV17(raw_packet: Uint8Array, num_sections: number): any;
220
235
 
@@ -227,6 +242,7 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
227
242
 
228
243
  export interface InitOutput {
229
244
  readonly memory: WebAssembly.Memory;
245
+ readonly __wbg_jslightengine_free: (a: number, b: number) => void;
230
246
  readonly computeWireframeEdges: (a: number, b: number, c: number, d: number) => [number, number];
231
247
  readonly computeWireframeEdgesU16: (a: number, b: number, c: number, d: number) => [number, number];
232
248
  readonly generateGeometryFromDump118: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number, e1: number, f1: number, g1: number, h1: number, i1: number, j1: number, k1: number) => any;
@@ -236,6 +252,16 @@ export interface InitOutput {
236
252
  readonly generateGeometryFromParsedV16V17Multi: (a: any, b: number, c: number, d: number, e: number, f: number, g: any, h: number, i: any, j: any, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number, e1: number, f1: number, g1: number, h1: number) => any;
237
253
  readonly generate_geometry: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number) => any;
238
254
  readonly generate_geometry_multi: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number, e1: number, f1: number) => any;
255
+ readonly jslightengine_fallbackRelights: (a: number) => number;
256
+ readonly jslightengine_getBlockLight: (a: number, b: number, c: number, d: number) => number;
257
+ readonly jslightengine_getSkyLight: (a: number, b: number, c: number, d: number) => number;
258
+ readonly jslightengine_js_new: (a: number, b: number) => number;
259
+ readonly jslightengine_pollCompletedPublication: (a: number) => any;
260
+ readonly jslightengine_pushEvent: (a: number, b: any) => void;
261
+ readonly jslightengine_setLightTables: (a: number, b: number, c: number, d: number, e: number) => void;
262
+ readonly jslightengine_setOcclusionTable: (a: number, b: number, c: number) => void;
263
+ readonly jslightengine_setSkyLightEnabled: (a: number, b: number) => void;
264
+ readonly jslightengine_step: (a: number, b: number) => number;
239
265
  readonly parseChunkDump118: (a: number, b: number, c: number, d: number, e: number) => any;
240
266
  readonly parseChunkDump118FullColumn: (a: number, b: number, c: number, d: number, e: number) => any;
241
267
  readonly parseChunkDump118FullColumnAll: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number) => any;
@@ -86,6 +86,11 @@ function getArrayU16FromWasm0(ptr, len) {
86
86
  return getUint16ArrayMemory0().subarray(ptr / 2, ptr / 2 + len);
87
87
  }
88
88
 
89
+ function getArrayU32FromWasm0(ptr, len) {
90
+ ptr = ptr >>> 0;
91
+ return getUint32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);
92
+ }
93
+
89
94
  function getArrayU8FromWasm0(ptr, len) {
90
95
  ptr = ptr >>> 0;
91
96
  return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
@@ -153,6 +158,10 @@ function handleError(f, args) {
153
158
  }
154
159
  }
155
160
 
161
+ function isLikeNone(x) {
162
+ return x === undefined || x === null;
163
+ }
164
+
156
165
  function passArray16ToWasm0(arg, malloc) {
157
166
  const ptr = malloc(arg.length * 2, 2) >>> 0;
158
167
  getUint16ArrayMemory0().set(arg, ptr / 2);
@@ -247,6 +256,107 @@ if (!('encodeInto' in cachedTextEncoder)) {
247
256
 
248
257
  let WASM_VECTOR_LEN = 0;
249
258
 
259
+ const JsLightEngineFinalization = (typeof FinalizationRegistry === 'undefined')
260
+ ? { register: () => {}, unregister: () => {} }
261
+ : new FinalizationRegistry(ptr => wasm.__wbg_jslightengine_free(ptr >>> 0, 1));
262
+
263
+ export class JsLightEngine {
264
+ __destroy_into_raw() {
265
+ const ptr = this.__wbg_ptr;
266
+ this.__wbg_ptr = 0;
267
+ JsLightEngineFinalization.unregister(this);
268
+ return ptr;
269
+ }
270
+ free() {
271
+ const ptr = this.__destroy_into_raw();
272
+ wasm.__wbg_jslightengine_free(ptr, 0);
273
+ }
274
+ /**
275
+ * @param {any} event
276
+ */
277
+ pushEvent(event) {
278
+ wasm.jslightengine_pushEvent(this.__wbg_ptr, event);
279
+ }
280
+ /**
281
+ * @param {number} x
282
+ * @param {number} y
283
+ * @param {number} z
284
+ * @returns {number}
285
+ */
286
+ getSkyLight(x, y, z) {
287
+ const ret = wasm.jslightengine_getSkyLight(this.__wbg_ptr, x, y, z);
288
+ return ret;
289
+ }
290
+ /**
291
+ * @param {number} x
292
+ * @param {number} y
293
+ * @param {number} z
294
+ * @returns {number}
295
+ */
296
+ getBlockLight(x, y, z) {
297
+ const ret = wasm.jslightengine_getBlockLight(this.__wbg_ptr, x, y, z);
298
+ return ret;
299
+ }
300
+ /**
301
+ * @param {Uint8Array} emission
302
+ * @param {Uint8Array} opacity
303
+ */
304
+ setLightTables(emission, opacity) {
305
+ const ptr0 = passArray8ToWasm0(emission, wasm.__wbindgen_malloc);
306
+ const len0 = WASM_VECTOR_LEN;
307
+ const ptr1 = passArray8ToWasm0(opacity, wasm.__wbindgen_malloc);
308
+ const len1 = WASM_VECTOR_LEN;
309
+ wasm.jslightengine_setLightTables(this.__wbg_ptr, ptr0, len0, ptr1, len1);
310
+ }
311
+ /**
312
+ * @returns {number}
313
+ */
314
+ get fallbackRelights() {
315
+ const ret = wasm.jslightengine_fallbackRelights(this.__wbg_ptr);
316
+ return ret >>> 0;
317
+ }
318
+ /**
319
+ * @param {Uint8Array} occupancy
320
+ */
321
+ setOcclusionTable(occupancy) {
322
+ const ptr0 = passArray8ToWasm0(occupancy, wasm.__wbindgen_malloc);
323
+ const len0 = WASM_VECTOR_LEN;
324
+ wasm.jslightengine_setOcclusionTable(this.__wbg_ptr, ptr0, len0);
325
+ }
326
+ /**
327
+ * @param {boolean} enabled
328
+ */
329
+ setSkyLightEnabled(enabled) {
330
+ wasm.jslightengine_setSkyLightEnabled(this.__wbg_ptr, enabled);
331
+ }
332
+ /**
333
+ * @returns {any}
334
+ */
335
+ pollCompletedPublication() {
336
+ const ret = wasm.jslightengine_pollCompletedPublication(this.__wbg_ptr);
337
+ return ret;
338
+ }
339
+ /**
340
+ * @param {number} budget_ms
341
+ * @returns {boolean}
342
+ */
343
+ step(budget_ms) {
344
+ const ret = wasm.jslightengine_step(this.__wbg_ptr, budget_ms);
345
+ return ret !== 0;
346
+ }
347
+ /**
348
+ * @param {number} world_min_y
349
+ * @param {number} world_height
350
+ */
351
+ constructor(world_min_y, world_height) {
352
+ const ret = wasm.jslightengine_js_new(world_min_y, world_height);
353
+ this.__wbg_ptr = ret >>> 0;
354
+ JsLightEngineFinalization.register(this, this.__wbg_ptr, this);
355
+ return this;
356
+ }
357
+ }
358
+ if (Symbol.dispose) JsLightEngine.prototype[Symbol.dispose] = JsLightEngine.prototype.free;
359
+
250
360
  /**
251
361
  * Compute wireframe edge positions from a triangle mesh.
252
362
  *
@@ -879,11 +989,11 @@ export function parseMapChunkV18Plus(raw_packet, num_sections, max_bits_per_bloc
879
989
  * `raw_packet` includes the leading packet-id varint (we skip it).
880
990
  * `num_sections` should match the column the light is for (16 in 1.17).
881
991
  *
882
- * Returns `{ x, z, skyLight: Uint8Array(num_sections * 4096),
883
- * blockLight: Uint8Array(num_sections * 4096), bytesRead }`.
884
- * Layout matches the existing 1.18+ light arrays
885
- * (`x + z*16 + y_abs*256`); the JS-side worker reorders into per-section
886
- * stack via the same path used for 1.18+ raw map_chunk parsing.
992
+ * Returns `{ x, z, trustEdges, skyLight, blockLight, skyLightMask,
993
+ * emptySkyLightMask, blockLightMask, emptyBlockLightMask,
994
+ * skyBelow?, skyAbove?, blockBelow?, blockAbove?, bytesRead }`.
995
+ * World arrays are `num_sections * 4096` (`x + z*16 + y_abs*256`).
996
+ * Omitted sections are left 0 and are not authoritative — use the masks.
887
997
  * @param {Uint8Array} raw_packet
888
998
  * @param {number} num_sections
889
999
  * @returns {any}
@@ -948,6 +1058,11 @@ function __wbg_get_imports() {
948
1058
  const ret = Error(getStringFromWasm0(arg0, arg1));
949
1059
  return ret;
950
1060
  };
1061
+ imports.wbg.__wbg___wbindgen_boolean_get_dea25b33882b895b = function(arg0) {
1062
+ const v = arg0;
1063
+ const ret = typeof(v) === 'boolean' ? v : undefined;
1064
+ return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
1065
+ };
951
1066
  imports.wbg.__wbg___wbindgen_debug_string_adfb662ae34724b6 = function(arg0, arg1) {
952
1067
  const ret = debugString(arg1);
953
1068
  const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
@@ -955,6 +1070,28 @@ function __wbg_get_imports() {
955
1070
  getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
956
1071
  getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
957
1072
  };
1073
+ imports.wbg.__wbg___wbindgen_is_null_dfda7d66506c95b5 = function(arg0) {
1074
+ const ret = arg0 === null;
1075
+ return ret;
1076
+ };
1077
+ imports.wbg.__wbg___wbindgen_is_undefined_f6b95eab589e0269 = function(arg0) {
1078
+ const ret = arg0 === undefined;
1079
+ return ret;
1080
+ };
1081
+ imports.wbg.__wbg___wbindgen_number_get_9619185a74197f95 = function(arg0, arg1) {
1082
+ const obj = arg1;
1083
+ const ret = typeof(obj) === 'number' ? obj : undefined;
1084
+ getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);
1085
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
1086
+ };
1087
+ imports.wbg.__wbg___wbindgen_string_get_a2a31e16edf96e42 = function(arg0, arg1) {
1088
+ const obj = arg1;
1089
+ const ret = typeof(obj) === 'string' ? obj : undefined;
1090
+ var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1091
+ var len1 = WASM_VECTOR_LEN;
1092
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
1093
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
1094
+ };
958
1095
  imports.wbg.__wbg___wbindgen_throw_dd24417ed36fc46e = function(arg0, arg1) {
959
1096
  throw new Error(getStringFromWasm0(arg0, arg1));
960
1097
  };
@@ -962,6 +1099,10 @@ function __wbg_get_imports() {
962
1099
  const ret = arg0[arg1 >>> 0];
963
1100
  return ret;
964
1101
  };
1102
+ imports.wbg.__wbg_get_af9dab7e9603ea93 = function() { return handleError(function (arg0, arg1) {
1103
+ const ret = Reflect.get(arg0, arg1);
1104
+ return ret;
1105
+ }, arguments) };
965
1106
  imports.wbg.__wbg_instanceof_Int32Array_b6281022039fba32 = function(arg0) {
966
1107
  let result;
967
1108
  try {
@@ -990,6 +1131,10 @@ function __wbg_get_imports() {
990
1131
  const ret = arg0.length;
991
1132
  return ret;
992
1133
  };
1134
+ imports.wbg.__wbg_length_89c3414ed7f0594d = function(arg0) {
1135
+ const ret = arg0.length;
1136
+ return ret;
1137
+ };
993
1138
  imports.wbg.__wbg_length_ab53989976907f11 = function(arg0) {
994
1139
  const ret = arg0.length;
995
1140
  return ret;
@@ -1002,10 +1147,26 @@ function __wbg_get_imports() {
1002
1147
  const ret = new Array();
1003
1148
  return ret;
1004
1149
  };
1150
+ imports.wbg.__wbg_new_6421f6084cc5bc5a = function(arg0) {
1151
+ const ret = new Uint8Array(arg0);
1152
+ return ret;
1153
+ };
1154
+ imports.wbg.__wbg_new_9f7fd5c3a6ba7298 = function(arg0) {
1155
+ const ret = new Uint16Array(arg0);
1156
+ return ret;
1157
+ };
1158
+ imports.wbg.__wbg_new_from_slice_e6bd3cfb5a35313d = function(arg0, arg1) {
1159
+ const ret = new Int32Array(getArrayI32FromWasm0(arg0, arg1));
1160
+ return ret;
1161
+ };
1005
1162
  imports.wbg.__wbg_new_with_length_1e8603a5c71d4e06 = function(arg0) {
1006
1163
  const ret = new Int32Array(arg0 >>> 0);
1007
1164
  return ret;
1008
1165
  };
1166
+ imports.wbg.__wbg_new_with_length_202b3db94ba5fc86 = function(arg0) {
1167
+ const ret = new Uint32Array(arg0 >>> 0);
1168
+ return ret;
1169
+ };
1009
1170
  imports.wbg.__wbg_new_with_length_aa5eaf41d35235e5 = function(arg0) {
1010
1171
  const ret = new Uint8Array(arg0 >>> 0);
1011
1172
  return ret;
@@ -1014,12 +1175,23 @@ function __wbg_get_imports() {
1014
1175
  const ret = new Uint16Array(arg0 >>> 0);
1015
1176
  return ret;
1016
1177
  };
1178
+ imports.wbg.__wbg_now_69d776cd24f5215b = function() {
1179
+ const ret = Date.now();
1180
+ return ret;
1181
+ };
1182
+ imports.wbg.__wbg_prototypesetcall_b0bea5f39077cfd3 = function(arg0, arg1, arg2) {
1183
+ Uint16Array.prototype.set.call(getArrayU16FromWasm0(arg0, arg1), arg2);
1184
+ };
1017
1185
  imports.wbg.__wbg_prototypesetcall_dd07c344a74d4bfd = function(arg0, arg1, arg2) {
1018
1186
  Int32Array.prototype.set.call(getArrayI32FromWasm0(arg0, arg1), arg2);
1019
1187
  };
1020
1188
  imports.wbg.__wbg_prototypesetcall_dfe9b766cdc1f1fd = function(arg0, arg1, arg2) {
1021
1189
  Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
1022
1190
  };
1191
+ imports.wbg.__wbg_push_7d9be8f38fc13975 = function(arg0, arg1) {
1192
+ const ret = arg0.push(arg1);
1193
+ return ret;
1194
+ };
1023
1195
  imports.wbg.__wbg_set_169e13b608078b7b = function(arg0, arg1, arg2) {
1024
1196
  arg0.set(getArrayU8FromWasm0(arg1, arg2));
1025
1197
  };
@@ -1036,6 +1208,9 @@ function __wbg_get_imports() {
1036
1208
  imports.wbg.__wbg_set_bb0c6a7fe60d81b5 = function(arg0, arg1, arg2) {
1037
1209
  arg0.set(getArrayU16FromWasm0(arg1, arg2));
1038
1210
  };
1211
+ imports.wbg.__wbg_set_e7cd108182596b7f = function(arg0, arg1, arg2) {
1212
+ arg0.set(getArrayU32FromWasm0(arg1, arg2));
1213
+ };
1039
1214
  imports.wbg.__wbindgen_cast_2241b6af4c4b2941 = function(arg0, arg1) {
1040
1215
  // Cast intrinsic for `Ref(String) -> Externref`.
1041
1216
  const ret = getStringFromWasm0(arg0, arg1);
@@ -2,6 +2,7 @@
2
2
  /* tslint:disable */
3
3
  /* eslint-disable */
4
4
  export const memory: WebAssembly.Memory;
5
+ export const __wbg_jslightengine_free: (a: number, b: number) => void;
5
6
  export const computeWireframeEdges: (a: number, b: number, c: number, d: number) => [number, number];
6
7
  export const computeWireframeEdgesU16: (a: number, b: number, c: number, d: number) => [number, number];
7
8
  export const generateGeometryFromDump118: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number, e1: number, f1: number, g1: number, h1: number, i1: number, j1: number, k1: number) => any;
@@ -11,6 +12,16 @@ export const generateGeometryFromParsedV16V17: (a: number, b: number, c: number,
11
12
  export const generateGeometryFromParsedV16V17Multi: (a: any, b: number, c: number, d: number, e: number, f: number, g: any, h: number, i: any, j: any, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number, e1: number, f1: number, g1: number, h1: number) => any;
12
13
  export const generate_geometry: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number) => any;
13
14
  export const generate_geometry_multi: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number, v: number, w: number, x: number, y: number, z: number, a1: number, b1: number, c1: number, d1: number, e1: number, f1: number) => any;
15
+ export const jslightengine_fallbackRelights: (a: number) => number;
16
+ export const jslightengine_getBlockLight: (a: number, b: number, c: number, d: number) => number;
17
+ export const jslightengine_getSkyLight: (a: number, b: number, c: number, d: number) => number;
18
+ export const jslightengine_js_new: (a: number, b: number) => number;
19
+ export const jslightengine_pollCompletedPublication: (a: number) => any;
20
+ export const jslightengine_pushEvent: (a: number, b: any) => void;
21
+ export const jslightengine_setLightTables: (a: number, b: number, c: number, d: number, e: number) => void;
22
+ export const jslightengine_setOcclusionTable: (a: number, b: number, c: number) => void;
23
+ export const jslightengine_setSkyLightEnabled: (a: number, b: number) => void;
24
+ export const jslightengine_step: (a: number, b: number) => number;
14
25
  export const parseChunkDump118: (a: number, b: number, c: number, d: number, e: number) => any;
15
26
  export const parseChunkDump118FullColumn: (a: number, b: number, c: number, d: number, e: number) => any;
16
27
  export const parseChunkDump118FullColumnAll: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number) => any;