Targets not preserved in saved games

From DoomWiki.org

When the game is saved in any Doom engine game, monster and missile targets are not registered in the save game file, so any monsters which were active at the time of saving the game become dormant upon loading the game again. However, their location and angle when the game was saved is preserved.

Some distinguishable effects become evident because of the bug. The target of an incomplete arch-vile attack, for example, is not preserved in a saved game because of the bug. This means loading a saved game that includes such a situation will render the arch-vile attack harmless apart from the flame animation on the arch-vile's ex-target, which is displayed all the way through (as the corresponding flame thing had been spawned there as an effect of the attack). Similarly, the target of a revenant's missile is not stored in the save game data. Therefore, the missiles will no longer follow anything after it is restored.

The cause of this effect can be found in the Doom source code in p_saveg.c, in the functions P_ArchiveThinkers and P_UnarchiveThinkers.

In the Doom source code, the mobj_t structure is used to represent game objects such as monsters. Monster targets are stored in these structures as a field named target, which is a pointer to another mobj_t that the monster is currently targeting.

The Doom engine saves games by directly writing the raw structures used in memory to disk. When reloading saved games, pointers such as the target field are no longer valid (as the layout of structures within memory is different). When loading a game, the P_UnarchiveThinkers function deliberately sets target on all map objects to NULL in order to avoid crashes due to accessing invalid areas of memory. A null target indicates that a monster has no current target, causing active monsters to return to sleep.

A number of source ports have fixed the save game exploit, producing save game files with monsters that will continue to hound their previous target upon reloading the saved game. It is also possible to reconstruct infighting targets from standard Doom savegames by treating the stored mobj_t pointers as unique identifiers and analyzing their mutual relationships to determine which monster used to be which thinker. Mocha Doom uses this approach to reconstruct full target relationships from standard Doom savegames.