minerender 2.1.0-alpha.34 → 2.1.0-alpha.36
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/dist/browser/index.d.mts +8 -13
- package/dist/browser/index.d.ts +8 -13
- package/dist/browser/index.js +62 -81
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +63 -82
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +64 -83
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +8 -13
- package/dist/node/index.d.ts +8 -13
- package/dist/node/index.js +62 -81
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +63 -82
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/browser/index.d.mts
CHANGED
|
@@ -584,13 +584,11 @@ declare class BatchedExecutor {
|
|
|
584
584
|
readonly interval: number;
|
|
585
585
|
readonly batch: number;
|
|
586
586
|
private readonly queue;
|
|
587
|
-
private readonly task;
|
|
588
587
|
constructor(interval?: number, batch?: number);
|
|
589
|
-
submit(task: Task):
|
|
590
|
-
|
|
591
|
-
private runNext;
|
|
588
|
+
submit<T>(task: Task<T>): Promise<T>;
|
|
589
|
+
stop(): void;
|
|
592
590
|
}
|
|
593
|
-
type Task = () =>
|
|
591
|
+
type Task<T = unknown> = () => T | Promise<T>;
|
|
594
592
|
|
|
595
593
|
declare function prefix(prefix?: string): string;
|
|
596
594
|
|
|
@@ -1691,7 +1689,6 @@ declare class Chunk {
|
|
|
1691
1689
|
readonly y: number;
|
|
1692
1690
|
readonly z: number;
|
|
1693
1691
|
private readonly _blocks;
|
|
1694
|
-
private readonly _anchor;
|
|
1695
1692
|
constructor(scene: MineRenderScene, x: number, y: number, z: number);
|
|
1696
1693
|
getBlockAt(x: number, y: number, z: number): Maybe<BlockInfo>;
|
|
1697
1694
|
getBlockAt(pos: Vector3): Maybe<BlockInfo>;
|
|
@@ -1703,11 +1700,12 @@ declare class Chunk {
|
|
|
1703
1700
|
setBlockAt(pos: Vector3, block: Maybe<Block>): Promise<Maybe<BlockInfo>>;
|
|
1704
1701
|
setBlockAt(pos: TripleArray, block: Maybe<Block>): Promise<Maybe<BlockInfo>>;
|
|
1705
1702
|
/**
|
|
1706
|
-
* Set block at
|
|
1703
|
+
* Set a block at integer chunk-local coordinates from 0 to 15.
|
|
1707
1704
|
*/
|
|
1708
1705
|
setBlockInChunkAt(pos: Vector3, block?: Block, worldPos?: Vector3): Promise<Maybe<BlockInfo>>;
|
|
1709
1706
|
clear(): Promise<void>;
|
|
1710
1707
|
dispose(): Promise<void>;
|
|
1708
|
+
static isAir(block: Maybe<Block>): boolean;
|
|
1711
1709
|
static chunkPosToBlockIndex(pos: Vector3): number;
|
|
1712
1710
|
worldPosToChunkPos(pos: Vector3): Vector3;
|
|
1713
1711
|
chunkPosToWorldPos(pos: Vector3): Vector3;
|
|
@@ -1715,23 +1713,20 @@ declare class Chunk {
|
|
|
1715
1713
|
|
|
1716
1714
|
declare class MineRenderWorld {
|
|
1717
1715
|
readonly scene: MineRenderScene;
|
|
1718
|
-
private _size;
|
|
1719
|
-
private _blockSize;
|
|
1720
1716
|
private readonly _chunks;
|
|
1721
1717
|
constructor(scene: MineRenderScene);
|
|
1722
1718
|
getBlockAt(x: number, y: number, z: number): Maybe<BlockInfo>;
|
|
1723
1719
|
getBlockAt(pos: Vector3): Maybe<BlockInfo>;
|
|
1724
1720
|
getBlockAt(pos: TripleArray): Maybe<BlockInfo>;
|
|
1725
|
-
setBlockAt(x: number, y: number, z: number, block: Block): Promise<Maybe<BlockInfo>>;
|
|
1726
|
-
setBlockAt(pos: Vector3, block: Block): Promise<Maybe<BlockInfo>>;
|
|
1727
|
-
setBlockAt(pos: TripleArray, block: Block): Promise<Maybe<BlockInfo>>;
|
|
1721
|
+
setBlockAt(x: number, y: number, z: number, block: Maybe<Block>): Promise<Maybe<BlockInfo>>;
|
|
1722
|
+
setBlockAt(pos: Vector3, block: Maybe<Block>): Promise<Maybe<BlockInfo>>;
|
|
1723
|
+
setBlockAt(pos: TripleArray, block: Maybe<Block>): Promise<Maybe<BlockInfo>>;
|
|
1728
1724
|
placeMultiBlock(multiblock: MultiBlockStructure, useBatches?: boolean, executor?: BatchedExecutor): Promise<void>;
|
|
1729
1725
|
clear(): Promise<void>;
|
|
1730
1726
|
private getOrCreateChunkAt;
|
|
1731
1727
|
getChunkAt(pos: Vector3): Maybe<Chunk>;
|
|
1732
1728
|
static worldToScenePosition(pos: Vector3): Vector3;
|
|
1733
1729
|
static sceneToWorldPosition(pos: Vector3): Vector3;
|
|
1734
|
-
worldPosToChunkIndex(pos: Vector3): number;
|
|
1735
1730
|
worldPosToChunkKey(pos: Vector3): string;
|
|
1736
1731
|
validatePosBounds(pos: Vector3): void;
|
|
1737
1732
|
}
|
package/dist/browser/index.d.ts
CHANGED
|
@@ -584,13 +584,11 @@ declare class BatchedExecutor {
|
|
|
584
584
|
readonly interval: number;
|
|
585
585
|
readonly batch: number;
|
|
586
586
|
private readonly queue;
|
|
587
|
-
private readonly task;
|
|
588
587
|
constructor(interval?: number, batch?: number);
|
|
589
|
-
submit(task: Task):
|
|
590
|
-
|
|
591
|
-
private runNext;
|
|
588
|
+
submit<T>(task: Task<T>): Promise<T>;
|
|
589
|
+
stop(): void;
|
|
592
590
|
}
|
|
593
|
-
type Task = () =>
|
|
591
|
+
type Task<T = unknown> = () => T | Promise<T>;
|
|
594
592
|
|
|
595
593
|
declare function prefix(prefix?: string): string;
|
|
596
594
|
|
|
@@ -1691,7 +1689,6 @@ declare class Chunk {
|
|
|
1691
1689
|
readonly y: number;
|
|
1692
1690
|
readonly z: number;
|
|
1693
1691
|
private readonly _blocks;
|
|
1694
|
-
private readonly _anchor;
|
|
1695
1692
|
constructor(scene: MineRenderScene, x: number, y: number, z: number);
|
|
1696
1693
|
getBlockAt(x: number, y: number, z: number): Maybe<BlockInfo>;
|
|
1697
1694
|
getBlockAt(pos: Vector3): Maybe<BlockInfo>;
|
|
@@ -1703,11 +1700,12 @@ declare class Chunk {
|
|
|
1703
1700
|
setBlockAt(pos: Vector3, block: Maybe<Block>): Promise<Maybe<BlockInfo>>;
|
|
1704
1701
|
setBlockAt(pos: TripleArray, block: Maybe<Block>): Promise<Maybe<BlockInfo>>;
|
|
1705
1702
|
/**
|
|
1706
|
-
* Set block at
|
|
1703
|
+
* Set a block at integer chunk-local coordinates from 0 to 15.
|
|
1707
1704
|
*/
|
|
1708
1705
|
setBlockInChunkAt(pos: Vector3, block?: Block, worldPos?: Vector3): Promise<Maybe<BlockInfo>>;
|
|
1709
1706
|
clear(): Promise<void>;
|
|
1710
1707
|
dispose(): Promise<void>;
|
|
1708
|
+
static isAir(block: Maybe<Block>): boolean;
|
|
1711
1709
|
static chunkPosToBlockIndex(pos: Vector3): number;
|
|
1712
1710
|
worldPosToChunkPos(pos: Vector3): Vector3;
|
|
1713
1711
|
chunkPosToWorldPos(pos: Vector3): Vector3;
|
|
@@ -1715,23 +1713,20 @@ declare class Chunk {
|
|
|
1715
1713
|
|
|
1716
1714
|
declare class MineRenderWorld {
|
|
1717
1715
|
readonly scene: MineRenderScene;
|
|
1718
|
-
private _size;
|
|
1719
|
-
private _blockSize;
|
|
1720
1716
|
private readonly _chunks;
|
|
1721
1717
|
constructor(scene: MineRenderScene);
|
|
1722
1718
|
getBlockAt(x: number, y: number, z: number): Maybe<BlockInfo>;
|
|
1723
1719
|
getBlockAt(pos: Vector3): Maybe<BlockInfo>;
|
|
1724
1720
|
getBlockAt(pos: TripleArray): Maybe<BlockInfo>;
|
|
1725
|
-
setBlockAt(x: number, y: number, z: number, block: Block): Promise<Maybe<BlockInfo>>;
|
|
1726
|
-
setBlockAt(pos: Vector3, block: Block): Promise<Maybe<BlockInfo>>;
|
|
1727
|
-
setBlockAt(pos: TripleArray, block: Block): Promise<Maybe<BlockInfo>>;
|
|
1721
|
+
setBlockAt(x: number, y: number, z: number, block: Maybe<Block>): Promise<Maybe<BlockInfo>>;
|
|
1722
|
+
setBlockAt(pos: Vector3, block: Maybe<Block>): Promise<Maybe<BlockInfo>>;
|
|
1723
|
+
setBlockAt(pos: TripleArray, block: Maybe<Block>): Promise<Maybe<BlockInfo>>;
|
|
1728
1724
|
placeMultiBlock(multiblock: MultiBlockStructure, useBatches?: boolean, executor?: BatchedExecutor): Promise<void>;
|
|
1729
1725
|
clear(): Promise<void>;
|
|
1730
1726
|
private getOrCreateChunkAt;
|
|
1731
1727
|
getChunkAt(pos: Vector3): Maybe<Chunk>;
|
|
1732
1728
|
static worldToScenePosition(pos: Vector3): Vector3;
|
|
1733
1729
|
static sceneToWorldPosition(pos: Vector3): Vector3;
|
|
1734
|
-
worldPosToChunkIndex(pos: Vector3): number;
|
|
1735
1730
|
worldPosToChunkKey(pos: Vector3): string;
|
|
1736
1731
|
validatePosBounds(pos: Vector3): void;
|
|
1737
1732
|
}
|
package/dist/browser/index.js
CHANGED
|
@@ -1655,24 +1655,20 @@ var AssetLoadError = class extends Error {
|
|
|
1655
1655
|
};
|
|
1656
1656
|
|
|
1657
1657
|
// src/util/BatchedExecutor.ts
|
|
1658
|
+
var import_jobqu2 = require("jobqu");
|
|
1658
1659
|
var BatchedExecutor = class {
|
|
1659
1660
|
constructor(interval = 1, batch = 30) {
|
|
1661
|
+
if (!Number.isFinite(interval) || interval < 0) throw new RangeError("Batch interval must be finite and nonnegative");
|
|
1662
|
+
if (!Number.isInteger(batch) || batch < 1) throw new RangeError("Batch size must be a positive integer");
|
|
1660
1663
|
this.interval = interval;
|
|
1661
1664
|
this.batch = batch;
|
|
1662
|
-
this.queue =
|
|
1663
|
-
this.task = setInterval(() => this.run());
|
|
1665
|
+
this.queue = new import_jobqu2.JobQueue(async (task) => task(), { interval, maxPerRun: batch, maxActive: batch });
|
|
1664
1666
|
}
|
|
1665
1667
|
submit(task) {
|
|
1666
|
-
this.queue.
|
|
1668
|
+
return this.queue.add(() => task());
|
|
1667
1669
|
}
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
this.runNext();
|
|
1671
|
-
}
|
|
1672
|
-
}
|
|
1673
|
-
runNext() {
|
|
1674
|
-
let next = this.queue.shift();
|
|
1675
|
-
if (next) next();
|
|
1670
|
+
stop() {
|
|
1671
|
+
this.queue.end();
|
|
1676
1672
|
}
|
|
1677
1673
|
};
|
|
1678
1674
|
|
|
@@ -7339,9 +7335,6 @@ var import_three25 = require("three");
|
|
|
7339
7335
|
var import_three24 = require("three");
|
|
7340
7336
|
var MineRenderWorld = class {
|
|
7341
7337
|
constructor(scene) {
|
|
7342
|
-
this._size = 4;
|
|
7343
|
-
//TODO: expandable
|
|
7344
|
-
this._blockSize = this._size * 16;
|
|
7345
7338
|
this._chunks = /* @__PURE__ */ new Map();
|
|
7346
7339
|
this.scene = scene;
|
|
7347
7340
|
}
|
|
@@ -7352,12 +7345,8 @@ var MineRenderWorld = class {
|
|
|
7352
7345
|
if (isTripleArray(posOrX)) {
|
|
7353
7346
|
return this.getBlockAt(new import_three24.Vector3(posOrX[0], posOrX[1], posOrX[2]));
|
|
7354
7347
|
}
|
|
7355
|
-
const chunk = this.getChunkAt(posOrX);
|
|
7356
|
-
if (typeof chunk === "undefined") {
|
|
7357
|
-
return void 0;
|
|
7358
|
-
}
|
|
7359
7348
|
this.validatePosBounds(posOrX);
|
|
7360
|
-
return
|
|
7349
|
+
return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
|
|
7361
7350
|
}
|
|
7362
7351
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
7363
7352
|
if (typeof posOrX == "number") {
|
|
@@ -7367,32 +7356,48 @@ var MineRenderWorld = class {
|
|
|
7367
7356
|
return this.setBlockAt(new import_three24.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
7368
7357
|
}
|
|
7369
7358
|
this.validatePosBounds(posOrX);
|
|
7370
|
-
const
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
const
|
|
7377
|
-
if (
|
|
7378
|
-
|
|
7379
|
-
|
|
7380
|
-
|
|
7381
|
-
|
|
7382
|
-
|
|
7383
|
-
|
|
7384
|
-
|
|
7359
|
+
const value = yOrBlock;
|
|
7360
|
+
const chunk = Chunk.isAir(value) ? this.getChunkAt(posOrX) : this.getOrCreateChunkAt(posOrX);
|
|
7361
|
+
return chunk?.setBlockAt(posOrX, value);
|
|
7362
|
+
}
|
|
7363
|
+
async placeMultiBlock(multiblock, useBatches = true, executor) {
|
|
7364
|
+
const keys = /* @__PURE__ */ new Map();
|
|
7365
|
+
for (const block of multiblock.blocks) {
|
|
7366
|
+
if (Chunk.isAir(block)) continue;
|
|
7367
|
+
const key = AssetKey.parse("blockstates", block.type);
|
|
7368
|
+
keys.set(key.serialize(), key);
|
|
7369
|
+
}
|
|
7370
|
+
await BlockStates.getAll(keys.values());
|
|
7371
|
+
if (!useBatches) {
|
|
7372
|
+
for (const block of multiblock.blocks) await this.setBlockAt(block.position, block);
|
|
7373
|
+
return;
|
|
7374
|
+
}
|
|
7375
|
+
const positions = /* @__PURE__ */ new Map();
|
|
7376
|
+
for (const block of multiblock.blocks) {
|
|
7377
|
+
const key = block.position.join(",");
|
|
7378
|
+
const group = positions.get(key);
|
|
7379
|
+
if (group) group.push(block);
|
|
7380
|
+
else positions.set(key, [block]);
|
|
7381
|
+
}
|
|
7382
|
+
const groups = [...positions.values()];
|
|
7383
|
+
const queue = executor ?? new BatchedExecutor();
|
|
7384
|
+
try {
|
|
7385
|
+
for (let i = 0; i < groups.length; i += queue.batch) {
|
|
7386
|
+
const results = await Promise.allSettled(groups.slice(i, i + queue.batch).map(
|
|
7387
|
+
(blocks) => queue.submit(async () => {
|
|
7388
|
+
for (const block of blocks) await this.setBlockAt(block.position, block);
|
|
7389
|
+
})
|
|
7390
|
+
));
|
|
7391
|
+
const failure = results.find((result) => result.status === "rejected");
|
|
7392
|
+
if (failure?.status === "rejected") throw failure.reason;
|
|
7385
7393
|
}
|
|
7386
|
-
}
|
|
7387
|
-
|
|
7388
|
-
await place(block);
|
|
7394
|
+
} finally {
|
|
7395
|
+
if (!executor) queue.stop();
|
|
7389
7396
|
}
|
|
7390
7397
|
}
|
|
7391
7398
|
async clear() {
|
|
7392
|
-
|
|
7393
|
-
|
|
7394
|
-
console.log("dispose chunk", chunk);
|
|
7395
|
-
await chunk?.dispose();
|
|
7399
|
+
for (const chunk of this._chunks.values()) {
|
|
7400
|
+
await chunk.dispose();
|
|
7396
7401
|
}
|
|
7397
7402
|
this._chunks.clear();
|
|
7398
7403
|
}
|
|
@@ -7406,8 +7411,7 @@ var MineRenderWorld = class {
|
|
|
7406
7411
|
return chunk;
|
|
7407
7412
|
}
|
|
7408
7413
|
getChunkAt(pos) {
|
|
7409
|
-
|
|
7410
|
-
return this._chunks[index];
|
|
7414
|
+
return this._chunks.get(this.worldPosToChunkKey(pos));
|
|
7411
7415
|
}
|
|
7412
7416
|
static worldToScenePosition(pos) {
|
|
7413
7417
|
return new import_three24.Vector3(
|
|
@@ -7423,12 +7427,6 @@ var MineRenderWorld = class {
|
|
|
7423
7427
|
pos.z / 16
|
|
7424
7428
|
);
|
|
7425
7429
|
}
|
|
7426
|
-
worldPosToChunkIndex(pos) {
|
|
7427
|
-
const chunkX = Math.floor(pos.x / 16);
|
|
7428
|
-
const chunkY = Math.floor(pos.y / 16);
|
|
7429
|
-
const chunkZ = Math.floor(pos.z / 16);
|
|
7430
|
-
return chunkZ * this._size * this._size + chunkY * this._size + chunkX;
|
|
7431
|
-
}
|
|
7432
7430
|
worldPosToChunkKey(pos) {
|
|
7433
7431
|
const chunkX = Math.floor(pos.x / 16);
|
|
7434
7432
|
const chunkY = Math.floor(pos.y / 16);
|
|
@@ -7436,12 +7434,9 @@ var MineRenderWorld = class {
|
|
|
7436
7434
|
return `${chunkX}_${chunkY}_${chunkZ}`;
|
|
7437
7435
|
}
|
|
7438
7436
|
validatePosBounds(pos) {
|
|
7439
|
-
if (pos.x
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
if (pos.x > this._blockSize) throw new Error("x>" + this._blockSize);
|
|
7443
|
-
if (pos.y > this._blockSize) throw new Error("y>" + this._blockSize);
|
|
7444
|
-
if (pos.z > this._blockSize) throw new Error("z>" + this._blockSize);
|
|
7437
|
+
if (![pos.x, pos.y, pos.z].every(Number.isInteger)) {
|
|
7438
|
+
throw new RangeError("Block coordinates must be integers");
|
|
7439
|
+
}
|
|
7445
7440
|
}
|
|
7446
7441
|
};
|
|
7447
7442
|
|
|
@@ -7454,16 +7449,6 @@ var Chunk = class _Chunk {
|
|
|
7454
7449
|
this.x = x;
|
|
7455
7450
|
this.y = y;
|
|
7456
7451
|
this.z = z;
|
|
7457
|
-
let anchor = new import_three25.Object3D();
|
|
7458
|
-
this._anchor = anchor;
|
|
7459
|
-
scene.add(anchor);
|
|
7460
|
-
anchor.position.set(this.x * 256 + 128 - 8, this.y * 256 + 128 - 8, this.z * 256 + 128 - 8);
|
|
7461
|
-
addBox3WireframeToObject(
|
|
7462
|
-
new import_three25.Box3(new import_three25.Vector3(0, 0, 0), new import_three25.Vector3(256, 256, 256)),
|
|
7463
|
-
anchor,
|
|
7464
|
-
16776960,
|
|
7465
|
-
4
|
|
7466
|
-
);
|
|
7467
7452
|
}
|
|
7468
7453
|
getBlockAt(posOrX, y, z) {
|
|
7469
7454
|
if (typeof posOrX == "number") {
|
|
@@ -7489,7 +7474,7 @@ var Chunk = class _Chunk {
|
|
|
7489
7474
|
return this.setBlockInChunkAt(pos, block, worldPos);
|
|
7490
7475
|
}
|
|
7491
7476
|
/**
|
|
7492
|
-
* Set block at
|
|
7477
|
+
* Set a block at integer chunk-local coordinates from 0 to 15.
|
|
7493
7478
|
*/
|
|
7494
7479
|
async setBlockInChunkAt(pos, block, worldPos) {
|
|
7495
7480
|
if (typeof worldPos === "undefined") {
|
|
@@ -7502,15 +7487,13 @@ var Chunk = class _Chunk {
|
|
|
7502
7487
|
current.object.removeFromScene();
|
|
7503
7488
|
delete this._blocks[index];
|
|
7504
7489
|
}
|
|
7505
|
-
if (
|
|
7490
|
+
if (!block || _Chunk.isAir(block)) return void 0;
|
|
7506
7491
|
const blockState = await BlockStates.get(AssetKey.parse("blockstates", block.type));
|
|
7507
7492
|
if (blockState) {
|
|
7508
7493
|
const blockObject = await this.scene.addBlock(blockState, {
|
|
7509
7494
|
mergeMeshes: true,
|
|
7510
7495
|
instanceMeshes: true,
|
|
7511
|
-
wireframe: true,
|
|
7512
7496
|
maxInstanceCount: 2e3
|
|
7513
|
-
//TODO: setting this to high kills FPS; increase on demand somehow?
|
|
7514
7497
|
});
|
|
7515
7498
|
if (block.properties) {
|
|
7516
7499
|
await blockObject.setState(block.properties);
|
|
@@ -7526,23 +7509,21 @@ var Chunk = class _Chunk {
|
|
|
7526
7509
|
return void 0;
|
|
7527
7510
|
}
|
|
7528
7511
|
async clear() {
|
|
7529
|
-
|
|
7530
|
-
|
|
7531
|
-
for (let x = 0; x < 16; x++) {
|
|
7532
|
-
for (let z = 0; z < 16; z++) {
|
|
7533
|
-
for (let y = 0; y < 16; y++) {
|
|
7534
|
-
promises.push(this.setBlockInChunkAt(pos.set(x, y, z), void 0));
|
|
7535
|
-
}
|
|
7536
|
-
}
|
|
7537
|
-
}
|
|
7538
|
-
return Promise.all(promises).then((ignored) => {
|
|
7539
|
-
});
|
|
7512
|
+
this._blocks.forEach((block) => block.object.removeFromScene());
|
|
7513
|
+
this._blocks.length = 0;
|
|
7540
7514
|
}
|
|
7541
7515
|
async dispose() {
|
|
7542
7516
|
await this.clear();
|
|
7543
|
-
|
|
7517
|
+
}
|
|
7518
|
+
static isAir(block) {
|
|
7519
|
+
if (typeof block === "undefined" || typeof block.type === "undefined") return true;
|
|
7520
|
+
const key = AssetKey.parse("blockstates", block.type);
|
|
7521
|
+
return key.namespace === "minecraft" && !key.type && ["air", "cave_air", "void_air"].includes(key.path);
|
|
7544
7522
|
}
|
|
7545
7523
|
static chunkPosToBlockIndex(pos) {
|
|
7524
|
+
if ([pos.x, pos.y, pos.z].some((value) => !Number.isInteger(value) || value < 0 || value >= 16)) {
|
|
7525
|
+
throw new RangeError("Block coordinates must be integers from 0 to 15 within a chunk");
|
|
7526
|
+
}
|
|
7546
7527
|
return pos.y * 16 * 16 + pos.z * 16 + pos.x;
|
|
7547
7528
|
}
|
|
7548
7529
|
worldPosToChunkPos(pos) {
|