diff --git a/scripts/chunk.gd b/scripts/chunk.gd new file mode 100644 index 0000000..1cbc21d --- /dev/null +++ b/scripts/chunk.gd @@ -0,0 +1,82 @@ +class_name Chunk +extends Node2D +## A single loaded chunk in the world. +## +## A chunk is a fixed-size, axis-aligned region of a room. It is the atomic +## unit of load, save, and stream. This node is instantiated by the +## [ChunkStreamer] when a chunk is loaded from the server and freed when the +## chunk is unloaded. + +## World-space size of a chunk along X (world units / tiles). +const CHUNK_SIZE_X := 32.0 +## World-space size of a chunk along Y (world units / tiles). +const CHUNK_SIZE_Y := 32.0 +## World-space size of a chunk along Z (world units / tiles). +const CHUNK_SIZE_Z := 1.0 + +## Canonical chunk key: "{world_id}:{room_id}:{cx}:{cy}:{cz}". +var key: String = "" +## World id this chunk belongs to. +var world_id: String = "" +## Room id this chunk belongs to. +var room_id: String = "" +## Integer chunk coordinate along X. +var cx: int = 0 +## Integer chunk coordinate along Y. +var cy: int = 0 +## Integer chunk coordinate along Z. +var cz: int = 0 + +## Whether this chunk is currently loaded and active in the scene tree. +var is_loaded := false + +## Emitted when the chunk has finished loading its content. +signal chunk_loaded(chunk: Chunk) +## Emitted when the chunk is about to be unloaded. +signal chunk_unloaded(chunk: Chunk) + + +## Build the canonical chunk key from the chunk's coordinates. +func build_key() -> String: + return "%s:%s:%d:%d:%d" % [world_id, room_id, cx, cy, cz] + + +## Compute the world-space origin (min corner) of this chunk. +func world_origin() -> Vector2: + return Vector2(cx * CHUNK_SIZE_X, cy * CHUNK_SIZE_Y) + + +## Compute the world-space bounding box of this chunk. +func world_bounds() -> Rect2: + var origin := world_origin() + return Rect2(origin, Vector2(CHUNK_SIZE_X, CHUNK_SIZE_Y)) + + +## Compute the integer chunk coordinate for a world-space position. +static func coord_for_position(pos: Vector2) -> Vector2i: + return Vector2i( + floori(pos.x / CHUNK_SIZE_X), + floori(pos.y / CHUNK_SIZE_Y) + ) + + +## Compute the canonical key for a world-space position. +static func key_for_position(pos: Vector2, p_world_id: String, p_room_id: String) -> String: + var c := coord_for_position(pos) + return "%s:%s:%d:%d:0" % [p_world_id, p_room_id, c.x, c.y] + + +## Load this chunk's content. In a real deployment this would fetch the chunk +## payload from the server (see world.md ยง5.3 `request_chunk` / `chunk_data`) +## and instantiate tiles/objects. For now it just marks the chunk loaded. +func load_chunk() -> void: + is_loaded = true + chunk_loaded.emit(self) + + +## Unload this chunk's content and free any child nodes. +func unload_chunk() -> void: + chunk_unloaded.emit(self) + for child in get_children(): + child.queue_free() + is_loaded = false