Files
AppleHillsProduction/docs/lifecycle_implementation_roadmap.md
2025-11-05 20:37:16 +01:00

948 lines
33 KiB
Markdown

# ManagedBehaviour Lifecycle System - Implementation Roadmap
**Project:** AppleHills
**Start Date:** [TBD]
**Target:** Option B+ (Streamlined ManagedBehaviour with Orchestrated Scene Transitions)
**End Goal:** Remove BootCompletionService and all legacy lifecycle patterns
---
## Overview
This roadmap outlines the step-by-step implementation of the ManagedBehaviour lifecycle system. The work is divided into **4 phases** that can be completed over 6-8 days.
**⚠️ PHASE 1 UPDATES (Nov 3, 2025):**
- **REMOVED:** LifecycleFlags enum - all components now participate in ALL lifecycle hooks by default
- **REMOVED:** ActiveLifecyclePhases property - no opt-in/opt-out needed
- **REMOVED:** ISaveParticipant auto-registration - save/load now built directly into ManagedBehaviour
- **SIMPLIFIED:** Registration logic - just add to all lists, no flag checking
**Final State:**
- ✅ LifecycleManager as single source of truth
- ✅ ManagedBehaviour as standard base class
- ✅ SceneManagerService orchestrates scene transitions
- ❌ BootCompletionService removed
- ❌ All RegisterInitAction calls eliminated
- ❌ All InitializePostBoot methods converted
---
## Phase 1: Core Infrastructure (Days 1-2) ✅ **COMPLETED**
**Goal:** Implement core lifecycle system without breaking existing code
### Day 1: Foundation Classes ✅
#### 1.1 Create LifecycleEnums.cs ✅
**Location:** `Assets/Scripts/Core/Lifecycle/LifecycleEnums.cs`
**Tasks:**
- [x] Create namespace `Core.Lifecycle`
- [x] Define `LifecyclePhase` enum: ManagedAwake, SceneUnloading, SceneReady, SaveRequested, RestoreRequested, ManagedDestroy
- [x] Add XML documentation for each value
- [x] **CHANGED:** Removed LifecycleFlags enum - all components participate in all hooks by default
**Validation:** ✅ File compiles without errors
---
#### 1.2 Create ManagedEventSubscription.cs ✅
**Location:** `Assets/Scripts/Core/Lifecycle/ManagedEventSubscription.cs`
**Tasks:**
- [x] Create internal class `EventSubscriptionInfo`
- Store: object target, Delegate handler, string eventName
- [x] Create public class `ManagedEventManager`
- List<EventSubscriptionInfo> _subscriptions
- Method: `RegisterEvent(object target, string eventName, Delegate handler)`
- Method: `UnregisterAllEvents()`
- Use reflection to dynamically `-=` unsubscribe
- [x] Add null checks and error handling
- [x] Add XML documentation
**Validation:** ✅ Create test MonoBehaviour, subscribe to event, verify auto-unsubscribe works
---
#### 1.3 Create ManagedBehaviour.cs (Structure Only) ✅
**Location:** `Assets/Scripts/Core/Lifecycle/ManagedBehaviour.cs`
**Tasks:**
- [x] Create abstract class `ManagedBehaviour : MonoBehaviour`
- [x] Add virtual priority properties (all with protected getters, public wrappers for LifecycleManager)
- [x] Add configuration properties: `AutoRegisterPausable` (default false, public virtual)
- [x] **REMOVED:** ActiveLifecyclePhases - all components participate in all hooks
- [x] **REMOVED:** AutoRegisterSaveParticipant - save/load is now built-in via OnSaveRequested/OnRestoreRequested
- [x] Add private fields
- [x] Add virtual lifecycle hooks (protected virtual with public invoke wrappers)
- [x] Add helper method: `RegisterManagedEvent(object target, string eventName, Delegate handler)`
- [x] Add XML documentation for all members
**Validation:** ✅ File compiles, can create derived class
---
### Day 2: LifecycleManager & Integration ✅
#### 2.1 Create LifecycleManager.cs ✅
**Location:** `Assets/Scripts/Core/Lifecycle/LifecycleManager.cs`
**Tasks:**
- [x] Create class `LifecycleManager : MonoBehaviour`
- [x] Implement singleton pattern
- [x] Add separate sorted lists for each phase
- [x] Add tracking dictionaries
- [x] **REMOVED:** `_componentPhases` dictionary - no longer needed without flags
- [x] Add state flags
- [x] Implement `Register(ManagedBehaviour component)` - **SIMPLIFIED:** No flag checking - add to ALL lists
- [x] Implement `Unregister(ManagedBehaviour component)`
- [x] Add debug logging
---
## Phase 2: Scene Management Integration (Days 3-4) ✅ **COMPLETED**
**Goal:** Hook LifecycleManager into SceneManagerService
### Completed Tasks ✅
#### 2.1 Update SceneManagerService ✅
- [x] Migrated to ManagedBehaviour (priority: 20)
- [x] Added OnManagedAwake() implementation
- [x] Integrated LifecycleManager initialization
- [x] Scene transition callbacks trigger lifecycle events
- [x] Loading screen orchestration preserved
#### 2.2 Update LoadingScreenController ✅
- [x] Migrated to ManagedBehaviour (priority: 15)
- [x] Removed BootCompletionService dependency
- [x] Integrated with LifecycleManager
#### 2.3 Core Services Migration ✅
- [x] **GameManager** - Priority 10, removed BootCompletionService
- [x] **AudioManager** - Priority 30, AutoRegisterPausable = true
- [x] **InputManager** - Priority 40, uses OnSceneReady
- [x] **SceneOrientationEnforcer** - Priority 5
- [x] **SaveLoadManager** - Priority 25, integrated with lifecycle
**Validation:** ✅ All core services migrated and compiling
---
## Phase 3: Component Migration (Days 5-6) ⚠️ **PARTIALLY COMPLETED**
**Goal:** Migrate all MonoBehaviours that use BootCompletionService to ManagedBehaviour
### Successfully Migrated Components ✅
**Tier 1 - UI Infrastructure:**
- [x] **UIPageController** - Priority 50, lifecycle integrated
- [x] **PauseMenu** - Priority 55, uses OnSceneReady
- [x] **CardAlbumUI** - Priority 65, event cleanup
- [x] **CardSystemSceneVisibility** - Priority 95, uses OnSceneReady
- [x] **DivingTutorial** - Priority 200, removed BootCompletionService
**Tier 2 - Data & Systems:**
- [x] **CardSystemManager** - Priority 60, ISaveParticipant
- [x] **DialogueComponent** - Priority 150, event subscriptions
- [x] **PuzzleManager** - Priority 80, ISaveParticipant, OnSceneReady
- [x] **ItemManager** - Priority 75, uses OnSceneReady
- [x] **CinematicsManager** - Priority 170, lifecycle integrated
- [x] **SkipCinematic** - Priority 180, event cleanup
**Tier 3 - Gameplay:**
- [x] **PlayerTouchController** - Priority 100, ISaveParticipant
- [x] **FollowerController** - Priority 110, ISaveParticipant
- [x] **Pickup** - Priority varies (SaveableInteractable), removed BootCompletionService
- [x] **DivingGameManager** - Priority 190, AutoRegisterPausable = true
### Failed/Incomplete Migrations ✅ **NOW COMPLETED (Nov 4, 2025)**
**Previously incomplete - now resolved:**
- [x] **MinigameSwitch** - SaveableInteractable, migrated with direct subscription pattern
- [x] **AppleMachine** - Used simple direct registration (no interface needed)
### Migration Statistics
- **Successfully Migrated:** 20 files (updated Nov 4, 2025)
- **Failed/Incomplete:** 0 files
- **Success Rate:** 100%
**Common Patterns Eliminated:**
- ✅ All `BootCompletionService.RegisterInitAction()` calls removed
- ✅ All `InitializePostBoot()` methods removed
- ✅ All `Bootstrap` using directives removed
- ✅ Replaced with `OnManagedAwake()`, `Start()`, or `OnSceneReady()` as appropriate
**Validation:** ⚠️ Most files compile cleanly, 2 files need retry
---
## Phase 4: Cleanup & Documentation (Days 7-8) ✅ **COMPLETED (Nov 4, 2025)**
**Goal:** Remove legacy code and finalize documentation
### Completed Tasks ✅
#### 4.1 Delete Legacy Code ✅
- [x] Deleted `BootCompletionService.cs`
- [x] Deleted all remaining `InitializePostBoot` methods
- [x] Removed all Bootstrap using directives where only used for BootCompletionService
- [x] Updated CustomBoot.cs to call LifecycleManager directly
#### 4.2 Retry Failed Migrations ✅
- [x] **MinigameSwitch** - Clean implementation without BootCompletionService
- Subscribed to `PuzzleManager.Instance.OnAllPuzzlesComplete` directly in Start()
- Removed InitializePostBoot method
- Added cleanup in OnDestroy()
- [x] **AppleMachine** - Simple direct registration approach
- Decided against IManagedLifecycle interface (over-engineering for single case)
- Direct SaveLoadManager registration in Start()
- SaveLoadManager.Instance guaranteed available (priority 25)
#### 4.3 Final Validation ⚠️ **PENDING USER TESTING**
- [ ] Run all scenes in editor
- [ ] Test scene transitions
- [ ] Test save/load functionality
- [ ] Test pause system
- [ ] Build and test final build
#### 4.4 Update Documentation ✅
- [x] Created bootcompletion_removal_summary.md with complete migration details
- [x] Updated this roadmap with completion dates
- [x] Added migration analysis document
- [ ] Mark lifecycle_technical_review.md as implemented (NEXT STEP)
- [ ] Update bootstrap_readme.md to remove BootCompletionService references (NEXT STEP)
---
## Migration Guidelines (Reference)
### Pattern 1: Simple BootCompletionService Replacement
```csharp
// OLD
void Awake() {
BootCompletionService.RegisterInitAction(InitializePostBoot);
}
private void InitializePostBoot() {
// initialization code
}
// NEW
public override int ManagedAwakePriority => [appropriate priority];
protected override void OnManagedAwake() {
// initialization code
}
```
### Pattern 2: Scene-Dependent Initialization
```csharp
// OLD
void Start() {
BootCompletionService.RegisterInitAction(() => {
SceneManagerService.Instance.SceneLoadCompleted += OnSceneLoaded;
});
}
// NEW
protected override void OnSceneReady() {
// Scene is ready, managers available
}
```
### Pattern 3: SaveableInteractable (like MinigameSwitch)
```csharp
// Already inherits from SaveableInteractable
// Just remove BootCompletionService calls
protected override void Start() {
base.Start();
// Direct subscription, no BootCompletionService needed
if (PuzzleManager.Instance != null) {
PuzzleManager.Instance.OnAllPuzzlesComplete += HandleComplete;
}
}
```
---
## Phase 5: Post-Migration Enhancements ⏳ **NEXT STEPS**
**All 4 core phases completed!** The lifecycle system is fully operational and BootCompletionService has been removed.
### Recommended Next Steps (Priority Order)
#### Immediate (This Week)
1.**Playtest the game** - Verify no regressions from migration
2. 📝 **Update lifecycle_technical_review.md** - Mark as fully implemented (~30 min)
3. 📝 **Update bootstrap_readme.md** - Remove BootCompletionService references (~20 min)
4. 🔍 **Verify UIPage subclasses** - Ensure all 5 work correctly with new base class (~15 min)
#### Short-term (Next 1-2 Weeks) - Optional Improvements
5. 📊 **Profile lifecycle overhead** - Measure performance impact (~1 hour)
6. 🔄 **Continue migration** - Move remaining MonoBehaviours to ManagedBehaviour as needed
7. 📝 **Create migration guide** - Document patterns for future components (~1 hour)
8. 🎨 **Add lifecycle debugging tools** - Editor visualization for priorities (~2-4 hours)
#### Medium-term - Enhancement Ideas
9.**Advanced features** - Async lifecycle hooks, conditional execution, etc.
10. 📚 **Comprehensive documentation** - Architecture guides, ADRs, diagrams
11. 🧪 **Automated testing** - Unit tests for LifecycleManager
12. 🎯 **Performance optimization** - Cache sorted lists, reduce allocations
### Components That Could Still Benefit from Migration
**High Value (Manual event cleanup needed):**
- Remaining Interactable subclasses with event subscriptions
- Camera systems that subscribe to player events
- Any MonoBehaviour with complex initialization dependencies
**Medium Value (Nice to have):**
- UIPage subclasses that need OnSceneReady (though they now inherit it)
- Player/NPC controllers with initialization order requirements
- Collectible/Pickup systems
**Low Priority (Keep as MonoBehaviour):**
- Simple visual effects
- Basic trigger volumes
- One-off utility scripts
- Third-party library components
### Success Criteria ✅
All original goals achieved:
- ✅ LifecycleManager as single source of truth
- ✅ ManagedBehaviour as standard base class
- ✅ SceneManagerService orchestrates transitions
- ✅ BootCompletionService removed completely
- ✅ All RegisterInitAction calls eliminated
- ✅ All InitializePostBoot methods converted
- ✅ 20 components successfully migrated
- ✅ Clean, maintainable codebase
---
4. **Final validation pass** - 20 minutes
**Estimated remaining time:** 1-2 hours
---
## Lessons Learned
### What Worked Well ✅
- ManagedBehaviour base class provides clean abstraction
- Priority-based execution ensures correct initialization order
- OnSceneReady hook eliminates timing issues
- AutoRegisterPausable eliminates manual GameManager registration
- Most migrations were straightforward
### Challenges Encountered ⚠️
- File corruption during batch edits (need more careful edits)
- Multiple inheritance conflicts (StateMachine + ManagedBehaviour)
- Need better error recovery when edits fail
### Recommendations for Future
- Migrate files one at a time, verify each before moving on
- Use git checkpoints between migrations
- Test after each file migration
- Have clear rollback strategy
---
#### 2.2 Implement LifecycleManager Broadcast Methods ✅
**Tasks:**
- [x] Implement `OnBootCompletionTriggered()`
- [x] Implement `BroadcastManagedAwake()`
- [x] Implement `BroadcastSceneUnloading(string sceneName)`
- [x] Implement `BroadcastSaveRequested(string sceneName)`
- [x] Implement `BroadcastSceneReady(string sceneName)`
- [x] Implement `BroadcastRestoreRequested(string sceneName)`
- [x] **NOTE:** `BroadcastManagedDestroy()` not needed - called automatically via Unity's OnDestroy
**Validation:** ✅ Can call broadcast methods, logging shows correct order
---
#### 2.3 Implement Auto-Registration Helper ✅
**Tasks:**
- [x] Implement private `HandleAutoRegistrations(ManagedBehaviour component)`
- [x] Check `AutoRegisterPausable` and call `GameManager.Instance.RegisterPausableComponent()`
- [x] **REMOVED:** AutoRegisterSaveParticipant check - using OnSaveRequested/OnRestoreRequested instead
- [x] Add null checks for manager instances
**Validation:** ✅ Auto-registration called during BroadcastManagedAwake
---
#### 2.4 Complete ManagedBehaviour Implementation ✅
**Tasks:**
- [x] Implement `protected virtual void Awake()`
- [x] Implement `protected virtual void OnDestroy()`
- [x] Auto-unregister from GameManager if IPausable registered
- [x] **REMOVED:** Auto-unregister from SaveLoadManager
- [x] Implement `RegisterManagedEvent()`
**Validation:** ✅ Create test ManagedBehaviour, verify register/unregister cycle works
---
#### 2.5 Inject LifecycleManager into Bootstrap ✅
**Tasks:**
- [x] Add `CreateInstance()` static method to LifecycleManager
- [x] Call `LifecycleManager.CreateInstance()` at start of `CustomBoot.Initialise()`
- [x] Ensure it's called BEFORE any bootstrap logic begins
- [x] LifecycleManager persists via DontDestroyOnLoad
**Validation:** ✅ LifecycleManager exists when bootstrap completes, singleton works
**Note:** No prefab needed - LifecycleManager created programmatically by CustomBoot
---
## Phase 2: Integration with Existing Systems (Day 3) ✅ **COMPLETED**
**Goal:** Connect LifecycleManager to existing bootstrap and save/load systems
### Day 3: Bootstrap & Managers Integration ✅
#### 3.1 Modify BootCompletionService ✅
**Location:** `Assets/Scripts/Bootstrap/BootCompletionService.cs`
**Tasks:**
- [x] In `HandleBootCompleted()`, before executing initialization actions:
- Add: `LifecycleManager.Instance?.OnBootCompletionTriggered()`
- Add null check and warning if LifecycleManager not found
- [x] Add using directive for `Core.Lifecycle`
- [x] Keep all existing functionality (backward compatibility)
**Validation:** ✅ Boot still works, BootCompletionService triggers LifecycleManager
---
#### 3.2 Extend SaveLoadManager ⚠️ **SKIPPED**
**Location:** `Assets/Scripts/Core/SaveLoad/SaveLoadManager.cs`
**Status:** NOT NEEDED - We removed ISaveParticipant auto-registration pattern. Save/load now handled via:
- **Level-specific data:** ManagedBehaviour.OnSaveRequested() / OnRestoreRequested() hooks
- **Global data:** Existing ISaveParticipant pattern (manual registration still supported)
**Tasks:**
- [x] ~~Add AutoRegisterParticipant/AutoUnregisterParticipant methods~~ - NOT NEEDED
---
#### 3.3 Extend GameManager ✅
**Location:** `Assets/Scripts/Core/GameManager.cs`
**Status:** Already has required methods `RegisterPausableComponent()` and `UnregisterPausableComponent()`
- LifecycleManager calls these methods directly from `HandleAutoRegistrations()`
- ManagedBehaviour auto-unregisters in `OnDestroy()`
**Tasks:**
- [x] ~~Add AutoRegisterPausable/AutoUnregisterPausable methods~~ - NOT NEEDED (using existing methods)
---
#### 3.4 Enhance SceneManagerService ✅
**Location:** `Assets/Scripts/Core/SceneManagerService.cs`
**Tasks:**
- [x] Add using directive for `Core.Lifecycle`
- [x] In `SwitchSceneAsync()` before unloading old scene:
- Call `LifecycleManager.Instance?.BroadcastSaveRequested(CurrentGameplayScene)`
- Call `LifecycleManager.Instance?.BroadcastSceneUnloading(CurrentGameplayScene)`
- [x] In `SwitchSceneAsync()` after loading new scene:
- Call `LifecycleManager.Instance?.BroadcastRestoreRequested(newSceneName)`
- Call `LifecycleManager.Instance?.BroadcastSceneReady(newSceneName)`
- [x] Proper ordering ensures save → unload → load → restore → ready
**Validation:** ✅ Scene transitions work, lifecycle events broadcast in correct order
---
## Phase 3: Scene Orchestration & Examples (Days 4-5) 🔄 **NEXT UP**
**Goal:** Create examples and documentation for the lifecycle system
### Day 4: Scene Lifecycle Integration ✅ **ALREADY COMPLETE**
#### 4.1 Enhance SceneManagerService.SwitchSceneAsync() ✅
**Location:** `Assets/Scripts/Core/SceneManagerService.cs`
**Status:** ✅ Already implemented in Phase 2
- SaveRequested and SceneUnloading called before unload
- RestoreRequested and SceneReady called after load
- Proper ordering maintained
---
### Day 5: Examples & Documentation ⏳ **TODO**
#### 5.1 Create Example Implementations
**Location:** `Assets/Scripts/Core/Lifecycle/Examples/`
**Tasks:**
- [ ] BACKUP current `SwitchSceneAsync()` implementation (comment out or copy to temp file)
- [ ] Rewrite `SwitchSceneAsync()` with orchestration:
```csharp
public async Task SwitchSceneAsync(string newSceneName, IProgress<float> progress = null, bool autoHideLoadingScreen = true)
{
// PHASE 1: Show loading screen
if (_loadingScreen != null && !_loadingScreen.IsActive)
{
_loadingScreen.ShowLoadingScreen(() => GetSceneTransitionProgress());
}
string oldSceneName = CurrentGameplayScene;
// PHASE 2: Pre-unload (lifecycle hooks for cleanup)
LifecycleManager.Instance?.BroadcastSceneUnloading(oldSceneName);
// PHASE 3: Save level-specific data
LifecycleManager.Instance?.BroadcastSaveRequested(oldSceneName);
// PHASE 4: Save global game state
if (SaveLoadManager.Instance != null &&
DeveloperSettingsProvider.Instance.GetSettings<DebugSettings>().useSaveLoadSystem)
{
SaveLoadManager.Instance.Save();
}
// PHASE 5: Unload old scene
// Remove AstarPath singletons (existing code)
var astarPaths = FindObjectsByType<AstarPath>(FindObjectsSortMode.None);
foreach (var astar in astarPaths)
{
if (Application.isPlaying) Destroy(astar.gameObject);
else DestroyImmediate(astar.gameObject);
}
if (!string.IsNullOrEmpty(CurrentGameplayScene) && CurrentGameplayScene != BootstrapSceneName)
{
var prevScene = SceneManager.GetSceneByName(CurrentGameplayScene);
if (prevScene.isLoaded)
{
await UnloadSceneAsync(CurrentGameplayScene);
// Unity calls OnDestroy → OnManagedDestroy() automatically
}
}
// PHASE 6: Load new scene
var bootstrap = SceneManager.GetSceneByName(BootstrapSceneName);
if (!bootstrap.isLoaded)
{
SceneManager.LoadScene(BootstrapSceneName, LoadSceneMode.Additive);
}
await LoadSceneAsync(newSceneName, progress);
CurrentGameplayScene = newSceneName;
// PHASE 7: Initialize new scene
LifecycleManager.Instance?.BroadcastSceneReady(newSceneName);
// ManagedBehaviours register during Awake, late registration calls OnManagedAwake immediately
// PHASE 8: Restore level-specific data
LifecycleManager.Instance?.BroadcastRestoreRequested(newSceneName);
// SaveLoadManager automatically restores ISaveParticipant data (global)
// PHASE 9: Hide loading screen
if (autoHideLoadingScreen && _loadingScreen != null)
{
_loadingScreen.HideLoadingScreen();
}
}
```
- [ ] Test scene transition with logging enabled
- [ ] Verify order: OnSceneUnloading → OnSaveRequested → Save → Unload → Load → OnSceneReady → OnRestoreRequested
**Validation:** Scene transitions work, lifecycle callbacks fire in correct order, save/restore data flows properly
---
#### 4.2 Create Example Implementations
**Location:** `Assets/Scripts/Core/Lifecycle/Examples/`
**Tasks:**
- [ ] Create `ExampleManagedSingleton.cs`:
- Singleton pattern with ManagedBehaviour
- Override OnManagedAwake (replaces Awake + InitializePostBoot)
- Show priority usage
- Demonstrate that bootstrap resources are available
- Extensive comments explaining pattern
- [ ] Create `ExampleManagedSceneComponent.cs`:
- Scene-specific component (e.g., puzzle manager)
- Override OnManagedAwake for boot-level setup
- Override OnSceneReady for scene-specific initialization
- Override OnSceneUnloading for cleanup
- Override OnSaveRequested/OnRestoreRequested for level-specific data
- Show ISaveParticipant auto-registration for global data
- Extensive comments explaining difference between global (ISaveParticipant) and level-specific (OnSave/OnRestore) data
- [ ] Create `ExampleDynamicallySpawned.cs`:
- Component that can be spawned at runtime
- Override OnManagedAwake
- Demonstrate that bootstrap is guaranteed complete even when spawned mid-game
- Access GameManager and other services safely
- Extensive comments
- [ ] Create `ExampleManagedPersistent.cs`:
- Persistent component (survives scene changes)
- No scene lifecycle hooks
- Show auto-registration for IPausable
- Extensive comments
**Validation:** Examples compile, demonstrate all features clearly, cover both boot-time and late-registration scenarios
---
### Day 5: Documentation & Testing
#### 5.1 Create Migration Guide
**Location:** `Assets/Scripts/Core/Lifecycle/MIGRATION_GUIDE.md`
**Tasks:**
- [ ] Write step-by-step migration process
- [ ] Include before/after code examples
- [ ] Document common pitfalls (forgetting base.Awake(), etc.)
- [ ] List all lifecycle hooks and when to use each
- [ ] Create priority guidelines table (which components should be 10, 50, 100, etc.)
**Validation:** Guide is clear and comprehensive
---
#### 5.2 Testing & Validation
**Tasks:**
- [ ] Create test scene with multiple ManagedBehaviours at different priorities
- [ ] Test boot flow: verify ManagedAwake → BootComplete order
- [ ] Test scene transition: verify Unloading → Save → Unload → Load → Ready
- [ ] Test late registration: instantiate ManagedBehaviour after boot
- [ ] Test auto-registration: verify ISaveParticipant and IPausable work
- [ ] Test managed events: verify auto-cleanup on destroy
- [ ] Test editor mode: verify works when playing from any scene
- [ ] Profile performance: measure overhead (should be < 1% at boot)
**Validation:** All tests pass, no errors in console
---
## Phase 4: Migration & Cleanup (Days 6-8)
**Goal:** Migrate existing components and remove BootCompletionService
### Day 6: Migrate Core Systems
#### 6.1 Migrate GameManager
**Location:** `Assets/Scripts/Core/GameManager.cs`
**Tasks:**
- [ ] Change base class: `public class GameManager : ManagedBehaviour`
- [ ] Override priority:
```csharp
protected override int ManagedAwakePriority => 10;
```
- [ ] Override ActiveLifecyclePhases:
```csharp
protected override LifecycleFlags ActiveLifecyclePhases =>
LifecycleFlags.ManagedAwake;
```
- [ ] Move Awake logic AND InitializePostBoot logic to `OnManagedAwake()`:
- Combine both old methods into single OnManagedAwake
- Bootstrap guaranteed complete, so all resources available
- [ ] Remove `BootCompletionService.RegisterInitAction(InitializePostBoot)` call
- [ ] Delete old `InitializePostBoot()` method
- [ ] Test thoroughly
**Validation:** GameManager boots correctly, settings load, pause system works
---
#### 6.2 Migrate SceneManagerService
**Location:** `Assets/Scripts/Core/SceneManagerService.cs`
**Tasks:**
- [ ] Change base class: `public class SceneManagerService : ManagedBehaviour`
- [ ] Override priority:
```csharp
protected override int ManagedAwakePriority => 15;
```
- [ ] Move Awake initialization logic AND InitializePostBoot logic to `OnManagedAwake()`
- [ ] Remove `BootCompletionService.RegisterInitAction` call
- [ ] Delete old `InitializePostBoot()` method
- [ ] Test scene loading/unloading
**Validation:** Scene transitions work, loading screen functions correctly
---
#### 6.3 Migrate SaveLoadManager
**Location:** `Assets/Scripts/Core/SaveLoad/SaveLoadManager.cs`
**Tasks:**
- [ ] Change base class: `public class SaveLoadManager : ManagedBehaviour`
- [ ] Override priority:
```csharp
protected override int ManagedAwakePriority => 20;
```
- [ ] Move Awake logic AND InitializePostBoot logic to `OnManagedAwake()`
- [ ] Remove `BootCompletionService.RegisterInitAction` call
- [ ] Delete old `InitializePostBoot()` method
- [ ] Test save/load functionality
**Validation:** Save/load works, participant registration functions correctly
---
### Day 7: Migrate UI & Gameplay Systems
#### 7.1 Migrate UI Systems (Priority 50-100)
**Files to migrate:**
- [ ] `UIPageController.cs`
- [ ] `LoadingScreenController.cs`
- [ ] `PauseMenu.cs`
- [ ] `CardAlbumUI.cs`
- [ ] `CardSystemSceneVisibility.cs`
**For each file:**
- [ ] Change base class to `ManagedBehaviour`
- [ ] Set appropriate priorities (50-100 range)
- [ ] Move Awake + InitializePostBoot logic → OnManagedAwake
- [ ] Remove BootCompletionService registration
- [ ] Use RegisterManagedEvent for event subscriptions
- [ ] Add scene lifecycle hooks if scene-specific (OnSceneReady/OnSceneUnloading)
- [ ] Consider OnSaveRequested/OnRestoreRequested if component has level-specific state
- [ ] Test functionality
**Validation:** UI navigation works, loading screens function, pause menu operates correctly
---
#### 7.2 Migrate Gameplay Systems (Priority 100-200)
**Files to migrate:**
- [ ] `PuzzleManager.cs` - Add scene lifecycle hooks
- [ ] `CardSystemManager.cs` - Persistent, no scene hooks
- [ ] `FollowerController.cs` - ISaveParticipant auto-registration
- [ ] `PlayerTouchController.cs` - ISaveParticipant auto-registration
- [ ] `DialogueComponent.cs`
- [ ] `AudioManager.cs` - IPausable auto-registration
- [ ] `MinigameSwitch.cs`
**For each file:**
- [ ] Change base class to `ManagedBehaviour`
- [ ] Set appropriate priorities (100-200 range)
- [ ] Move Awake + InitializePostBoot logic → OnManagedAwake
- [ ] Remove BootCompletionService registration
- [ ] Enable AutoRegisterSaveParticipant if ISaveParticipant (for global save/load)
- [ ] Enable AutoRegisterPausable if IPausable
- [ ] Add scene lifecycle hooks for scene-specific managers:
- OnSceneReady for scene-specific initialization
- OnSceneUnloading for cleanup
- OnSaveRequested/OnRestoreRequested for level-specific data (if needed)
- [ ] Test gameplay features
**Validation:** Puzzles work, card system functions, save/load operates, dialogue plays, audio works
---
### Day 8: Final Cleanup & BootCompletionService Removal
#### 8.1 Verify All Migrations Complete
**Tasks:**
- [ ] Search codebase for `InitializePostBoot` - should find 0 results (or only in old backups)
- [ ] Search codebase for `BootCompletionService.RegisterInitAction` - should find 0 results
- [ ] Search codebase for `: MonoBehaviour` - verify all appropriate classes use ManagedBehaviour
- [ ] Run full game playthrough - no errors
**Validation:** All components migrated, no remaining legacy patterns
---
#### 8.2 Remove BootCompletionService
**Tasks:**
- [ ] In `CustomBoot.cs`, replace `BootCompletionService.HandleBootCompleted()` with:
```csharp
// Direct call to LifecycleManager
if (LifecycleManager.Instance != null)
{
LifecycleManager.Instance.OnBootCompletionTriggered();
}
```
- [ ] Delete or archive `BootCompletionService.cs`
- [ ] Remove all using statements for `Bootstrap.BootCompletionService`
- [ ] Update bootstrap documentation to remove BootCompletionService references
- [ ] Test full boot sequence
**Validation:** Game boots without BootCompletionService, all systems initialize correctly
---
#### 8.3 Final Testing & Documentation
**Tasks:**
- [ ] Full game playthrough testing
- Boot from StartingScene (build mode)
- Navigate to main menu
- Transition between multiple gameplay scenes
- Save/load state
- Pause/resume
- Test all major features
- [ ] Editor mode testing
- Enter play mode from MainMenu scene
- Enter play mode from gameplay scene
- Hot reload testing
- [ ] Performance profiling
- Measure boot time overhead
- Measure scene transition overhead
- Verify < 1% performance impact
- [ ] Update all documentation:
- Mark BootCompletionService as removed in bootstrap_readme.md
- Update lifecycle_technical_review.md status
- Update this roadmap with completion dates
- [ ] Create summary document of changes
**Validation:** All systems work, performance acceptable, documentation updated
---
## Completion Checklist
### Phase 1: Core Infrastructure
- [x] LifecycleEnums.cs created (LifecycleFlags REMOVED - all components participate in all hooks)
- [x] ManagedEventSubscription.cs created
- [x] ManagedBehaviour.cs created (ActiveLifecyclePhases REMOVED, AutoRegisterSaveParticipant REMOVED)
- [x] LifecycleManager.cs created (flags checking REMOVED, simplified registration)
- [x] LifecycleManager injected into CustomBoot.Initialise() - created before bootstrap begins
- [x] All core classes compile and tested
### Phase 2: Integration
- [ ] BootCompletionService triggers LifecycleManager
- [ ] SaveLoadManager auto-registration implemented
- [ ] GameManager auto-registration implemented
- [ ] SceneManagerService enhanced with orchestration
### Phase 3: Scene Orchestration
- [ ] SceneManagerService.SwitchSceneAsync() orchestrates full flow
- [ ] Example implementations created
- [ ] Migration guide written
- [ ] Full testing completed
### Phase 4: Migration & Cleanup
- [ ] Core systems migrated (GameManager, SceneManagerService, SaveLoadManager)
- [ ] UI systems migrated (5+ files)
- [ ] Gameplay systems migrated (7+ files)
- [ ] BootCompletionService removed
- [ ] All legacy patterns eliminated
- [ ] Documentation updated
---
## Success Criteria
**Functionality:**
- All 20+ components migrated to ManagedBehaviour
- BootCompletionService completely removed
- Zero RegisterInitAction calls remain
- Scene transitions orchestrated with proper lifecycle
- Save/load integrated with scene lifecycle
**Code Quality:**
- No memory leaks (verified via profiler)
- Clean, consistent lifecycle pattern across codebase
- Clear priority ordering
- Auto-cleanup working correctly
**Performance:**
- < 1% overhead at boot
- < 0.5% overhead during scene transitions
- No frame time impact during gameplay
**Documentation:**
- Migration guide complete
- Example implementations clear
- Technical review updated
- Bootstrap documentation updated
---
## Rollback Plan
If critical issues arise:
1. **During Phase 1-2:** Simply don't call LifecycleManager, existing systems still work
2. **During Phase 3:** Revert SceneManagerService.SwitchSceneAsync() from backup
3. **During Phase 4:** Keep BootCompletionService, revert migrated components one by one
---
## Notes & Decisions Log
**Date** | **Decision** | **Rationale**
---------|--------------|---------------
[TBD] | Approved Option B+ | Best balance for 6-month project with scene orchestration needs
[TBD] | SceneTransitionOrchestrator removed | Logic integrated into SceneManagerService instead
[TBD] | BootCompletionService to be deprecated | Goal is complete removal after migration
---
## Daily Progress Tracking
### Day 1: [Date]
- [ ] Morning: LifecycleEnums + ManagedEventSubscription
- [ ] Afternoon: ManagedBehaviour structure
- **Blockers:**
- **Notes:**
### Day 2: [Date]
- [ ] Morning: LifecycleManager core
- [ ] Afternoon: Broadcast methods + prefab setup
- **Blockers:**
- **Notes:**
### Day 3: [Date]
- [ ] Morning: BootCompletionService integration
- [ ] Afternoon: SaveLoadManager + GameManager extensions
- **Blockers:**
- **Notes:**
### Day 4: [Date]
- [ ] Morning: SceneManagerService orchestration
- [ ] Afternoon: Example implementations
- **Blockers:**
- **Notes:**
### Day 5: [Date]
- [ ] Morning: Migration guide
- [ ] Afternoon: Testing & validation
- **Blockers:**
- **Notes:**
### Day 6: [Date]
- [ ] Core systems migration (GameManager, SceneManagerService, SaveLoadManager)
- **Blockers:**
- **Notes:**
### Day 7: [Date]
- [ ] UI systems migration (5 files)
- [ ] Gameplay systems migration (7 files)
- **Blockers:**
- **Notes:**
### Day 8: [Date]
- [ ] Final verification
- [ ] BootCompletionService removal
- [ ] Testing & documentation
- **Blockers:**
- **Notes:**
---
**Status:** Awaiting Approval
**Last Updated:** [Will be updated as work progresses]