Skip to main content

Shared Mode

Expected Output

  • What is Shared Mode here refer to?
  • How to implement Shared Mode
  • Any insight on using Shared Mode

Key Solution

In Shared Mode, we will start a Game Client that will connect to Game Server in the Photon Cloud.

We must not set DisableClientSessionCreation to true, otherwise the player can’t create session (thanks @Fadhli Hibatul Haqqi).

Pros

  • No Server-Setup required, anyone can directly join to a session
  • No Client as Host, if the first client (SharedModeMasterClient) that started the game is disconnect, the other players can still continue the session

Cons

  • Need to request StateAuthority first to despawn objects that belongs to a disconnected player (but so far no problem)

How to Start Shared Mode

  • Just change the game mode on the StartGame function, eg:

    await _runner.StartGame(new StartGameArgs
    {
        GameMode = GameMode.Shared,
        SessionName = "Test",
        ObjectPool = _pool,
        SceneObjectProvider = _sceneProvider
    });
    

How to Spawn Player Object

  • OnPlayerJoined will never be triggered, so you only need to instantiate at OnConnectedToServer, eg:

    // For Client-Host Mode
    public void OnPlayerJoined(NetworkRunner runner, PlayerRef player)
    {
        if (runner.IsServer)
        {
            runner.Spawn(_playerPrefab, Vector3.zero, Quaternion.identity, player);
        }
    }
    
    // For Shared Mode
    public void OnConnectedToServer(NetworkRunner runner)
    {
        if (runner.GameMode == GameMode.Shared) // To prevent Client-Host get into this
        {
            runner.Spawn(_playerPrefab, Vector3.zero, Quaternion.identity, runner.LocalPlayer);
        }
    }
    

How to Despawn Disconnected Player Object

  • Before you despawn another player object, you need to request its StateAuthority, eg:

    // For Client-Host Mode
    if (Object.HasStateAuthority)
    {
        runner.Despawn(Object); // Host can just directly despawn its client
    }
    
    // For Shared Mode
    else if (Runner.IsSharedModeMasterClient)
    {
        Object.RequestStateAuthority();
    
        while (!Object.HasStateAuthority)
        {
            // Wait for Auth Transfer
            await Task.Delay(100);
        }
    
        if (Object.HasStateAuthority)
        {
            runner.Despawn(Object);
        }
    }
    

Conclusion