minecraft-renderer 0.1.79 → 0.1.80

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 (200) hide show
  1. package/README.md +29 -25
  2. package/dist/mesher.js +36 -36
  3. package/dist/mesher.js.map +4 -4
  4. package/dist/mesherWasm.js +217 -217
  5. package/dist/minecraft-renderer.js +27 -27
  6. package/dist/minecraft-renderer.js.meta.json +1 -1
  7. package/dist/threeWorker.js +133 -133
  8. package/package.json +5 -2
  9. package/src/bundler/bundlePrepare.ts +3 -8
  10. package/src/graphicsBackend/appViewer.ts +10 -7
  11. package/src/graphicsBackend/config.ts +1 -5
  12. package/src/graphicsBackend/playerState.ts +35 -34
  13. package/src/graphicsBackend/preloadWorkers.ts +43 -41
  14. package/src/graphicsBackend/rendererDefaultOptions.ts +68 -70
  15. package/src/graphicsBackend/rendererOptionsSync.ts +24 -50
  16. package/src/graphicsBackend/types.ts +2 -2
  17. package/src/index.ts +6 -27
  18. package/src/lib/DebugGui.ts +34 -31
  19. package/src/lib/animationController.ts +9 -9
  20. package/src/lib/bakeLegacyLight.ts +1 -6
  21. package/src/lib/bindAbortableListener.test.ts +32 -12
  22. package/src/lib/bindAbortableListener.ts +14 -6
  23. package/src/lib/blockEntityLightRegistry.ts +11 -20
  24. package/src/lib/blockEntityLighting.test.ts +1 -6
  25. package/src/lib/blockEntityLighting.ts +5 -5
  26. package/src/lib/buildSharedConfig.mjs +4 -4
  27. package/src/lib/buildWorkerMcDataIndexes.test.ts +4 -4
  28. package/src/lib/buildWorkerMcDataIndexes.ts +11 -19
  29. package/src/lib/cameraBobbing.ts +1 -1
  30. package/src/lib/canvas2DOverlay.example.ts +13 -33
  31. package/src/lib/canvas2DOverlay.quickstart.ts +24 -54
  32. package/src/lib/canvas2DOverlay.ts +28 -47
  33. package/src/lib/cleanupDecorator.ts +2 -2
  34. package/src/lib/createPlayerObject.test.ts +2 -7
  35. package/src/lib/createPlayerObject.ts +18 -25
  36. package/src/lib/frameTimingCollector.ts +2 -5
  37. package/src/lib/guiRenderer.ts +57 -42
  38. package/src/lib/items.ts +15 -9
  39. package/src/lib/mesherlogReader.ts +5 -6
  40. package/src/lib/simpleUtils.ts +5 -5
  41. package/src/lib/skyLight.ts +3 -3
  42. package/src/lib/smoothSwitcher.ts +11 -18
  43. package/src/lib/ui/newStats.ts +10 -12
  44. package/src/lib/utils/proxy.ts +7 -1
  45. package/src/lib/utils/skins.ts +4 -4
  46. package/src/lib/utils.ts +1 -1
  47. package/src/lib/workerMessageSanitize.ts +5 -12
  48. package/src/lib/workerProxy.ts +52 -42
  49. package/src/lib/workerSyncOps.test.ts +58 -41
  50. package/src/lib/worldrendererCommon.reconfigure.test.ts +24 -21
  51. package/src/lib/worldrendererCommon.removeColumn.test.ts +11 -13
  52. package/src/lib/worldrendererCommon.ts +338 -211
  53. package/src/mesher-legacy/mesher.ts +9 -4
  54. package/src/mesher-legacy/test/a.ts +1 -1
  55. package/src/mesher-legacy/test/mesherTester.ts +2 -2
  56. package/src/mesher-legacy/test/playground.ts +1 -1
  57. package/src/mesher-legacy/test/run/test-js.ts +1 -1
  58. package/src/mesher-legacy/test/snapshotUtils.ts +3 -8
  59. package/src/mesher-legacy/test/test-perf.ts +1 -1
  60. package/src/mesher-legacy/test/tests.test.ts +2 -2
  61. package/src/mesher-shared/blockEntityMetadata.test.ts +7 -5
  62. package/src/mesher-shared/blockEntityMetadata.ts +28 -19
  63. package/src/mesher-shared/blockPropertiesForMeshing.ts +2 -2
  64. package/src/mesher-shared/computeHeightmap.ts +2 -4
  65. package/src/mesher-shared/exportedGeometryTypes.ts +3 -3
  66. package/src/mesher-shared/faceOcclusion.ts +324 -0
  67. package/src/mesher-shared/models.ts +80 -131
  68. package/src/mesher-shared/modelsGeometryCommon.ts +30 -15
  69. package/src/mesher-shared/shared.ts +46 -46
  70. package/src/mesher-shared/standaloneRenderer.ts +40 -44
  71. package/src/mesher-shared/tests/faceOcclusion.test.ts +179 -0
  72. package/src/mesher-shared/tests/liquidQuadInvariant.test.ts +12 -8
  73. package/src/mesher-shared/vertexShading.ts +2 -11
  74. package/src/mesher-shared/world.ts +19 -19
  75. package/src/mesher-shared/worldLighting.test.ts +2 -2
  76. package/src/performanceMonitor/PerformanceMonitor.ts +4 -13
  77. package/src/performanceMonitor/formatPerformanceFactorsDebug.ts +2 -2
  78. package/src/performanceMonitor/index.ts +1 -5
  79. package/src/performanceMonitor/types.ts +1 -1
  80. package/src/playerState/playerState.ts +55 -50
  81. package/src/playerState/types.ts +2 -8
  82. package/src/playground/allEntitiesDebug.ts +19 -16
  83. package/src/playground/baseScene.ts +29 -32
  84. package/src/playground/mobileControls.tsx +133 -129
  85. package/src/playground/playground.html +76 -73
  86. package/src/playground/playground.ts +14 -1
  87. package/src/playground/playgroundUi.tsx +100 -74
  88. package/src/playground/reactUtils.ts +3 -7
  89. package/src/playground/scenes/entities.ts +10 -7
  90. package/src/playground/scenes/frequentUpdates.ts +5 -5
  91. package/src/playground/scenes/geometryExport.ts +6 -20
  92. package/src/playground/scenes/highPosEntityUpdates.ts +2 -10
  93. package/src/playground/scenes/index.ts +1 -1
  94. package/src/playground/scenes/lightingStarfield.ts +18 -12
  95. package/src/playground/scenes/main.ts +15 -11
  96. package/src/playground/scenes/partialBlockCulling.ts +31 -0
  97. package/src/playground/scenes/railsCobweb.ts +1 -1
  98. package/src/playground/scenes/rotationIssue.ts +1 -1
  99. package/src/playground/scenes/slabsOptimization.ts +1 -2
  100. package/src/playground/scenes/transparencyIssue.ts +1 -1
  101. package/src/playground/shared.ts +2 -2
  102. package/src/resourcesManager/resourcesManager.ts +29 -54
  103. package/src/resourcesManager/resourcesManager.worker.test.ts +6 -10
  104. package/src/shims/minecraftData.ts +70 -24
  105. package/src/sign-renderer/index.html +10 -12
  106. package/src/sign-renderer/index.ts +29 -29
  107. package/src/sign-renderer/playground.ts +22 -15
  108. package/src/sign-renderer/tests.test.ts +16 -13
  109. package/src/sign-renderer/vite.config.ts +2 -2
  110. package/src/three/appShared.ts +46 -25
  111. package/src/three/bannerRenderer.ts +33 -61
  112. package/src/three/cameraShake.ts +15 -6
  113. package/src/three/chunkMeshManager.ts +239 -282
  114. package/src/three/cinimaticScript.ts +26 -15
  115. package/src/three/cubeDrawSpans.ts +27 -37
  116. package/src/three/cubeMultiDraw.ts +9 -22
  117. package/src/three/documentRenderer.ts +15 -18
  118. package/src/three/entities.ts +175 -150
  119. package/src/three/entity/EntityMesh.ts +114 -108
  120. package/src/three/entity/animations.js +3 -3
  121. package/src/three/entity/armorModels.ts +15 -15
  122. package/src/three/entity/gltfAnimationUtils.ts +2 -5
  123. package/src/three/fireworks.ts +34 -32
  124. package/src/three/fireworksRenderer.ts +32 -29
  125. package/src/three/globalBlockBuffer.ts +167 -100
  126. package/src/three/globalLegacyBuffer.ts +257 -166
  127. package/src/three/graphicsBackendBase.ts +19 -25
  128. package/src/three/graphicsBackendOffThread.ts +12 -15
  129. package/src/three/hand.ts +21 -21
  130. package/src/three/handLegacy.ts +3 -13
  131. package/src/three/holdingBlock.ts +116 -79
  132. package/src/three/holdingBlockFactory.ts +1 -4
  133. package/src/three/holdingBlockItemIdentity.test.ts +25 -17
  134. package/src/three/holdingBlockItemIdentity.ts +9 -6
  135. package/src/three/holdingBlockLegacy.ts +113 -132
  136. package/src/three/itemMesh.ts +20 -29
  137. package/src/three/legacyMultiDraw.ts +10 -16
  138. package/src/three/legacySectionCull.ts +8 -14
  139. package/src/three/menuBackground/activeView.ts +1 -4
  140. package/src/three/menuBackground/assetUrl.ts +1 -1
  141. package/src/three/menuBackground/classic.ts +4 -12
  142. package/src/three/menuBackground/gpuPreference.ts +1 -3
  143. package/src/three/menuBackground/index.ts +2 -11
  144. package/src/three/menuBackground/renderer.ts +1 -5
  145. package/src/three/menuBackground/types.ts +1 -4
  146. package/src/three/menuBackground/v2.ts +196 -96
  147. package/src/three/menuBackground/v2Meta.ts +3 -3
  148. package/src/three/menuBackground/worldBlocks.ts +37 -35
  149. package/src/three/modules/blockBreakParticles.ts +59 -28
  150. package/src/three/modules/cameraBobbing.ts +3 -6
  151. package/src/three/modules/index.ts +1 -1
  152. package/src/three/modules/rain.ts +10 -23
  153. package/src/three/modules/sciFiWorldReveal.ts +11 -25
  154. package/src/three/modules/starfield.ts +7 -13
  155. package/src/three/renderSlot.ts +28 -16
  156. package/src/three/rendererModuleSystem.ts +1 -3
  157. package/src/three/sceneOrigin.ts +96 -33
  158. package/src/three/sectionRaycastAabb.ts +30 -18
  159. package/src/three/shaderCubeMesh.ts +6 -17
  160. package/src/three/shaders/cubeBlockShader.ts +85 -96
  161. package/src/three/shaders/legacyBlockShader.ts +21 -43
  162. package/src/three/shaders/textureIndexMapping.ts +89 -95
  163. package/src/three/shaders/tintPalette.ts +156 -170
  164. package/src/three/signTextureCache.ts +9 -12
  165. package/src/three/skyboxRenderer.ts +62 -70
  166. package/src/three/tests/chunkMeshManagerLegacy.test.ts +34 -34
  167. package/src/three/tests/cubeDrawSpans.test.ts +55 -25
  168. package/src/three/tests/globalBlockBuffer.test.ts +217 -0
  169. package/src/three/tests/globalLegacyBuffer.test.ts +300 -41
  170. package/src/three/tests/legacyMultiDraw.test.ts +8 -29
  171. package/src/three/tests/pr3PerFrameCpuCuts.test.ts +106 -29
  172. package/src/three/tests/signTextureCache.test.ts +4 -4
  173. package/src/three/threeJsMedia.ts +55 -72
  174. package/src/three/threeJsParticles.ts +32 -41
  175. package/src/three/threeJsSound.ts +3 -3
  176. package/src/three/threeJsUtils.ts +3 -3
  177. package/src/three/threeWorker.ts +2 -2
  178. package/src/three/waypointSprite.ts +55 -82
  179. package/src/three/waypoints.ts +20 -23
  180. package/src/three/world/cursorBlock.ts +25 -12
  181. package/src/three/world/vr.ts +11 -17
  182. package/src/three/worldGeometryExport.ts +15 -34
  183. package/src/three/worldRendererThree.ts +117 -129
  184. package/src/wasm-mesher/bridge/convertChunk.ts +3 -9
  185. package/src/wasm-mesher/bridge/render-from-wasm.ts +204 -229
  186. package/src/wasm-mesher/bridge/shaderCubeBridge.ts +26 -67
  187. package/src/wasm-mesher/tests/cullingRegression.test.ts +307 -0
  188. package/src/wasm-mesher/tests/heightmapParity.test.ts +8 -18
  189. package/src/wasm-mesher/tests/mesherWasmConversionCache.test.ts +2 -2
  190. package/src/wasm-mesher/tests/sectionRaycastAabb.test.ts +17 -4
  191. package/src/wasm-mesher/tests/shaderCubeInstances.test.ts +103 -141
  192. package/src/wasm-mesher/tests/splitColumnWasmOutput.test.ts +14 -22
  193. package/src/wasm-mesher/worker/mesherWasm.ts +150 -141
  194. package/src/wasm-mesher/worker/mesherWasmConversionCache.ts +2 -8
  195. package/src/wasm-mesher/worker/mesherWasmLightDirty.test.ts +1 -3
  196. package/src/wasm-mesher/worker/mesherWasmLightDirty.ts +1 -5
  197. package/src/wasm-mesher/worker/mesherWasmRequestTracker.ts +42 -42
  198. package/src/worldView/worldView.spiral.test.ts +1 -1
  199. package/src/worldView/worldView.ts +34 -39
  200. package/src/worldView/worldViewWorkerBridge.test.ts +4 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minecraft-renderer",
3
- "version": "0.1.79",
3
+ "version": "0.1.80",
4
4
  "description": "The most Modular Minecraft world renderer with Three.js WebGL backend",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -83,6 +83,7 @@
83
83
  "minecraft-data": "3.98.0",
84
84
  "mineflayer": "^4.33.0",
85
85
  "npm-run-all": "^4.1.5",
86
+ "prettier": "^3.8.4",
86
87
  "prismarine-block": "github:zardoy/prismarine-block#next-era",
87
88
  "prismarine-chunk": "github:zardoy/prismarine-chunk#master",
88
89
  "prismarine-world": "github:zardoy/prismarine-world#next-era",
@@ -129,6 +130,8 @@
129
130
  "unit-test": "vitest",
130
131
  "dev": "run-p watch:mesher watch:threeworker dev:playground",
131
132
  "dev:playground": "rsbuild dev --config rsbuild.config.ts",
132
- "typecheck": "tsc --noEmit"
133
+ "typecheck": "tsc --noEmit",
134
+ "format": "prettier --write .",
135
+ "format:check": "prettier --check ."
133
136
  }
134
137
  }
@@ -4,12 +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 = [
8
- 'mesher.js',
9
- 'mesher.js.map',
10
- 'mesherWasm.js',
11
- 'mesherWasm.js.map',
12
- ] as const
7
+ export const MESHER_DIST_FILES = ['mesher.js', 'mesher.js.map', 'mesherWasm.js', 'mesherWasm.js.map'] as const
13
8
 
14
9
  export type BundlePrepareMesherOptions = {
15
10
  cwd?: string
@@ -19,14 +14,14 @@ export type BundlePrepareMesherOptions = {
19
14
  files?: readonly string[]
20
15
  }
21
16
 
22
- function resolveSrcDist (opts: BundlePrepareMesherOptions | undefined, cwd: string): string {
17
+ function resolveSrcDist(opts: BundlePrepareMesherOptions | undefined, cwd: string): string {
23
18
  if (opts?.mesherDistDir) return path.resolve(cwd, opts.mesherDistDir)
24
19
  const pkg = opts?.packageName ?? 'minecraft-renderer'
25
20
  const req = createRequire(path.join(cwd, 'package.json'))
26
21
  return path.join(path.dirname(req.resolve(`${pkg}/package.json`)), 'dist')
27
22
  }
28
23
 
29
- export async function bundlePrepareMesherWorkers (opts?: BundlePrepareMesherOptions): Promise<string[]> {
24
+ export async function bundlePrepareMesherWorkers(opts?: BundlePrepareMesherOptions): Promise<string[]> {
30
25
  const cwd = opts?.cwd ?? process.cwd()
31
26
  const outDir = path.resolve(cwd, opts?.outDir ?? 'dist')
32
27
  const srcDist = resolveSrcDist(opts, cwd)
@@ -85,7 +85,10 @@ export class AppViewer {
85
85
  /** Bound by `subscribeRendererOptions` / `bindRendererOptions` — source of truth for renderer-owned settings. */
86
86
  private getRendererOptions?: () => RendererStorageOptions
87
87
 
88
- constructor(options: AppViewerOptions = {}, public resourcesManager: ResourcesManager = new ResourcesManager()) {
88
+ constructor(
89
+ options: AppViewerOptions = {},
90
+ public resourcesManager: ResourcesManager = new ResourcesManager()
91
+ ) {
89
92
  this.config = {
90
93
  ...defaultGraphicsBackendConfig,
91
94
  ...options.config
@@ -116,7 +119,7 @@ export class AppViewer {
116
119
  * Preload mesher worker script (HTTP validate + ephemeral Worker + `mc-web-ping` / `mc-web-pong`).
117
120
  * Chooses `/mesherWasm.js` vs `/mesher.js` from `inWorldRenderingConfig.wasmMesher`.
118
121
  */
119
- preloadWorkers (): Promise<void> {
122
+ preloadWorkers(): Promise<void> {
120
123
  const script = this.inWorldRenderingConfig.wasmMesher ? 'mesherWasm.js' : 'mesher.js'
121
124
  return preloadMesherWorkerScript({ script })
122
125
  }
@@ -143,7 +146,7 @@ export class AppViewer {
143
146
  config: this.config,
144
147
  getRendererOptions: this.getRendererOptions,
145
148
  callbacks: {
146
- displayCriticalError: (error) => {
149
+ displayCriticalError: error => {
147
150
  console.error('[AppViewer] Critical error:', error)
148
151
  },
149
152
  setRendererSpecificSettings: (key, value) => {
@@ -165,7 +168,7 @@ export class AppViewer {
165
168
  this.startMenuBackground(...this.currentState.args)
166
169
  } else {
167
170
  const { method, args } = this.currentState
168
- ; (this.backend as any)[method](...args)
171
+ ;(this.backend as any)[method](...args)
169
172
  }
170
173
  }
171
174
  }
@@ -290,7 +293,7 @@ export class AppViewer {
290
293
  if (this.worldView) {
291
294
  // Listen to bot events if worldView supports it
292
295
  if (typeof (this.worldView as any).listenToBot === 'function') {
293
- (this.worldView as any).listenToBot(bot)
296
+ ;(this.worldView as any).listenToBot(bot)
294
297
  }
295
298
  }
296
299
  }
@@ -301,7 +304,7 @@ export class AppViewer {
301
304
  destroyAll(): void {
302
305
  this.disconnectBackend(true)
303
306
  if (this.resourcesManager && typeof (this.resourcesManager as any).destroy === 'function') {
304
- (this.resourcesManager as any).destroy()
307
+ ;(this.resourcesManager as any).destroy()
305
308
  }
306
309
  }
307
310
 
@@ -314,7 +317,7 @@ export class AppViewer {
314
317
  async waitingForChunks(): Promise<void> {
315
318
  if ((backend as any)?.worldState?.allChunksLoaded) return
316
319
 
317
- return new Promise<void>((resolve) => {
320
+ return new Promise<void>(resolve => {
318
321
  const interval = setInterval(() => {
319
322
  if ((backend as any)?.worldState?.allChunksLoaded) {
320
323
  clearInterval(interval)
@@ -5,11 +5,7 @@
5
5
 
6
6
  import { proxy } from 'valtio'
7
7
  import { defaultPerformanceInstabilityFactors } from '../performanceMonitor'
8
- import type {
9
- GraphicsBackendConfig,
10
- RendererReactiveState,
11
- NonReactiveState
12
- } from './types'
8
+ import type { GraphicsBackendConfig, RendererReactiveState, NonReactiveState } from './types'
13
9
 
14
10
  /**
15
11
  * Default world renderer configuration.
@@ -9,40 +9,41 @@ import { PlayerStateReactive } from '../playerState/playerState'
9
9
  /**
10
10
  * Get initial player state with default values.
11
11
  */
12
- export const getInitialPlayerState = (): PlayerStateReactive => proxy({
13
- playerSkin: undefined,
14
- inWater: false,
15
- waterBreathing: false,
16
- backgroundColor: [0, 0, 0] as [number, number, number],
17
- ambientLight: 0,
18
- directionalLight: 0,
19
- eyeHeight: 0,
20
- gameMode: undefined,
21
- lookingAtBlock: undefined,
22
- diggingBlock: undefined,
23
- movementState: 'NOT_MOVING',
24
- onGround: true,
25
- sneaking: false,
26
- flying: false,
27
- sprinting: false,
28
- walkDist: 0,
29
- prevWalkDist: 0,
30
- bob: 0,
31
- prevBob: 0,
32
- itemUsageTicks: 0,
33
- username: '',
34
- onlineMode: false,
35
- cardinalLight: 'default',
36
- lightingDisabled: false,
37
- shouldHideHand: false,
38
- heldItemMain: undefined,
39
- heldItemOff: undefined,
40
- perspective: 'first_person',
41
- onFire: false,
42
- fovMultiplier: 1,
43
- cameraSpectatingEntity: undefined,
44
- team: undefined,
45
- })
12
+ export const getInitialPlayerState = (): PlayerStateReactive =>
13
+ proxy({
14
+ playerSkin: undefined,
15
+ inWater: false,
16
+ waterBreathing: false,
17
+ backgroundColor: [0, 0, 0] as [number, number, number],
18
+ ambientLight: 0,
19
+ directionalLight: 0,
20
+ eyeHeight: 0,
21
+ gameMode: undefined,
22
+ lookingAtBlock: undefined,
23
+ diggingBlock: undefined,
24
+ movementState: 'NOT_MOVING',
25
+ onGround: true,
26
+ sneaking: false,
27
+ flying: false,
28
+ sprinting: false,
29
+ walkDist: 0,
30
+ prevWalkDist: 0,
31
+ bob: 0,
32
+ prevBob: 0,
33
+ itemUsageTicks: 0,
34
+ username: '',
35
+ onlineMode: false,
36
+ cardinalLight: 'default',
37
+ lightingDisabled: false,
38
+ shouldHideHand: false,
39
+ heldItemMain: undefined,
40
+ heldItemOff: undefined,
41
+ perspective: 'first_person',
42
+ onFire: false,
43
+ fovMultiplier: 1,
44
+ cameraSpectatingEntity: undefined,
45
+ team: undefined
46
+ })
46
47
 
47
48
  /**
48
49
  * Get player state utils.
@@ -56,7 +56,7 @@ export async function preloadMesherWorkerScript(opts?: {
56
56
  res = await fetch(scriptUrl, {
57
57
  credentials: 'same-origin',
58
58
  cache: 'force-cache',
59
- signal: ctrl.signal,
59
+ signal: ctrl.signal
60
60
  })
61
61
  } finally {
62
62
  clearTimeout(t)
@@ -64,40 +64,37 @@ export async function preloadMesherWorkerScript(opts?: {
64
64
  } catch (e: unknown) {
65
65
  const err = e as { name?: string; message?: string }
66
66
  if (err?.name === 'AbortError') {
67
- throw new MesherWorkerPreloadError(
68
- `Mesher script fetch timed out after ${fetchTimeoutMs}ms (${scriptUrl}).`,
69
- { phase: 'fetch', code: 'timeout' }
70
- )
67
+ throw new MesherWorkerPreloadError(`Mesher script fetch timed out after ${fetchTimeoutMs}ms (${scriptUrl}).`, { phase: 'fetch', code: 'timeout' })
71
68
  }
72
- throw new MesherWorkerPreloadError(
73
- `Mesher script fetch failed (network): ${err?.message ?? e}. URL: ${scriptUrl}`,
74
- { phase: 'fetch', code: 'network', detail: String(err?.message ?? e) }
75
- )
69
+ throw new MesherWorkerPreloadError(`Mesher script fetch failed (network): ${err?.message ?? e}. URL: ${scriptUrl}`, {
70
+ phase: 'fetch',
71
+ code: 'network',
72
+ detail: String(err?.message ?? e)
73
+ })
76
74
  }
77
75
 
78
76
  if (!res.ok) {
79
- throw new MesherWorkerPreloadError(
80
- `Mesher script HTTP ${res.status} ${res.statusText}: ${scriptUrl}`,
81
- { phase: 'fetch', code: 'bad-status', status: res.status }
82
- )
77
+ throw new MesherWorkerPreloadError(`Mesher script HTTP ${res.status} ${res.statusText}: ${scriptUrl}`, {
78
+ phase: 'fetch',
79
+ code: 'bad-status',
80
+ status: res.status
81
+ })
83
82
  }
84
83
 
85
84
  const contentType = res.headers.get('content-type') ?? ''
86
85
  const buf = await res.arrayBuffer()
87
86
  if (buf.byteLength === 0) {
88
- throw new MesherWorkerPreloadError(
89
- `Mesher script response was empty: ${scriptUrl}`,
90
- { phase: 'fetch', code: 'invalid-body', hint: 'empty' }
91
- )
87
+ throw new MesherWorkerPreloadError(`Mesher script response was empty: ${scriptUrl}`, { phase: 'fetch', code: 'invalid-body', hint: 'empty' })
92
88
  }
93
89
 
94
90
  const headSize = Math.min(1024, buf.byteLength)
95
91
  const head = new TextDecoder().decode(buf.slice(0, headSize)).trimStart()
96
92
  if (head.startsWith('<!DOCTYPE') || head.startsWith('<html') || head.startsWith('<HTML')) {
97
- throw new MesherWorkerPreloadError(
98
- `Mesher URL returned HTML (wrong path, redirect, or SPA fallback), not JavaScript: ${scriptUrl}`,
99
- { phase: 'fetch', code: 'invalid-body', hint: 'html' }
100
- )
93
+ throw new MesherWorkerPreloadError(`Mesher URL returned HTML (wrong path, redirect, or SPA fallback), not JavaScript: ${scriptUrl}`, {
94
+ phase: 'fetch',
95
+ code: 'invalid-body',
96
+ hint: 'html'
97
+ })
101
98
  }
102
99
 
103
100
  if (contentType.length > 0 && !/javascript|ecmascript/i.test(contentType)) {
@@ -109,10 +106,11 @@ export async function preloadMesherWorkerScript(opts?: {
109
106
  worker = new Worker(scriptUrl)
110
107
  } catch (e: unknown) {
111
108
  const msg = e instanceof Error ? e.message : String(e)
112
- throw new MesherWorkerPreloadError(
113
- `Could not construct Worker for mesher (${scriptUrl}): ${msg}`,
114
- { phase: 'worker', code: 'construct-failed', message: msg }
115
- )
109
+ throw new MesherWorkerPreloadError(`Could not construct Worker for mesher (${scriptUrl}): ${msg}`, {
110
+ phase: 'worker',
111
+ code: 'construct-failed',
112
+ message: msg
113
+ })
116
114
  }
117
115
 
118
116
  await new Promise<void>((resolve, reject) => {
@@ -121,10 +119,12 @@ export async function preloadMesherWorkerScript(opts?: {
121
119
  if (settled) return
122
120
  settled = true
123
121
  cleanup()
124
- reject(new MesherWorkerPreloadError(
125
- `Mesher worker did not reply with mc-web-pong within ${pingTimeoutMs}ms (wrong script, SW stale cache, worker blocked, or COEP/CORP). URL: ${scriptUrl}`,
126
- { phase: 'ping', code: 'timeout' }
127
- ))
122
+ reject(
123
+ new MesherWorkerPreloadError(
124
+ `Mesher worker did not reply with mc-web-pong within ${pingTimeoutMs}ms (wrong script, SW stale cache, worker blocked, or COEP/CORP). URL: ${scriptUrl}`,
125
+ { phase: 'ping', code: 'timeout' }
126
+ )
127
+ )
128
128
  }, pingTimeoutMs)
129
129
 
130
130
  const cleanup = () => {
@@ -157,17 +157,22 @@ export async function preloadMesherWorkerScript(opts?: {
157
157
  }
158
158
 
159
159
  function onError(ev: ErrorEvent) {
160
- fail(new MesherWorkerPreloadError(
161
- `Mesher worker script failed to load or threw during startup: ${ev.message || 'unknown'} @ ${scriptUrl}`,
162
- { phase: 'worker', code: 'script-error', message: ev.message }
163
- ))
160
+ fail(
161
+ new MesherWorkerPreloadError(`Mesher worker script failed to load or threw during startup: ${ev.message || 'unknown'} @ ${scriptUrl}`, {
162
+ phase: 'worker',
163
+ code: 'script-error',
164
+ message: ev.message
165
+ })
166
+ )
164
167
  }
165
168
 
166
169
  function onMessageError() {
167
- fail(new MesherWorkerPreloadError(
168
- `Mesher worker message channel error (structured clone / deserialization). URL: ${scriptUrl}`,
169
- { phase: 'ping', code: 'messageerror' }
170
- ))
170
+ fail(
171
+ new MesherWorkerPreloadError(`Mesher worker message channel error (structured clone / deserialization). URL: ${scriptUrl}`, {
172
+ phase: 'ping',
173
+ code: 'messageerror'
174
+ })
175
+ )
171
176
  }
172
177
 
173
178
  worker!.addEventListener('message', onMessage)
@@ -178,10 +183,7 @@ export async function preloadMesherWorkerScript(opts?: {
178
183
  worker!.postMessage({ type: 'mc-web-ping', t: performance.now(), workerIndex: 0 })
179
184
  } catch (e: unknown) {
180
185
  const detail = e instanceof Error ? e.message : String(e)
181
- fail(new MesherWorkerPreloadError(
182
- `Failed to post mc-web-ping to mesher worker: ${detail}`,
183
- { phase: 'ping', code: 'post-failed', detail }
184
- ))
186
+ fail(new MesherWorkerPreloadError(`Failed to post mc-web-ping to mesher worker: ${detail}`, { phase: 'ping', code: 'post-failed', detail }))
185
187
  }
186
188
  })
187
189
  }
@@ -24,19 +24,14 @@ export type RendererOptionMeta = {
24
24
 
25
25
  export type RendererMesherPipeline = 'wasm' | 'legacy-js'
26
26
 
27
- export type RendererShaderCubeDebugMode =
28
- | 'off'
29
- | 'holes'
30
- | 'texIndex'
31
- | 'faces'
32
- | 'atlasAlpha'
27
+ export type RendererShaderCubeDebugMode = 'off' | 'holes' | 'texIndex' | 'faces' | 'atlasAlpha'
33
28
 
34
29
  const SHADER_CUBE_DEBUG_MODE_TO_VALUE: Record<RendererShaderCubeDebugMode, number> = {
35
30
  off: 0,
36
31
  holes: 1,
37
32
  texIndex: 2,
38
33
  faces: 3,
39
- atlasAlpha: 4,
34
+ atlasAlpha: 4
40
35
  }
41
36
 
42
37
  /** Maps stored option → `inWorldRenderingConfig.shaderCubeDebugMode` (0–4). */
@@ -119,7 +114,7 @@ export function migrateRendererOptions(saved: Record<string, unknown>): void {
119
114
  ['menuBackgroundFuturisticCamera', 'menuBackgroundV2Camera'],
120
115
  ['menuBackgroundFuturisticBlockGroup', 'menuBackgroundV2BlockGroup'],
121
116
  ['menuBackgroundFuturisticCameraSpeed', 'menuBackgroundV2CameraSpeed'],
122
- ['menuBackgroundFuturisticBlockSpeed', 'menuBackgroundV2BlockSpeed'],
117
+ ['menuBackgroundFuturisticBlockSpeed', 'menuBackgroundV2BlockSpeed']
123
118
  ]
124
119
  for (const [oldKey, newKey] of futuristicToV2) {
125
120
  if (saved[oldKey] !== undefined && saved[newKey] === undefined) {
@@ -132,7 +127,10 @@ export function migrateRendererOptions(saved: Record<string, unknown>): void {
132
127
  /** Settings UI metadata for {@link RENDERER_DEFAULT_OPTIONS} keys. */
133
128
  export const RENDERER_OPTIONS_META: Partial<Record<RendererDefaultOptionKey, RendererOptionMeta>> = {
134
129
  menuBackgroundMode: {
135
- possibleValues: [['classic', 'Classic'], ['v2', 'V2']],
130
+ possibleValues: [
131
+ ['classic', 'Classic'],
132
+ ['v2', 'V2']
133
+ ],
136
134
  requiresRestart: true
137
135
  },
138
136
  menuBackgroundMinecraftTextures: {
@@ -191,10 +189,14 @@ export const RENDERER_OPTIONS_META: Partial<Record<RendererDefaultOptionKey, Ren
191
189
  tooltip: 'Skips signs, banners, heads, maps, etc.'
192
190
  },
193
191
  rendererMesher: {
194
- possibleValues: [['wasm', 'WASM'], ['legacy-js', 'Legacy JS']],
192
+ possibleValues: [
193
+ ['wasm', 'WASM'],
194
+ ['legacy-js', 'Legacy JS']
195
+ ],
195
196
  text: 'Mesher pipeline',
196
- tooltip: 'Browser technology for processing world geometry before render. WASM is the fastest; if you see a dead tab icon, reloads, or other errors, switch to Legacy JS.',
197
- requiresChunksReload: true,
197
+ tooltip:
198
+ 'Browser technology for processing world geometry before render. WASM is the fastest; if you see a dead tab icon, reloads, or other errors, switch to Legacy JS.',
199
+ requiresChunksReload: true
198
200
  },
199
201
  rendererShaderCubeDebugMode: {
200
202
  text: 'Shader cube debug',
@@ -204,8 +206,8 @@ export const RENDERER_OPTIONS_META: Partial<Record<RendererDefaultOptionKey, Ren
204
206
  ['holes', 'Hole test (red)'],
205
207
  ['texIndex', 'Tile index colors'],
206
208
  ['faces', 'Face id colors'],
207
- ['atlasAlpha', 'Atlas alpha'],
208
- ],
209
+ ['atlasAlpha', 'Atlas alpha']
210
+ ]
209
211
  },
210
212
  showChunkBorders: {
211
213
  text: 'Chunk borders'
@@ -291,59 +293,55 @@ export const RENDERER_RENDER_GUI_SECTIONS: ReadonlyArray<{
291
293
  title: string
292
294
  keys: readonly RendererDefaultOptionKey[]
293
295
  }> = [
294
- {
295
- title: 'World rendering',
296
- keys: [
297
- 'rendererWorldPerformance',
298
- 'starfieldRendering',
299
- 'defaultSkybox',
300
- 'disableBlockEntityTextures',
301
- 'showChunkBorders',
302
- 'renderEntities',
303
- 'smoothLighting',
304
- 'vanillaLook',
305
- 'newVersionsLighting',
306
- 'dayCycleAndLighting',
307
- 'loadPlayerSkins',
308
- 'renderEars',
309
- 'showHand',
310
- 'viewBobbing',
311
- 'fov',
312
- 'keepChunksDistance',
313
- 'highlightBlockColor',
314
- 'clipWorldBelowY'
315
- ]
316
- },
317
- {
318
- title: 'Frame pacing',
319
- keys: ['frameLimit', 'backgroundRendering', 'renderDebug', 'gpuPreference']
320
- },
321
- {
322
- title: 'VR',
323
- keys: ['vrSupport', 'vrPageGameRendering']
324
- },
325
- {
326
- title: 'Menu background',
327
- keys: [
328
- 'menuBackgroundMode',
329
- 'menuBackgroundMinecraftTextures',
330
- 'menuBackgroundV2Scene',
331
- 'menuBackgroundV2Camera',
332
- 'menuBackgroundV2BlockGroup',
333
- 'menuBackgroundV2CameraSpeed',
334
- 'menuBackgroundV2BlockSpeed'
335
- ]
336
- },
337
- {
338
- title: 'Mesher',
339
- keys: ['rendererMesher']
340
- },
341
- {
342
- title: 'Renderer debug',
343
- keys: [
344
- 'rendererFuturisticReveal',
345
- 'rendererPerfDebugOverlay',
346
- 'rendererShaderCubeDebugMode',
347
- ]
348
- }
349
- ]
296
+ {
297
+ title: 'World rendering',
298
+ keys: [
299
+ 'rendererWorldPerformance',
300
+ 'starfieldRendering',
301
+ 'defaultSkybox',
302
+ 'disableBlockEntityTextures',
303
+ 'showChunkBorders',
304
+ 'renderEntities',
305
+ 'smoothLighting',
306
+ 'vanillaLook',
307
+ 'newVersionsLighting',
308
+ 'dayCycleAndLighting',
309
+ 'loadPlayerSkins',
310
+ 'renderEars',
311
+ 'showHand',
312
+ 'viewBobbing',
313
+ 'fov',
314
+ 'keepChunksDistance',
315
+ 'highlightBlockColor',
316
+ 'clipWorldBelowY'
317
+ ]
318
+ },
319
+ {
320
+ title: 'Frame pacing',
321
+ keys: ['frameLimit', 'backgroundRendering', 'renderDebug', 'gpuPreference']
322
+ },
323
+ {
324
+ title: 'VR',
325
+ keys: ['vrSupport', 'vrPageGameRendering']
326
+ },
327
+ {
328
+ title: 'Menu background',
329
+ keys: [
330
+ 'menuBackgroundMode',
331
+ 'menuBackgroundMinecraftTextures',
332
+ 'menuBackgroundV2Scene',
333
+ 'menuBackgroundV2Camera',
334
+ 'menuBackgroundV2BlockGroup',
335
+ 'menuBackgroundV2CameraSpeed',
336
+ 'menuBackgroundV2BlockSpeed'
337
+ ]
338
+ },
339
+ {
340
+ title: 'Mesher',
341
+ keys: ['rendererMesher']
342
+ },
343
+ {
344
+ title: 'Renderer debug',
345
+ keys: ['rendererFuturisticReveal', 'rendererPerfDebugOverlay', 'rendererShaderCubeDebugMode']
346
+ }
347
+ ]