BeginPlay called before ReadyToStartMatch

Hi

I have following setup: I have two instances of my game, both are connected to a lobby-map, one being a listen server, other being a client. When host clicks “Start Game”, a servertravel command is issued, so both listen server and client transition to game-map. So far so good. Since I want both players (or potentially more than 2) to start game synchronously, I have a player counter in GameMode of new map, which checks how many players have finished loading, and only returns true for ReadyToStartMatch, if all players have finished loading map.

Now here’s my problem: listen server always starts game about 1 second before all clients do. All clients start game synchronously. When I add log statements to PlayerController’s BeginPlay, I can clearly see, that BeginPlay on listen server’s PlayerController is called BEFORE ReadyToStartMatch returns true (log statements confirm, that function is returning false, when BeginPlay is called)! According to documentation, BeginPlay should only be called AFTER ReadyToStartMatch returns true.

Is this behaviour intended/correct? To me it seems, like BeginPlay shouldn’t be called.

Thanks in advance,

Elewyth

PS: Experienced with UE4.7.2

Hi Elewyth,

Can you post your code setup in your AGameMode? Thanks!

Hi, my GameMode looks like this:

bool AMyGameMode::ReadyToStartMatch() {
	return Super::ReadyToStartMatch() && GetNumPlayers() == Cast<UMyGameInstance>(GameState->GetGameInstance())->NumPlayers;
}

UMyGameInstance::NumPlayers is a simple int32, which is set in lobby and held on GameInstance, so we know in new map, how many players we are expecting to join (in case of host + 1 client, this would be set to 2)

Hi Elewyth,

Sorry for delay in response. This is some information I got from networking developers here:

Looks like documentation you’re referring to is a bit misleading… Looking at AGameMode::HandleMatchIsWaitingToStart, it has this code:

// Calls begin play on actors, unless we're about to transition to match start

if (!ReadyToStartMatch())
{
	GetWorldSettings()->NotifyBeginPlay();
}

So BeginPlay can be called here. But HandleMatchIsWaitingToStart is virtual, so it’s possible to override this behavior in an AGameMode subclass, which might be easiest route for you at moment.

Thanks, overriding HandleMatchIsWaitingToStart worked for me. There is still a little delay between server’s and clients’ calls to BeginPlay on PlayerControllers, but I suppose this is because of network latency, and there can’t be anything done about it.