Begin play execution order changed after moving from 4.17 to 4.20

Hi
I’ve just moved my project from 4.17 to 4.20. There is a very peculiar issue I am facing:

Begin play execution order in 4.17:

PlayerController ClassCharacter ClassGameMode

Begin play execution order in 4.20:

GameModePlayerController ClassCharacter Class

Is anyone else having this issue? There is not a single change in my code. I am totally clueless on how and why this might be happening.

Thanks!

One thing that I always do when dealing with event-based programming is to not assume any particular order in events. Maybe they are using a different event dispatcher, maybe the priority for these events changed, it is simply not good to assume this order.

If you really need this specific order you should probably create a custom event that you trigger yourself. There is another solution discussed in the following question

But I don’t think that is a good one.

As a general advice, I would suggest for you not to assume order in events.

Thanks for the answer. After encountering this problem, I did realize I made a glaring mistake of initializing some of my variables in Begin Play. Even though I’ve fixed that now, I’m curious to know why Begin Play for actors cannot have a deterministic order.

After a bit of digging, I landed on WorldSettings.cpp where BeginPlay for actors is being called from AWorldSettings::NotifyBeginPlay() Line:222

void AWorldSettings::NotifyBeginPlay()
{
	UWorld* World = GetWorld();
	if (!World->bBegunPlay)
	{
		for (FActorIterator It(World); It; ++It)
		{
			SCOPE_CYCLE_COUNTER(STAT_ActorBeginPlay);
			It->DispatchBeginPlay();
		}
		World->bBegunPlay = true;
	}
}

When It iterator is put in the Watch window, the ObjectArray inside It has pointers to all the actors in the level. The order of this array differs from 4.17 to 4.20.

I understand that the order in which the actor pointers populete this ObjectArray is not deterministic. I have made necessary changes in my code to fix the mistake I made. But out of curiosity I want to know if it’s indeed possible to achieve a deterministic execution order for BeginPlay.

Before DispatchBeginPlay is called, is it possible to have one pass to sort this ObjectArray based on some kind of priority which can be set through an int? This can result in a more deterministic behavior for execution order.

Please don’t get me wrong. It is not that events cannot happen in a deterministic order, they usually do! However, different systems may handle events in particular ways. Events can go to a priority queue or they can be postponed to be handled later. I am not saying this is the case of Unreal, I am just saying I don’t think it is a good idea to rely on the order of events. The underlying implementation of the event handling system can change and your logic might brake.

Think of them as a fire and forget thing. If you really want to enforce order the best approach is to use a function call.