Incremental Actor Removal - Potential Bugs due to UWorld::CleanupActors?

I’m currently upgrading a project from 5.4 to 5.7, I noticed as part of this upgrade that Epic has added incremental actor EndPlaying to RemoveFromWorld. This is great as this is a mod we had implemented ourselves back in 5.4, so we can remove that- however we had to make an additional important change to make incremental end playing safe that doesn’t appear to have been made in 5.7 (and it took us months to catch) so I wanted to double check with Epic that the 5.7 code doesn’t need the same fix. It’s possible I’m missing something in the code and what we had to fix this in 5.4 is no longer a problem in 5.7 (I haven’t tried to repro, the repro wouldn’t be super consistent because it depends on various sliced processes lining up just right)- but skimming the code I don’t think that is the case.

UWorld::CleanupActors is called on each world after GC is ran- this is to deal with holes left in the actor array due to actors being destroyed, etc. The CleanupActors function very specifically will not operate on levels being made visible because systems like incremental registration/etc. tracks an index into the actors array as it works, and if the actors array is reshuffled during the registration it will break down/cause issues/skip actors/etc. This same problem exists for component unregistration and end playing actors- but CleanupActors does not have a check to skip levels being made invisible. Prior to incrementalizing actors endplaying play this was _fine_ because if an actor missed having its components incrementally unregistered the actor end play will unregister the components anyways (AActor::RouteEndPlay -> AActor::UninitializeComponents). However if the actor array is rearranged/compacted while routing EndPlays you can miss EndPlaying an actor- this then allows actors to potentially destroy without ending play, or if the level is reused without destroying the actor will be reused without endingplay and beginning play again (since it had already begun play). Again I haven’t reproed this in 5.7 / confirmed this bug exists in 5.7 but looking over code the end play incrementalization process seems like it should have the same pitfall our mod we made to 5.4 did and this same problem should exist.

If this is a problem the fix should be simple- simply skip compacting the actors array on levels being made invisible like is already done for levels being made visible.

[Image Removed]

Sorry if I’m incorrect about this being an issue in 5.7!

[Attachment Removed]

Steps to Reproduce

  1. Have a level being made invisible, it’s incrementally ending play on actors, and there are holes in it’s actor array
  2. Garbage collection runs while the level is being made invisible and UWorld::CleanupActors is called, compacting the actors array
  3. RouteActorEndPlayForRemoveFromWorldIndex (or CurrentActorIndexForUnregisterComponents) is potentially now incorrect and actors in the level may never end play
    [Attachment Removed]

Nevermind, I now see this is a dupe [Content removed]

And the fix made on 48992742 is the same as what I suggested here.

Thanks!

[Attachment Removed]

Glad to hear! I’ll close this ticket then :+1:

[Attachment Removed]