Welcome to the AFK Mods bug tracker. In order to report an issue, you need to have a VALIDATED account to post one. Once you have followed the link the registration email sent you, please select a project from the drop down menu below. Select “Open New Issue” and fill out the form with as many details as possible.

Please also consider sending your bug report to Bethesda if you are reporting on an issue with Skyrim Special Edition, Fallout 4, or Starfield. Doing so will help everyone on all platforms.

Issue Data
Status: Closed
Issue Type: Bug Report
Project: Unofficial Fallout 4 Patch
Component: Fallout 4: Vanilla
Category: Papyrus
Assigned To: Sclerocephalus
Platform: All
Severity: Low
Votes: 1
Watching: N/A
Opened By BlackPete on Dec 29, 2019 7:56 am
Last Edited By Sclerocephalus on Dec 29, 2019 9:43 am
Closed By Arthmoor on Jul 5, 2022 10:16 pm
Resolution: Fixed
Comment: Fixed for UFO4P 2.1.4.

Issue #28303: bos100fightmonitor: Unable to call IsDead/Cannot check for detection LOS with a None target

 
[12/28/2019 - 05:07:15PM] error: Unable to call IsDead - no native object bound to the script object, or object is of incorrect type
stack:
[<nullptr form> (FF000DC6)].Actor.IsDead() - "<native>" Line ?
[BoS100Fight (00068D7B)].bos100fightmonitor.GetCountOfLivingGhouls() - "C:\Users\Dr. Peter Haas\AppData\Local\Temp\PapyrusTemp\bos100fightmonitor.psc" Line 445
[BoS100Fight (00068D7B)].bos100fightmonitor.OnTimer() - "C:\Users\Dr. Peter Haas\AppData\Local\Temp\PapyrusTemp\bos100fightmonitor.psc" Line 333
[12/28/2019 - 05:07:15PM] warning: Assigning None to a non-object variable named "::temp108"
stack:
[BoS100Fight (00068D7B)].bos100fightmonitor.GetCountOfLivingGhouls() - "C:\Users\Dr. Peter Haas\AppData\Local\Temp\PapyrusTemp\bos100fightmonitor.psc" Line 445
[BoS100Fight (00068D7B)].bos100fightmonitor.OnTimer() - "C:\Users\Dr. Peter Haas\AppData\Local\Temp\PapyrusTemp\bos100fightmonitor.psc" Line 333
[12/28/2019 - 05:07:22PM] error: Cannot check for detection LOS with a None target
stack:
[ (00000014)].Actor.HasDetectionLOS() - "<native>" Line ?
[BoS100Fight (00068D7B)].bos100fightmonitor.ForceKillGhouls() - "C:\Users\Dr. Peter Haas\AppData\Local\Temp\PapyrusTemp\bos100fightmonitor.psc" Line 462
[BoS100Fight (00068D7B)].bos100fightmonitor.OnTimer() - "C:\Users\Dr. Peter Haas\AppData\Local\Temp\PapyrusTemp\bos100fightmonitor.psc" Line 368

Note: These appear to be stuck in an endless loop, which gives you a really large papyrus log file. Mine was around 6.5 MB after playing for 2 hours. I'm not sure what triggered the issue, but it could have something to do with not talking to Paladin Danse immediately after killing all of the feral ghouls at the Cambridge Police Station (just a guess).

Comments

3 comment(s) [Closed]
Arthmoor said:
 
The script has safety checks for NONE values in all the right places, but this looks like it's trying to reference deleted ones as well. Perhaps adding IsDeleted() checks in the same places will reduce the chances of this happening?

EyeDeck said:
 
Just came here to report this myself.

This is a lower-level engine issue where the engine occasionally garbage collects the base ObjectReference forms to without also cleaning up their ObjectReference (and Actor and any other scripts that used to be attached) script instances. The engine, at least as far back as Skyrim, has a tendency to prematurely garbage collect anything spawned by PlaceAtMe() called with either abForcePersist = false, or maybe abDeleteWhenAble = true, I'm not sure. This happens very rarely, so it's extremely difficult to investigate in detail. Anyway, IsDeleted() won't work (it'll come back false because the function will fail completely, and print another <nullptr form> error to the log), nor will checking for None (because the script instance does exist, ergo is not None).

There are two ways to fix this: changing the PlaceAtMe calls so abForcePersist = true and abDeleteWhenAble = false will fix the "underlying" issue, but will not retroactively fix affected saves, and you'd need to carefully audit the script to be absolutely certain that anything spawned is manually Delete()d at some point, otherwise the script could cause save bloat.

The easier way to deal with this is to add checks for IsBoundGameObjectAvailable(), like so (starting at like 440):
int Function GetCountOfLivingGhouls()
	int i = 0
	int ghoulCount
	While (i < indexAllGhouls)
		;Debug.Trace("GetCountOfLivingGhouls at " + i + ": " + AllGhouls[i ])
		if (AllGhouls[i ] != None && AllGhouls[i ].IsBoundGameObjectAvailable() && !AllGhouls[i ].IsDead())
			ghoulCount = ghoulCount + 1
		EndIf
		i = i + 1
	EndWhile
	;Debug.Trace("GetCountOfLivingGhouls="+ghoulCount)
	return ghoulCount
EndFunction
(ignore the weirdly formatted [i ]s, just avoiding them being picked up as bbcode)

However, it gets worse. Much worse. Because the original spawned FormIDs of the garbage collected ghouls may be recycled, if the save goes on for a while, the ghoul references in the array (such as, in OP's case, FF000DC6) may end up pointing to a new object, instead of just nothing.
In my case, after fixing the previous thing, I had this error:
[07/23/2020 - 11:20:25AM] error: Unable to call Kill - no native object bound to the script object, or object is of incorrect type
stack:
	[ (FF00133F)].Actor.Kill() - "<native>" Line ?
	[BoS100Fight (00068D7B)].bos100fightmonitor.ForceKillGhouls() - "C:\Program Files (x86)\Steam\steamapps\common\Fallout 4\Data\Scripts\Source\User\BoS100FightMonitor.psc" Line 469
	[BoS100Fight (00068D7B)].bos100fightmonitor.OnTimer() - "C:\Program Files (x86)\Steam\steamapps\common\Fallout 4\Data\Scripts\Source\User\BoS100FightMonitor.psc" Line 368

And when I prid'd FF00133F, it was actually a (deleted) instance of the Nuclear Launch Key from Far Harbor that some other script had spawned in at some point. Which, oh my god, BoS100FightMonitor disabled and deleted via CleanupGhouls() at some point, because the key ended up in the AllGhouls array!!! Which means that this script can actually cause entirely random spawned references to disappear from the game, and who knows what else.

So, with that in mind, this is a serious bug that must be properly fixed. So, I have:
  • Fixed the one place where PlaceAtMe() is called so abForcePersist = true and abDeleteWhenAble = false
  • Made sure that anything spawned by PlaceAtMe() is explicitly Delete()d at some point
  • Added a VerifyAllGhoulsArray() function that makes sure everything in AllGhouls really is a ghoul before attempting to operate on it
  • Added a skipUFO4Pretroactive bool that will skip the extra processing required by VerifyAllGhoulsArray() in new games, which won't be affected by the underlying bug anymore (performance optimization)

In my own save, loading up the game with my fix in place prints this out to my Papyrus log:
[07/23/2020 - 12:52:07PM] [bos100fightmonitor <BoS100Fight (00068D7B)>] UFO4P: Cleaned out index 11=[Actor < (FF00133F)>] from AllGhouls array that doesn't point to a ghoul anymore
[07/23/2020 - 12:52:07PM] [bos100fightmonitor <BoS100Fight (00068D7B)>] UFO4P: Cleaned out index 10=[Actor <<nullptr form> (FF001332)>] from AllGhouls array that's no longer bound to a game object
No related errors print to my log anymore, and the infinitely looping timer has also correctly stopped.

Unfortunately this also raises the issue of: where else in the game can this PlaceAtMe() issue ultimately rise up? A quick file search for calls to this function reveal ~400 other instances of this function being used, any one of which could potentially cause similar issues, and none of which are trivial fixes. Ugh...



Attached Files:

Scripts.7z

Arthmoor said:
 
Better late than never to get this one incorporated. What a nasty little mess. Hopefully this is also going to indirectly fix the associated BOS100Fight quest getting stuck as this seems like a likely reason it could happen. I don't think premature culling is limited to just objects spawned this way either as CK placed corpses often get purged before they should be too.

Showing Comments 1 - 3 of 3