minecraft-renderer 0.1.39 → 0.1.40

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minecraft-renderer",
3
- "version": "0.1.39",
3
+ "version": "0.1.40",
4
4
  "description": "The most Modular Minecraft world renderer with Three.js WebGL backend",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -35,6 +35,10 @@ export const defaultWorldRendererConfig = {
35
35
  * iOS Safari and other low-RAM environments). Trades performance for
36
36
  * lower per-worker RAM. */
37
37
  disableMesherConversionCache: false,
38
+ /** Whether to dedicate the last worker exclusively to block-update
39
+ * remeshing (change worker). When true, initial chunk meshing is
40
+ * distributed only across workers[0 .. n-2]. */
41
+ dedicatedChangeWorker: false,
38
42
 
39
43
  // Rendering engine settings
40
44
  /** Face shading: vanilla Minecraft vs higher-contrast client look */
@@ -997,6 +997,30 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
997
997
  getWorkerNumber(pos: Vec3, updateAction = false) {
998
998
  const CHUNK_SIZE = 16
999
999
  const sectionHeight = this.getSectionHeight()
1000
+ const dedicated = this.worldRendererConfig.dedicatedChangeWorker
1001
+
1002
+ if (dedicated && this.workers.length > 1) {
1003
+ // WASM column meshing must keep all vertical sections of a chunk
1004
+ // column on one worker — skip dedicated change worker to avoid
1005
+ // concurrent column meshing across different workers.
1006
+ if (this.worldRendererConfig.wasmMesher) {
1007
+ return mod(Math.floor(pos.x / CHUNK_SIZE) + Math.floor(pos.z / CHUNK_SIZE), this.workers.length)
1008
+ }
1009
+ if (updateAction) {
1010
+ const key = `${Math.floor(pos.x / CHUNK_SIZE) * CHUNK_SIZE},${Math.floor(pos.y / sectionHeight) * sectionHeight},${Math.floor(pos.z / CHUNK_SIZE) * CHUNK_SIZE}`
1011
+ const busy = this.sectionsWaiting.get(key) && !this.finishedSections[key]
1012
+ if (busy) {
1013
+ // Section is already being meshed by a general worker — route
1014
+ // the update to the same worker to avoid concurrent meshing.
1015
+ const generalWorkers = this.workers.length - 1
1016
+ return mod(Math.floor(pos.x / CHUNK_SIZE) + Math.floor(pos.y / sectionHeight) + Math.floor(pos.z / CHUNK_SIZE), generalWorkers)
1017
+ }
1018
+ return this.workers.length - 1
1019
+ }
1020
+ const generalWorkers = this.workers.length - 1
1021
+ return mod(Math.floor(pos.x / CHUNK_SIZE) + Math.floor(pos.y / sectionHeight) + Math.floor(pos.z / CHUNK_SIZE), generalWorkers)
1022
+ }
1023
+
1000
1024
  if (this.worldRendererConfig.wasmMesher) {
1001
1025
  // WASM column meshing must keep all vertical sections of a chunk column
1002
1026
  // on one worker. Hash by x/z only and bypass the change-worker shortcut
@@ -1097,7 +1121,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
1097
1121
  // Dispatch sections to workers based on position
1098
1122
  // This guarantees uniformity accross workers and that a given section
1099
1123
  // is always dispatched to the same worker
1100
- const hash = this.getWorkerNumber(pos, useChangeWorker && this.mesherLogger.active)
1124
+ const hash = this.getWorkerNumber(pos, useChangeWorker && (this.mesherLogger.active || this.worldRendererConfig.dedicatedChangeWorker))
1101
1125
  this.sectionsWaiting.set(key, (this.sectionsWaiting.get(key) ?? 0) + 1)
1102
1126
  if (this.forceCallFromMesherReplayer) {
1103
1127
  this.workers[hash].postMessage({