Files
AppleHillsProduction/docs/critical_boot_lifecycle_bug_fix.md

170 lines
5.3 KiB
Markdown
Raw Normal View History

# CRITICAL BUG: BroadcastSceneReady Never Called During Boot
## Problem Report
User reported: "I don't have that log in my console" referring to:
```csharp
LogDebug($"Broadcasting SceneReady for scene: {sceneName}");
```
## Root Cause Analysis
### The Discovery
Searched console logs for "Broadcasting" - **ZERO results**!
This means `BroadcastSceneReady()` was **NEVER called**, which explains why:
- ❌ LevelSwitch.OnSceneReady() never called
- ❌ PuzzleManager.OnSceneReady() never called (before we fixed it)
- ❌ All scene lifecycle hooks completely broken during boot
### The Investigation
**Where BroadcastSceneReady SHOULD be called:**
1. ✅ SceneManagerService.SwitchSceneAsync() - line 364 - **BUT NOT USED DURING BOOT**
2. ❌ BootSceneController.LoadMainScene() - **MISSING!**
**The Problem Code Path:**
When you play from StartingScene:
```csharp
// BootSceneController.LoadMainScene() - line 192
var op = SceneManager.LoadSceneAsync(mainSceneName, LoadSceneMode.Additive);
// ... waits for scene to load
SceneManagerService.Instance.CurrentGameplayScene = mainSceneName;
_sceneLoadingProgress = 1f;
// ❌ STOPS HERE - NO LIFECYCLE BROADCASTS!
```
**What's missing:**
- No call to `LifecycleManager.BroadcastSceneReady()`
- No call to `LifecycleManager.BroadcastRestoreRequested()`
- Components in the loaded scene never get their lifecycle hooks!
### Why It Happened
BootSceneController was implemented BEFORE the lifecycle system was fully integrated. It loads scenes directly using Unity's `SceneManager.LoadSceneAsync()` instead of using `SceneManagerService.SwitchSceneAsync()`, which means it completely bypasses the lifecycle broadcasts.
**The Broken Flow:**
```
StartingScene loads
BootSceneController.OnManagedAwake()
LoadMainScene()
SceneManager.LoadSceneAsync("AppleHillsOverworld") ← Direct Unity call
Scene loads, all Awake() methods run
LevelSwitch registers with LifecycleManager
... nothing happens ❌
NO BroadcastSceneReady() ❌
NO OnSceneReady() calls ❌
```
## The Fix
Added lifecycle broadcasts to BootSceneController after scene loading completes:
```csharp
// Update the current gameplay scene in SceneManagerService
SceneManagerService.Instance.CurrentGameplayScene = mainSceneName;
// Ensure progress is complete
_sceneLoadingProgress = 1f;
// CRITICAL: Broadcast lifecycle events so components get their OnSceneReady callbacks
LogDebugMessage($"Broadcasting OnSceneReady for: {mainSceneName}");
LifecycleManager.Instance?.BroadcastSceneReady(mainSceneName);
LogDebugMessage($"Broadcasting OnRestoreRequested for: {mainSceneName}");
LifecycleManager.Instance?.BroadcastRestoreRequested(mainSceneName);
```
## The Corrected Flow
```
StartingScene loads
BootSceneController.OnManagedAwake()
LoadMainScene()
SceneManager.LoadSceneAsync("AppleHillsOverworld")
Scene loads, all Awake() methods run
LevelSwitch registers with LifecycleManager (late registration)
✅ BroadcastSceneReady("AppleHillsOverworld") ← NEW!
✅ LevelSwitch.OnSceneReady() called!
✅ BroadcastRestoreRequested("AppleHillsOverworld")
✅ Components can restore save data
```
## Expected Logs After Fix
When playing from StartingScene, you should now see:
```
[BootSceneController] Loading main menu scene: AppleHillsOverworld
[BootSceneController] Broadcasting OnSceneReady for: AppleHillsOverworld
[LifecycleManager] Broadcasting SceneReady for scene: AppleHillsOverworld ← THIS WAS MISSING!
[LevelSwitch] OnSceneReady called for CementFactory ← NOW WORKS!
[LevelSwitch] OnSceneReady called for Quarry
[LevelSwitch] OnSceneReady called for Dump
[BootSceneController] Broadcasting OnRestoreRequested for: AppleHillsOverworld
[LifecycleManager] Broadcasting RestoreRequested for scene: AppleHillsOverworld
```
## Impact
### Before Fix ❌
- Boot scene loading bypassed lifecycle system completely
- No OnSceneReady() calls during initial boot
- No OnRestoreRequested() calls
- Late registration check in LifecycleManager only helped with subsequent scene loads
- All scene-specific initialization broken during boot!
### After Fix ✅
- Boot scene loading now properly integrates with lifecycle system
- OnSceneReady() called for all components in initial scene
- OnRestoreRequested() called for save/load integration
- Consistent lifecycle behavior whether loading from boot or switching scenes
- Full lifecycle system functional!
## Files Modified
1. **BootSceneController.cs** - Added lifecycle broadcasts after scene load
## Design Lesson
**ANY code that loads scenes must broadcast lifecycle events!**
This includes:
- ✅ SceneManagerService.SwitchSceneAsync() - already does this
- ✅ BootSceneController.LoadMainScene() - NOW does this
- ⚠️ Any future scene loading code must also do this!
The lifecycle broadcasts are NOT automatic - they must be explicitly called after scene loading completes.
## Related Issues Fixed
This single fix resolves:
1. ✅ LevelSwitch.OnSceneReady() not being called during boot
2. ✅ Any component's OnSceneReady() not being called during boot
3. ✅ OnRestoreRequested() not being called during boot
4. ✅ Save/load integration broken during boot
5. ✅ Inconsistent lifecycle behavior between boot and scene switching
---
**Status**: ✅ FIXED - Boot scene loading now properly broadcasts lifecycle events!