minecraft-renderer 0.1.62 → 0.1.64

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 (36) hide show
  1. package/README.md +1 -1
  2. package/dist/mesherWasm.js +22 -22
  3. package/dist/minecraft-renderer.js +54 -54
  4. package/dist/minecraft-renderer.js.meta.json +1 -1
  5. package/dist/threeWorker.js +407 -407
  6. package/package.json +1 -1
  7. package/src/graphicsBackend/config.ts +3 -3
  8. package/src/graphicsBackend/rendererDefaultOptions.ts +41 -24
  9. package/src/graphicsBackend/rendererOptionsSync.ts +23 -23
  10. package/src/graphicsBackend/types.ts +3 -3
  11. package/src/index.ts +8 -8
  12. package/src/lib/bindAbortableListener.test.ts +65 -0
  13. package/src/lib/bindAbortableListener.ts +41 -0
  14. package/src/lib/workerProxy.ts +238 -118
  15. package/src/lib/workerSyncOps.test.ts +154 -0
  16. package/src/lib/worldrendererCommon.removeColumn.test.ts +182 -0
  17. package/src/lib/worldrendererCommon.ts +86 -54
  18. package/src/three/documentRenderer.ts +1 -1
  19. package/src/three/entities.ts +21 -11
  20. package/src/three/graphicsBackendBase.ts +18 -8
  21. package/src/three/menuBackground/activeView.ts +1 -1
  22. package/src/three/menuBackground/config.ts +9 -9
  23. package/src/three/menuBackground/index.ts +10 -10
  24. package/src/three/menuBackground/renderer.ts +12 -12
  25. package/src/three/menuBackground/types.ts +9 -9
  26. package/src/three/menuBackground/{futuristic.ts → v2.ts} +110 -59
  27. package/src/three/menuBackground/{futuristicMeta.ts → v2Meta.ts} +6 -6
  28. package/src/three/modules/rain.ts +1 -1
  29. package/src/three/worldRendererThree.ts +2 -1
  30. package/src/wasm-mesher/tests/mesherWasmRequestTracker.test.ts +29 -0
  31. package/src/wasm-mesher/worker/mesherWasm.ts +7 -0
  32. package/src/wasm-mesher/worker/mesherWasmRequestTracker.ts +10 -0
  33. package/src/worldView/worldView.spiral.test.ts +38 -0
  34. package/src/worldView/worldView.ts +41 -8
  35. package/src/worldView/worldViewWorkerBridge.test.ts +59 -0
  36. package/src/lib/workerProxy.restore.test.ts +0 -29
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minecraft-renderer",
3
- "version": "0.1.62",
3
+ "version": "0.1.64",
4
4
  "description": "The most Modular Minecraft world renderer with Three.js WebGL backend",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -117,8 +117,8 @@ export const getDefaultRendererState = (): {
117
117
  return {
118
118
  reactive: proxy({
119
119
  world: {
120
- chunksLoaded: new Set<string>(),
121
- heightmaps: new Map<string, Int16Array>(),
120
+ chunksLoaded: {},
121
+ heightmaps: {},
122
122
  allChunksLoaded: false,
123
123
  mesherWork: false,
124
124
  instabilityFactors: defaultPerformanceInstabilityFactors(),
@@ -132,7 +132,7 @@ export const getDefaultRendererState = (): {
132
132
  worstRenderTime: 0,
133
133
  avgRenderTime: 0,
134
134
  world: {
135
- chunksLoaded: new Set(),
135
+ chunksLoadedCount: 0,
136
136
  chunksTotalNumber: 0,
137
137
  chunksFullInfo: '-'
138
138
  },
@@ -1,12 +1,12 @@
1
1
  //@ts-nocheck
2
2
  import {
3
- FUTURISTIC_CAMERA_IDS,
4
- FUTURISTIC_CAMERA_LABELS,
5
- FUTURISTIC_SCENE_IDS,
6
- FUTURISTIC_SCENE_LABELS,
3
+ V2_CAMERA_IDS,
4
+ V2_CAMERA_LABELS,
5
+ V2_SCENE_IDS,
6
+ V2_SCENE_LABELS,
7
7
  MINECRAFT_BLOCK_GROUP_IDS,
8
8
  MINECRAFT_BLOCK_GROUP_LABELS
9
- } from '../three/menuBackground/futuristicMeta'
9
+ } from '../three/menuBackground/v2Meta'
10
10
  import { MENU_BACKGROUND_OPTION_DEFAULTS } from '../three/menuBackground/config'
11
11
  import type { RendererGpuPreference } from '../three/menuBackground/gpuPreference'
12
12
 
@@ -54,11 +54,11 @@ export const RENDERER_DEFAULT_OPTIONS = {
54
54
  defaultSkybox: true as boolean,
55
55
  menuBackgroundMode: MB.mode,
56
56
  menuBackgroundMinecraftTextures: MB.minecraftTextures as boolean,
57
- menuBackgroundFuturisticScene: MB.futuristicScene,
58
- menuBackgroundFuturisticCamera: MB.futuristicCamera,
59
- menuBackgroundFuturisticBlockGroup: MB.futuristicBlockGroup,
60
- menuBackgroundFuturisticCameraSpeed: MB.futuristicCameraSpeedPercent,
61
- menuBackgroundFuturisticBlockSpeed: MB.futuristicBlockSpeedPercent,
57
+ menuBackgroundV2Scene: MB.v2Scene,
58
+ menuBackgroundV2Camera: MB.v2Camera,
59
+ menuBackgroundV2BlockGroup: MB.v2BlockGroup,
60
+ menuBackgroundV2CameraSpeed: MB.v2CameraSpeedPercent,
61
+ menuBackgroundV2BlockSpeed: MB.v2BlockSpeedPercent,
62
62
  rendererFuturisticReveal: false as boolean,
63
63
  rendererPerfDebugOverlay: false as boolean,
64
64
  disableBlockEntityTextures: false as boolean,
@@ -110,37 +110,54 @@ export function migrateRendererOptions(saved: Record<string, unknown>): void {
110
110
  }
111
111
  delete saved.wasmExperimentalMesher
112
112
  delete saved.rendererWasmMesher
113
+
114
+ if (saved.menuBackgroundMode === 'futuristic') {
115
+ saved.menuBackgroundMode = 'v2'
116
+ }
117
+ const futuristicToV2: Array<[string, string]> = [
118
+ ['menuBackgroundFuturisticScene', 'menuBackgroundV2Scene'],
119
+ ['menuBackgroundFuturisticCamera', 'menuBackgroundV2Camera'],
120
+ ['menuBackgroundFuturisticBlockGroup', 'menuBackgroundV2BlockGroup'],
121
+ ['menuBackgroundFuturisticCameraSpeed', 'menuBackgroundV2CameraSpeed'],
122
+ ['menuBackgroundFuturisticBlockSpeed', 'menuBackgroundV2BlockSpeed'],
123
+ ]
124
+ for (const [oldKey, newKey] of futuristicToV2) {
125
+ if (saved[oldKey] !== undefined && saved[newKey] === undefined) {
126
+ saved[newKey] = saved[oldKey]
127
+ }
128
+ delete saved[oldKey]
129
+ }
113
130
  }
114
131
 
115
132
  /** Settings UI metadata for {@link RENDERER_DEFAULT_OPTIONS} keys. */
116
133
  export const RENDERER_OPTIONS_META: Partial<Record<RendererDefaultOptionKey, RendererOptionMeta>> = {
117
134
  menuBackgroundMode: {
118
- possibleValues: [['classic', 'Classic'], ['futuristic', 'Futuristic']],
135
+ possibleValues: [['classic', 'Classic'], ['v2', 'V2']],
119
136
  requiresRestart: true
120
137
  },
121
138
  menuBackgroundMinecraftTextures: {
122
139
  text: 'Minecraft block textures',
123
- tooltip: 'Use block atlas on futuristic menu cubes (loads assets on menu)'
140
+ tooltip: 'Use block atlas on V2 menu cubes (loads assets on menu)'
124
141
  },
125
- menuBackgroundFuturisticScene: {
126
- possibleValues: FUTURISTIC_SCENE_IDS.map(id => [id, FUTURISTIC_SCENE_LABELS[id]] as [string, string])
142
+ menuBackgroundV2Scene: {
143
+ possibleValues: V2_SCENE_IDS.map(id => [id, V2_SCENE_LABELS[id]] as [string, string])
127
144
  },
128
- menuBackgroundFuturisticCamera: {
129
- possibleValues: FUTURISTIC_CAMERA_IDS.map(id => [id, FUTURISTIC_CAMERA_LABELS[id]] as [string, string])
145
+ menuBackgroundV2Camera: {
146
+ possibleValues: V2_CAMERA_IDS.map(id => [id, V2_CAMERA_LABELS[id]] as [string, string])
130
147
  },
131
- menuBackgroundFuturisticBlockGroup: {
148
+ menuBackgroundV2BlockGroup: {
132
149
  possibleValues: MINECRAFT_BLOCK_GROUP_IDS.map(id => [id, MINECRAFT_BLOCK_GROUP_LABELS[id]] as [string, string]),
133
150
  text: 'Block pool',
134
151
  tooltip: 'Block set for textured menu cubes (requires Minecraft textures)'
135
152
  },
136
- menuBackgroundFuturisticCameraSpeed: {
153
+ menuBackgroundV2CameraSpeed: {
137
154
  text: 'Camera speed',
138
155
  tooltip: 'Orbit / fly-through camera path speed. 0 freezes the path; mouse parallax still works.',
139
156
  min: 0,
140
157
  max: 200,
141
158
  unit: '%'
142
159
  },
143
- menuBackgroundFuturisticBlockSpeed: {
160
+ menuBackgroundV2BlockSpeed: {
144
161
  text: 'Block speed',
145
162
  tooltip: 'Floating blocks and sky rotation. Independent of camera path speed.',
146
163
  min: 0,
@@ -315,11 +332,11 @@ export const RENDERER_RENDER_GUI_SECTIONS: ReadonlyArray<{
315
332
  keys: [
316
333
  'menuBackgroundMode',
317
334
  'menuBackgroundMinecraftTextures',
318
- 'menuBackgroundFuturisticScene',
319
- 'menuBackgroundFuturisticCamera',
320
- 'menuBackgroundFuturisticBlockGroup',
321
- 'menuBackgroundFuturisticCameraSpeed',
322
- 'menuBackgroundFuturisticBlockSpeed'
335
+ 'menuBackgroundV2Scene',
336
+ 'menuBackgroundV2Camera',
337
+ 'menuBackgroundV2BlockGroup',
338
+ 'menuBackgroundV2CameraSpeed',
339
+ 'menuBackgroundV2BlockSpeed'
323
340
  ]
324
341
  },
325
342
  {
@@ -11,7 +11,7 @@ import { rendererShaderCubeDebugModeToValue } 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'
14
- import type { FuturisticCameraId, FuturisticSceneId, MinecraftBlockGroupId } from '../three/menuBackground/futuristic'
14
+ import type { V2CameraId, V2SceneId, MinecraftBlockGroupId } from '../three/menuBackground/v2'
15
15
  import { setSkinsConfig } from '../lib/utils/skins'
16
16
 
17
17
  export type { RendererStorageOptions } from './rendererDefaultOptions'
@@ -37,20 +37,20 @@ export function menuBackgroundOptionsFromStorage(o: Pick<
37
37
  RendererStorageOptions,
38
38
  | 'menuBackgroundMode'
39
39
  | 'menuBackgroundMinecraftTextures'
40
- | 'menuBackgroundFuturisticScene'
41
- | 'menuBackgroundFuturisticCamera'
42
- | 'menuBackgroundFuturisticBlockGroup'
43
- | 'menuBackgroundFuturisticCameraSpeed'
44
- | 'menuBackgroundFuturisticBlockSpeed'
40
+ | 'menuBackgroundV2Scene'
41
+ | 'menuBackgroundV2Camera'
42
+ | 'menuBackgroundV2BlockGroup'
43
+ | 'menuBackgroundV2CameraSpeed'
44
+ | 'menuBackgroundV2BlockSpeed'
45
45
  >): MenuBackgroundOptions {
46
46
  return {
47
47
  mode: o.menuBackgroundMode as MenuBackgroundOptions['mode'],
48
48
  useMinecraftTextures: o.menuBackgroundMinecraftTextures,
49
- futuristicScene: o.menuBackgroundFuturisticScene as FuturisticSceneId,
50
- futuristicCamera: o.menuBackgroundFuturisticCamera as FuturisticCameraId,
51
- futuristicBlockGroup: o.menuBackgroundFuturisticBlockGroup as MinecraftBlockGroupId,
52
- futuristicCameraSpeed: menuBackgroundSpeedToMultiplier(o.menuBackgroundFuturisticCameraSpeed),
53
- futuristicBlockSpeed: menuBackgroundSpeedToMultiplier(o.menuBackgroundFuturisticBlockSpeed),
49
+ v2Scene: o.menuBackgroundV2Scene as V2SceneId,
50
+ v2Camera: o.menuBackgroundV2Camera as V2CameraId,
51
+ v2BlockGroup: o.menuBackgroundV2BlockGroup as MinecraftBlockGroupId,
52
+ v2CameraSpeed: menuBackgroundSpeedToMultiplier(o.menuBackgroundV2CameraSpeed),
53
+ v2BlockSpeed: menuBackgroundSpeedToMultiplier(o.menuBackgroundV2BlockSpeed),
54
54
  }
55
55
  }
56
56
 
@@ -58,20 +58,20 @@ export function applyMenuBackgroundLiveOptions(
58
58
  menu: MenuBackgroundRenderer,
59
59
  o: Pick<
60
60
  RendererStorageOptions,
61
- | 'menuBackgroundFuturisticScene'
62
- | 'menuBackgroundFuturisticCamera'
63
- | 'menuBackgroundFuturisticBlockGroup'
64
- | 'menuBackgroundFuturisticCameraSpeed'
65
- | 'menuBackgroundFuturisticBlockSpeed'
61
+ | 'menuBackgroundV2Scene'
62
+ | 'menuBackgroundV2Camera'
63
+ | 'menuBackgroundV2BlockGroup'
64
+ | 'menuBackgroundV2CameraSpeed'
65
+ | 'menuBackgroundV2BlockSpeed'
66
66
  >
67
67
  ): void {
68
- const futuristic = menu.futuristic
69
- if (!futuristic) return
70
- futuristic.setScene?.(o.menuBackgroundFuturisticScene)
71
- futuristic.setCamera?.(o.menuBackgroundFuturisticCamera)
72
- void futuristic.setBlockGroup?.(o.menuBackgroundFuturisticBlockGroup)
73
- futuristic.setCameraSpeed?.(menuBackgroundSpeedToMultiplier(o.menuBackgroundFuturisticCameraSpeed))
74
- futuristic.setBlockSpeed?.(menuBackgroundSpeedToMultiplier(o.menuBackgroundFuturisticBlockSpeed))
68
+ const v2 = menu.v2
69
+ if (!v2) return
70
+ v2.setScene?.(o.menuBackgroundV2Scene)
71
+ v2.setCamera?.(o.menuBackgroundV2Camera)
72
+ void v2.setBlockGroup?.(o.menuBackgroundV2BlockGroup)
73
+ v2.setCameraSpeed?.(menuBackgroundSpeedToMultiplier(o.menuBackgroundV2CameraSpeed))
74
+ v2.setBlockSpeed?.(menuBackgroundSpeedToMultiplier(o.menuBackgroundV2BlockSpeed))
75
75
  }
76
76
 
77
77
  function resolveWasmMesherActive(o: RendererStorageOptions): boolean {
@@ -58,7 +58,7 @@ export interface NonReactiveState {
58
58
  worstRenderTime: number
59
59
  avgRenderTime: number
60
60
  world: {
61
- chunksLoaded: Set<string>
61
+ chunksLoadedCount: number
62
62
  chunksTotalNumber: number
63
63
  chunksFullInfo: string
64
64
  allChunksLoaded?: boolean
@@ -75,8 +75,8 @@ export interface NonReactiveState {
75
75
  /** Renderer reactive state */
76
76
  export interface RendererReactiveState {
77
77
  world: {
78
- chunksLoaded: Set<string>
79
- heightmaps: Map<string, Int16Array>
78
+ chunksLoaded: Record<string, true>
79
+ heightmaps: Record<string, Int16Array>
80
80
  allChunksLoaded: boolean
81
81
  mesherWork: boolean
82
82
  /** Low-FPS / render instability factors (see `performanceMonitor`). */
package/src/index.ts CHANGED
@@ -85,21 +85,21 @@ export type {
85
85
  MenuBackgroundMode,
86
86
  MenuBackgroundOptions,
87
87
  MenuBackgroundView,
88
- FuturisticSceneId,
89
- FuturisticCameraId,
90
- FuturisticMenuBackgroundOptions,
88
+ V2SceneId,
89
+ V2CameraId,
90
+ V2MenuBackgroundOptions,
91
91
  MinecraftBlockGroupId
92
92
  } from './three/menuBackground'
93
93
  export {
94
94
  MenuBackgroundRenderer,
95
95
  ClassicMenuBackground,
96
- FuturisticMenuBackground,
96
+ V2MenuBackground,
97
97
  WorldBlocksMenuBackground,
98
98
  MENU_BACKGROUND_MC_VERSION,
99
- FUTURISTIC_SCENE_IDS,
100
- FUTURISTIC_CAMERA_IDS,
101
- FUTURISTIC_SCENE_LABELS,
102
- FUTURISTIC_CAMERA_LABELS,
99
+ V2_SCENE_IDS,
100
+ V2_CAMERA_IDS,
101
+ V2_SCENE_LABELS,
102
+ V2_CAMERA_LABELS,
103
103
  MINECRAFT_BLOCK_GROUPS,
104
104
  MINECRAFT_BLOCK_GROUP_IDS,
105
105
  MINECRAFT_BLOCK_GROUP_LABELS,
@@ -0,0 +1,65 @@
1
+ //@ts-nocheck
2
+ import { EventEmitter } from 'events'
3
+ import { describe, expect, it } from 'vitest'
4
+ import { bindAbortableEmitterListener, bindAbortableListener } from './bindAbortableListener'
5
+ import { WorldViewWorker } from '../worldView'
6
+
7
+ describe('bindAbortableListener', () => {
8
+ it('removes handler on abort', () => {
9
+ const emitter = new WorldViewWorker()
10
+ const controller = new AbortController()
11
+ let calls = 0
12
+ bindAbortableListener(emitter, 'renderDistance', () => {
13
+ calls++
14
+ }, controller.signal)
15
+
16
+ emitter.emit('renderDistance', 8)
17
+ expect(calls).toBe(1)
18
+
19
+ controller.abort()
20
+ emitter.emit('renderDistance', 12)
21
+ expect(calls).toBe(1)
22
+ })
23
+
24
+ it('abort removes only the bound handler on a shared emitter', () => {
25
+ const emitter = new WorldViewWorker()
26
+ const controllerA = new AbortController()
27
+ const controllerB = new AbortController()
28
+ let callsA = 0
29
+ let callsB = 0
30
+
31
+ bindAbortableListener(emitter, 'renderDistance', () => {
32
+ callsA++
33
+ }, controllerA.signal)
34
+ bindAbortableListener(emitter, 'renderDistance', () => {
35
+ callsB++
36
+ }, controllerB.signal)
37
+
38
+ emitter.emit('renderDistance', 4)
39
+ expect(callsA).toBe(1)
40
+ expect(callsB).toBe(1)
41
+
42
+ controllerA.abort()
43
+ emitter.emit('renderDistance', 6)
44
+ expect(callsA).toBe(1)
45
+ expect(callsB).toBe(2)
46
+ })
47
+ })
48
+
49
+ describe('bindAbortableEmitterListener', () => {
50
+ it('removes handler on abort', () => {
51
+ const emitter = new EventEmitter()
52
+ const controller = new AbortController()
53
+ let calls = 0
54
+ bindAbortableEmitterListener(emitter, 'test', () => {
55
+ calls++
56
+ }, controller.signal)
57
+
58
+ emitter.emit('test')
59
+ expect(calls).toBe(1)
60
+
61
+ controller.abort()
62
+ emitter.emit('test')
63
+ expect(calls).toBe(1)
64
+ })
65
+ })
@@ -0,0 +1,41 @@
1
+ //@ts-nocheck
2
+ import type { EventEmitter } from 'events'
3
+ import type { WorldViewEvents } from '../worldView/types'
4
+ import type { WorldViewWorker } from '../worldView'
5
+
6
+ /**
7
+ * Register an EventEmitter listener removed when `signal` aborts.
8
+ * Safe for shared emitters (e.g. worldView) — only removes this handler.
9
+ */
10
+ export function bindAbortableListener<E extends keyof WorldViewEvents>(
11
+ emitter: Pick<WorldViewWorker, 'on' | 'off'>,
12
+ event: E,
13
+ handler: (...args: WorldViewEvents[E]) => void,
14
+ signal: AbortSignal
15
+ ): void {
16
+ emitter.on(event, handler as (...args: any[]) => void)
17
+ if (signal.aborted) {
18
+ emitter.off(event, handler as (...args: any[]) => void)
19
+ return
20
+ }
21
+ signal.addEventListener('abort', () => {
22
+ emitter.off(event, handler as (...args: any[]) => void)
23
+ }, { once: true })
24
+ }
25
+
26
+ /** Same pattern for plain EventEmitters (e.g. resourcesManager). */
27
+ export function bindAbortableEmitterListener(
28
+ emitter: Pick<EventEmitter, 'on' | 'off'>,
29
+ event: string,
30
+ handler: (...args: any[]) => void,
31
+ signal: AbortSignal
32
+ ): void {
33
+ emitter.on(event, handler)
34
+ if (signal.aborted) {
35
+ emitter.off(event, handler)
36
+ return
37
+ }
38
+ signal.addEventListener('abort', () => {
39
+ emitter.off(event, handler)
40
+ }, { once: true })
41
+ }