76 lines
3.0 KiB
TypeScript
76 lines
3.0 KiB
TypeScript
import { assert, assertEquals } from "@std/assert";
|
|
import { CHUNK_AREA, CHUNK_HEIGHT, SEA_LEVEL } from "$/common/constants.ts";
|
|
import { generate_raw_chunk } from "$/common/generation.ts";
|
|
import { test_game } from "./helpers.ts";
|
|
|
|
Deno.test("the overworld generates the same way every time, with water only below sea level", async () => {
|
|
const { game } = await test_game("mods");
|
|
const ids = game.world.block_ids;
|
|
const water = ids["bworld:water"];
|
|
|
|
for (let cx = -4; cx < 4; cx++) {
|
|
for (let cz = -4; cz < 4; cz++) {
|
|
const { blocks } = generate_raw_chunk(cx, cz, "worldgen-test", ids);
|
|
assertEquals(blocks, generate_raw_chunk(cx, cz, "worldgen-test", ids).blocks, "same chunk, same blocks");
|
|
|
|
for (let i = 0; i < CHUNK_AREA; i++) {
|
|
assert(blocks[i] !== 0, "the bottom of the world is solid");
|
|
assertEquals(blocks[(CHUNK_HEIGHT - 1) * CHUNK_AREA + i], 0, "nothing reaches the top of the world");
|
|
}
|
|
blocks.forEach((block, i) => {
|
|
if (block === water) {
|
|
assert(Math.floor(i / CHUNK_AREA) < SEA_LEVEL, "water above sea level");
|
|
}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
Deno.test("new players spawn on dry land, all in the same place", async () => {
|
|
const { game, join } = await test_game("mods");
|
|
const joined = join(1, "alice");
|
|
const { x, y, z } = joined.spawn;
|
|
const ground = game.world.get_block_id(Math.floor(x), y - 1, Math.floor(z));
|
|
assert(ground !== "bworld:air" && ground !== "bworld:water", `spawned on ${ground}`);
|
|
assertEquals(game.world.get_block_id(Math.floor(x), y, Math.floor(z)), "bworld:air");
|
|
assert(y > SEA_LEVEL, "above the sea");
|
|
|
|
// the same place for the next new player
|
|
assertEquals(join(2, "bob").spawn, joined.spawn);
|
|
});
|
|
|
|
Deno.test("trees grow on the ground, never closer than 4 blocks, even across chunk borders", async () => {
|
|
const { game } = await test_game("mods");
|
|
const ids = game.world.block_ids;
|
|
const log = ids["bworld:log"];
|
|
const ground = new Set([ids["bworld:grass"], ids["bworld:dirt"], ids["bworld:snow"]]);
|
|
|
|
// the bottom log of every trunk, in world coordinates
|
|
const trunks: [number, number][] = [];
|
|
let spilled_leaves = 0;
|
|
for (let cx = -6; cx < 6; cx++) {
|
|
for (let cz = -6; cz < 6; cz++) {
|
|
const { blocks, spills } = generate_raw_chunk(cx, cz, "trees-test", ids);
|
|
blocks.forEach((block, i) => {
|
|
if (block === log && ground.has(blocks[i - CHUNK_AREA])) {
|
|
const x = cx * 16 + (i % 16);
|
|
const z = cz * 16 + Math.floor(i / 16) % 16;
|
|
trunks.push([x, z]);
|
|
}
|
|
});
|
|
for (let i = 3; i < spills.length; i += 4) {
|
|
if (spills[i] === ids["bworld:leaves"]) spilled_leaves++;
|
|
}
|
|
}
|
|
}
|
|
|
|
assert(trunks.length > 50, `only ${trunks.length} trees`);
|
|
assert(spilled_leaves > 0, "leaves reach into neighboring chunks");
|
|
for (let a = 0; a < trunks.length; a++) {
|
|
for (let b = a + 1; b < trunks.length; b++) {
|
|
const distance = Math.hypot(trunks[a][0] - trunks[b][0], trunks[a][1] - trunks[b][1]);
|
|
assert(distance >= 4, `trees at ${trunks[a]} and ${trunks[b]} are ${distance.toFixed(1)} apart`);
|
|
}
|
|
}
|
|
});
|