Better world generation
This commit is contained in:
@@ -466,6 +466,8 @@ export class GameServer {
|
||||
const saved = this.#saved_players[player.name];
|
||||
if (saved) {
|
||||
player.load(saved);
|
||||
} else {
|
||||
Object.assign(player, this.world.spawn_point());
|
||||
}
|
||||
|
||||
this.#send(player, {
|
||||
|
||||
+35
-3
@@ -6,9 +6,11 @@ import { AIR_ID, BlockChange } from "$/common/protocol.ts";
|
||||
import { block_value, chunk_key, default_block_value } from "$/common/utils.ts";
|
||||
import { LruMap } from "./lru.ts";
|
||||
|
||||
// generation only, rebuilt when needed. 128 KB each
|
||||
const RAW_CACHE_SIZE = 256;
|
||||
const CHUNK_CACHE_SIZE = 512;
|
||||
// generation only, rebuilt when needed. 256 KB each
|
||||
const RAW_CACHE_SIZE = 128;
|
||||
const CHUNK_CACHE_SIZE = 256;
|
||||
// how far from the middle of the world to look for dry land to spawn on, in chunks
|
||||
const SPAWN_SEARCH_CHUNKS = 32;
|
||||
|
||||
// a block with state the server keeps, like a chest's items. never sent to clients as is
|
||||
export interface Tile {
|
||||
@@ -56,6 +58,36 @@ export class ServerWorld {
|
||||
});
|
||||
}
|
||||
|
||||
#spawn: { x: number; y: number; z: number } | undefined;
|
||||
|
||||
// where new players start: the dry land closest to the middle of the world, like minecraft's world spawn
|
||||
spawn_point() {
|
||||
if (!this.#spawn) {
|
||||
this.#spawn = this.#find_spawn();
|
||||
}
|
||||
return this.#spawn;
|
||||
}
|
||||
|
||||
#find_spawn() {
|
||||
const water = this.block_ids["bworld:water"];
|
||||
// chunks in rings around the middle, one column each
|
||||
for (let radius = 0; radius <= SPAWN_SEARCH_CHUNKS; radius++) {
|
||||
for (let cz = -radius; cz <= radius; cz++) {
|
||||
for (let cx = -radius; cx <= radius; cx++) {
|
||||
if (Math.max(Math.abs(cx), Math.abs(cz)) !== radius) continue;
|
||||
const x = cx * CHUNK_SIZE + CHUNK_SIZE / 2;
|
||||
const z = cz * CHUNK_SIZE + CHUNK_SIZE / 2;
|
||||
let y = CHUNK_HEIGHT - 1;
|
||||
while (y > 0 && this.get_block_nid(x, y, z) === AIR) y--;
|
||||
if (y > 0 && this.get_block_nid(x, y, z) !== water) {
|
||||
return { x: x + 0.5, y: y + 1, z: z + 0.5 };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return { x: 0.5, y: CHUNK_HEIGHT - 1, z: 0.5 };
|
||||
}
|
||||
|
||||
get_block_id(x: number, y: number, z: number): string {
|
||||
const nid = this.get_block_nid(x, y, z);
|
||||
return nid === AIR ? AIR_ID : EverythingRegistry.get_by_id<BlockRegistry>("blocks", nid)?.id ?? AIR_ID;
|
||||
|
||||
Reference in New Issue
Block a user