Move party vessel spawning to always-active PartyVesselSpawner#129
Open
Shombith03 wants to merge 371 commits into
Open
Move party vessel spawning to always-active PartyVesselSpawner#129Shombith03 wants to merge 371 commits into
Shombith03 wants to merge 371 commits into
Conversation
…ors-LTKde Add missing assembly definition dependencies
ProfileModal was routing through the disabled PlayFab PlayerDataController instead of the active UGS PlayerDataService, so name changes were silently dropped. ArcadeProfileWidget and ProfileIconSelectView lacked a singleton fallback for PlayerDataService (whose Awake detaches from hierarchy via DontDestroyOnLoad, breaking serialized Inspector refs) and gated saves on IsInitialized when the service is usable as soon as CurrentProfile exists. Default display name changed from static "Pilot" to "Pilot#XXXX" with a random 4-digit suffix so new players get unique names out of the box. https://claude.ai/code/session_018uU3m2F5XVUMoynp8jxdM4
In party mode, environment GameObjects are deactivated during network spawn and reactivated per round via SetActive. This leaves NetworkCrystalManager.IsSpawned potentially false after reactivation (same root cause as RPCs being unregistered on mini-game controllers). When IsSpawned is false: - OnEnable skipped event subscription (gated on IsSpawned) - OnTurnStarted returned early (IsServer false when !IsSpawned) - No positions generated → no crystals spawned Fix adds IsPartyMode flag to CrystalManager (set via SetPartyModeOnEnvironment alongside controllers and cinematics) and falls back to direct local spawning when IsSpawned is unreliable: - OnEnable: subscribe when IsPartyMode even if !IsSpawned - OnTurnStarted: use SpawnBatchIfMissing() fallback (like LocalCrystalManager) when IsPartyMode && !IsSpawned - OnResetForReplay/OnTurnEnded: destroy crystals directly - RespawnCrystal/ExplodeCrystal: bypass ServerRpc/ClientRpc This mirrors the established party mode pattern where MultiplayerDomainGamesController.OnReadyClicked_ already bypasses RPCs with a direct local countdown for the same reason. https://claude.ai/code/session_01Piy2uQvUaeqfJhG3eaR4Dj
Default name is now "Pilot1234" instead of "Pilot#1234". https://claude.ai/code/session_018uU3m2F5XVUMoynp8jxdM4
Add NativeShare.Runtime, Reflex, Unity.Cinemachine, Unity.Services.Multiplayer, and Unity.Entities.UI references to fix CS0246 compilation errors in ShareByEmail, NetworkMonitor, WildlifeBlitzEndGameCinematicController, PrismImplosionPoolManager, GameDataSO, and FloraConfigurationSO. https://claude.ai/code/session_01UF2ffnmtP5fKPgDTEe2YhA
…s-FUUh6 Add missing assembly definition references for new features
Resolved 73 merge conflicts: - 50+ files: kept using CosmicShore.Models.Enums from app-shell-polish (enum namespace reorganization) - Kept Reflex DI [Inject] pattern over singleton Instance pattern - Kept SOAP event-driven auth over AuthenticationController.Instance - Removed deprecated MiniGame.cs and ProtectMissionGame.cs (deleted in app-shell-polish) - Accepted WidescreenLayoutAdapter.cs in relocated path - Kept HEAD's BoidSimulationController (development had garbled merge artifacts) - Combined PlayFab disabled flag with SOAP-style network subscriptions - Kept development's PrismScale property in SpawnableEllipsoid (needed for compilation) https://claude.ai/code/session_01RGWp6PVjTsB34uTBcFZnEP
Root causes: - IsPartyMode && !IsSpawned fallback never triggered because IsSpawned stays true after SetActive(false) — all party mode code paths fell through to the unreliable NetworkList/RPC mechanism - Both HexRace and CrystalCapture use spawnOnClientReady=true, which fires OnClientReady at 0.5s (round 2+) before Cell.Initialize at 1s, causing null refs in SnowChangerManager Fixes: - NetworkCrystalManager: remove !IsSpawned from ALL party mode checks, always use direct local spawning via SpawnBatchIfMissing() - In party mode, subscribe to OnMiniGameTurnStarted instead of OnClientReady to ensure Cell is initialized before crystal spawn - Add unsubscribe-before-subscribe guard against double subscriptions - SnowChangerManager: add null safety for cellData.Config and cellData.CellTransform, stay subscribed until cell is ready https://claude.ai/code/session_01Piy2uQvUaeqfJhG3eaR4Dj
CosmicShore.Runtime: +Unity.Services.Analytics, Unity.Collections, Unity.TextMeshPro, Unity.Mathematics, Unity.Burst, Unity.Entities, Unity.Netcode.Components CosmicShore.Utility: +Reflex, Unity.Cinemachine, Unity.Services.Multiplayer, Unity.Entities.UI CosmicShore.Editor: +PlayFab CosmicShore.DialogueSystem: +Unity.TextMeshPro https://claude.ai/code/session_01RGWp6PVjTsB34uTBcFZnEP
…s-JfEWt Optimize prism VFX and AOE damage with batched Jobs, add HyperSea skybox
Systematically updated namespace declarations across 1019 files to align with their directory paths under Assets/_Scripts/ and Assets/FTUE/: - Changed 651+ namespace declarations to match folder hierarchy (e.g., CosmicShore.Game -> CosmicShore.Game.Ship.ShipActions) - Added namespaces to 200+ files that previously had none - Updated using directives across the codebase to reference new namespaces - Fixed FTUE scripts (split CosmicShore.FTUE into Data/Drivers/Handlers/etc.) - Handled folder names with spaces (e.g., "Abstract Effect Types" -> AbstractEffectTypes) - Skipped third-party packages and ~ChoppingBlock deprecated code https://claude.ai/code/session_01QxKnfNHPy1woQ9chAkZGB5
…-1ZgoJ Claude/add missing sounds 1 zgo j
…spaces-61yHn Refactor namespace organization and update import statements
- PrismFactory.cs: CosmicShore.Utilities → CosmicShore.Utility.SOAP.ScriptableEventWithReturn - ThemeManagerDataContainerSO.cs: CosmicShore.Utilities → CosmicShore.Models.ScriptableObjects - Remove nonexistent CosmicShore.Soap using from 4 files (LifeFormsKilledScoring, SinglePlayerWildlifeBlitzController, SingleplayerWildlifeBlitzTurnMonitor, SparrowDebuffByRhinoDangerPrismEffectSO) https://claude.ai/code/session_01GfuGtrE29i2FvfaY3o57Ea
…ors-YSMoK Clean up unused imports and update namespace references
Remove unused using directives (CosmicShore.Game.Managers, CosmicShore.Game.Environment.FlowField, CosmicShore.Game.Ship) from RoundStats.cs and IRoundStats.cs. Fully qualify Editor base class as UnityEditor.Editor in SSUScripts editors to resolve namespace shadowing. https://claude.ai/code/session_01MNcgikkBy86nmNR2uQpZey
…ors-7ybMl Clean up unused imports and fully qualify Editor base class
The previous namespace update commit erroneously inserted the `namespace CosmicShore.Utility.DataPersistence` declaration inside the Load<T> method body instead of wrapping the class. This corrupted the brace structure and broke compilation. Fix by properly wrapping the class in the namespace and adding the using directive to all 6 callers. https://claude.ai/code/session_01Pd8XCQjdTmbzhNjxu2bBvP
…o9Boc Refactor DataAccessor into namespace and fix import statements
Qualify bare 'Editor' as 'UnityEditor.Editor' in three SSU Interactive Editor files where the namespace segment 'Editor' shadowed the type. Move NetworkMonitor.cs from CosmicShore.Utility assembly to CosmicShore.Runtime assembly (Services folder) so it can access SOAP types that live in Runtime via .asmref redirect. https://claude.ai/code/session_01A1k4zWuunagSpsfG9yKoKK
Refactor: Move NetworkMonitor to Services namespace and fix Editor class references
DOFillAmount is an extension method from DOTweenModuleUI.cs which compiles into the default assembly. BoostFillAnimator lives in the CosmicShore.Utility asmdef, which cannot reference the default assembly. Using DOTween.To() from the core DLL achieves the same result and is accessible from any assembly. https://claude.ai/code/session_018XSMyynxCrPbEnWD4XFXLg
Refactor BoostFillAnimator to use DOTween.To for fill animation
Move misplaced namespace declarations to properly wrap class bodies in VesselTransformer, DriftTrailAction, ScoutTrailPrismScaler, FullAutoActionExecutor, and SpawnableWaypointTrack. Remove invalid `using CosmicShore.DialogueSystem.Models` directives from IDialogueService and IDialogueViewResolver (types already in scope via containing namespace). https://claude.ai/code/session_016mfEPyHGnW6yyWX5EoRs7J
…ors-iAjEt Fix namespace declarations positioning in C# files
…nces - Remove 'using CosmicShore.Core;' from 23 files (namespace doesn't exist, types are in CosmicShore.Models.Enums which is already imported) - Remove 'using CosmicShore.Editor;' from 3 runtime files (editor-only assembly not accessible from runtime) - Remove 'using CosmicShore.DialogueSystem.Editor;' from 4 runtime files (editor-only assembly not accessible from runtime) - Fix 'using CosmicShore.App.UI;' → 'using CosmicShore.UI;' in 2 files (ScreenSwitcher lives in CosmicShore.UI) - Remove unused 'using CosmicShore.App.UI.Controllers;' from OverviewPanelUI - Remove invalid 'using Unity.Multiplayer.Samples.Utilities;' from NetworkVesselClientCache (types are local in CosmicShore.Game.Ship) - Delete duplicate ShipSelectionSlot struct (defined in both ShipSelectionSlot.cs and inline in ShipSelectionView.cs) https://claude.ai/code/session_017Bxu4xkBksyonCKup2TLvK
The ScriptablePartyData directory and its 7 scripts were committed without .meta files, as was HostConnectionDataSO.cs. Unity requires .meta files for proper asset tracking and GUID-based serialized references. https://claude.ai/code/session_01VUuKBf6Rwadg5U9yMMhtdb
…ues-ihQXn Remove unused imports and delete obsolete ShipSelectionSlot class
…b reference The prefab was kept in the previous commit with its script swapped to SceneLoader, but it is no longer needed — scenes already have their own SceneLoader components from the GUID swap. Also removes the deleted prefab's entry from the vestigial _gameplayManagerPrefabs list in AppManager.prefab. https://claude.ai/code/session_01FxqDVaymsgJiMjzwTUqvF9
Resolve conflict in AppManager.prefab: take incoming field names (captainManager, iapManager, etc.) and rename gameManager → sceneLoader to match our refactor. Drop vestigial _gameplayManagerPrefabs list and orphaned component from HEAD. https://claude.ai/code/session_01FxqDVaymsgJiMjzwTUqvF9
…agement-RkhkF Consolidate GameManager into SceneLoader for unified scene management
The ReflexSettings.asset RootScopes field referenced fileID 5456740058571604360 on AppManager.prefab, but that fileID does not exist in the prefab (likely stale after prefab re-import). The actual ContainerScope component has fileID 4798048649644018183. With the broken reference, Reflex created an empty root container. AppManager.InstallBindings() populated a scene-scoped container instead, so all subsequent scenes inherited nothing — causing UnknownContractException for AuthenticationServiceFacade and null [Inject] fields on SceneLoader, MultiplayerSetup, and CameraManager. https://claude.ai/code/session_01WzSYJbtkyDkjSZAa5tma2w
…-reference-ivKQj Update ReflexSettings root scope reference
Introduce a new ContainerScope prefab and metadata, and embed it as a prefab instance in Bootstrap and Authentication scenes (added scene root entries and prefab modifications). Remove the runtime SceneContainerScopeBridge script that auto-created scene scopes, switching to an explicit prefab-based scope so scenes have a persistent DI ContainerScope. Also add a few auth-related timeout fields (cachedAuthTimeout, playerDataTimeout, safetyTimeout) in the Authentication scene.
…enu_Main The AppManager.prefab RootScope component used the wrong script GUID (583638035e4a15c42b2fa9de5d6213fa) instead of the actual Reflex ContainerScope GUID (5312032623c34414a54ea00e35a7eb8e). This caused Reflex to ignore the RootScope, creating an empty root container with no bindings from AppManager.InstallBindings(). All scene containers inherited nothing, producing UnknownContractException for AuthenticationServiceFacade and null [Inject] fields on SceneLoader, MultiplayerSetup, and CameraManager. Changes: - Fix script GUID on AppManager.prefab ContainerScope component to match the actual Reflex ContainerScope class - Add ContainerScope prefab instance to Menu_Main.unity so Reflex injects scene objects there (Bootstrap and Authentication already had it) - Add null guard in CameraManager.InitializeSceneCamera() for _sceneNameList to produce a clear error instead of NullReferenceException https://claude.ai/code/session_016SQwXR4SX8PWcrVuRJkZ1D
…R5jje Add ContainerScope prefab to main menu and improve CameraManager initialization
- Bootstrap: BootstrapController merged into AppManager, IBootstrapService removed - Scene management: GameManager/NetworkGameManager replaced by SceneLoader - DI: document Reflex DI registration patterns, GameDataSO [Inject] migration - New systems: SceneNameListSO for centralized scene names, ContainerScope per scene - Multiplayer: MainMenuServerVesselInitializer removed, AI spawning deduplicated - Update BOOTSTRAP_AUDIT.md file references and async bootstrap flow - Update README.md application flow and project structure https://claude.ai/code/session_015rxfje3tpa1tLP6GGeSgs3
…s-13mKg Refactor bootstrap & scene loading: AppManager as DI root + SceneLoader
…n as networked scene After successful authentication, the AuthenticationSceneController now: 1. Instantiates the NetworkManager prefab (if not already present) 2. Starts a local Netcode host with a temporary connection approval callback 3. Loads Menu_Main via NetworkManager.SceneManager.LoadScene (networked) 4. Falls back to direct scene load if NetworkManager prefab is unassigned Also updates SceneLoader.ReturnToMainMenu() to use network scene loading when a Netcode host is active, for consistency with the new flow. MultiplayerSetup in Menu_Main already handles a pre-started host gracefully (EnsureHostStarted is a no-op when host is already listening). Inspector setup required: assign the NetworkManager prefab from _Prefabs/CORE/NetworkManager.prefab to AuthenticationSceneController's "Networking > Network Manager Prefab" field. https://claude.ai/code/session_01PuRkcNmnRaNeg4zxjy3Hz1
…erSetup MultiplayerSetup lives in Bootstrap (DontDestroyOnLoad), so it should own the NetworkManager lifecycle instead of AuthenticationSceneController. MultiplayerSetup changes: - Remove Awake() that eagerly cached NetworkManager.Singleton (null in Bootstrap) - Add [SerializeField] _networkManagerPrefab for lazy instantiation - EnsureHostStarted → async EnsureHostStartedAsync: instantiates prefab if NetworkManager.Singleton is null, registers Netcode callbacks, starts host - OnAuthenticationSignedIn wraps async flow properly AuthenticationSceneController changes: - Remove NetworkManager prefab field and host-start logic - Remove connection approval callback (MultiplayerSetup owns it) - NavigateToMainMenu now waits for NetworkManager.Singleton.IsListening (with configurable timeout) then does networked scene load - Falls back to direct scene load if host not ready in time Flow: OnSignedIn → MultiplayerSetup.EnsureHostStartedAsync (instantiate NetworkManager, start host) → AuthScene.LoadMainMenuNetworkedAsync (wait for host ready, nm.SceneManager.LoadScene) Inspector setup: assign NetworkManager prefab to MultiplayerSetup's "Networking > Network Manager Prefab" field in the Bootstrap scene. https://claude.ai/code/session_01PuRkcNmnRaNeg4zxjy3Hz1
The AuthPanel was missing a TMP_Text for login error feedback. Added a LoginStatusText GameObject (auto-sizing italic, gray, anchored to bottom of AuthPanel) and wired it to the statusText serialized field on AuthenticationSceneController. Also serialized the new networkHostTimeout field (default 3s). All AuthenticationSceneController serialized fields are now assigned: - authPanel, usernameSetupPanel, loadingPanel - guestLoginButton, statusText (was null, now wired) - usernameInputField, confirmUsernameButton, usernameStatusText - cachedAuthTimeout, playerDataTimeout, safetyTimeout, networkHostTimeout https://claude.ai/code/session_01PuRkcNmnRaNeg4zxjy3Hz1
…l spawning Extract Menu_Main vessel lifecycle into a dedicated ServerPlayerVesselInitializer subclass that spawns the host's vessel (without AI opponents) and activates it in autopilot mode after initialization. - MenuServerPlayerVesselInitializer overrides OnClientConnected to skip AI opponent spawning, and subscribes to OnClientReady to activate the player, enable AI pilot, pause input, and fire menu lifecycle events. - MainMenuPlayerSpawnerAdapter simplified to only configure game data (vessel class, spawn positions) — post-init logic moved to the new initializer. https://claude.ai/code/session_019ouda61ZL9RKcDQUd2q3nV
Add CameraManager.FollowVesselInMainMenu() that switches back to the Cinemachine main menu camera and sets its Follow/LookAt targets to the vessel transform, cancelling the default crystal look-at. Called from MenuServerPlayerVesselInitializer.OnClientReady() after autopilot activation so the menu camera tracks the flying vessel. https://claude.ai/code/session_019ouda61ZL9RKcDQUd2q3nV
…cation-setup-QdBXb Implement networked scene loading for authentication flow
… MenuServerPlayerVesselInitializer Transfer game data setup (force Squirrel vessel class, InitializeGame) into MenuServerPlayerVesselInitializer.Start(). Spawn positions are already handled by the base class OnNetworkSpawn via _playerOrigins. Delete MainMenuPlayerSpawnerAdapter — MenuServerPlayerVesselInitializer now owns the full menu vessel lifecycle end-to-end. https://claude.ai/code/session_019ouda61ZL9RKcDQUd2q3nV
…st-kaG0p Refactor menu vessel initialization into dedicated server class
Merges 348 commits from app-shell-polish. Key changes: - Files moved from Game/Arcade/ to Controller/Arcade/ (namespace CosmicShore.Gameplay) - Files moved from Game/UI/ to UI/ (namespace CosmicShore.UI) - MultiplayerSetup moved to persistent Controller/Multiplayer/ - New party lobby system (HostConnectionService, PartyGameLauncher) - AI backfill support (RequestedAIBackfillCount) Conflict resolution: - Scene files: took theirs (code-only changes on our side) - Game controllers/turn monitors: took theirs (clean version, will re-apply party fixes) - GameDataSO: kept IsPartyMode + added RequestedAIBackfillCount - Party files: moved to new directory structure with namespace updates - NetcodeExtensions: retained IsServerSafe() extension https://claude.ai/code/session_01Piy2uQvUaeqfJhG3eaR4Dj
After merging app-shell-polish, game controllers moved from Game/Arcade/ to Controller/Arcade/ (namespace CosmicShore.Gameplay). This commit re-applies the IsServerSafe() and party mode fixes to the new locations: - MultiplayerMiniGameControllerBase: IsServerSafe, PartyMode_Activate/Deactivate, activeInHierarchy guard, party auto-start, local RPC fallbacks - MultiplayerDomainGamesController: IsServerSafe in OnCountdownTimerEnded, SetupNewRound - NetworkScoreTracker: IsServerSafe, OnEnable/OnDisable for SetActive toggling - NetworkCrystalCollisionTurnMonitor: IsServerSafe, local crystal target fallback - NetworkJoustCollisionTurnMonitor: IsServerSafe in OnCollisionChanged, CheckForEndOfTurn - NetworkCrystalManager: OnEnable/OnDisable for party mode, party reset via ResetSpawnState - ServerPlayerVesselInitializer: PartyModeState enum, InertMode/SpawnMode guards - HexRaceController, MultiplayerJoustController: fix stale ClassExtensions using https://claude.ai/code/session_01Piy2uQvUaeqfJhG3eaR4Dj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Refactored party mode vessel spawning to use a dedicated
PartyVesselSpawnercomponent on the always-activePartyGameManager, instead of calling spawn methods onServerPlayerVesselInitializer(SPVI) which lives on disabled environment GameObjects. This ensures ClientRpcs are only invoked on NetworkBehaviours registered with Netcode at startup, preventing "RPC called on unregistered NetworkBehaviour" errors.Key Changes
New
PartyVesselSpawnerclass: Dedicated NetworkBehaviour that handles all vessel spawning and repositioning for party modeSpawnVesselsForParty(): Spawns host player vessel and AI opponents on first roundRepositionForNewRound(): Repositions existing vessels for subsequent roundsInitializeAllPlayersForParty_ClientRpc(): Safe ClientRpc on always-active GameObjectRemoved party spawning from SPVI: Deleted
SpawnVesselsForParty()andSpawnPlayerThenAIForParty()methods fromServerPlayerVesselInitializerthat were unsafe to call via RPCUpdated
PartyGameController:PartyVesselSpawnerinstead of calling SPVI spawn methodsInertMode(no longer switches betweenSpawnMode/InertMode)GetSpawnOriginsFromEnv()and passes to spawnerPartyVesselSpawner.RepositionForNewRound()Implementation Details
PartyVesselSpawnerspawns player vessel first, waits 1 second, then spawns AI opponents with staggered spawn indicesInitializePlayerAndVessel()which waits for network objects to be registered before calling initialization methodshttps://claude.ai/code/session_01Piy2uQvUaeqfJhG3eaR4Dj