Monsters are now persisting, so Tombstoning is back to functional. I went with a fixup model; each actor has a “hydration Id” (which is just their index in Level.Actors), and references to other actors are persisted as their hydration id. Level.Persist starts by setting the Actors’ hydration Ids:

            // In order to persist references between Actors, each Actor is assigned a unique
            // value (their index in Level.Actors), which is then used in Restore to 'fixup' references
            for (int i = 0; i < Actors.Count; i++)
                Actors[i].HydrationId = i;

That’s then persisted in Actor.Persist:

        public override void Persist(FileWriter writer)

then, instead of persisting AggroTarget, I persist AggroTarget.HydrationId (handling null as “-1”):

            if (AggroTarget == null)

On Restore, when an Actor is loaded it loads and stores the hydration Id for the aggro target:

        public override void Restore(FileReader reader, Level level)
            base.Restore(reader, level);

            _aggroTargetHydrationId = reader.ReadInt();

and then when all actors are loaded, we do one last pass in which all actors in the level have “Fixup” called on them:

        internal override void Fixup(List Actors)
            if (_aggroTargetHydrationId == -1)
                AggroTarget = null;
                AggroTarget = Actors[_aggroTargetHydrationId];

Other object references should follow the same pattern. Items don’t have the same issue as they’re always “bound” to something and don’t reference other Items.

No new screenshot (looks the same), but at least it doesn’t throw an exception on exit šŸ˜‰

Updated source:

Updated executable: