Server generation of star system and authority for gravity
This commit is contained in:
22
src/scenes/celestial_bodies/barycenter.tscn
Normal file
22
src/scenes/celestial_bodies/barycenter.tscn
Normal file
@ -0,0 +1,22 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://b7bh45nrtdom5"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b2hb3bwrlh40c" path="res://scenes/celestial_bodies/barycenter.gd" id="1_e776o"]
|
||||
|
||||
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_e776o"]
|
||||
properties/0/path = NodePath(".:linear_velocity")
|
||||
properties/0/spawn = true
|
||||
properties/0/replication_mode = 1
|
||||
properties/1/path = NodePath(".:position")
|
||||
properties/1/spawn = true
|
||||
properties/1/replication_mode = 1
|
||||
|
||||
[node name="Barycenter" type="RigidBody3D" unique_id=1389317234]
|
||||
script = ExtResource("1_e776o")
|
||||
metadata/_custom_type_script = "uid://wlm40n8ywr"
|
||||
|
||||
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=717759965]
|
||||
replication_config = SubResource("SceneReplicationConfig_e776o")
|
||||
|
||||
[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="." unique_id=2061784354]
|
||||
_spawnable_scenes = PackedStringArray("uid://dv18eg4xrlefe")
|
||||
spawn_path = NodePath("..")
|
||||
@ -2,11 +2,12 @@ class_name CelestialBody extends OrbitalBody3D
|
||||
|
||||
# --- Set in corresponding scene ---
|
||||
# var auto_proxy_gravity = false
|
||||
@export var radius: float = 100.0
|
||||
@export var radius: float = 100.0:
|
||||
set(value):
|
||||
radius = value
|
||||
_set_radi()
|
||||
|
||||
func set_radius(value: float):
|
||||
radius = value
|
||||
|
||||
func _set_radi():
|
||||
if $Surface.mesh is SphereMesh:
|
||||
$Surface.mesh.radius = radius
|
||||
$Surface.mesh.height = radius * 2.0
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://dv18eg4xrlefe"]
|
||||
[gd_scene load_steps=6 format=3 uid="uid://dv18eg4xrlefe"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dok35h0q4pseh" path="res://scenes/celestial_bodies/celestial_body.gd" id="1_uxu4s"]
|
||||
[ext_resource type="Material" uid="uid://de0xnmjf12ted" path="res://scenes/celestial_bodies/materials/sun_mat.tres" id="2_vi0nt"]
|
||||
@ -11,18 +11,38 @@ height = 4000.0
|
||||
|
||||
[sub_resource type="SphereShape3D" id="SphereShape3D_uxu4s"]
|
||||
|
||||
[node name="CelestialBody" type="RigidBody3D"]
|
||||
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_vi0nt"]
|
||||
properties/0/path = NodePath(".:position")
|
||||
properties/0/spawn = true
|
||||
properties/0/replication_mode = 1
|
||||
properties/1/path = NodePath(".:rotation")
|
||||
properties/1/spawn = true
|
||||
properties/1/replication_mode = 1
|
||||
properties/2/path = NodePath(".:linear_velocity")
|
||||
properties/2/spawn = true
|
||||
properties/2/replication_mode = 1
|
||||
properties/3/path = NodePath(".:angular_velocity")
|
||||
properties/3/spawn = true
|
||||
properties/3/replication_mode = 1
|
||||
properties/4/path = NodePath(".:radius")
|
||||
properties/4/spawn = true
|
||||
properties/4/replication_mode = 1
|
||||
|
||||
[node name="CelestialBody" type="RigidBody3D" unique_id=345490070]
|
||||
script = ExtResource("1_uxu4s")
|
||||
auto_proxy_gravity = false
|
||||
metadata/_custom_type_script = "uid://dok35h0q4pseh"
|
||||
|
||||
[node name="Surface" type="MeshInstance3D" parent="."]
|
||||
[node name="Surface" type="MeshInstance3D" parent="." unique_id=193823349]
|
||||
mesh = SubResource("SphereMesh_vi0nt")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=232085687]
|
||||
shape = SubResource("SphereShape3D_uxu4s")
|
||||
|
||||
[node name="OmniLight3D" type="OmniLight3D" parent="."]
|
||||
[node name="OmniLight3D" type="OmniLight3D" parent="." unique_id=1965995953]
|
||||
light_color = Color(0.958646, 0.7997282, 0.55087835, 1)
|
||||
omni_range = 200000.0
|
||||
omni_attenuation = 2.0
|
||||
|
||||
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=2090029903]
|
||||
replication_config = SubResource("SceneReplicationConfig_vi0nt")
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
extends Node
|
||||
|
||||
var port = 42069
|
||||
var default_ip = "127.0.0.1"
|
||||
|
||||
func create_server() -> void:
|
||||
print(multiplayer.multiplayer_peer)
|
||||
print("Starting Server on port %d..." % port)
|
||||
var peer = ENetMultiplayerPeer.new()
|
||||
|
||||
# Ensure we disconnect old signals if any
|
||||
_disconnect_signals()
|
||||
setup_connections()
|
||||
|
||||
var error = peer.create_server(port)
|
||||
@ -14,37 +17,66 @@ func create_server() -> void:
|
||||
return
|
||||
|
||||
multiplayer.multiplayer_peer = peer
|
||||
|
||||
print("Server Unique ID: ", multiplayer.get_unique_id())
|
||||
|
||||
func create_client() -> void:
|
||||
func create_client(ip: String = "") -> void:
|
||||
var target_ip = ip if not ip.is_empty() else default_ip
|
||||
print("Connecting to Server at %s:%d..." % [target_ip, port])
|
||||
|
||||
_disconnect_signals()
|
||||
setup_connections()
|
||||
|
||||
var peer = ENetMultiplayerPeer.new()
|
||||
var error = peer.create_client("127.0.0.1", port)
|
||||
var error = peer.create_client(target_ip, port)
|
||||
if error:
|
||||
push_error(error)
|
||||
return
|
||||
|
||||
multiplayer.multiplayer_peer = peer
|
||||
print("Client Unique ID: ", multiplayer.get_unique_id())
|
||||
print("Client waiting for connection...")
|
||||
|
||||
func close_connection():
|
||||
if multiplayer.multiplayer_peer:
|
||||
multiplayer.multiplayer_peer.close()
|
||||
multiplayer.multiplayer_peer = null
|
||||
print("Connection closed.")
|
||||
_disconnect_signals()
|
||||
|
||||
func setup_connections():
|
||||
multiplayer.peer_connected.connect(on_peer_connected)
|
||||
multiplayer.peer_disconnected.connect(on_peer_disconnected)
|
||||
multiplayer.connected_to_server.connect(on_connected_to_server)
|
||||
if not multiplayer.peer_connected.is_connected(on_peer_connected):
|
||||
multiplayer.peer_connected.connect(on_peer_connected)
|
||||
if not multiplayer.peer_disconnected.is_connected(on_peer_disconnected):
|
||||
multiplayer.peer_disconnected.connect(on_peer_disconnected)
|
||||
if not multiplayer.connected_to_server.is_connected(on_connected_to_server):
|
||||
multiplayer.connected_to_server.connect(on_connected_to_server)
|
||||
if not multiplayer.server_disconnected.is_connected(on_server_disconnected):
|
||||
multiplayer.server_disconnected.connect(on_server_disconnected)
|
||||
|
||||
func _disconnect_signals():
|
||||
if multiplayer.peer_connected.is_connected(on_peer_connected):
|
||||
multiplayer.peer_connected.disconnect(on_peer_connected)
|
||||
if multiplayer.peer_disconnected.is_connected(on_peer_disconnected):
|
||||
multiplayer.peer_disconnected.disconnect(on_peer_disconnected)
|
||||
if multiplayer.connected_to_server.is_connected(on_connected_to_server):
|
||||
multiplayer.connected_to_server.disconnect(on_connected_to_server)
|
||||
if multiplayer.server_disconnected.is_connected(on_server_disconnected):
|
||||
multiplayer.server_disconnected.disconnect(on_server_disconnected)
|
||||
|
||||
func on_peer_connected(peer_id: int) -> void:
|
||||
print("Peer %s recieved connection: %s" % [multiplayer.get_unique_id(), peer_id])
|
||||
|
||||
# For each peer that connects, we put them in the queue to spawn
|
||||
print("Peer %s received connection: %s" % [multiplayer.get_unique_id(), peer_id])
|
||||
if multiplayer.is_server():
|
||||
GameManager.queue_spawn_player(peer_id)
|
||||
|
||||
|
||||
func on_peer_disconnected(peer_id: int) -> void:
|
||||
print("Peer %s lost connection to: %s" % [multiplayer.get_unique_id(), peer_id])
|
||||
print(multiplayer.get_peers())
|
||||
# TODO: GameManager should cleanup the player's pawn
|
||||
|
||||
func on_connected_to_server() -> void:
|
||||
print("%s connected to server!" % multiplayer.get_unique_id())
|
||||
# If we are in the main menu, this is the trigger to switch scenes
|
||||
if get_tree().current_scene.name == "MainMenu":
|
||||
get_tree().change_scene_to_file("res://main.tscn")
|
||||
|
||||
func on_server_disconnected() -> void:
|
||||
print("Disconnected from server.")
|
||||
get_tree().change_scene_to_file("res://scenes/UI/main_menu.tscn")
|
||||
@ -86,6 +86,7 @@ func _update_mass_and_inertia():
|
||||
|
||||
|
||||
func _integrate_forces(state: PhysicsDirectBodyState3D):
|
||||
if not is_multiplayer_authority(): return
|
||||
# Safety Check for Division by Zero
|
||||
if mass <= 0.0:
|
||||
accumulated_force = Vector3.ZERO
|
||||
|
||||
@ -4,16 +4,33 @@ extends Node3D
|
||||
|
||||
@export_group("System Metadata")
|
||||
@export var system_name: String = "Kepler-186"
|
||||
@export var system_seed: int = 0
|
||||
@export var galactic_coordinates: Vector2i = Vector2i.ZERO
|
||||
|
||||
var system_data: SystemData
|
||||
|
||||
func _ready():
|
||||
# 1. Create the generator tool.
|
||||
var generator = StarSystemGenerator.new()
|
||||
|
||||
if multiplayer.is_server():
|
||||
if system_seed == 0:
|
||||
system_seed = randi()
|
||||
seed(system_seed)
|
||||
print("StarSystem (Server): Generating system with seed: %d" % system_seed)
|
||||
|
||||
var generator = StarSystemGenerator.new()
|
||||
system_data = generator.generate(self)
|
||||
|
||||
# At this point, the generator has added children to 'self'.
|
||||
# Because we have a MultiplayerSpawner watching 'self', these new children
|
||||
# will automatically be replicated to connected clients!
|
||||
else:
|
||||
print("StarSystem (Client): Waiting for planets from server...")
|
||||
# The client does NOT generate. It just waits for the Spawner to do its job.
|
||||
# We can reconstruct 'system_data' by scanning children if needed,
|
||||
# or just let GameManager find them via 'get_children()'.
|
||||
|
||||
# 2. Tell the generator to build the system within this StarSystem node.
|
||||
system_data = generator.generate(self)
|
||||
|
||||
# 3. Register the completed system with the GameManager.
|
||||
GameManager.register_star_system(self)
|
||||
|
||||
15
src/scripts/star_system.tscn
Normal file
15
src/scripts/star_system.tscn
Normal file
@ -0,0 +1,15 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://b554pkth6hox4"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bkcouefvi7iup" path="res://scripts/star_system.gd" id="1_gbrlo"]
|
||||
|
||||
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_gbrlo"]
|
||||
|
||||
[node name="StarSystem" type="Node3D" unique_id=1547322980]
|
||||
script = ExtResource("1_gbrlo")
|
||||
|
||||
[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="." unique_id=1117979460]
|
||||
_spawnable_scenes = PackedStringArray("uid://dv18eg4xrlefe", "uid://b7bh45nrtdom5", "uid://bkwogkfqk2uxo")
|
||||
spawn_path = NodePath("..")
|
||||
|
||||
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=801189521]
|
||||
replication_config = SubResource("SceneReplicationConfig_gbrlo")
|
||||
@ -11,6 +11,7 @@ const MAX_PLANETS = 8
|
||||
const MAX_MOONS_PER_PLANET = 5
|
||||
const ORBIT_SAFETY_FACTOR = 5
|
||||
|
||||
var BarycenterScene: PackedScene = preload("res://scenes/celestial_bodies/barycenter.tscn")
|
||||
var CelestialBodyScene: PackedScene = preload("res://scenes/celestial_bodies/celestial_body.tscn")
|
||||
|
||||
func generate(star_system: StarSystem) -> SystemData:
|
||||
@ -20,7 +21,7 @@ func generate(star_system: StarSystem) -> SystemData:
|
||||
|
||||
system_data.star = star
|
||||
star.name = "Star"
|
||||
star.set_radius(2000.0)
|
||||
star.radius = 2000.0
|
||||
star.base_mass = STAR_MASS
|
||||
star_system.add_child(star)
|
||||
|
||||
@ -28,12 +29,12 @@ func generate(star_system: StarSystem) -> SystemData:
|
||||
var current_orbit_radius = 15000.0
|
||||
|
||||
for i in range(num_planets):
|
||||
var planet_barycenter = Barycenter.new()
|
||||
var planet_barycenter = BarycenterScene.instantiate()
|
||||
planet_barycenter.name = "PlanetSystem_%d" % (i + 1)
|
||||
star_system.add_child(planet_barycenter)
|
||||
|
||||
var planet: CelestialBody = CelestialBodyScene.instantiate()
|
||||
planet.set_radius(randf_range(50.0, 200.0))
|
||||
planet.radius = randf_range(50.0, 200.0)
|
||||
system_data.planets.append(planet)
|
||||
planet.name = "Planet_%d" % (i + 1)
|
||||
planet.base_mass = randf_range(PLANET_MASS * 0.2, PLANET_MASS * 5.0)
|
||||
@ -69,7 +70,7 @@ func _generate_moons(planet: OrbitalBody3D, planet_barycenter: Barycenter, syste
|
||||
|
||||
for i in range(num_moons):
|
||||
var moon = CelestialBodyScene.instantiate()
|
||||
moon.set_radius(10.0)
|
||||
moon.radius = 10.0
|
||||
system_data.moons.append(moon)
|
||||
planet_barycenter.add_child(moon)
|
||||
planet_barycenter.recalculate_total_mass()
|
||||
|
||||
Reference in New Issue
Block a user