Does Netcode for GameObjects have 'offline mode'?

Playing around with NfG trying to calculate if it works for me or not to develop a small tactical RPG with 1-4 players per playthrough. Obviously with Relay and Lobby and all.
Everything looks promising, except for one thing. I couldn't find anything which would resemble Photon's 'offline mode', where basically they feed back all the RPCs and everything into the same game, essentially render the game to single player and all connected players are the same local player.
This means we don't need to architect our game code around these two modes, everything can go through the usual RPC calls and all normal synchronization, the final game looks like a connected game, but in reality it's a single player mode, where the local player can play alone or even steer all the "connected" characters.

Am I just missing something painstakingly obvious or is it not a feature? If it is not a feature, is it possible to have it as a feature? This essentially cut the complexity of all connected code in half since we don't need to check for game mode constantly and making branches for them.

You can just start the NetworkManager in host mode and use an IP based transport like UnityTransport. That way you are hosting a single player session on your own where no one can join.

1 Like

Hello,
Regarding this solution, is it possible to set the Unity Transport Protocol Type from Relay Unity Transport to Unity Transport or is there a way to set the Network Transport at runtime and have two different transports configured on a NetworkManager object?

Thanks for your help!

1 Like

Should I take that as a no ? :smile:

well why not try it? this is somethings I’m curious about too.

Yes this is possible. I suggest having a look at our Boss Room sample. Inside that project we are using multiple transports and we switch them at runtime depending on which connection method the player chooses in the UI.

1 Like

But what about webgl? I would like to implement a single player mode on WebGL? Host mode is not available there, could you please give an advice how handle this?

I think you’ve got your answer here

1 Like

Hello,
I have a co-op game with Steam Facepunch network transport (Netcode for GameObjects). Where one player is a host.
How should I make offline mode?
Is it possible to switch NetworkManager transport from Facepunch to UnityTransport(IP) and vise versa in play mode?
Or should I use 2 Network managers and switch between them? It has NetworkManager.Singleton. Only one NetworkManager should be enabled at a time.
Maybe use some TransportSwitcher set to NetworkManager' NetworkTransport (will it even work)?
public class TransportSwitcher : NetworkTransport
{
[SerializeField] private NetworkTransport[ ] _networkTransports;
private NetworkTransport _currentTransport;
private void Awake()
{
SetTransport(0);
}
public void SetTransport(int v)
{
_currentTransport = _networkTransports[v];
}
...
NetworkTransport override methods using _currentTransport
...
}

And switch it before StartHost().

In my projects I use prefabs to switch the transport. When the transport is switched (for example, from Steam to single-player), I destroy the old transport GO, instantiate the relevant prefab and just assign the Transport component to NetworkManager.Singleton.NetworkConfig.NetworkTransport.

Seems to have worked without any issues so far.

Example:

        private void StartTransport(bool? useSteamOverride = null)
        {
            if (useSteamOverride ?? UseSteam) {
                StartFacepunchTransport();
            } else {
                StartUnityTransport();
            }

            void StartFacepunchTransport()
            {
                if(TransportType == Transports.Facepunch)
                    return;
                if(currentTransport != null) {
                    Destroy(currentTransport);
                }

                GameObject transportGO = Instantiate(facepunchTransportPrefab, NetworkManager.Singleton.transform);
                FacepunchTransport transport = transportGO.GetComponent<FacepunchTransport>();
                NetworkManager.Singleton.NetworkConfig.NetworkTransport = transport;
                currentTransport = transportGO;
                TransportType = Transports.Facepunch;
            }

            void StartUnityTransport()
            {
                if(TransportType == Transports.Unity)
                    return;
                if(currentTransport != null) {
                    Destroy(currentTransport);
                }

                GameObject transportGO = Instantiate(unityTransportPrefab, NetworkManager.Singleton.transform);
                UnityTransport transport = transportGO.GetComponent<UnityTransport>();
                NetworkManager.Singleton.NetworkConfig.NetworkTransport = transport;
                currentTransport = transportGO;
                TransportType = Transports.Unity;
            }
        }