WIP checkpoint: Implement chunk streaming system in GDScript
This commit is contained in:
@@ -109,7 +109,7 @@ func _update_streaming() -> void:
|
|||||||
if player == null or not is_inside_tree():
|
if player == null or not is_inside_tree():
|
||||||
return
|
return
|
||||||
|
|
||||||
var current_coord := Chunk.coord_for_position(player.global_position)
|
var current_coord: Vector3i = Chunk.coord_for_position(player.global_position)
|
||||||
if current_coord == _player_chunk_coord:
|
if current_coord == _player_chunk_coord:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ func _update_streaming() -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _rebuild_queues() -> void:
|
func _rebuild_queues() -> void:
|
||||||
var target_set := _compute_target_chunks()
|
var target_set: Dictionary = _compute_target_chunks()
|
||||||
|
|
||||||
# Determine which chunks need to be loaded
|
# Determine which chunks need to be loaded
|
||||||
var to_load: Array[Vector3i] = []
|
var to_load: Array[Vector3i] = []
|
||||||
@@ -142,12 +142,12 @@ func _rebuild_queues() -> void:
|
|||||||
|
|
||||||
func _compute_target_chunks() -> Dictionary:
|
func _compute_target_chunks() -> Dictionary:
|
||||||
"""Compute the set of chunk coordinates that should be loaded."""
|
"""Compute the set of chunk coordinates that should be loaded."""
|
||||||
var target := {}
|
var target: Dictionary = {}
|
||||||
var half := streaming_radius
|
var half: int = streaming_radius
|
||||||
for dx in range(-half, half + 1):
|
for dx in range(-half, half + 1):
|
||||||
for dy in range(-half, half + 1):
|
for dy in range(-half, half + 1):
|
||||||
for dz in range(-half, half + 1):
|
for dz in range(-half, half + 1):
|
||||||
var coord := Vector3i(
|
var coord: Vector3i = Vector3i(
|
||||||
_player_chunk_coord.x + dx,
|
_player_chunk_coord.x + dx,
|
||||||
_player_chunk_coord.y + dy,
|
_player_chunk_coord.y + dy,
|
||||||
_player_chunk_coord.z + dz
|
_player_chunk_coord.z + dz
|
||||||
@@ -158,30 +158,30 @@ func _compute_target_chunks() -> Dictionary:
|
|||||||
|
|
||||||
func _compare_distance(a: Vector3i, b: Vector3i) -> bool:
|
func _compare_distance(a: Vector3i, b: Vector3i) -> bool:
|
||||||
"""Compare chunk coordinates by distance from player chunk."""
|
"""Compare chunk coordinates by distance from player chunk."""
|
||||||
var dist_a := _chunk_distance_squared(_player_chunk_coord, a)
|
var dist_a: int = _chunk_distance_squared(_player_chunk_coord, a)
|
||||||
var dist_b := _chunk_distance_squared(_player_chunk_coord, b)
|
var dist_b: int = _chunk_distance_squared(_player_chunk_coord, b)
|
||||||
return dist_a < dist_b
|
return dist_a < dist_b
|
||||||
|
|
||||||
|
|
||||||
func _chunk_distance_squared(a: Vector3i, b: Vector3i) -> int:
|
func _chunk_distance_squared(a: Vector3i, b: Vector3i) -> int:
|
||||||
var dx := a.x - b.x
|
var dx: int = a.x - b.x
|
||||||
var dy := a.y - b.y
|
var dy: int = a.y - b.y
|
||||||
var dz := a.z - b.z
|
var dz: int = a.z - b.z
|
||||||
return dx * dx + dy * dy + dz * dz
|
return dx * dx + dy * dy + dz * dz
|
||||||
|
|
||||||
|
|
||||||
func _process_load_queue() -> void:
|
func _process_load_queue() -> void:
|
||||||
var count := 0
|
var count: int = 0
|
||||||
while count < max_loads_per_frame and not _load_queue.is_empty():
|
while count < max_loads_per_frame and not _load_queue.is_empty():
|
||||||
var coord := _load_queue.pop_front()
|
var coord: Vector3i = _load_queue.pop_front()
|
||||||
_load_chunk(coord)
|
_load_chunk(coord)
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
|
|
||||||
func _process_unload_queue() -> void:
|
func _process_unload_queue() -> void:
|
||||||
var count := 0
|
var count: int = 0
|
||||||
while count < max_unloads_per_frame and not _unload_queue.is_empty():
|
while count < max_unloads_per_frame and not _unload_queue.is_empty():
|
||||||
var coord := _unload_queue.pop_front()
|
var coord: Vector3i = _unload_queue.pop_front()
|
||||||
_unload_chunk(coord)
|
_unload_chunk(coord)
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
@@ -204,14 +204,14 @@ func _load_chunk(coord: Vector3i) -> void:
|
|||||||
|
|
||||||
func _on_chunk_data_received(key: String, binary_data: PackedByteArray) -> void:
|
func _on_chunk_data_received(key: String, binary_data: PackedByteArray) -> void:
|
||||||
"""Called by the networking layer when chunk data arrives from server."""
|
"""Called by the networking layer when chunk data arrives from server."""
|
||||||
var coord := _parse_coord_from_key(key)
|
var coord: Vector3i = _parse_coord_from_key(key)
|
||||||
if coord == null:
|
if coord == null:
|
||||||
return
|
return
|
||||||
|
|
||||||
_loading_in_progress.erase(coord)
|
_loading_in_progress.erase(coord)
|
||||||
|
|
||||||
# Decode the binary chunk data
|
# Decode the binary chunk data
|
||||||
var chunk_data := ChunkDataDecoder.decode_binary(binary_data)
|
var chunk_data: ChunkDataDecoder.ChunkPayload = ChunkDataDecoder.decode_binary(binary_data)
|
||||||
if chunk_data == null:
|
if chunk_data == null:
|
||||||
chunk_load_failed.emit(coord, "Failed to decode chunk data")
|
chunk_load_failed.emit(coord, "Failed to decode chunk data")
|
||||||
return
|
return
|
||||||
@@ -228,7 +228,7 @@ func _on_chunk_load_error(coord: Vector3i, error_msg: String) -> void:
|
|||||||
|
|
||||||
func _instantiate_chunk_scene(coord: Vector3i) -> void:
|
func _instantiate_chunk_scene(coord: Vector3i) -> void:
|
||||||
"""Create an empty chunk scene for the given coordinate."""
|
"""Create an empty chunk scene for the given coordinate."""
|
||||||
var chunk_scene := ChunkScene.new()
|
var chunk_scene: ChunkScene = ChunkScene.new()
|
||||||
chunk_scene.coord = coord
|
chunk_scene.coord = coord
|
||||||
chunk_scene.key = Chunk.build_key("", "", coord)
|
chunk_scene.key = Chunk.build_key("", "", coord)
|
||||||
chunk_scene.bounds = Chunk.compute_bounds(coord)
|
chunk_scene.bounds = Chunk.compute_bounds(coord)
|
||||||
@@ -237,7 +237,7 @@ func _instantiate_chunk_scene(coord: Vector3i) -> void:
|
|||||||
|
|
||||||
func _instantiate_chunk_scene_with_data(coord: Vector3i, data: ChunkDataDecoder.ChunkPayload) -> void:
|
func _instantiate_chunk_scene_with_data(coord: Vector3i, data: ChunkDataDecoder.ChunkPayload) -> void:
|
||||||
"""Create a chunk scene populated with server data."""
|
"""Create a chunk scene populated with server data."""
|
||||||
var chunk_scene := ChunkScene.new()
|
var chunk_scene: ChunkScene = ChunkScene.new()
|
||||||
chunk_scene.coord = coord
|
chunk_scene.coord = coord
|
||||||
chunk_scene.key = data.key
|
chunk_scene.key = data.key
|
||||||
chunk_scene.bounds = data.bounds
|
chunk_scene.bounds = data.bounds
|
||||||
@@ -246,7 +246,7 @@ func _instantiate_chunk_scene_with_data(coord: Vector3i, data: ChunkDataDecoder.
|
|||||||
|
|
||||||
# Add tiles
|
# Add tiles
|
||||||
for layer in data.tile_layers:
|
for layer in data.tile_layers:
|
||||||
var tile_layer := TileLayer.new()
|
var tile_layer: TileLayer = TileLayer.new()
|
||||||
tile_layer.name = layer.name
|
tile_layer.name = layer.name
|
||||||
tile_layer.layer_id = layer.layer_id
|
tile_layer.layer_id = layer.layer_id
|
||||||
tile_layer.width = layer.width
|
tile_layer.width = layer.width
|
||||||
@@ -258,7 +258,7 @@ func _instantiate_chunk_scene_with_data(coord: Vector3i, data: ChunkDataDecoder.
|
|||||||
|
|
||||||
# Add objects
|
# Add objects
|
||||||
for obj_data in data.objects:
|
for obj_data in data.objects:
|
||||||
var world_obj := WorldObject.new()
|
var world_obj: WorldObject = WorldObject.new()
|
||||||
world_obj.id = obj_data.id
|
world_obj.id = obj_data.id
|
||||||
world_obj.type = obj_data.type
|
world_obj.type = obj_data.type
|
||||||
world_obj.asset_id = obj_data.asset_id
|
world_obj.asset_id = obj_data.asset_id
|
||||||
@@ -287,7 +287,7 @@ func _unload_chunk(coord: Vector3i) -> void:
|
|||||||
if not _loaded_chunks.has(coord):
|
if not _loaded_chunks.has(coord):
|
||||||
return
|
return
|
||||||
|
|
||||||
var chunk_scene = _loaded_chunks[coord]
|
var chunk_scene: Node = _loaded_chunks[coord]
|
||||||
if is_instance_valid(chunk_scene):
|
if is_instance_valid(chunk_scene):
|
||||||
chunk_scene.queue_free()
|
chunk_scene.queue_free()
|
||||||
|
|
||||||
@@ -339,16 +339,16 @@ func force_reload_chunk(coord: Vector3i) -> void:
|
|||||||
|
|
||||||
func clear_all_chunks() -> void:
|
func clear_all_chunks() -> void:
|
||||||
"""Unload all chunks immediately."""
|
"""Unload all chunks immediately."""
|
||||||
var coords := get_all_loaded_coords()
|
var coords: Array[Vector3i] = get_all_loaded_coords()
|
||||||
for coord in coords:
|
for coord in coords:
|
||||||
_unload_chunk(coord)
|
_unload_chunk(coord)
|
||||||
_load_queue.clear()
|
_load_queue.clear()
|
||||||
_unload_queue.clear()
|
_unload_queue.clear()
|
||||||
|
|
||||||
|
|
||||||
func _parse_coord_from_key(key: String) -> Vector3i:
|
func _parse_coord_from_key(key: String) -> Variant:
|
||||||
"""Parse chunk coordinate from a canonical chunk key."""
|
"""Parse chunk coordinate from a canonical chunk key."""
|
||||||
var parts := key.split(":")
|
var parts: Array[String] = key.split(":")
|
||||||
if parts.size() < 5:
|
if parts.size() < 5:
|
||||||
return null
|
return null
|
||||||
return Vector3i(
|
return Vector3i(
|
||||||
|
|||||||
Reference in New Issue
Block a user