feat: expand progression and multiplayer systems

Add named save slots, progression import/export, and a unified play flow. Add live friend requests, presence, invitations, and relationship controls without durable discovery-server social storage. Advance the network protocol with isolated channels, movement reconciliation, late-join recovery, fishing replication, and animation synchronization. Preserve per-species catch totals, refine generated-world startup and water recovery, and complete the related input and interface improvements.
This commit is contained in:
Alexander Sellite 2026-08-23 20:48:38 -04:00
parent 1db1a5b754
commit 3b84bfe3a0
97 changed files with 7869 additions and 982 deletions

View file

@ -30,6 +30,7 @@ const WORLD_BOUNDARY_SHORELINE_CLEARANCE := 18.0
var _world_layout: StringName = WorldLayoutType.GENERATED
var _world_seed: int = PlayerSaveManager.DEFAULT_WORLD_SEED
var _light_performance_profile: bool = false
var _dedicated_simulation: bool = false
func get_player_water_triggers() -> Array[PlayerWaterTrigger]:
@ -74,6 +75,62 @@ func set_light_performance_profile(enabled: bool) -> void:
_active_region.set_light_performance_profile(enabled)
func set_dedicated_simulation(enabled: bool) -> void:
_dedicated_simulation = enabled
if _active_region != null:
_set_region_presentation_enabled(_active_region, not enabled)
_world_environment.process_mode = (
Node.PROCESS_MODE_DISABLED if enabled else Node.PROCESS_MODE_INHERIT
)
_sun.visible = not enabled
_sun.process_mode = (
Node.PROCESS_MODE_DISABLED if enabled else Node.PROCESS_MODE_INHERIT
)
func _set_region_presentation_enabled(
region: WorldRegion,
enabled: bool,
) -> void:
for class_name_value: String in [
"WaterSurfaceMotion",
"LocalStormCloudLayer",
"WorldCharacterDisplay",
]:
for value: Node in region.find_children(
"*", class_name_value, true, false
):
value.process_mode = (
Node.PROCESS_MODE_INHERIT
if enabled
else Node.PROCESS_MODE_DISABLED
)
for value: Node in region.find_children("*", "GeometryInstance3D", true, false):
(value as GeometryInstance3D).visible = enabled
for value: Node in region.find_children("*", "GPUParticles3D", true, false):
var particles := value as GPUParticles3D
particles.emitting = enabled
particles.process_mode = (
Node.PROCESS_MODE_INHERIT if enabled else Node.PROCESS_MODE_DISABLED
)
for value: Node in region.find_children("*", "AnimationPlayer", true, false):
var animation_player := value as AnimationPlayer
animation_player.active = enabled
animation_player.process_mode = (
Node.PROCESS_MODE_INHERIT if enabled else Node.PROCESS_MODE_DISABLED
)
for class_name_value: String in ["AudioStreamPlayer", "AudioStreamPlayer3D"]:
for value: Node in region.find_children(
"*", class_name_value, true, false
):
value.call("stop")
value.process_mode = (
Node.PROCESS_MODE_INHERIT
if enabled
else Node.PROCESS_MODE_DISABLED
)
func get_fishable_water_regions() -> Array[FishableWaterRegion]:
return (
_active_region.get_fishable_water_regions()
@ -129,6 +186,17 @@ func get_generation_seed() -> int:
return _world_seed
func is_world_ready() -> bool:
if _active_region == null:
return false
if _world_layout != WorldLayoutType.GENERATED:
return true
return (
_active_region.has_method(&"is_world_generated")
and bool(_active_region.call(&"is_world_generated"))
)
func get_diggable_area_triangles(
area_id: StringName,
) -> Array[PackedVector3Array]:
@ -182,6 +250,8 @@ func _replace_active_region(layout: StringName, seed: int) -> bool:
_active_region = replacement
_regions_root.add_child(_active_region)
_active_region.set_light_performance_profile(_light_performance_profile)
if _dedicated_simulation:
_set_region_presentation_enabled(_active_region, false)
return true