Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Single player hosting in WebGL using RPC #3035

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

BenHamrick
Copy link

Expose the ability to use RPC especially on WebGL to allow us to easily make a single player mode while still using netcode usually as a host.

Changelog

  • Added: The ability to use RPC using a property in the Transport.
  • Changed: Allowed the ability to host a game if using RPC in WebGL to allow us to easily create a single player mode.

Testing and Documentation

  • No tests have been added.
  • No documentation changes or additions were necessary.

…ly make a single player mode while still using netcode usually as a host.
@BenHamrick BenHamrick requested a review from a team as a code owner August 27, 2024 04:53
@BenHamrick BenHamrick changed the title Single player hosting in WebGL using RPC feat: Single player hosting in WebGL using RPC Aug 27, 2024
@CodeSmile-0000011110110111
Copy link

CodeSmile-0000011110110111 commented Sep 24, 2024

@BenHamrick Where is the RPCNetworkInterface type defined? I tried to add this change but cannot find such a class in the entire codebase, not even in your fork, and not on the Internet at large.

@BenHamrick
Copy link
Author

@BenHamrick Where is the RPCNetworkInterface type defined? I tried to add this change but cannot find such a class in the entire codebase, not even in your fork, and not on the Internet at large.

My bad! It's supposed to be IPCNetworkInterface

@NoelStephensUnity
Copy link
Collaborator

@BenHamrick
You can opt to assign or create your own NetworkTransport that you switch to when running in a single player mode. You can make that implementation a "mock transport". You can see an example of a mock transport here.
Since you don't need any network connectivity in single player (other than services possibly which doesn't use UTP), all netcode related scripts should work. If you feel that this is not enough could you provide a working example for this PR so we can review it?

@BenHamrick
Copy link
Author

BenHamrick commented Jan 8, 2025

@NoelStephensUnity I tried using the mock transport but it seems like NetworkManager.RealTimeProvider is private so the script won't work as is. Also seems a little extreme to require me to make a whole new transport to run my game in single player. Is there maybe a more complete example somewhere I can use without the private reference? I also fixed this branch to work now.

@NoelStephensUnity
Copy link
Collaborator

NoelStephensUnity commented Jan 9, 2025

@NoelStephensUnity I tried using the mock transport but it seems like NetworkManager.RealTimeProvider is private so the script won't work as is. Also seems a little extreme to require me to make a whole new transport to run my game in single player. Is there maybe a more complete example somewhere I can use without the private reference? I also fixed this branch to work now.

Ahhh... I meant to look at it as an example/reference.

In reality, you really should only need to do something like this:

/// <summary>
/// Add this component to the same GameObject as your NetworkManager
/// </summary>
public class GameModeHandler : MonoBehaviour
{
    private NetworkManager m_NetworkManager;
    private UnityTransport m_UnityTransport;

    private UnityTransport.ConnectionAddressData m_Multiplayer;
    private UnityTransport.ConnectionAddressData m_SinglePlayer;

    private void Start()
    {
        m_NetworkManager = GetComponent<NetworkManager>();
        if (m_NetworkManager)
        {
            m_UnityTransport = m_NetworkManager.NetworkConfig.NetworkTransport as UnityTransport;
            if (m_UnityTransport)
            {
                m_Multiplayer = m_UnityTransport.ConnectionData;
            }

            // Single player would use the device's local/private loopback address
            // (i.e. no external client on another device could connect to the session)
            m_SinglePlayer.Port = 7777;
            m_SinglePlayer.Address = "127.0.0.1";
            m_SinglePlayer.ServerListenAddress = "127.0.0.1";
        }
    }

    /// <summary>
    /// Invoke this prior to starting NetworkManager
    /// </summary>
    public void ApplyGameMode(bool isSinglePlayer)
    {
        if (!m_UnityTransport)
        {
            Debug.LogError("Transport is not set.");
        }

        // Defines the transport for single or multiplayer use
        m_UnityTransport.UseWebSockets = !isSinglePlayer;
        m_UnityTransport.UseEncryption = !isSinglePlayer;
        m_UnityTransport.ConnectionData = isSinglePlayer ? m_SinglePlayer : m_Multiplayer;
    }
}

Where you just make the single player use the device's local loopback address, use the default port (7777), disable web sockets and encryption, and start the NetworkManager as a host. This would allow you to start a single player game using standard UDP.

The real issue is what builds are available. A WebGL build vs a device specific build... which I will need to look into that side of the equation... because a WebGL build will require the device to host the webservice to deliver the content via browser instance where a device specific build will allow you to launch the game from the device in question (could get tricky depending upon the device and could impact performance depending upon the device).

It might be the simplest answer is to make two builds...but I don't know the specifics of your game/project and if you are trying to provide a way to build upon something in single player and then use progress made in single player within a multiplayer WebGL instance.

@NoelStephensUnity NoelStephensUnity added the Tracking Has been added to tracking label Jan 10, 2025
@michalChrobot michalChrobot added the stat:awaiting triage Status - Awaiting triage from the Netcode team. label Jan 16, 2025
@BenHamrick
Copy link
Author

@NoelStephensUnity Reason why I am even here is because a player of mine had something running on 7777 and so could not start a server. Probably a second instances of the game 🤷 , but that does not matter here. I would rather run it using IPC that is used for testing anyways so we know it works. I never want to run a server on a port locally, even just by accident, if someone wants to play singe player.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stat:awaiting triage Status - Awaiting triage from the Netcode team. Tracking Has been added to tracking
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants