Server actually ticks

This commit is contained in:
2026-09-25 13:25:25 -03:00
parent 2a2ccae9ce
commit dfabe40e7a
18 changed files with 763 additions and 79 deletions
+24 -11
View File
@@ -1,5 +1,5 @@
import { Component } from "$/common/ecs/mod.ts";
import { chunk_key } from "$/common/utils.ts";
import { block_value, chunk_key, default_block_value } from "$/common/utils.ts";
import { AIR_ID, BlockChange } from "$/common/protocol.ts";
import { BlockRegistry, EverythingRegistry } from "$/common/everything_registry.ts";
import { AIR, CHUNK_AREA, CHUNK_HEIGHT, CHUNK_SIZE, Faces, ID_MASK, VOID } from "../../common/constants.ts";
@@ -101,7 +101,8 @@ export class Dimension extends Component {
return this.chunks.get(chunk_key(x, z));
}
add_block(block: Block) {
// state is the block's state bits, its defaults when not given
add_block(block: Block, state?: number) {
const block_chunk_x = Math.floor(block.x / CHUNK_SIZE);
const block_chunk_z = Math.floor(block.z / CHUNK_SIZE);
let chunk = this.get_chunk(block_chunk_x, block_chunk_z);
@@ -109,7 +110,7 @@ export class Dimension extends Component {
chunk = this.add_chunk(block_chunk_x, block_chunk_z);
}
const nid = EverythingRegistry.get_id("blocks", block.id)!;
const [nid, info] = EverythingRegistry.get_full<BlockRegistry>("blocks", block.id)!;
const lx = block.x - block_chunk_x * CHUNK_SIZE;
const lz = block.z - block_chunk_z * CHUNK_SIZE;
@@ -117,11 +118,23 @@ export class Dimension extends Component {
const index = ly * CHUNK_SIZE * CHUNK_SIZE + lz * CHUNK_SIZE + lx;
chunk.blocks[index] = nid;
chunk.blocks[index] = state === undefined ? default_block_value(nid, info) : block_value(nid, state);
chunk.dirty = true;
this.#mark_border_neighbors_dirty(block_chunk_x, block_chunk_z, lx, lz);
}
// the id with its state bits, VOID outside loaded chunks
get_block_value(x: number, y: number, z: number) {
const chunk_x = Math.floor(x / CHUNK_SIZE);
const chunk_z = Math.floor(z / CHUNK_SIZE);
const chunk = this.get_chunk(chunk_x, chunk_z);
if (!chunk) {
return VOID;
}
return chunk.blocks[y * CHUNK_AREA + (z - chunk_z * CHUNK_SIZE) * CHUNK_SIZE + (x - chunk_x * CHUNK_SIZE)] ??
AIR;
}
get_block(x: number, y: number, z: number) {
const chunk_x = Math.floor(x / CHUNK_SIZE);
const chunk_z = Math.floor(z / CHUNK_SIZE);
@@ -196,18 +209,18 @@ export class Dimension extends Component {
return [x, y, z];
}
record_change(x: number, y: number, z: number, id: string) {
record_change(x: number, y: number, z: number, id: string, state = 0) {
const chunk_key = `${Math.floor(x / CHUNK_SIZE)},${Math.floor(z / CHUNK_SIZE)}`;
let chunk_changes = this.changes.get(chunk_key);
if (!chunk_changes) {
chunk_changes = new Map();
this.changes.set(chunk_key, chunk_changes);
}
chunk_changes.set(`${x},${y},${z}`, [x, y, z, id]);
chunk_changes.set(`${x},${y},${z}`, [x, y, z, id, state]);
}
// set a block the server told us about
apply_change(x: number, y: number, z: number, id: string) {
apply_change(x: number, y: number, z: number, id: string, state = 0) {
const chunk = this.get_chunk(Math.floor(x / CHUNK_SIZE), Math.floor(z / CHUNK_SIZE));
if (!chunk || !chunk.generated) {
return;
@@ -222,15 +235,15 @@ export class Dimension extends Component {
}
const nid = EverythingRegistry.get_id("blocks", id);
if (nid === undefined || nid === current) {
if (nid === undefined || block_value(nid, state) === this.get_block_value(x, y, z)) {
return;
}
this.add_block({ x, y, z, id });
this.add_block({ x, y, z, id }, state);
}
apply_chunk_changes(cx: number, cz: number) {
for (const [x, y, z, id] of this.changes.get(`${cx},${cz}`)?.values() ?? []) {
this.apply_change(x, y, z, id);
for (const [x, y, z, id, state] of this.changes.get(`${cx},${cz}`)?.values() ?? []) {
this.apply_change(x, y, z, id, state);
}
}