What did you do before the bug occurred?
KSP 1.12.5.3190, fairly heavy mod list (KSPCommunityFixes 1.41.1, Kopernicus, Waterfall, ReStock, B9PartSwitch, ModuleManager, plus BetterTimeWarp, DistantObjectEnhancement, AmbientLightAdjustment). I hit this 3 times out of 3.
- Be in flight with a crewed vessel.
- EVA a kerbal so the camera ends up following the EVA kerbal (in my case it was two kerbals out of the same capsule), then get rid of those EVA kerbals (board them back or recover them) so their vessels get destroyed.
- Reload the flight scene while still in flight. Any flight-to-flight reload triggers it: a quickload (F9), or a StartAndFocusVessel / LoadScene(FLIGHT) coming from a mod. The vessel that becomes active on the reload is just a normal landed craft, not the EVA kerbal.
Worth noting: the exact same reload works fine dozens of times in a row as long as no EVA happened first. It only blows up on the first reload after the EVA.
What happened?
On that reload the game throws a NullReferenceException in FlightCamera.SetModeImmediate, called from Vessel.MakeActive during FlightDriver.Start. SetModeImmediate is basically just fetch.setModeImmediate(m), so FlightCamera.fetch is null. That exception aborts FlightDriver.Start partway through, which leaves FlightGlobals half-initialized, and from then on FlightGlobals.UpdateInformation plus everything that reads FlightCamera.fetch every frame (stock UIPartActionController / CrewHatchController, and mods like Waterfall, BetterTimeWarp, DistantObject and AmbienceControl that touch FlightCamera.fetch.mainCamera) throws an NRE on every single frame.
The bad part is that it's permanent. Reloading flight again doesn't fix it: fetch stays null and "Camera Mode:" never prints again. The only thing that brought the camera back was bouncing out to the Space Center and back into flight. In my session the log ended up around 1.5 GB (roughly 13 million exceptions) and the game went to a black screen.
What I expected: the camera survives the reload like it does after any non-EVA reload, and fetch stays valid.
I ran it through a decompiler to figure out why. The short version:
FlightCamera only survives a flight-to-flight reload because FlightCamera.Start() does DontDestroyOnLoad on its "pivot" GameObject (the only DDOL call in the class) and parents the camera under that pivot. So across a reload the same FlightCamera lives on, and the fresh one the new scene spawns just self-destructs on the if (fetch != null) DestroyImmediate(...) check in Awake(). fetch stays valid, which is the normal working case.
The catch is that the pivot gets re-parented under the active vessel by SetTarget / OnVesselChange during flight. The thing that saves it before a scene unload is FlightCamera.OnSceneSwitch, which re-parents the pivot to PSystemSetup.Instance.transform (a DDOL root). That's why ordinary reloads are fine.
When you EVA, though, the pivot ends up parented under the transient EVA-kerbal vessel. When that vessel is Vessel.Die()'d (Object.Destroy on the GameObject, which takes its children with it) while it's still the camera target, FlightCamera.OnTargetDestroyed does not re-home the pivot. It only does that when the dead target is not the active vessel. So the DDOL pivot, and the FlightCamera parented under it, get destroyed along with the EVA vessel, and FlightCamera.OnDestroy sets fetch = null. After that there's no persistent camera left, and nothing recreates it on a same-scene reload.
Suggested fix: have OnTargetDestroyed (and/or OnSceneSwitch) always move the pivot back onto a guaranteed-surviving DDOL root (PSystemSetup.Instance.transform) before the target vessel's GameObject is destroyed, whether or not the dead target is the active vessel. Then the pivot and camera never get taken down with a vessel.
Methods in play: FlightCamera.Start / Awake / OnDestroy / SetTarget / OnVesselChange / OnSceneSwitch / OnTargetDestroyed / SetModeImmediate, Vessel.Die / MakeActive, FlightGlobals.setActiveVessel / ForceSetActiveVessel, FlightEVA.SpawnEVA.
For what it's worth, I'm working around it in my own mod by forcing Flight camera mode (CameraManager.Instance.SetCameraFlight()) and re-targeting the live active vessel (FlightCamera.fetch.SetTargetVessel(FlightGlobals.ActiveVessel)) right before the reload. After that the stock OnSceneSwitch / PSystemSetup rescue keeps the camera alive.
Upload your ksp.log file
KSP-FlightCamera-fetch-null-Bug4803.log
A screenshot of the problem
No response
What did you do before the bug occurred?
KSP 1.12.5.3190, fairly heavy mod list (KSPCommunityFixes 1.41.1, Kopernicus, Waterfall, ReStock, B9PartSwitch, ModuleManager, plus BetterTimeWarp, DistantObjectEnhancement, AmbientLightAdjustment). I hit this 3 times out of 3.
Worth noting: the exact same reload works fine dozens of times in a row as long as no EVA happened first. It only blows up on the first reload after the EVA.
What happened?
On that reload the game throws a NullReferenceException in FlightCamera.SetModeImmediate, called from Vessel.MakeActive during FlightDriver.Start. SetModeImmediate is basically just
fetch.setModeImmediate(m), so FlightCamera.fetch is null. That exception aborts FlightDriver.Start partway through, which leaves FlightGlobals half-initialized, and from then on FlightGlobals.UpdateInformation plus everything that reads FlightCamera.fetch every frame (stock UIPartActionController / CrewHatchController, and mods like Waterfall, BetterTimeWarp, DistantObject and AmbienceControl that touch FlightCamera.fetch.mainCamera) throws an NRE on every single frame.The bad part is that it's permanent. Reloading flight again doesn't fix it: fetch stays null and "Camera Mode:" never prints again. The only thing that brought the camera back was bouncing out to the Space Center and back into flight. In my session the log ended up around 1.5 GB (roughly 13 million exceptions) and the game went to a black screen.
What I expected: the camera survives the reload like it does after any non-EVA reload, and fetch stays valid.
I ran it through a decompiler to figure out why. The short version:
FlightCamera only survives a flight-to-flight reload because FlightCamera.Start() does DontDestroyOnLoad on its "pivot" GameObject (the only DDOL call in the class) and parents the camera under that pivot. So across a reload the same FlightCamera lives on, and the fresh one the new scene spawns just self-destructs on the
if (fetch != null) DestroyImmediate(...)check in Awake(). fetch stays valid, which is the normal working case.The catch is that the pivot gets re-parented under the active vessel by SetTarget / OnVesselChange during flight. The thing that saves it before a scene unload is FlightCamera.OnSceneSwitch, which re-parents the pivot to PSystemSetup.Instance.transform (a DDOL root). That's why ordinary reloads are fine.
When you EVA, though, the pivot ends up parented under the transient EVA-kerbal vessel. When that vessel is Vessel.Die()'d (Object.Destroy on the GameObject, which takes its children with it) while it's still the camera target, FlightCamera.OnTargetDestroyed does not re-home the pivot. It only does that when the dead target is not the active vessel. So the DDOL pivot, and the FlightCamera parented under it, get destroyed along with the EVA vessel, and FlightCamera.OnDestroy sets fetch = null. After that there's no persistent camera left, and nothing recreates it on a same-scene reload.
Suggested fix: have OnTargetDestroyed (and/or OnSceneSwitch) always move the pivot back onto a guaranteed-surviving DDOL root (PSystemSetup.Instance.transform) before the target vessel's GameObject is destroyed, whether or not the dead target is the active vessel. Then the pivot and camera never get taken down with a vessel.
Methods in play: FlightCamera.Start / Awake / OnDestroy / SetTarget / OnVesselChange / OnSceneSwitch / OnTargetDestroyed / SetModeImmediate, Vessel.Die / MakeActive, FlightGlobals.setActiveVessel / ForceSetActiveVessel, FlightEVA.SpawnEVA.
For what it's worth, I'm working around it in my own mod by forcing Flight camera mode (CameraManager.Instance.SetCameraFlight()) and re-targeting the live active vessel (FlightCamera.fetch.SetTargetVessel(FlightGlobals.ActiveVessel)) right before the reload. After that the stock OnSceneSwitch / PSystemSetup rescue keeps the camera alive.
Upload your ksp.log file
KSP-FlightCamera-fetch-null-Bug4803.log
A screenshot of the problem
No response