WIP Networking

This commit is contained in:
2025-11-02 20:37:46 +01:00
parent c4fd7f1330
commit 5e851049b5
4 changed files with 33 additions and 6 deletions

View File

@ -62,6 +62,22 @@ Character progression is based on distinct species with physical advantages and
- Ship AI: A non-physical class that interacts directly with ship systems at the cost of high power and heat generation.
### 6. Runtime Component Design & Engineering
To move beyond pre-defined ship parts, the game will feature an in-game system for players to design, prototype, and manufacture their own components. This is achieved through a "Component Blueprint" architecture that separates a component's data definition from its physical form.
- **Component Blueprints:** A `ComponentBlueprint` is a `Resource` file (`.tres`) that acts as a schematic. It contains metadata (name, description), a reference to a generic base scene (e.g., a "thruster chassis"), and a dictionary of overridden properties (e.g., `{"thrust_force": 7500, "mass": 120}`).
- **Generic Template Scenes:** Instead of dozens of unique component scenes, the game will use a small number of generic, unconfigured "template" scenes (e.g., `generic_thruster.tscn`, `generic_power_plant.tscn`). These scenes have scripts with exported variables that define their performance characteristics.
- **The Design Lab:** Players will use a dedicated `SystemStation` (the "Design Lab") to create and modify blueprints. This UI will dynamically generate controls (sliders, input fields) based on the exported variables of the selected template scene. Players can tweak parameters, balancing trade-offs like performance vs. resource cost, and save the result as a new blueprint resource in their personal data folder.
- **Networked Construction:** When a player builds an object in-game, they are selecting one of their saved blueprints.
1. The client sends an RPC to the server with the path to the chosen `ComponentBlueprint` resource.
2. The server validates the request and loads the blueprint. (This requires a system for syncing player-created blueprints to the server upon connection).
3. A global `ComponentFactory` singleton on the server takes the blueprint, instantiates the correct generic template scene, and applies the blueprint's property overrides to the new instance.
4. This fully-configured node is then passed to the `MultiplayerSpawner`, which replicates the object across the network, ensuring all clients see the correctly customized component.
## 4. Technical Overview
- Architecture: The project uses a decoupled, modular architecture heavily reliant on a global SignalBus for inter-scene communication and a GameManager for global state. Ships feature their own local ShipSignalBus for internal component communication.

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=8 format=3 uid="uid://7yc6a07xoccy"]
[gd_scene load_steps=9 format=3 uid="uid://7yc6a07xoccy"]
[ext_resource type="Script" uid="uid://cdmmiixa75f3x" path="res://scenes/tests/3d/character_pawn_3d.gd" id="1_4frsu"]
[ext_resource type="Script" uid="uid://vjfk3xnapfti" path="res://scenes/tests/3d/player_controller_3d.gd" id="2_r62el"]
@ -12,6 +12,11 @@
[sub_resource type="SphereShape3D" id="SphereShape3D_gnddn"]
radius = 1.0
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_8jhjh"]
properties/0/path = NodePath("CharacterPawn3d:global_transform")
properties/0/spawn = true
properties/0/replication_mode = 1
[node name="CharacterPawn3D" type="CharacterBody3D"]
script = ExtResource("1_4frsu")
metadata/_custom_type_script = "uid://cdmmiixa75f3x"
@ -49,3 +54,6 @@ script = ExtResource("4_8jhjh")
metadata/_custom_type_script = "uid://y3vo40i16ek3"
[node name="EVAMovementComponent" parent="." instance=ExtResource("3_gnddn")]
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
replication_config = SubResource("SceneReplicationConfig_8jhjh")

View File

@ -28,7 +28,7 @@ func _unhandled_input(event: InputEvent):
var sensitivity_modified_mouse_input = Vector2(yaw_input, pitch_input) * mouse_sensitivity
# Send rotation input via RPC immediately
server_process_rotation_input.rpc_id(player_id, sensitivity_modified_mouse_input)
server_process_rotation_input.rpc_id(multiplayer.multiplayer_peer.get_unique_id(), sensitivity_modified_mouse_input)
func _physics_process(_delta):
if not is_multiplayer_authority() or not is_instance_valid(possessed_pawn):
@ -43,9 +43,9 @@ func _physics_process(_delta):
var l_input = KeyInput.new(Input.is_action_just_pressed("left_click"), Input.is_action_pressed("left_click"), Input.is_action_just_released("left_click"))
var r_input = KeyInput.new(Input.is_action_just_pressed("right_click"), Input.is_action_pressed("right_click"), Input.is_action_just_released("right_click"))
server_process_movement_input.rpc_id(player_id, move_vec, roll_input, vertical_input)
server_process_interaction_input.rpc_id(player_id, interact_input)
server_process_clicks.rpc_id(player_id, l_input, r_input)
server_process_movement_input.rpc_id(multiplayer.multiplayer_peer.get_unique_id(), move_vec, roll_input, vertical_input)
server_process_interaction_input.rpc_id(multiplayer.multiplayer_peer.get_unique_id(), interact_input)
server_process_clicks.rpc_id(multiplayer.multiplayer_peer.get_unique_id(), l_input, r_input)
@rpc("any_peer", "call_local")
func server_process_movement_input(move: Vector2, roll: float, vertical: float):
@ -69,7 +69,7 @@ func server_process_clicks(l_action: KeyInput, r_action: KeyInput):
func possess(pawn_to_control: CharacterPawn3D):
possessed_pawn = pawn_to_control
print("PlayerController3D possessed: ", possessed_pawn.name)
print("PlayerController3D possessed: ", possessed_pawn.name)
# Optional: Release mouse when losing focus
func _notification(what):

View File

@ -162,3 +162,6 @@ shape = SubResource("CylinderShape3D_nvgim")
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 21.143803, 0, -10.62656)
script = ExtResource("2_jlvj7")
metadata/_custom_type_script = "uid://db1u2qqihhnq4"
[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="."]
spawn_path = NodePath("../Spawner")