Files
VRyHungry1/Scenes/multiplayer_world.gd
T
algodoogle 596d777fae asd
2026-07-25 19:26:43 +01:00

87 lines
2.9 KiB
GDScript

extends Node3D
## World script for the multiplayer scene. Consumes the host/join request set
## by the main menu, spawns the world's stations/items on whichever machine
## owns the world (server, or the local player when offline), spawns/despawns
## a player avatar per connected peer, and returns to the menu if the session
## ends.
##
## The world's actual content (stations, items) is NOT baked into this scene —
## it's spawned at runtime from Net/world_layout.gd via NetworkManager, so a
## joining client receives it from the server (MultiplayerSpawner replays
## existing spawns to late joiners) instead of relying on its own local copy
## matching.
const PLAYER_SCENE := preload("res://Player/net_player.tscn")
var xr_interface: XRInterface
var _populated := false
func _ready() -> void:
xr_interface = XRServer.find_interface("OpenXR")
if xr_interface and xr_interface.is_initialized():
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
get_viewport().use_xr = true
NetworkManager.register_world(self, $PlayersSpawner, $ItemsSpawner)
NetworkManager.player_joined.connect(_on_player_joined)
NetworkManager.player_left.connect(_on_player_left)
NetworkManager.session_started.connect(_on_session_started)
NetworkManager.session_ended.connect(_on_session_ended)
NetworkManager.connection_failed.connect(_on_connection_failed)
# Offline (single player / dev run): owns_world() is already true, so
# populate immediately. Online host case is handled by session_started.
_populate_world_if_owner()
NetworkManager.world_ready()
func _exit_tree() -> void:
NetworkManager.unregister_world()
func _on_session_started(_is_server: bool) -> void:
_populate_world_if_owner()
## Spawns the world's stations/items exactly once, on the machine that owns
## world logic (server or offline). Safe to call multiple times/entry points.
func _populate_world_if_owner() -> void:
if not NetworkManager.owns_world() or _populated:
return
_populated = true
GameManager.meals_in_play = ["hamburger"]
for d in WorldLayout.get_stations():
NetworkManager.spawn_item(d["scene"], d["xform"], d["name"], d["props"])
for d in WorldLayout.get_items():
NetworkManager.spawn_item(d["scene"], d["xform"], d["name"], d["props"])
## Only the server (or the single offline machine) materialises player
## avatars; MultiplayerSpawner replicates the result to everyone else,
## including late joiners.
func _on_player_joined(peer_id: int) -> void:
if not NetworkManager.owns_world() or $Players.has_node(str(peer_id)):
return
var p := PLAYER_SCENE.instantiate()
p.name = str(peer_id)
$Players.add_child(p, true)
func _on_player_left(peer_id: int) -> void:
if not NetworkManager.owns_world():
return
var p := $Players.get_node_or_null(str(peer_id))
if p:
p.queue_free()
func _on_session_ended() -> void:
get_tree().change_scene_to_file("res://Scenes/mainMenu.tscn")
func _on_connection_failed() -> void:
get_tree().change_scene_to_file("res://Scenes/mainMenu.tscn")