extends Node # Attached to ChunkManager node. # Server: intercepts block changes and broadcasts to clients. # Client: receives and applies block changes locally. var _chunk_manager: Node = null func _ready() -> void: _chunk_manager = get_parent() # Called by Main.gd instead of world.break_block / world.place_block when in multiplayer. func server_break_block(world_pos: Vector3) -> int: if not NetworkManager.is_server(): # Client sends request to server request_break.rpc_id(1, world_pos) return 0 var broken_id: int = _chunk_manager.break_block(world_pos) if broken_id > 0: broadcast_block_change.rpc(world_pos, 0) return broken_id func server_place_block(world_pos: Vector3, block_id: int) -> bool: if not NetworkManager.is_server(): # Client sends request to server request_place.rpc_id(1, world_pos, block_id) return false var placed: bool = _chunk_manager.place_block(world_pos, block_id) if placed: broadcast_block_change.rpc(world_pos, block_id) return placed @rpc("any_peer", "reliable") func request_break(pos: Vector3) -> void: if not NetworkManager.is_server(): return var sender_id: int = multiplayer.get_remote_sender_id() var broken_id: int = _chunk_manager.break_block(pos) if broken_id > 0: broadcast_block_change.rpc(pos, 0) # Notify requesting peer of item pickup notify_break_result.rpc_id(sender_id, broken_id) @rpc("any_peer", "reliable") func request_place(pos: Vector3, block_id: int) -> void: if not NetworkManager.is_server(): return var placed: bool = _chunk_manager.place_block(pos, block_id) if placed: broadcast_block_change.rpc(pos, block_id) @rpc("authority", "call_local", "reliable") func broadcast_block_change(world_pos: Vector3, new_id: int) -> void: # Applied on all peers including server via call_local if multiplayer.is_server(): return # already applied on server if new_id == 0: _chunk_manager.break_block(world_pos) else: _chunk_manager.place_block(world_pos, new_id) @rpc("authority", "reliable") func notify_break_result(broken_id: int) -> void: # Signal to Main.gd to add item to local inventory var main := get_tree().get_first_node_in_group("main") if is_instance_valid(main) and main.has_method("_on_remote_block_broken"): main._on_remote_block_broken(broken_id)