From df727c4c888074286a86c2f2cc69e4efe39a5508 Mon Sep 17 00:00:00 2001 From: Torsten Date: Thu, 19 Feb 2026 21:50:51 +0100 Subject: [PATCH] Signal + RPC Refactoring --- weltenauge/PROJEKT_UEBERSICHT.md | 4 +-- weltenauge/project.godot | 5 ---- weltenauge/systems/core/game_events.gd | 6 ++-- weltenauge/systems/data/character_data.gd | 28 +++++++++++++++++++ .../systems/interaction/portal/portal.gd | 3 -- weltenauge/systems/network/chat_manager.gd | 10 +++---- weltenauge/systems/network/network_manager.gd | 16 +++++------ .../systems/player/player_controller.gd | 6 ++-- .../player/tests/test_player_movement.gd | 2 +- .../ui/character_create/character_create.gd | 2 +- .../ui/character_select/character_select.gd | 4 +-- 11 files changed, 52 insertions(+), 34 deletions(-) diff --git a/weltenauge/PROJEKT_UEBERSICHT.md b/weltenauge/PROJEKT_UEBERSICHT.md index 5427075..42ebd16 100644 --- a/weltenauge/PROJEKT_UEBERSICHT.md +++ b/weltenauge/PROJEKT_UEBERSICHT.md @@ -131,7 +131,7 @@ Verwenden Sie einheitliche Präfixe, um die Quelle des Signals anzugeben (z.B. p Verwenden Sie Verben in der Vergangenheitsform, um anzuzeigen, dass ein Ereignis stattgefunden hat (z.B. player_moved, ui_buttonPressed, network_connected). RPCs: -An den Server gerichtet RPCs beginnen mit src_ und an den Client gerictete RPCs beginnen mit cl_ +An den Server gerichtet RPCs beginnen mit srv_ und an den Client gerictete RPCs beginnen mit cl_ Variablen: - snake_case für lokale Variablen und Funktionsnamen (z.B. player_health, calculate_damage). @@ -147,7 +147,7 @@ Variablen: * GameEvents.ui_join_requested.emit(ip_input.text, username, password) * Der NetworkManager des Clients hat das Signal abonniert und startet join_game, das den MultiplayerPeer instanziert. * Der NetworkManager des Servers empfängt das Signal _on_player_connected aktiviert auf dem Client - => client_show_characters.rpc_id(id, []) , was auf dem Client die Charakterliste anzeigt( die aktuell leer ist). + => cl_show_characters.rpc_id(id, []) , was auf dem Client die Charakterliste anzeigt( die aktuell leer ist). In der Charakterliste kann über einen Button ein neuer Charakter angelegt werden. Der Button löst aus: GameEvents.create_character_screen.emit() , der von CharacterCreate abonniert ist, und dort die Methode show_creation_screen auslöst. diff --git a/weltenauge/project.godot b/weltenauge/project.godot index 556d53b..06e78f7 100644 --- a/weltenauge/project.godot +++ b/weltenauge/project.godot @@ -24,11 +24,6 @@ GameEvents="*uid://4xof67e363t4" ChatManager="*uid://c351ysuym2mdm" NetworkManager="*uid://tniwwfk5703p" -[debug] - -settings/stdout/print_fps=true -settings/stdout/print_gpu_profile=true - [display] window/size/viewport_width=1280 diff --git a/weltenauge/systems/core/game_events.gd b/weltenauge/systems/core/game_events.gd index 2d9e63e..c66a3d9 100644 --- a/weltenauge/systems/core/game_events.gd +++ b/weltenauge/systems/core/game_events.gd @@ -1,17 +1,15 @@ extends Node -@warning_ignore("unused_signal") signal ui_join_requested(ip: String, username: String, password: String) -@warning_ignore("unused_signal") signal ui_host_requested() signal player_area_join_requested(area_key: String) signal ui_area_join_requested(area_key: String) -signal ui_show_characters(characters:Array) +signal network_show_characters(characters:Array) -signal ui_show_character_create() +signal ui_create_character_screen() signal ui_character_created(character: CharacterData) diff --git a/weltenauge/systems/data/character_data.gd b/weltenauge/systems/data/character_data.gd index b076f04..6ed0079 100644 --- a/weltenauge/systems/data/character_data.gd +++ b/weltenauge/systems/data/character_data.gd @@ -5,3 +5,31 @@ var name: String = "Neuer Held" var level: int = 1 var area: String = "keuwin_grasland" var position: Vector3 = Vector3.ZERO + +# Erstellt ein Dictionary – Vector3 bleibt ein Vector3! +func to_dict() -> Dictionary: + return { + "id": id, + "name": name, + "level": level, + "area": area, + "position": position + } + +func from_dict(data: Dictionary) -> void: + id = data.get("id", id) + name = data.get("name", name) + level = data.get("level", level) + area = data.get("area", area) + position = data.get("position", position) + +## Auf dem Client +#var data = mein_charakter.to_dict() +#update_server_pos.rpc(data) + +## Die RPC Funktion +#@rpc("any_peer") +#func update_server_pos(data: Dictionary): +# var server_char = CharacterData.new() +# server_char.from_dict(data) +# print(server_char.position) # Funktioniert sofort als Vector3 diff --git a/weltenauge/systems/interaction/portal/portal.gd b/weltenauge/systems/interaction/portal/portal.gd index 615e285..32ec95a 100644 --- a/weltenauge/systems/interaction/portal/portal.gd +++ b/weltenauge/systems/interaction/portal/portal.gd @@ -1,7 +1,4 @@ extends Area3D -## Definiert, wohin dieses Portal führt und ermöglicht die Interaktion. -## Löst einen RPC an den NetworkManager aus, um einen Area-Wechsel anzufordern. - # Dieser Wert muss einem Schlüssel in NetworkManager.area_paths entsprechen (z.B. "ahnenhalle"). @export var target_area_key: String = "" diff --git a/weltenauge/systems/network/chat_manager.gd b/weltenauge/systems/network/chat_manager.gd index ef19492..6e87f7a 100644 --- a/weltenauge/systems/network/chat_manager.gd +++ b/weltenauge/systems/network/chat_manager.gd @@ -1,7 +1,7 @@ extends Node # Signal für die UI, um neue Nachrichten anzuzeigen -signal message_received(sender_name: String, message: String, channel: String) +signal network_message_received(sender_name: String, message: String, channel: String) @rpc("any_peer", "call_remote", "reliable") func send_message(message: String): @@ -19,8 +19,8 @@ func send_message(message: String): # Broadcast: Nur an Spieler in der gleichen Area senden (NWN-Style) for id in NetworkManager.player_area_map: if NetworkManager.player_area_map[id] == area: - rpc_id(id, "receive_message", sender_name, message, "local") - + cl_receive_message.rpc_id(id, sender_name, message, "local") + @rpc("authority", "call_remote", "reliable") -func receive_message(sender_name: String, message: String, channel: String): - message_received.emit(sender_name, message, channel) +func cl_receive_message(sender_name: String, message: String, channel: String): + network_message_received.emit(sender_name, message, channel) diff --git a/weltenauge/systems/network/network_manager.gd b/weltenauge/systems/network/network_manager.gd index 5daddcd..c6a6001 100644 --- a/weltenauge/systems/network/network_manager.gd +++ b/weltenauge/systems/network/network_manager.gd @@ -39,13 +39,13 @@ func join_game(ip: String, username: String, password: String): func _on_player_connected(id): print("Player connected with id:", id) - client_show_characters.rpc_id(id, []) + cl_show_characters.rpc_id(id, []) @rpc("authority", "call_remote", "reliable") -func client_show_characters(characters): +func cl_show_characters(characters): print("Got client_show_characters") - GameEvents.show_characters.emit(characters) + GameEvents.network_show_characters.emit(characters) func _on_player_disconnected(id): @@ -97,7 +97,7 @@ func change_player_area(id: int, area_key: String): player_worlds[id] = container_node # Client anweisen, Szene zu laden - rpc_id(id, "client_load_area", area_key) + cl_load_area.rpc_id(id, area_key) # Avatar auf Server erstellen erfolgt erst wenn Client Vollzug meldet (client_ready_to_spawn) @@ -120,7 +120,7 @@ func client_ready_to_spawn(area_key:String): @rpc("authority", "call_remote", "reliable") -func client_load_area(area_key): +func cl_load_area(area_key): print("Client loads area") # Client löscht alte Map, lädt neue lokal in das Root for child in get_children(): @@ -194,10 +194,10 @@ func _spawn_player_in_world(id, spawn_target_node): # Wir schicken dem Client eine Info, welchen Node er verfolgen soll # (Da der Name des Player-Nodes die ID ist, weiß der Client welcher seiner ist) - rpc_id(id, "assign_camera_target", str(id)) + cl_assign_camera_target.rpc_id(id, str(id)) @rpc("authority", "call_remote", "reliable") -func assign_camera_target(node_name: String): +func cl_assign_camera_target(node_name: String): # Der Client sucht seinen Player-Node im Baum var p = get_tree().root.find_child(node_name, true, false) if p and local_camera: @@ -206,7 +206,7 @@ func assign_camera_target(node_name: String): # var camera = get_viewport().get_camera_3d() @rpc("any_peer", "call_remote", "reliable") -func handle_area_change_request(area_key: String): +func srv_handle_area_change_request(area_key: String): var id = multiplayer.get_remote_sender_id() if not player_worlds.has(id): return diff --git a/weltenauge/systems/player/player_controller.gd b/weltenauge/systems/player/player_controller.gd index 796c57b..fb6708b 100644 --- a/weltenauge/systems/player/player_controller.gd +++ b/weltenauge/systems/player/player_controller.gd @@ -63,7 +63,7 @@ func _physics_process(delta): @rpc("any_peer", "call_remote", "reliable") -func request_move(target: Vector3): +func srv_request_move(target: Vector3): if not multiplayer.is_server(): return #print("Server: Request Move received from client") @@ -97,12 +97,12 @@ func _input(event): if is_instance_valid(collider) and collider.is_in_group("portals"): print("Portal angeklickt. Fordere Area-Wechsel an zu: ", collider.target_area_key) # Sende RPC direkt an den NetworkManager mit dem Ziel des Portals - NetworkManager.handle_area_change_request.rpc_id(1, collider.target_area_key) + NetworkManager.srv_handle_area_change_request.rpc_id(1, collider.target_area_key) return # Wichtig: Aktion ist beendet, nichts weiter tun. # PRIORITÄT 2 (Fallback): Wir haben etwas anderes getroffen (vermutlich den Boden), also bewegen. var target_position = click_result.position - request_move.rpc_id(1, target_position) + srv_request_move.rpc_id(1, target_position) diff --git a/weltenauge/systems/player/tests/test_player_movement.gd b/weltenauge/systems/player/tests/test_player_movement.gd index 9d0a966..e48a9f4 100644 --- a/weltenauge/systems/player/tests/test_player_movement.gd +++ b/weltenauge/systems/player/tests/test_player_movement.gd @@ -37,7 +37,7 @@ func start_test(): print("Simuliere Klick auf: ", target_position) # Hier MÜSSEN wir den RPC direkt aufrufen. InputEvent geht nicht. - player.request_move.rpc_id(1, target_position) # 1 = Server + player.server_request_move.rpc_id(1, target_position) # 1 = Server # Auf Bewegung warten (etwas unsauber, aber für den Moment ok) await get_tree().create_timer(1.0).timeout # Warte 1 Sekunde diff --git a/weltenauge/ui/character_create/character_create.gd b/weltenauge/ui/character_create/character_create.gd index 41e5ef3..277be6a 100644 --- a/weltenauge/ui/character_create/character_create.gd +++ b/weltenauge/ui/character_create/character_create.gd @@ -3,7 +3,7 @@ extends Control @onready var name_line_edit: LineEdit = $NameLineEdit func _ready(): - GameEvents.ui_show_character_create.connect(show_creation_screen) + GameEvents.ui_create_character_screen.connect(show_creation_screen) func show_creation_screen(): name_line_edit.text = "" diff --git a/weltenauge/ui/character_select/character_select.gd b/weltenauge/ui/character_select/character_select.gd index 197491a..e2267fc 100644 --- a/weltenauge/ui/character_select/character_select.gd +++ b/weltenauge/ui/character_select/character_select.gd @@ -5,7 +5,7 @@ extends Control var characters: Array[CharacterData] = [] func _ready(): - GameEvents.ui_show_characters.connect(show_list) + GameEvents.network_show_characters.connect(show_list) GameEvents.ui_character_created.connect(character_created) func character_created(character): @@ -29,7 +29,7 @@ func _on_character_selected(index): func _on_create_character_button_pressed() -> void: - GameEvents.create_character_screen.emit() + GameEvents.ui_create_character_screen.emit() hide() # Doubleclick on Character should start area transition