minecraft-renderer 0.1.106 → 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 (98) 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 +105 -76
  7. package/dist/minecraft-renderer.js.meta.json +1 -1
  8. package/dist/threeWorker.js +537 -508
  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 +8 -0
  14. package/src/graphicsBackend/rendererDefaultOptions.test.ts +51 -0
  15. package/src/graphicsBackend/rendererDefaultOptions.ts +18 -1
  16. package/src/graphicsBackend/rendererOptionsSync.ts +4 -3
  17. package/src/lib/blockEntityLightRegistry.ts +4 -0
  18. package/src/lib/skyLight.ts +17 -0
  19. package/src/lib/worldrendererCommon.lightOwner.test.ts +916 -0
  20. package/src/lib/worldrendererCommon.removeColumn.test.ts +16 -0
  21. package/src/lib/worldrendererCommon.ts +340 -67
  22. package/src/lighting/cache/rendererLightCache.test.ts +158 -0
  23. package/src/lighting/cache/rendererLightCache.ts +248 -0
  24. package/src/lighting/coordinator/clientLightCoordinator.test.ts +102 -0
  25. package/src/lighting/coordinator/clientLightCoordinator.ts +574 -0
  26. package/src/lighting/debug/clientLightProbe.test.ts +24 -0
  27. package/src/lighting/debug/clientLightProbe.ts +20 -0
  28. package/src/lighting/debug/clientLightTrace.test.ts +271 -0
  29. package/src/lighting/debug/clientLightTrace.ts +335 -0
  30. package/src/lighting/entity/entityLightController.test.ts +216 -0
  31. package/src/lighting/entity/entityLightController.ts +322 -0
  32. package/src/lighting/owner/clientLightOwner.test.ts +467 -0
  33. package/src/lighting/owner/clientLightOwner.ts +523 -0
  34. package/src/lighting/owner/lightOwnerHost.test.ts +78 -0
  35. package/src/lighting/owner/lightOwnerHost.ts +202 -0
  36. package/src/lighting/owner/lightOwnerWorker.ts +154 -0
  37. package/src/lighting/owner/updateLight1171OwnerPath.test.ts +68 -0
  38. package/src/lighting/owner/updateLightToOwnerEvents.ts +49 -0
  39. package/src/lighting/tables/lightTables1171.generated.json +10 -0
  40. package/src/lighting/tables/lightTables1171.test.ts +168 -0
  41. package/src/lighting/tables/lightTables1171.ts +59 -0
  42. package/src/lighting/versioning/clientLightVersions.test.ts +241 -0
  43. package/src/lighting/versioning/clientLightVersions.ts +203 -0
  44. package/src/lighting/versioning/pendingSectionFlush.test.ts +214 -0
  45. package/src/lighting/versioning/pendingSectionFlush.ts +123 -0
  46. package/src/mesher-shared/lightNibblePack.ts +26 -0
  47. package/src/mesher-shared/mcDataWorkerShim.cjs +9 -7
  48. package/src/mesher-shared/modelsGeometryCommon.test.ts +6 -1
  49. package/src/mesher-shared/shared.ts +48 -1
  50. package/src/three/chunkMeshManager.ts +26 -0
  51. package/src/three/entities.ts +97 -8
  52. package/src/three/entity/EntityMesh.ts +1 -0
  53. package/src/three/entity/legWalkAnimation.test.ts +154 -0
  54. package/src/three/entity/legWalkAnimation.ts +193 -0
  55. package/src/three/globalBlockBuffer.ts +94 -2
  56. package/src/three/globalLegacyBuffer.ts +94 -2
  57. package/src/three/graphicsBackendBase.ts +2 -9
  58. package/src/three/modules/clouds.ts +191 -0
  59. package/src/three/modules/index.ts +4 -0
  60. package/src/three/modules/sunMoon.ts +151 -0
  61. package/src/three/skyboxRenderer.ts +15 -8
  62. package/src/three/tests/clouds.test.ts +59 -0
  63. package/src/three/tests/globalBlockBuffer.test.ts +98 -0
  64. package/src/three/tests/globalLegacyBuffer.test.ts +108 -0
  65. package/src/three/tests/waterFog.test.ts +25 -0
  66. package/src/three/waterFog.ts +28 -0
  67. package/src/three/worldRendererThree.ts +84 -39
  68. package/src/wasm-mesher/bridge/render-from-wasm.ts +46 -1
  69. package/src/wasm-mesher/runtime-build/wasm_mesher.d.ts +31 -5
  70. package/src/wasm-mesher/runtime-build/wasm_mesher.js +180 -5
  71. package/src/wasm-mesher/runtime-build/wasm_mesher_bg.wasm +0 -0
  72. package/src/wasm-mesher/runtime-build/wasm_mesher_bg.wasm.d.ts +11 -0
  73. package/src/wasm-mesher/tests/mesherLightDependencies.test.ts +83 -0
  74. package/src/wasm-mesher/tests/mesherWasmColumnTickSelect.test.ts +39 -0
  75. package/src/wasm-mesher/tests/mesherWasmConversionCache.test.ts +30 -1
  76. package/src/wasm-mesher/tests/mesherWasmTickParseCache.test.ts +73 -0
  77. package/src/wasm-mesher/tests/mesherWasmTickSchedule.test.ts +51 -0
  78. package/src/wasm-mesher/tests/mesherWasmTopologyPostCache.test.ts +78 -0
  79. package/src/wasm-mesher/worker/clientLightDarkPublication.probe.test.ts +32 -0
  80. package/src/wasm-mesher/worker/mesherLightDependencies.ts +43 -0
  81. package/src/wasm-mesher/worker/mesherWasm.ownerLightSync.test.ts +198 -0
  82. package/src/wasm-mesher/worker/mesherWasm.ts +506 -96
  83. package/src/wasm-mesher/worker/mesherWasmChunkBuffer.ts +1 -0
  84. package/src/wasm-mesher/worker/mesherWasmColumnTickSelect.ts +47 -0
  85. package/src/wasm-mesher/worker/mesherWasmConversionCache.ts +16 -5
  86. package/src/wasm-mesher/worker/mesherWasmLightDirty.test.ts +17 -1
  87. package/src/wasm-mesher/worker/mesherWasmLightDirty.ts +10 -0
  88. package/src/wasm-mesher/worker/mesherWasmLightMerge.test.ts +208 -0
  89. package/src/wasm-mesher/worker/mesherWasmLightMerge.ts +228 -0
  90. package/src/wasm-mesher/worker/mesherWasmOwnerLight.test.ts +161 -0
  91. package/src/wasm-mesher/worker/mesherWasmOwnerLight.ts +112 -0
  92. package/src/wasm-mesher/worker/mesherWasmTickParseCache.ts +45 -0
  93. package/src/wasm-mesher/worker/mesherWasmTickSchedule.ts +44 -0
  94. package/src/wasm-mesher/worker/mesherWasmTopologyPostCache.ts +63 -0
  95. package/src/worldView/types.ts +3 -0
  96. package/src/worldView/worldView.geometryReload.test.ts +68 -0
  97. package/src/worldView/worldView.spiral.test.ts +1 -1
  98. package/src/worldView/worldView.ts +49 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minecraft-renderer",
3
- "version": "0.1.106",
3
+ "version": "0.1.108",
4
4
  "description": "The most Modular Minecraft world renderer with Three.js WebGL backend",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,25 @@
1
+ //@ts-nocheck
2
+ import { mkdtemp, readFile, writeFile } from 'node:fs/promises'
3
+ import { tmpdir } from 'node:os'
4
+ import { join } from 'node:path'
5
+ import { describe, expect, it } from 'vitest'
6
+ import { bundlePrepareMesherWorkers, MESHER_DIST_FILES } from './bundlePrepare'
7
+
8
+ describe('MESHER_DIST_FILES', () => {
9
+ it('is the source of truth for lightOwnerWorker.js', () => {
10
+ expect(MESHER_DIST_FILES).toContain('lightOwnerWorker.js')
11
+ expect(MESHER_DIST_FILES).toContain('lightOwnerWorker.js.map')
12
+ })
13
+
14
+ it('copies lightOwnerWorker.js from renderer dist', async () => {
15
+ const mesherDistDir = await mkdtemp(join(tmpdir(), 'renderer-dist-'))
16
+ const outDir = await mkdtemp(join(tmpdir(), 'app-dist-'))
17
+ for (const name of MESHER_DIST_FILES) {
18
+ await writeFile(join(mesherDistDir, name), `asset:${name}`)
19
+ }
20
+
21
+ const copied = await bundlePrepareMesherWorkers({ cwd: outDir, mesherDistDir, outDir })
22
+ expect(copied.some(path => path.endsWith('lightOwnerWorker.js'))).toBe(true)
23
+ expect(await readFile(join(outDir, 'lightOwnerWorker.js'), 'utf8')).toBe('asset:lightOwnerWorker.js')
24
+ })
25
+ })
@@ -4,7 +4,7 @@ import { createRequire } from 'node:module'
4
4
  import path from 'node:path'
5
5
 
6
6
  /** Worker-related basenames inside `minecraft-renderer`/`dist`; skipped if missing. */
7
- export const MESHER_DIST_FILES = ['mesher.js', 'mesher.js.map', 'mesherWasm.js', 'mesherWasm.js.map'] as const
7
+ export const MESHER_DIST_FILES = ['mesher.js', 'mesher.js.map', 'mesherWasm.js', 'mesherWasm.js.map', 'lightOwnerWorker.js', 'lightOwnerWorker.js.map'] as const
8
8
 
9
9
  export type BundlePrepareMesherOptions = {
10
10
  cwd?: string
@@ -25,6 +25,7 @@ import type {
25
25
  import { WorldView, WorldProvider, WorldViewWorker } from '../worldView'
26
26
  import { getInitialPlayerState } from './playerState'
27
27
  import { defaultWorldRendererConfig, defaultGraphicsBackendConfig, getDefaultRendererState, WorldRendererConfig } from './config'
28
+ import { maybeEnableClientLightTraceFromLocation } from '../lighting/debug/clientLightTrace'
28
29
  import { PlayerStateReactive } from '../playerState/playerState'
29
30
  import { ResourcesManager, ResourcesManagerTransferred } from '../resourcesManager'
30
31
  import { preloadMesherWorkerScript } from './preloadWorkers'
@@ -102,6 +103,20 @@ export class AppViewer {
102
103
  ...defaultWorldRendererConfig,
103
104
  ...options.rendererConfig
104
105
  })
106
+ // Manual live-test hatch: `?clientLight=1` sets `enableClientLightOwner`. Spawn still
107
+ // requires session version 1.17.1 (`shouldSpawnClientLightOwner`); other versions keep
108
+ // server light. An explicit code override always wins; without a browser location this
109
+ // is a no-op (unit tests keep testing the default).
110
+ if (options.rendererConfig?.enableClientLightOwner === undefined && typeof location !== 'undefined') {
111
+ try {
112
+ if (new URLSearchParams(location.search).get('clientLight') === '1') {
113
+ this.inWorldRenderingConfig.enableClientLightOwner = true
114
+ }
115
+ } catch {
116
+ // ignore malformed URL in non-browser runtimes
117
+ }
118
+ }
119
+ maybeEnableClientLightTraceFromLocation()
105
120
 
106
121
  const defaultState = getDefaultRendererState()
107
122
  this.rendererState = defaultState.reactive
@@ -43,6 +43,11 @@ export const defaultWorldRendererConfig = {
43
43
  * remeshing (change worker). When true, initial chunk meshing is
44
44
  * distributed only across workers[0 .. n-2]. */
45
45
  dedicatedChangeWorker: false,
46
+ /**
47
+ * Dedicated WASM light-owner worker. Default OFF: wiring exists so a
48
+ * human can flip this for live 1.17.1 runs. Do not enable for players.
49
+ */
50
+ enableClientLightOwner: false,
46
51
 
47
52
  // Rendering engine settings
48
53
  /** Face shading: vanilla Minecraft vs higher-contrast client look */
@@ -54,6 +59,9 @@ export const defaultWorldRendererConfig = {
54
59
  enableLighting: true,
55
60
  starfield: true,
56
61
  defaultSkybox: true,
62
+ clouds: true,
63
+ /** World Y of the cloud layer (vanilla overworld: 192 since 1.18, 128 before). */
64
+ cloudHeight: 192,
57
65
  renderEntities: true,
58
66
  extraBlockRenderers: true,
59
67
  foreground: true,
@@ -0,0 +1,51 @@
1
+ //@ts-nocheck
2
+ import { describe, expect, it } from 'vitest'
3
+ import { migrateRendererOptions, RENDERER_DEFAULT_OPTIONS, resolveEnableLighting } from './rendererDefaultOptions'
4
+
5
+ describe('migrateRendererOptions', () => {
6
+ it('drops the leaked migration flag so it is not a user option', () => {
7
+ const saved: Record<string, unknown> = {
8
+ newVersionsLighting: false,
9
+ migratedNewVersionsLightingDefault: true
10
+ }
11
+ migrateRendererOptions(saved)
12
+ expect(saved.newVersionsLighting).toBe(false)
13
+ expect(saved).not.toHaveProperty('migratedNewVersionsLightingDefault')
14
+ })
15
+ })
16
+
17
+ describe('newer-version lighting defaults', () => {
18
+ it('keeps lighting opt-in on 1.13+', () => {
19
+ expect(RENDERER_DEFAULT_OPTIONS.newVersionsLighting).toBe(false)
20
+ expect(resolveEnableLighting(RENDERER_DEFAULT_OPTIONS.newVersionsLighting, true)).toBe(false)
21
+ })
22
+
23
+ it.each([false, true])('preserves a saved lighting preference (%s)', value => {
24
+ const saved: Record<string, unknown> = { newVersionsLighting: value }
25
+ migrateRendererOptions(saved)
26
+ expect(saved.newVersionsLighting).toBe(value)
27
+ })
28
+
29
+ it('does not invent a stored value when the key was never saved', () => {
30
+ const saved: Record<string, unknown> = {}
31
+ migrateRendererOptions(saved)
32
+ expect(saved).not.toHaveProperty('newVersionsLighting')
33
+ })
34
+ })
35
+
36
+ describe('resolveEnableLighting', () => {
37
+ it('follows the option on 1.13+ (blockStateId)', () => {
38
+ expect(resolveEnableLighting(true, true)).toBe(true)
39
+ expect(resolveEnableLighting(false, true)).toBe(false)
40
+ })
41
+
42
+ it('always enables lighting on pre-1.13', () => {
43
+ expect(resolveEnableLighting(false, false)).toBe(true)
44
+ expect(resolveEnableLighting(true, false)).toBe(true)
45
+ })
46
+
47
+ it('treats a missing protocol probe as pre-1.13 so a menu toggle cannot throw', () => {
48
+ expect(resolveEnableLighting(false, undefined)).toBe(true)
49
+ expect(resolveEnableLighting(true, undefined)).toBe(true)
50
+ })
51
+ })
@@ -46,6 +46,7 @@ export const RENDERER_DEFAULT_OPTIONS = {
46
46
  rendererWorldPerformance: 'normal' as 'low-energy' | 'normal' | 'maximum',
47
47
  rendererMeshersCountOverride: null as number | null,
48
48
  starfieldRendering: true as boolean,
49
+ cloudsRendering: true as boolean,
49
50
  defaultSkybox: true as boolean,
50
51
  menuBackgroundMode: MB.mode,
51
52
  menuBackgroundMinecraftTextures: MB.minecraftTextures as boolean,
@@ -122,6 +123,17 @@ export function migrateRendererOptions(saved: Record<string, unknown>): void {
122
123
  }
123
124
  delete saved[oldKey]
124
125
  }
126
+
127
+ // Internal one-shot flag from an earlier lighting-default migration. Never a user option.
128
+ delete saved.migratedNewVersionsLightingDefault
129
+ }
130
+
131
+ /**
132
+ * Runtime `enableLighting` from the stored option and protocol.
133
+ * Pre-1.13 (no blockStateId) always lights. Missing protocol (menu, no bot) must not throw.
134
+ */
135
+ export function resolveEnableLighting(newVersionsLighting: boolean, blockStateIdSupported: boolean | undefined): boolean {
136
+ return blockStateIdSupported !== true || newVersionsLighting
125
137
  }
126
138
 
127
139
  /** Settings UI metadata for {@link RENDERER_DEFAULT_OPTIONS} keys. */
@@ -175,6 +187,9 @@ export const RENDERER_OPTIONS_META: Partial<Record<RendererDefaultOptionKey, Ren
175
187
  starfieldRendering: {
176
188
  text: 'Starfield'
177
189
  },
190
+ cloudsRendering: {
191
+ text: 'Clouds'
192
+ },
178
193
  defaultSkybox: {
179
194
  text: 'Default skybox'
180
195
  },
@@ -236,7 +251,8 @@ export const RENDERER_OPTIONS_META: Partial<Record<RendererDefaultOptionKey, Ren
236
251
  },
237
252
  smoothLighting: {},
238
253
  newVersionsLighting: {
239
- text: 'Lighting in newer versions'
254
+ text: 'Lighting in newer versions',
255
+ tooltip: 'Block, sky, and entity lighting for 1.13+. Off renders the world fullbright.'
240
256
  },
241
257
  vrSupport: {
242
258
  text: 'VR support',
@@ -298,6 +314,7 @@ export const RENDERER_RENDER_GUI_SECTIONS: ReadonlyArray<{
298
314
  keys: [
299
315
  'rendererWorldPerformance',
300
316
  'starfieldRendering',
317
+ 'cloudsRendering',
301
318
  'defaultSkybox',
302
319
  'disableBlockEntityTextures',
303
320
  'showChunkBorders',
@@ -7,7 +7,7 @@
7
7
  import { subscribe } from 'valtio/vanilla'
8
8
  import type { AppViewer } from './appViewer'
9
9
  import type { RendererStorageOptions } from './rendererDefaultOptions'
10
- import { rendererShaderCubeDebugModeToValue } from './rendererDefaultOptions'
10
+ import { rendererShaderCubeDebugModeToValue, resolveEnableLighting } from './rendererDefaultOptions'
11
11
  import type { MenuBackgroundOptions } from '../three/menuBackground/types'
12
12
  import type { MenuBackgroundRenderer } from '../three/menuBackground/renderer'
13
13
  import { menuBackgroundSpeedToMultiplier } from '../three/menuBackground/config'
@@ -153,6 +153,7 @@ export function applyRendererOptions(appViewer: AppViewer, o: RendererStorageOpt
153
153
  cfg.smoothLighting = o.smoothLighting
154
154
  cfg.shadingTheme = o.vanillaLook ? 'vanilla' : 'high-contrast'
155
155
  cfg.starfield = o.starfieldRendering
156
+ cfg.clouds = o.cloudsRendering
156
157
  cfg.defaultSkybox = o.defaultSkybox
157
158
  cfg.fov = o.fov
158
159
  cfg.shaderCubeDebugMode = rendererShaderCubeDebugModeToValue(o.rendererShaderCubeDebugMode)
@@ -216,6 +217,6 @@ export function subscribeRendererOptions<T extends RendererStorageOptions>(
216
217
  }
217
218
 
218
219
  /** Call when mineflayer bot is created (lighting depends on protocol features). */
219
- export function applyRendererEnableLighting(appViewer: AppViewer, newVersionsLighting: boolean, blockStateIdSupported: boolean): void {
220
- appViewer.inWorldRenderingConfig.enableLighting = !blockStateIdSupported || newVersionsLighting
220
+ export function applyRendererEnableLighting(appViewer: AppViewer, newVersionsLighting: boolean, blockStateIdSupported: boolean | undefined): void {
221
+ appViewer.inWorldRenderingConfig.enableLighting = resolveEnableLighting(newVersionsLighting, blockStateIdSupported)
221
222
  }
@@ -41,6 +41,10 @@ export class BlockEntityLightRegistry {
41
41
  return this.skyLevel
42
42
  }
43
43
 
44
+ getLightmapParams(): BlockLightmapParams {
45
+ return { ...this.lightmapParams }
46
+ }
47
+
44
48
  private refreshAll(): void {
45
49
  for (const entry of this.entries) {
46
50
  this.applyBrightness(entry)
@@ -29,6 +29,23 @@ export const getCelestialAngle = (timeOfDay: number): number => {
29
29
  return smoothedAngle
30
30
  }
31
31
 
32
+ /**
33
+ * Vanilla `DimensionType.timeOfDay`: 0 = noon (sun overhead), 0.25 = sunset, 0.5 = midnight,
34
+ * ~0.78 at tick 0 (sunrise). Drives sun/moon placement and sky/cloud brightness.
35
+ */
36
+ export const vanillaCelestialAngle = (timeOfDay: number): number => {
37
+ const t = timeOfDay / 24_000 - 0.25
38
+ const d = t - Math.floor(t)
39
+ const e = 0.5 - Math.cos(d * Math.PI) / 2
40
+ return (d * 2 + e) / 3
41
+ }
42
+
43
+ /** Vanilla daylight factor (0 at night, 1 at day) used to tint clouds and celestial bodies. */
44
+ export const vanillaDayBrightness = (celestialAngle: number): number => {
45
+ const b = Math.cos(celestialAngle * Math.PI * 2) * 2 + 0.5
46
+ return Math.max(0, Math.min(1, b))
47
+ }
48
+
32
49
  /**
33
50
  * Calculate sky light level (0-15) based on time of day in ticks.
34
51
  * Matches Minecraft vanilla behavior.