From 65d18d8d96feb919c6ec0742a9407461ac15f7df Mon Sep 17 00:00:00 2001 From: Yogi Wiguna Date: Mon, 9 Feb 2026 17:46:18 +0800 Subject: [PATCH] feat: Implement core multiplayer lobby system with room management, player profiles, and game settings. --- scenes/lobby.tscn | 1 + scripts/managers/lobby_manager.gd | 2 +- scripts/managers/user_profile_manager.gd | 20 ++++++++++++++------ scripts/ui/profile_panel.gd | 8 ++++++++ 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/scenes/lobby.tscn b/scenes/lobby.tscn index f94962c..d6270f9 100644 --- a/scenes/lobby.tscn +++ b/scenes/lobby.tscn @@ -221,6 +221,7 @@ layout_mode = 2 text = "PROFILE" [node name="LobbyPanel" type="Control" parent="." unique_id=1745714811] +visible = false layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 diff --git a/scripts/managers/lobby_manager.gd b/scripts/managers/lobby_manager.gd index 4006cdd..9acaac1 100644 --- a/scripts/managers/lobby_manager.gd +++ b/scripts/managers/lobby_manager.gd @@ -293,7 +293,7 @@ func set_player_name(new_name: String) -> void: break # Sync to all peers if connected - if multiplayer.has_multiplayer_peer(): + if multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED: rpc("sync_player_name", my_id, new_name) emit_signal("player_list_changed") diff --git a/scripts/managers/user_profile_manager.gd b/scripts/managers/user_profile_manager.gd index 61eb2e4..c2b9808 100644 --- a/scripts/managers/user_profile_manager.gd +++ b/scripts/managers/user_profile_manager.gd @@ -120,17 +120,25 @@ func load_stats() -> Dictionary: # ============================================================================= func update_display_name(new_name: String) -> bool: - if not NakamaManager.session: - emit_signal("profile_update_failed", "Not authenticated") - return false - if new_name.strip_edges().is_empty(): emit_signal("profile_update_failed", "Display name cannot be empty") return false - if new_name.length() > 50: - emit_signal("profile_update_failed", "Display name too long (max 50 characters)") + if new_name.length() > 6: + emit_signal("profile_update_failed", "Display name too long (max 6 characters)") return false + + var regex = RegEx.new() + regex.compile("^[A-Za-z]+$") + if not regex.search(new_name): + emit_signal("profile_update_failed", "Name must contain only letters") + return false + + # Allow guest name updates locally + if not NakamaManager.session or AuthManager.is_guest: + profile["display_name"] = new_name + emit_signal("profile_updated") + return true var result: NakamaAsyncResult = await NakamaManager.client.update_account_async( NakamaManager.session, diff --git a/scripts/ui/profile_panel.gd b/scripts/ui/profile_panel.gd index ea7dbdf..4d1292c 100644 --- a/scripts/ui/profile_panel.gd +++ b/scripts/ui/profile_panel.gd @@ -40,6 +40,7 @@ func _load_profile_data() -> void: # Display name display_name_input.text = profile.get("display_name", "Guest") + display_name_input.max_length = 6 # Avatar var avatar_url: String = UserProfileManager.get_avatar_url() @@ -132,9 +133,13 @@ func _on_save_name_pressed() -> void: save_name_btn.disabled = false if success: + status_label.add_theme_color_override("font_color", Color.GREEN) status_label.text = "Name updated!" emit_signal("profile_updated") + await get_tree().create_timer(3.0).timeout + status_label.text = "" else: + status_label.add_theme_color_override("font_color", Color.RED) status_label.text = "Failed to update name" func _on_link_account_pressed() -> void: @@ -187,7 +192,10 @@ func _on_profile_updated() -> void: _load_profile_data() func _on_profile_update_failed(error: String) -> void: + status_label.add_theme_color_override("font_color", Color.RED) status_label.text = error + await get_tree().create_timer(3.0).timeout + status_label.text = "" func show_panel() -> void: _load_profile_data()