Files
dauphincraft/scripts/net/WorldSyncComponent.gd
Floppyrj45 5db858527e feat(multiplayer): ENet networking + player/world sync + lobby menu + chat
Add dedicated server / host / client modes via NetworkManager autoload,
PlayerSyncComponent (20 Hz unreliable RPC), WorldSyncComponent (authoritative
block break/place), ChatManager (F2), LobbyMenu scene, updated MainMenu
with Solo/Heberger/Rejoindre/Quitter buttons. Port changed to 7777
(9999 occupied by sntlkeyssrvr on this machine). Mobs disabled in multi
(spawn solo only). Solo mode untouched.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 17:48:48 +02:00

75 lines
2.2 KiB
GDScript

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)