Refactor architecture: consolidate managers and update namespaces#378
Open
Shombith03 wants to merge 811 commits into
Open
Refactor architecture: consolidate managers and update namespaces#378Shombith03 wants to merge 811 commits into
Shombith03 wants to merge 811 commits into
Conversation
… mode Changes gameplay vCam binding mode from LockToTargetWithWorldUp to LockToTargetNoRoll so the camera stays behind the vessel through yaw and pitch, giving a proper third-person chase feel without roll-induced instability. https://claude.ai/code/session_017EQYHoiaCwLqjqCLBhx3KT
…tead of custom vCam Reverts gameplay camera to use CameraManager.SetupGamePlayCameras(), which activates CM PlayerCam with the vessel's own CameraSettingsSO applied via VesselCameraCustomizer. This restores the per-vessel camera behavior (e.g. Squirrel's specific follow offset and damping) that was replaced by a dynamically created Cinemachine vCam with hardcoded offsets. Removed: - _gameplayFollowOffset serialized field - _gameplayVCam dynamic creation (CreateGameplayVCam) - Cinemachine priority-based switching for gameplay camera - Unity.Cinemachine.TargetTracking using directive https://claude.ai/code/session_017EQYHoiaCwLqjqCLBhx3KT
… states Provides a simple inspector-driven way to control which UI panels start active or inactive when Menu_Main loads, without manually toggling GameObjects in the scene hierarchy. https://claude.ai/code/session_013oWqfLV9PdCoMh3CrDwT1n
…es-zewzl Add InitialPanelStateApplier for UI panel state initialization
…position-RYqgP Refactor MainMenuCameraController to delegate gameplay camera setup
… priority blending Replace the instant cut between menu orbit camera (CinemachineCamera) and gameplay camera (CustomCameraController) with a smooth Cinemachine blend. A new "CM Freestyle" CinemachineCamera is created as a sibling of "CM Main Menu" on CameraManager. Both feed into the same CinemachineBrain. Transitions are driven by priority swaps — the brain handles the blend automatically. This eliminates the need to activate/deactivate separate Camera objects, keeping the entire menu camera pipeline within Cinemachine. Changes: - MainMenuCameraController: add EnsureFreestyleVCam() that creates/finds a "CM Freestyle" vCam with CinemachineFollow + CinemachineRotationComposer. ActivateGameplayCamera() now configures the freestyle vCam's tracking target and follow offset from the vessel's CameraSettingsSO, then switches priorities. ActivateMenuCamera() raises menu vCam priority and lowers freestyle priority, keeping both active so the CinemachineBrain can blend between them. - VesselCameraCustomizer: expose public Settings getter so MainMenuCameraController can read the vessel's CameraSettingsSO for the freestyle vCam's follow offset. Blend duration/curve is controlled by the CinemachineBrain's DefaultBlend setting on the main camera. https://claude.ai/code/session_01V2hxWA5gN1U4ceF68hoLLP
… Menu_Main UI Add SetVisible/IsVisible extension methods to GameObjectExtension that use CanvasGroup (alpha, interactable, blocksRaycasts) instead of GameObject.SetActive to avoid Unity canvas rebuild costs when toggling UI element visibility at runtime. Converted 41 files across screens, views, modals, and elements: - ScreenSwitcher (navbar, nav icons, freestyle toggle) - All screen implementations (Home, Arcade, Episode, Hangar, Leaderboards, Store) - All modal windows (ModalWindowManager base, Profile, PurchaseConfirmation, etc.) - All view panels (Friends, OnlinePlayers, Party, AddFriend, etc.) - All button/card elements (LoadoutCard, DailyRewardCard, GameplayRewardButton, etc.) - InitialPanelStateApplier panel initialization Custom SetActive methods on NavLink, HangarTrainingGameButton, IntensitySelectButton, and HangarShipSelectNavLink are left unchanged as they control visual state (sprites/crossfade), not visibility. https://claude.ai/code/session_01ENB9tCSnmqK37EoS7W7bgj
…nvasgroup-menu-main-5NUH3
…set-play-mode-changes-PMDLC
…-Y7rbR Add comprehensive unit testing guide for Cosmic Shore
Two issues prevented the initial PlayModeSOProtector from working:
1. Race condition: [InitializeOnLoad] registers its callback before
SOAP ScriptableVariable.OnEnable(), so our restore ran first, then
SOAP's ResetToInitialValue() re-dirtied every asset with default(T)
via EditorUtility.SetDirty(). Fix: defer restore with delayCall.
2. Asset discovery: FindAssets("t:ScriptableVariableBase") may return
empty for abstract base types. Fix: scan all .asset files under
Assets/_SO_Assets/ via Directory.GetFiles instead.
Also switched from AssetDatabase.Refresh() to per-file ImportAsset
with ForceUpdate to ensure Unity reloads each SO from disk and clears
dirty flags left by SOAP's callbacks.
https://claude.ai/code/session_01TEVgqk3GbdPKYvzfxb275q
…set-play-mode-changes-PMDLC
The freestyle CinemachineCamera was using the default binding mode, which interprets FollowOffset in world space — so the camera didn't rotate with the vessel and ended up at the wrong position/orientation. Fix: set TrackerSettings.BindingMode = LockToTarget both at creation time and when applying per-vessel settings. LockToTarget interprets FollowOffset in the target's local space, matching CustomCameraController's _followTarget.rotation * _followOffset behavior (camera stays behind the vessel as it pitches/yaws/rolls). Also: - Apply TrackerSettings.PositionDamping from CameraSettingsSO.followSmoothTime so follow responsiveness matches the gameplay camera. - Use dynamicMinDistance directly (matching CustomCameraController.ApplySettings) instead of negating it. https://claude.ai/code/session_01V2hxWA5gN1U4ceF68hoLLP
…anges-PMDLC Add PlayModeSOProtector to prevent runtime mutations to ScriptableObjects
The default Cinemachine blend linearly interpolates position between the menu orbit camera and the freestyle camera. Since these cameras are in very different positions (orbit around crystal vs behind vessel), the linear path cuts through arbitrary space during the transition. Fix: set CinemachineBlendHint.InheritPosition on the freestyle vCam. When it goes live, the camera starts from the current Unity Camera position (wherever the menu orbit camera was) and CinemachineFollow's own damping smoothly converges to the correct position behind the vessel. No linear blend = no weird intermediate positions. https://claude.ai/code/session_01V2hxWA5gN1U4ceF68hoLLP
The SetVisible extension method is defined on GameObject, not MonoBehaviour. IntensitySelectButton and PlayerCountButton are MonoBehaviours, so .gameObject must be used to access the extension. https://claude.ai/code/session_01ENB9tCSnmqK37EoS7W7bgj
…ain-5NUH3 Replace SetActive with SetVisible for UI visibility management
…priority-BdYGR Refactor menu camera to use Cinemachine priority blending
CinemachineBlendHint.InheritPosition does not exist in Cinemachine 3.1.2, causing a compile error. The default CinemachineBrain blend already provides simple position/rotation lerping between the menu orbit and freestyle follow cameras, which is the desired behavior. https://claude.ai/code/session_01Km4HzptY9EXzg1Q9W13AuX
…lity Add an editor window (Tools > Cosmic Shore > Canvas Group Editor) that scans the active scene for all CanvasGroup GameObjects and displays them in a hierarchy tree. Each CanvasGroup node has a toggle to configure whether it should be visible or hidden at game start, stored in the scene's InitialPanelStateApplier component. Features: - Hierarchy tree matching Unity's scene structure - Search filter to find panels by name - Expand/Collapse all, Add All, Show All, Hide All bulk actions - Click names to ping/select in hierarchy - Bold labels for tracked panels, "untracked" indicator for others - Remove (×) button to untrack individual panels - Clean Nulls to purge deleted references - Auto-refreshes on hierarchy changes and undo/redo Also updates InitialPanelStateApplier.Awake() to call SetActive(true) on deactivated panels before SetVisible, ensuring editor state doesn't affect runtime initial visibility. https://claude.ai/code/session_01WRYM3VarPbnxMWqEDs8t5x
Remove CinemachineRotationComposer from the freestyle vCam — it had its own damping that caused rotation to converge faster than position. With BindingMode.LockToTarget, the tracker already drives rotation to match the vessel's orientation (camera Up = vessel Up, camera forward = vessel forward). Setting RotationDamping = PositionDamping ensures both reach the vessel at the same time. https://claude.ai/code/session_01Km4HzptY9EXzg1Q9W13AuX
PanelEntry now has both fields: - bool startActive: controls GameObject.SetActive at game start - float startAlpha: controls CanvasGroup.alpha (0-1) at game start Editor window shows both per row: an active toggle and an alpha float field. Bulk actions: Activate All, Deactivate All. Column headers added for clarity. https://claude.ai/code/session_01WRYM3VarPbnxMWqEDs8t5x
… target The freestyle camera was not reading SquirrelCameraSettingsSO because GetComponent<VesselCameraCustomizer>() was called on CameraFollowTarget, which can be a different Transform than VesselStatus's GameObject. VesselCameraCustomizer is a [RequireComponent] on VesselStatus, so fetching it via player.Vessel.VesselStatus.VesselCameraCustomizer is guaranteed to find it. Also: FixedCamera mode now uses zero damping (snap) matching CustomCameraController behavior, while DynamicCamera uses followSmoothTime. https://claude.ai/code/session_01Km4HzptY9EXzg1Q9W13AuX
…ntdown - MultiplayerDomainGamesController: compare readyClientCount against NetworkManager.ConnectedClientsIds.Count (humans only) instead of gameData.SelectedPlayerCount (which includes AI backfill) - MultiplayerWildlifeBlitzMiniGame: same fix - ArcadeConfigSyncManager: use Max(PartyMembers count, ConnectedClients) for _expectedHumanCount to guard against stale party data Previously only the host's click was needed because SelectedPlayerCount could include AI players who never click Ready, or PartyMembers count could be stale when the modal opened. https://claude.ai/code/session_01AyfN2EWC1Z7zL7mRJs33Nk
….com/froglet-studio/Cosmic-Shore into claude/sync-team-selection-rpc-OsjWf
…n-rpc-OsjWf Add multiplayer arcade config sync with per-client vessel selection
…gister-gamelist-inject-GUVGK
…rcadeConfigSyncManager New file from app-shell-polish merge had a [SerializeField] SO_GameList that should use DI like the other consumers. https://claude.ai/code/session_01TUBT6px6Mh54VG4WpagZFh
…inject-GUVGK Inject SO_GameList via DI instead of SerializeField
…on-host clients On non-host clients, the countdown ClientRpc can arrive before ClientPlayerVesselInitializer has resolved all player-vessel pairs. This causes a NullReferenceException at Vessel.StartVessel() because the Player was added to gameData.Players (in OnNetworkSpawn) before its Vessel was assigned (in InitializePair). Add a null guard with warning log, matching the existing pattern in Player.ResetForPlay() which handles the same transient Netcode state. https://claude.ai/code/session_01XnzpyCSBAkzLeGiHE2N8mP
…on-host clients On non-host clients, the countdown ClientRpc can arrive before ClientPlayerVesselInitializer has resolved all player-vessel pairs. This causes a NullReferenceException at Vessel.StartVessel() because the Player was added to gameData.Players (in OnNetworkSpawn) before its Vessel was assigned (in InitializePair). Guard at top of method before ToggleActive — a player with no Vessel should not be marked active. Matches the existing null-Vessel pattern in Player.ResetForPlay(). https://claude.ai/code/session_01XnzpyCSBAkzLeGiHE2N8mP
…nt MissingReferenceException The SpawnLoopAsync UniTask continuation could race with GameObject destruction, accessing transform.position after the object was destroyed. Linking the CTS with GetCancellationTokenOnDestroy() ensures the token cancels immediately on destroy, before any queued continuation can run. https://claude.ai/code/session_017GuQ3FnZurZc8KtZxBHnPC
…nstead of stale PartyMembers PartyMembers is a SOAP list updated by a 3-second polling loop in HostConnectionService.RefreshPartyMembersAsync(). When the host launches a game before the next refresh cycle, PartyMembers only contains the host (count=1), causing ConfigurePlayerCounts to compute AI=1 even when a second human player is connected. Use NetworkManager.ConnectedClientsIds.Count as the ground truth for connected human players. This is always accurate regardless of the SOAP refresh timing. Fall back to PartyMembers.Count for non-host instances. Also deduplicate the humanCount computation in SyncAllGameDataForLaunch() to reuse the CurrentPartyHumanCount property. https://claude.ai/code/session_01XnzpyCSBAkzLeGiHE2N8mP
…plash during Menu_Main reload VesselController.DestroyVessel() and Player.DestroyPlayer() silently skipped destruction for networked objects (IsSpawned guard). This left stale NetworkObjects registered with Netcode, causing MissingReferenceException when delta messages arrived for destroyed GameObjects. Now calls NetworkObject.Despawn(true) on the server before returning. HostConnectionService.ReloadMenuSceneIfActive() now fades to black before reloading Menu_Main during the local-to-Relay host transition, and fades back in when the new scene signals ready via OnClientReady. https://claude.ai/code/session_017GuQ3FnZurZc8KtZxBHnPC
…ference-nFoyt Handle null Vessel in StartPlayer to prevent initialization race
…x-vessel-prism-reference-SM2ZL
…eference-SM2ZL Link spawn cancellation token to GameObject destruction
Brings in all development work since PR #329 including: - Quest progression system (intensity-based unlocks, vessel hangar gate) - Hangar grid + detail panel UI overhaul with vessel unlock flow - VesselUnlockSystem with crystal currency purchasing - Cloud data persistence (UGS) for quest/hangar/profile - Impact effect refactors (overtake, elemental systems) - Cell membrane exploration - Toast notification system - Element pips and elemental bars UI Conflict resolution strategy: - Quest/Hangar/Vessel SOs: took development (newer fields) - Scene files: kept app-shell-polish (newer menu layout) - ScreenSwitcher: kept app-shell-polish (Reflex DI, arcade CanvasGroup) - PlayerDataService: merged both (singleton Instance + Reflex DI auth) - Editor/UI infrastructure: kept app-shell-polish (newer architecture) - Arcade game assets: took development (latest game mode data) https://claude.ai/code/session_01S3Fet87FpCsgUg1hJ5Bjux
- FriendsPanel: slide-up show with OutBack ease, fade-out hide, animated tab transitions with crossfade, staggered friend list population (50ms delay per entry), badge punch-scale on request count change - FriendEntryView: breathing pulse animation on online indicator (InOutSine loop), pop-in scale animation on invite-sent indicator (OutBack) - FriendRequestEntryView: punch-scale on accept, fade-out on decline/cancel - AddFriendPanel: feedback text scale-in with OutBack ease, extra punch on success feedback https://claude.ai/code/session_01S3Fet87FpCsgUg1hJ5Bjux
… merge Files from the development branch used old namespace conventions (CosmicShore.App.*, CosmicShore.Game.*, CosmicShore.Models.*, CosmicShore.Integrations.*, CosmicShore.Services.*) that were reorganized in app-shell-polish. Fixes across 19 files: - CosmicShore.App.Profile → CosmicShore.UI (PlayerDataService) - CosmicShore.App.Systems.Audio → CosmicShore.Core (AudioSystem) - CosmicShore.Game.Analytics → CosmicShore.Gameplay (VesselStatsCloudData) - CosmicShore.Game.IO → CosmicShore.Gameplay (HapticController) - CosmicShore.Models.Enums → CosmicShore.Data (Element, VesselClassType) - CosmicShore.Services.Auth → CosmicShore.Core (AuthenticationController) - CosmicShore.Integrations.PlayFab.* → CosmicShore.Core - CosmicShore.Utilities → CosmicShore.Utility (typo fix) - Delete duplicate Models/ScriptableObjects/SO_Captain.cs - Fix ScriptableObjects/SO_Captain.cs: SO_Ship→SO_Vessel (SO_Ship never existed) - Change VesselOvertakeBySkimmerEffectSO namespace to CosmicShore.Gameplay - Change CaptainManager namespace to CosmicShore.Core https://claude.ai/code/session_01S3Fet87FpCsgUg1hJ5Bjux
- Replace SO_Ship → SO_Vessel and SO_ShipList → SO_VesselList across 8 files - Update game.Captains → game.Vessels and captain.Ship → captain.Vessel for SO_ArcadeGame/SO_Captain data model renames - Remove duplicate ShipSelectionSlot struct from VesselSelectionView.cs - Create stub classes for missing types: ConnectingPanel, DoTweenTypewriterAnimator, ConnectingDotsAnimator, HangarOverviewView - Comment out Arcade.Instance references (singleton removed in app-shell-polish) https://claude.ai/code/session_01S3Fet87FpCsgUg1hJ5Bjux
Add namespace imports for types that moved during app-shell-polish reorganization. Files from development reference types like Element, GameModes, Domains, SO_Element, SO_TrainingGame, CrystalManager, VesselHUDController, etc. that now live in CosmicShore.Data, CosmicShore.Gameplay, CosmicShore.ScriptableObjects, CosmicShore.UI, and CosmicShore.Game.Cinematics namespaces. 28 files updated with correct using directives. https://claude.ai/code/session_01S3Fet87FpCsgUg1hJ5Bjux
- Fix SOAP event subscription pattern (OnRaised) in NetworkCrystalManager, EndGameCinematicController, GameModeProgressionService - Replace AudioSystem.Instance with [Inject] DI in CountdownTimer, HangarTrainingModal, EndGameCinematicController - Add using CosmicShore.Core to all 10 CloudData repository files for UGSKeys - Add xp field to PlayerProfileData and GetXP/AddXP methods to PlayerDataService - Fix AuthenticationController.Instance in UGSDataService to use AuthenticationService.Instance directly - Add ElementBars property to SilhouetteController for overtake effect - Fix SnowChanger.crystalLattice → shards reference - Fix PlayerDataService Utility.Tools.LogControlWindow path - Add using CosmicShore.App.Systems for DailyChallengeSystem in 5 UI files - Fix DoTweenTypewriterAnimator async UniTaskVoid https://claude.ai/code/session_01S3Fet87FpCsgUg1hJ5Bjux
… errors - Add using CosmicShore.App.Systems.CloudData to PlayerDataService for UGSDataService - Change instance access to static CaptainManager.OnLoadCaptainData in HangarCaptainsView - Replace nameof(HangarScreen) with string literal (different namespace) https://claude.ai/code/session_01S3Fet87FpCsgUg1hJ5Bjux
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
This PR refactors the application architecture by consolidating manager prefabs, updating namespace organization, and reorganizing asset directories. The changes modernize the codebase structure while maintaining functionality.
Key Changes
GameManagerandNetworkStatsManagerprefabs, consolidated into newAppManagerandPartyServicesprefabs for cleaner dependency managementCosmicShore.Core,CosmicShore.UI,CosmicShore.Data) instead of oldCosmicShore.App.Systems.CTAandCosmicShore.FTUEnamespacesPrismMeshGeneratorinCosmicShore.Editor.MeshGenerationnamespace for better organizationContainerScopeprefab for dependency injectionGameCanvasprefab references to removed components_Graphicsand_ModelsReflexSettings.assetfor dependency injection configurationDeprecated- MainMenuDependencyLoaderandArcadeprefabsImplementation Details
GameCanvasto point to new manager structurehttps://claude.ai/code/session_01S3Fet87FpCsgUg1hJ5Bjux