Merge multiplayer_spawner and lobby-map into develop #3
@@ -1 +1,14 @@
|
|||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
|
@onready var debug_ui: PackedScene = preload("res://ui/multiplayer-debug-ui/multiplayer-debug-ui.tscn")
|
||||||
|
var debug_ui_instance
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
debug_ui_instance = debug_ui.instantiate()
|
||||||
|
get_tree().root.add_child.call_deferred(debug_ui_instance)
|
||||||
|
debug_ui_instance.hide()
|
||||||
|
|
||||||
|
|
||||||
|
func _input(event: InputEvent) -> void:
|
||||||
|
if event.is_action_pressed("toggle_watch"):
|
||||||
|
debug_ui_instance.visible = !debug_ui_instance.visible
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
[gd_scene load_steps=9 format=3 uid="uid://bj52j4ew2lfr6"]
|
[gd_scene load_steps=8 format=3 uid="uid://bj52j4ew2lfr6"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://5vggmy1srgxb" path="res://tools/human-height-reference.tscn" id="1_yyu2g"]
|
[ext_resource type="PackedScene" uid="uid://5vggmy1srgxb" path="res://tools/human-height-reference.tscn" id="1_yyu2g"]
|
||||||
[ext_resource type="PackedScene" uid="uid://b5xb0fsfpn7r3" path="res://levels/lobby-scene/lobby-terrain.blend" id="3_f73ky"]
|
[ext_resource type="PackedScene" uid="uid://b5xb0fsfpn7r3" path="res://levels/lobby-scene/lobby-terrain.blend" id="3_f73ky"]
|
||||||
[ext_resource type="PackedScene" uid="uid://csmfxg011xisf" path="res://player/Player.tscn" id="4_0aw1h"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://c4cew4af3h306" path="res://levels/lobby-scene/tent/tent.blend" id="4_qjimh"]
|
[ext_resource type="PackedScene" uid="uid://c4cew4af3h306" path="res://levels/lobby-scene/tent/tent.blend" id="4_qjimh"]
|
||||||
[ext_resource type="PackedScene" uid="uid://wcsd1tb0quj3" path="res://levels/lobby-scene/campfire/campfire.tscn" id="5_qjimh"]
|
[ext_resource type="PackedScene" uid="uid://wcsd1tb0quj3" path="res://levels/lobby-scene/campfire/campfire.tscn" id="5_qjimh"]
|
||||||
|
|
||||||
@@ -44,9 +43,6 @@ spawn_limit = 1
|
|||||||
[node name="Marker3D" type="Marker3D" parent="."]
|
[node name="Marker3D" type="Marker3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.269072, -8.35164)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.269072, -8.35164)
|
||||||
|
|
||||||
[node name="Player" parent="." instance=ExtResource("4_0aw1h")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.444747, 0.992996, -4.71496)
|
|
||||||
|
|
||||||
[node name="Campsite" type="Node3D" parent="."]
|
[node name="Campsite" type="Node3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.724, 0, -17.6721)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.724, 0, -17.6721)
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ var steam_username: String = ""
|
|||||||
var lobby_id = 0
|
var lobby_id = 0
|
||||||
var lobby_max_members = 4
|
var lobby_max_members = 4
|
||||||
var lobby_members: Array = []
|
var lobby_members: Array = []
|
||||||
|
var peer_to_steam_id_map: Dictionary = {}
|
||||||
|
var players: Dictionary = {}
|
||||||
|
|
||||||
var steam_initialized: bool = false
|
var steam_initialized: bool = false
|
||||||
|
|
||||||
@@ -46,7 +48,6 @@ func _ready() -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _on_p2p_session_request(steam_id_remote: int) -> void:
|
func _on_p2p_session_request(steam_id_remote: int) -> void:
|
||||||
## ADDED: More detailed logging to confirm P2P acceptance.
|
|
||||||
print("[P2P] ==> Session request from: %s. Accepting." % steam_id_remote)
|
print("[P2P] ==> Session request from: %s. Accepting." % steam_id_remote)
|
||||||
var accepted = Steam.acceptP2PSessionWithUser(steam_id_remote)
|
var accepted = Steam.acceptP2PSessionWithUser(steam_id_remote)
|
||||||
if not accepted:
|
if not accepted:
|
||||||
@@ -54,14 +55,12 @@ func _on_p2p_session_request(steam_id_remote: int) -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
## ADDED: Guard clause in case Steam fails to initialize.
|
|
||||||
if not steam_initialized:
|
if not steam_initialized:
|
||||||
return
|
return
|
||||||
|
|
||||||
Steam.run_callbacks()
|
Steam.run_callbacks()
|
||||||
|
|
||||||
if Input.is_action_just_pressed("interact"):
|
if Input.is_action_just_pressed("interact"):
|
||||||
## ADDED: Replaced simple print with a detailed diagnostic function.
|
|
||||||
log_multiplayer_info()
|
log_multiplayer_info()
|
||||||
|
|
||||||
|
|
||||||
@@ -97,7 +96,6 @@ func init_steam() -> bool:
|
|||||||
|
|
||||||
|
|
||||||
func setup_multiplayer_peer(is_host: bool = false) -> void:
|
func setup_multiplayer_peer(is_host: bool = false) -> void:
|
||||||
## ADDED: Check if a peer is already active before creating a new one.
|
|
||||||
if multiplayer.multiplayer_peer and multiplayer.multiplayer_peer.get_connection_status() != MultiplayerPeer.CONNECTION_DISCONNECTED:
|
if multiplayer.multiplayer_peer and multiplayer.multiplayer_peer.get_connection_status() != MultiplayerPeer.CONNECTION_DISCONNECTED:
|
||||||
print("[Multiplayer] Peer already exists. Disconnecting old one.")
|
print("[Multiplayer] Peer already exists. Disconnecting old one.")
|
||||||
multiplayer.multiplayer_peer.close()
|
multiplayer.multiplayer_peer.close()
|
||||||
@@ -106,7 +104,7 @@ func setup_multiplayer_peer(is_host: bool = false) -> void:
|
|||||||
|
|
||||||
if is_host:
|
if is_host:
|
||||||
print("[Multiplayer] Creating Host...")
|
print("[Multiplayer] Creating Host...")
|
||||||
var err = peer.create_host(0) ## REMOVED: Channel is handled by the peer automatically now.
|
var err = peer.create_host(0)
|
||||||
if err != OK:
|
if err != OK:
|
||||||
print("[Multiplayer] !!! Failed to create host. Error: %s" % err)
|
print("[Multiplayer] !!! Failed to create host. Error: %s" % err)
|
||||||
return
|
return
|
||||||
@@ -120,7 +118,7 @@ func setup_multiplayer_peer(is_host: bool = false) -> void:
|
|||||||
|
|
||||||
var host_id = Steam.getLobbyOwner(lobby_id)
|
var host_id = Steam.getLobbyOwner(lobby_id)
|
||||||
print("[Multiplayer] Creating Client, attempting to connect to host: %s" % host_id)
|
print("[Multiplayer] Creating Client, attempting to connect to host: %s" % host_id)
|
||||||
var err = peer.create_client(host_id, 0) ## REMOVED: Channel is handled by the peer automatically.
|
var err = peer.create_client(host_id, 0)
|
||||||
if err != OK:
|
if err != OK:
|
||||||
print("[Multiplayer] !!! Failed to create client. Error: %s" % err)
|
print("[Multiplayer] !!! Failed to create client. Error: %s" % err)
|
||||||
return
|
return
|
||||||
@@ -142,10 +140,12 @@ func _on_lobby_created(connect: int, this_lobby_id: int):
|
|||||||
|
|
||||||
Steam.setLobbyJoinable(lobby_id, true)
|
Steam.setLobbyJoinable(lobby_id, true)
|
||||||
Steam.setLobbyData(lobby_id, "name", steam_username + "'s Lobby")
|
Steam.setLobbyData(lobby_id, "name", steam_username + "'s Lobby")
|
||||||
Steam.setLobbyData(lobby_id, "mode", "Splunk")
|
|
||||||
|
|
||||||
Steam.allowP2PPacketRelay(true)
|
Steam.allowP2PPacketRelay(true)
|
||||||
setup_multiplayer_peer(true) # Setup as host
|
|
||||||
|
setup_multiplayer_peer(true)
|
||||||
|
|
||||||
|
peer_to_steam_id_map[1] = steam_id
|
||||||
|
spawn_player.rpc(1)
|
||||||
else :
|
else :
|
||||||
print("!!! Failed to create lobby.")
|
print("!!! Failed to create lobby.")
|
||||||
|
|
||||||
@@ -162,7 +162,6 @@ func _on_lobby_joined(this_lobby_id: int, permissions: int, locked: bool, respon
|
|||||||
print("Successfully joined lobby: %s" % lobby_id)
|
print("Successfully joined lobby: %s" % lobby_id)
|
||||||
get_lobby_members()
|
get_lobby_members()
|
||||||
|
|
||||||
# FIXED: Use Steam.getLobbyOwner() to determine if we should be host or client
|
|
||||||
var lobby_owner_id = Steam.getLobbyOwner(lobby_id)
|
var lobby_owner_id = Steam.getLobbyOwner(lobby_id)
|
||||||
var am_i_owner = (lobby_owner_id == steam_id)
|
var am_i_owner = (lobby_owner_id == steam_id)
|
||||||
|
|
||||||
@@ -170,11 +169,10 @@ func _on_lobby_joined(this_lobby_id: int, permissions: int, locked: bool, respon
|
|||||||
|
|
||||||
if not am_i_owner:
|
if not am_i_owner:
|
||||||
print("[Multiplayer] I am not the lobby owner, setting up as client...")
|
print("[Multiplayer] I am not the lobby owner, setting up as client...")
|
||||||
setup_multiplayer_peer(false) # Setup as client
|
setup_multiplayer_peer(false)
|
||||||
else:
|
else:
|
||||||
print("[Multiplayer] I am the lobby owner, but multiplayer peer should already be set up as host.")
|
print("[Multiplayer] I am the lobby owner, but multiplayer peer should already be set up as host.")
|
||||||
else:
|
else:
|
||||||
## ADDED: Log the specific reason for the join failure.
|
|
||||||
print("!!! Failed to join lobby. Reason: %s" % get_join_fail_reason(response))
|
print("!!! Failed to join lobby. Reason: %s" % get_join_fail_reason(response))
|
||||||
|
|
||||||
|
|
||||||
@@ -206,7 +204,6 @@ func _on_lobby_data_update(lobby: int, user: int, success: int) -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _on_persona_change(steam_id_changed: int, flag: int) -> void:
|
func _on_persona_change(steam_id_changed: int, flag: int) -> void:
|
||||||
# This can be spammy, but useful for debugging name changes.
|
|
||||||
# print("Persona state changed for %s. Refreshing lobby members." % steam_id_changed)
|
# print("Persona state changed for %s. Refreshing lobby members." % steam_id_changed)
|
||||||
get_lobby_members()
|
get_lobby_members()
|
||||||
|
|
||||||
@@ -226,35 +223,82 @@ func _on_lobby_chat_update(lobby_id_update: int, user_changed_id: int, user_maki
|
|||||||
|
|
||||||
print("[Lobby] Chat Update: User %s has %s." % [user_changed_id, state_string])
|
print("[Lobby] Chat Update: User %s has %s." % [user_changed_id, state_string])
|
||||||
|
|
||||||
# Any change in lobby membership should trigger a refresh.
|
|
||||||
get_lobby_members()
|
get_lobby_members()
|
||||||
|
|
||||||
|
|
||||||
|
@rpc("any_peer", "call_local")
|
||||||
|
func spawn_player(peer_id: int):
|
||||||
|
var steam_id_of_player = peer_to_steam_id_map.get(peer_id)
|
||||||
|
if steam_id_of_player == null:
|
||||||
|
print("!!! Cannot spawn player, peer %s not found in map." % peer_id)
|
||||||
|
return
|
||||||
|
|
||||||
|
print("Spawning player for peer: %s" % peer_id)
|
||||||
|
var player_name = Steam.getFriendPersonaName(steam_id_of_player)
|
||||||
|
|
||||||
|
var new_player = player_scene.instantiate() as Player
|
||||||
|
new_player.name = str(peer_id)
|
||||||
|
|
||||||
|
add_child(new_player)
|
||||||
|
players[peer_id] = new_player
|
||||||
|
new_player.set_player_name(player_name) # Call the simple RPC on the player node
|
||||||
|
new_player.position = Vector3(0,1,0)
|
||||||
|
# The server has the final say on who owns what
|
||||||
|
if multiplayer.is_server():
|
||||||
|
new_player.set_multiplayer_authority(peer_id)
|
||||||
|
|
||||||
|
|
||||||
|
@rpc("authority", "call_local")
|
||||||
|
func register_player(new_player_steam_id: int):
|
||||||
|
# This function only runs on the server
|
||||||
|
var new_player_peer_id = multiplayer.get_remote_sender_id()
|
||||||
|
print("Server: Registering peer %s with Steam ID %s" % [new_player_peer_id, new_player_steam_id])
|
||||||
|
|
||||||
|
# Add the new player to our map
|
||||||
|
peer_to_steam_id_map[new_player_peer_id] = new_player_steam_id
|
||||||
|
|
||||||
|
# Now, tell the new player about everyone who is already here
|
||||||
|
for peer_id in players:
|
||||||
|
spawn_player.rpc_id(new_player_peer_id, peer_id)
|
||||||
|
|
||||||
|
# Finally, tell EVERYONE to spawn the new player
|
||||||
|
spawn_player.rpc(new_player_peer_id)
|
||||||
|
|
||||||
|
|
||||||
func _on_peer_connected(id: int) -> void:
|
func _on_peer_connected(id: int) -> void:
|
||||||
print("[Multiplayer] ✅ Peer connected: %s" % id)
|
print("[Multiplayer] ✅ Peer connected: %s" % id)
|
||||||
var new_player = player_scene.instantiate() as Player
|
for peerd_id in players:
|
||||||
new_player.set_multiplayer_authority(id)
|
spawn_player.rpc_id(id, peerd_id)
|
||||||
$".".add_child(new_player)
|
spawn_player.rpc(id)
|
||||||
new_player.position = Vector3(0,1,0)
|
|
||||||
|
|
||||||
# It's good practice to re-check lobby members when a peer connects successfully.
|
|
||||||
get_lobby_members()
|
get_lobby_members()
|
||||||
|
|
||||||
|
|
||||||
func _on_peer_disconnected(id: int) -> void:
|
func _on_peer_disconnected(id: int) -> void:
|
||||||
print("[Multiplayer] ❌ Peer disconnected: %s" % id)
|
print("[Multiplayer] ❌ Peer disconnected: %s" % id)
|
||||||
|
if players.has(id):
|
||||||
|
players[id].queue_free()
|
||||||
|
players.erase(id)
|
||||||
|
|
||||||
|
if peer_to_steam_id_map.has(id):
|
||||||
|
peer_to_steam_id_map.erase(id)
|
||||||
|
|
||||||
|
|
||||||
func _on_connected_to_server() -> void:
|
func _on_connected_to_server() -> void:
|
||||||
print("[Multiplayer] ✅ Successfully connected to the host.")
|
print("[Multiplayer] ✅ Successfully connected to the host.")
|
||||||
print("[Multiplayer] - My Peer ID is now: %s" % multiplayer.get_unique_id())
|
print("[Multiplayer] - My Peer ID is now: %s" % multiplayer.get_unique_id())
|
||||||
|
|
||||||
|
register_player.rpc_id(1, steam_id)
|
||||||
|
|
||||||
|
|
||||||
func _on_connection_failed() -> void:
|
func _on_connection_failed() -> void:
|
||||||
print("[Multiplayer] ❌ Connection to the host failed.")
|
print("[Multiplayer] ❌ Connection to the host failed.")
|
||||||
|
|
||||||
|
|
||||||
func _on_server_disconnected() -> void:
|
func _on_server_disconnected() -> void:
|
||||||
print("[Multiplayer] ❌ Disconnected from the host.")
|
print("[Multiplayer] ❌ Disconnected from the host.")
|
||||||
|
|
||||||
|
|
||||||
## ADDED: New function to log all relevant multiplayer and lobby information.
|
|
||||||
func log_multiplayer_info():
|
func log_multiplayer_info():
|
||||||
print("\n--- DIAGNOSTIC INFO ---")
|
print("\n--- DIAGNOSTIC INFO ---")
|
||||||
print("## Multiplayer Status:")
|
print("## Multiplayer Status:")
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
[gd_scene load_steps=8 format=3 uid="uid://csmfxg011xisf"]
|
[gd_scene load_steps=7 format=3 uid="uid://csmfxg011xisf"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://dopyfulbw2mx5" path="res://player/player.gd" id="1_ulp21"]
|
[ext_resource type="Script" uid="uid://dopyfulbw2mx5" path="res://player/player.gd" id="1_ulp21"]
|
||||||
[ext_resource type="PackedScene" uid="uid://8phs2e161db1" path="res://ui/multiplayer-debug-ui/multiplayer-debug-ui.tscn" id="2_3c3w1"]
|
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_ehsmr"]
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_ehsmr"]
|
||||||
|
|
||||||
@@ -33,7 +32,6 @@ script = ExtResource("1_ulp21")
|
|||||||
[node name="Camera3D" type="Camera3D" parent="."]
|
[node name="Camera3D" type="Camera3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.399442, 0.0644827)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.399442, 0.0644827)
|
||||||
cull_mask = 1048573
|
cull_mask = 1048573
|
||||||
current = true
|
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
shape = SubResource("CapsuleShape3D_ehsmr")
|
shape = SubResource("CapsuleShape3D_ehsmr")
|
||||||
@@ -72,7 +70,3 @@ replication_config = SubResource("SceneReplicationConfig_ulp21")
|
|||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.887858, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.887858, 0)
|
||||||
billboard = 1
|
billboard = 1
|
||||||
text = "Username"
|
text = "Username"
|
||||||
|
|
||||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
|
||||||
|
|
||||||
[node name="Multiplayer-debug-ui" parent="CanvasLayer" instance=ExtResource("2_3c3w1")]
|
|
||||||
|
|||||||
@@ -9,17 +9,22 @@ var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
|
|||||||
var camera_node: Camera3D
|
var camera_node: Camera3D
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
if !is_multiplayer_authority():
|
if is_multiplayer_authority():
|
||||||
pass
|
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||||
camera_node = $Camera3D # Assuming Camera3D is a direct child
|
camera_node = $Camera3D
|
||||||
camera_node.current = true
|
camera_node.current = true
|
||||||
|
$Mesh.hide()
|
||||||
|
|
||||||
|
var peer_id = int(name)
|
||||||
|
|
||||||
|
@rpc("any_peer", "call_local")
|
||||||
|
func set_player_name(player_name: String):
|
||||||
|
$Label3D.text = player_name
|
||||||
|
|
||||||
$Label3D.text = SteamManager.steam_username
|
|
||||||
|
|
||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
if !is_multiplayer_authority():
|
if !is_multiplayer_authority():
|
||||||
pass
|
return
|
||||||
# Apply gravity
|
# Apply gravity
|
||||||
if not is_on_floor():
|
if not is_on_floor():
|
||||||
velocity.y -= gravity * delta
|
velocity.y -= gravity * delta
|
||||||
@@ -48,7 +53,7 @@ func _physics_process(delta):
|
|||||||
|
|
||||||
func _input(event):
|
func _input(event):
|
||||||
if !is_multiplayer_authority():
|
if !is_multiplayer_authority():
|
||||||
pass
|
return
|
||||||
if event is InputEventMouseMotion:
|
if event is InputEventMouseMotion:
|
||||||
# Rotate the CharacterBody3D around the Y-axis for horizontal look
|
# Rotate the CharacterBody3D around the Y-axis for horizontal look
|
||||||
rotate_y(-event.relative.x * mouse_sensitivity)
|
rotate_y(-event.relative.x * mouse_sensitivity)
|
||||||
@@ -63,6 +68,3 @@ func _input(event):
|
|||||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||||
else:
|
else:
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||||
|
|
||||||
if event.is_action_pressed("toggle_watch"):
|
|
||||||
$"CanvasLayer/Multiplayer-debug-ui".visible = !$"CanvasLayer/Multiplayer-debug-ui".visible
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ config/icon="res://icon.svg"
|
|||||||
[autoload]
|
[autoload]
|
||||||
|
|
||||||
SteamManager="*res://networking/steam-manager.gd"
|
SteamManager="*res://networking/steam-manager.gd"
|
||||||
|
GameManager="*res://game-logic/game_manager.gd"
|
||||||
|
|
||||||
[editor_plugins]
|
[editor_plugins]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user