When is it "safe" to send my first client rpc/command

Hi,

I’ve noticed a bit of an inconsistency when trying to set up my game. When I start a new game, I want the server to set the necessary parameters and then send a message to clients (including the server itself) to show a screen. However at the moment I’m having to put a delay in, in order to make it work consistently. All functions below are in the same class which derives from a NetworkBehaviour.

    public override void OnStartServer ()
    {
        if(LobbyManager.singleton.numPlayers == PlayerManager.instance.GetNumberOfPlayers())
        {
            StartServer();
        }
        base.OnStartServer ();
    }

Server functions below:

[Server]
    public void StartServer()
    {
        StartCoroutine (ServerNewGame ());
    }

    [Server]
    IEnumerator ServerNewGame()
    {
        yield return new WaitForSeconds (1f);
        RelationshipInitializer.Instance.Initialize();
        ChangeCampaign();
    }
  
    [Server]
    public void ChangeCampaign()
    {
        Campaign newCampaign = new Campaign();
        RpcStartBudgetAllocation ();
    }

ClientRPC function.

    [ClientRpc]
    public void RpcStartBudgetAllocation()
    {
        PickBudgetScreen.Instance.ShowScreen ();
    }

I’m noticing however that without the delay in my ServerNewGame function, the RpcStartBudgetAllocation function is not called at all. Not on the client on the server or any other clients.

Is there a particular reason why or a better way I should do this?

It seems the the NetworkManager calls OnStartServer and OnStartHost before the hosts actually get started, in fact, there’s currently no difference between the two functions really. (This may be a design flaw and may change) You’re getting the issue because you’re trying to call the RPC on a server instance that hasn’t been initialized yet so nothing happens.

I believe a decent workaround at the moment would be to use OnClientStart on the host machine like below.

public override void OnStartClient(NetworkClient client)
{
    base.OnStartClient(client);
    if (Network.isServer)
    {
        //Initialization that occurs right after server starts
        StartServer();
    }
}

Basically, OnStartClient is called right after the server is successfully started up on the server so it’s your best bet at doing initialization right after the server gets setup.

well client connections should be ready to receive RPCs. in order to know when all clients are ready you should either iterate on all connections on NetworkServer and check if they are ready and then send the RPC or just send a ready command from each client to server (client’s objects will be available after they are ready) and then gather all ready messages on server and then start after everyone is ready.

the process is two phase
first server gets initialized and all clients get connected
then each clients signals the server that he/she is ready ClientScene.ReadyXXX (if you don’t use network manager)
after clients say they are ready all objects are spawned on them and RPCs can be received , before that only messages can be sent/received.