extends Node signal main_loaded signal player_connected(peer_id: int, player_info: Dictionary) signal network_error(message: String) const DEFAULT_PORT: int = 10567 const MAX_PEERS: int = 20 var _peer: ENetMultiplayerPeer var _local_player_info := {"name": ""} var _players := {} var _title_scene := preload("res://scenes/title.tscn") var _main_scene := preload("res://scenes/main.tscn") var _player_scene := preload("res://scenes/player.tscn") func _ready() -> void: multiplayer.peer_connected.connect(_on_multiplayer_peer_connected) multiplayer.peer_disconnected.connect(_on_multiplayer_peer_disconnected) multiplayer.connected_to_server.connect(_on_multiplayer_connected_to_server) multiplayer.connection_failed.connect(_on_multiplayer_connection_failed) multiplayer.server_disconnected.connect(_on_multiplayer_server_disconnected) func _process(_delta: float) -> void: Debugger.text("_local_player_info", _local_player_info) Debugger.text("_players", _players) func set_local_player_info(username: String) -> void: _local_player_info["name"] = username func host_game(dedicated: bool = false) -> void: print("Hosting...") _peer = ENetMultiplayerPeer.new() var error := _peer.create_server(DEFAULT_PORT, MAX_PEERS) if error: match error: ERR_ALREADY_IN_USE: network_error.emit("Already in use") ERR_CANT_CREATE: network_error.emit("Cannot create server") return multiplayer.set_multiplayer_peer(_peer) _load_main() if not dedicated: _players[1] = _local_player_info player_connected.emit(1, _local_player_info) _add_player(multiplayer.get_unique_id()) func join_game(ip: String) -> void: print("Joining " + ip + "...") _peer = ENetMultiplayerPeer.new() var error := _peer.create_client(ip, DEFAULT_PORT) if error: match error: ERR_ALREADY_IN_USE: network_error.emit("Already in use") ERR_CANT_CREATE: network_error.emit("Cannot create server") return multiplayer.set_multiplayer_peer(_peer) _load_main() func _switch_scene(from: Node, to: PackedScene) -> void: if from: from.queue_free() var new_scene := to.instantiate() get_tree().get_root().add_child(new_scene) print("Scene loaded") func _load_main() -> void: print("Loading Main...") _switch_scene($/root/Title, _main_scene) main_loaded.emit() func _add_player(peer_id: int) -> void: if not multiplayer.is_server(): return print("Adding player ", peer_id) var player := _player_scene.instantiate() as Player player.name = str(peer_id) var player_holder: Node = $/root/Main/Players player_holder.add_child(player, true) func _remove_player(peer_id: int) -> void: if not multiplayer.is_server(): return print("Removing player ", peer_id) var player_holder: Node = $/root/Main/Players var player := player_holder.get_node_or_null(str(peer_id)) if player: player.queue_free() @rpc("any_peer", "reliable") func _register_player(player_info: Dictionary) -> void: print("Registering player ", player_info) var player_id := multiplayer.get_remote_sender_id() _players[player_id] = player_info player_connected.emit(player_id, player_info) func _on_multiplayer_peer_connected(peer_id: int) -> void: print("Peer connected ", peer_id) _add_player(peer_id) _register_player.rpc_id(peer_id, _local_player_info) func _on_multiplayer_peer_disconnected(peer_id: int) -> void: print("Peer disconnected ", peer_id) _players.erase(peer_id) _remove_player(peer_id) func _on_multiplayer_connected_to_server() -> void: print("Connected to server") var peer_id := multiplayer.get_unique_id() _players[peer_id] = _local_player_info player_connected.emit(peer_id, _local_player_info) func _on_multiplayer_connection_failed() -> void: printerr("Connection failed") multiplayer.set_multiplayer_peer(null) network_error.emit("Connection failed") func _on_multiplayer_server_disconnected() -> void: printerr("Server disconnected") _players.clear() _switch_scene($/root/Main, _title_scene) network_error.emit("Server disconnected")