Unity networking service feedback. May 2022

Unity networking service feedback

Consider this as feedback of people that really loyal to Unity and new Netcode for GameObjects and Unity multiplayer services. I am not alone with thoughts that will be explained next with this posts.

So story goes that a few people decide to make multiplayer game. Before that we created only single player…
The main trouble was that in our game main gameplay with physics

Two flying players hitting each others with stones, bricks and so on. We try to use photon “PUN2”. It is good to sent “coordinates” by network, but not physics. All that we get - really bad lags.
Second try Photon Fusion - it were better. It have lag compestation sistem, network rigidbody but… still we got lags and this did not fit. We ask at forum, watch at youtube, whole people says that physics is really hard to create, nomatter that you use Tick-based Simulation, or physics prediction or their “Full Physics Prediction” still we got lags from any hard “add.force”.
But photon have really easy"creating rooms" tool, and “quick match” and so on. :frowning:

Next that we found was mirror. But trouble with Physics was same.

So we were VERRY HAPPY when found unity Netcode for GameObjects!! That a great product. We try to make all on our own server machine ( sort of dedicated server) and every thing was great! No lags, all physics are best! unity best! :slight_smile:

And to all that we need matchmaking, lobbies, room creating and so on.

Next we decide to have dedicated server on PlayFab because they have matchmaking and again we have lost because from march on 2022 they changed their price for matchmaking and not its - Matchmaking Requests - $0.0000099 per request. sure this is not much, but as developers we knew that we will have about 100-200 request a day on different machines after this we found that we can join beta on Unity Multiplayer Services! That was happiest day in whole year. :slight_smile:

We downloaded boss room (from 2021) that was great and we found familiar photon there :slight_smile:

btw we got start to develop with unity multiplayer at February 2022.

Still we were missing lobbies and matchmaking in our game. This is same - player download game to phone - open it - click “play” - game searching for any free lobby room (if not - he create one automatically) - then two players have fun.
(Photon can easily make this!) :frowning:


Then we start to play with Netcode for GameObjects documentation is really messi. Example

  1. We decided to use dedicated server ok. We got application that have NGO - press start server ok. Come clients may press “start client” - they will connect good its cool and simple BUT the main trouble is

  2. when server will “start game” - load next scene game will move on ok. BUT when another clients somewhere in world press “start client” they cannon connect because is game already running, so we need another game instance on server - why this did not describe in documentation? or maybe not another instance but use another port forwarding on server so that it will be another application.

  3. We knew that we need lobbies for this task. This will solve problem of different instances ok. Unity Multiplayer Services are the best. ok -
    We saw youtube tutorial “dapper dino” or “Dilmer Valecillos” they are really great for prototyping. But not for production. Same question - dapper dino - we create lobby. 4 players connect ok. game started, 5th player can not launch another game instance.
    same as other youtube creators. they all creates “local server with 1 game instance”. ok so we look at unity documentation and find “Game Lobby Sample” great thing but… its writed with Observer pattern that does break typical unity code following via references. and its really hard to understand.

  4. Game Lobby Sample - something observe something that been observed by something that been observed…
    Cmon unity we want to know how to create lobbie, how to connect and how to launch game, but not searching many dependencies in lobby sample. (photon and mirror really have more simplest examples, please unity do more and you will get new users of engine)

  5. “Lobby Hello World sample” really good and simple lobby sample which we manage to understand how it works. then we go to documentation - how create, how to connect, how to join and so on.
    but documentation missing MAIN think why this tool is used →

  6. We created lobby - great, we connected players - great. and what next? how to exactly start game? how to connect people peer2peer or dedicated server? how to load new game scene?

this questions was new to us as unity developers.
We looked again Game Lobby Sample with its kung fu observers and saw that is uses relay connection ok -

  1. we opened documentation about relay, how to start relay, how to connect, how to set password ok. HOW TO START GAME? again. only think that we wave left is Dilmer Valecillos tutorial with relay set up and play game, but again its is only 1 server instance. and he uses his own Singelton with his tutorial.

So I asking please for all unity new developers who love this engine and wants to create with it :slight_smile:

  1. Finlay get a nice documentation (some pages “not found”, some pages have old “unet is deprecated” some pages cant get difference of MLAPI and UGO )

  2. Show us with simple examples (like mirror or photon do )

  • how to create rooms/lobibes/relay
  • how to launch different server instances
  • ho to actually start the game after all that “connection done”
  1. Write manual or tutorial about all above, because all this journey that we have - many other people have also. I watch this forum and see people asking same questions as I with this long thread -
    person asking how to integrate lobby with relay -
    How to integrate Relay and Lobby

another person says that Game Lobby Sample is hard to understand because of its unlimited observers

another topic of golden path relay and lobbie
“1) How to create the relay and it’s lobby.
2) How to join the lobby and go from the lobby to the relay.
3) How to migrate hosts”

so I may say - people did not understand how to use unity network tools! Help them please!
As for my game we still did not figure out how to actually connect relay and lobby or how make dedicated server + manny lobbies on it
or how to actually start the game. Sorry for such long thread :frowning:

Hello there!

I’m part of the product team on Multiplayer Services. I wanted to say thank you for taking the time to share your journey and experience in so much detail.

There’s definitely a lot to unpack here, you are making some really good points. The new-user experience with our services is something that’s super important to us and that we continuously want to improve. This type of feedback is invaluable.

Regarding your specific issue of supporting more than one instance (of either Relay or game servers), I’ll dig up what I can.

Do you have code snippets you could share, specifically around how you create new lobbies, have players join lobbies, and how to create and join Relay allocations?

Sure I have all. Share right here?

If you’re comfortable with that, please :slight_smile:

Sure its ok. So after we created working scene with players flying, RPC, physics and so on - we created new “main menu scene” that player will see after launch game.
It got 3 buttons
“Offline” - usually game 1 vs bot
“online” - our main interest
“exit” - exit

then we start to learn “Lobby Hello World sample . cs” we saw that it automatically made “steps with lobbies”:
Trying to log in a players …
Player signed in as *****
Created new lobby
and so on… (btw query are did not work there :slight_smile: don’t know why, may be my mistake)
-------- this example is really good, it continue documentation and fit well. (still it did not show how to launch game :slight_smile: after lobby)

so we decide make same steps but each step will be made by different button
so button “online” make first - Trying to log in - this will mean that we want to play online version →

async public void StartOnlineButton()
    {
        await ExecuteLobbyConnect();
    }
 
    //and
 
async Task ExecuteLobbyConnect()
    {
        await UnityServices.InitializeAsync();
         loggedInPlayer = await GetPlayerFromAnonymousLoginAsync();
        loggedInPlayer.Data.Add("Ready", new PlayerDataObject(PlayerDataObject.VisibilityOptions.Member, "Yes"));
         async Task<Player> GetPlayerFromAnonymousLoginAsync()
        {
            if (!AuthenticationService.Instance.IsSignedIn)
            {
                Debug.Log($"Trying to log in a player ...");
                await AuthenticationService.Instance.SignInAnonymouslyAsync();
                if (!AuthenticationService.Instance.IsSignedIn)
                {
                    throw new InvalidOperationException("Player was not signed in successfully; unable to continue without a logged in player");
                }
            }
            Debug.Log("Player signed in as " + AuthenticationService.Instance.PlayerId);
            PlayerInfoPanel.text = ("Player signed in as " + AuthenticationService.Instance.PlayerId);
            // Player objects have Get-only properties, so you need to initialize the data bag here if you want to use it
            return new Player(AuthenticationService.Instance.PlayerId, null, new Dictionary<string, PlayerDataObject>());
        }
    }

this is just as you see from Lobby Hello World.cs. May be did not get what is “data bag” from now, but now we don’t need it.

Ok next player saw - “back button”, “QuickStart” (need to search lobbies, if cant find create one), and “room list” →
which leads to lobbies list. We did not have it yet, and even don’t know how to instantiate prefab “lobbie3 1/4”. Because I cant understand from example “Lobby relay demo” how to actually get it, too many dependencies.
And next player press button “create” and see new input field that asking name of lobby.

So button “create lobby”, input field “MyTest” →

async public void CreateLobbyButton()
    {
        newLobbyName = RoomNameText.text + Guid.NewGuid();
        await CreatyLobbyTask();
    }

async Task CreatyLobbyTask()
    {
        var lobbyData = new Dictionary<string, DataObject>()
        {
            ["Test"] = new DataObject(DataObject.VisibilityOptions.Public, "true", DataObject.IndexOptions.S1),
            ["GameMode"] = new DataObject(DataObject.VisibilityOptions.Public, "ctf", DataObject.IndexOptions.S2),
            ["Skill"] = new DataObject(DataObject.VisibilityOptions.Public, Random.Range(1, 51).ToString(), DataObject.IndexOptions.N1),
            ["Rank"] = new DataObject(DataObject.VisibilityOptions.Public, Random.Range(1, 51).ToString()),
        };
        // Create a new lobby
        currentLobby = await Lobbies.Instance.CreateLobbyAsync(
            lobbyName: newLobbyName,
            maxPlayers: maxPlayers,
            options: new CreateLobbyOptions()
            {
                Data = lobbyData,
                IsPrivate = isPrivate,
                Player = loggedInPlayer
            });
        Debug.Log($"Created new lobby {currentLobby.Name} ({currentLobby.Id})");
        LobbyDebText.text = $"Created new lobby {currentLobby.Name} ({currentLobby.Id})";
        Debug.Log("Lobby info:\n" + JsonConvert.SerializeObject(currentLobby));
    }

We dont actually need “lobbyData” dictionary, but this is cool thing and I decide to keep it for later querries and so on.

then with usual canvas and text on it - may see - Created new lobby MyTest16890d59-08c9-4833-a444-60c6abea2fc3 (9xwQRsJsnYshvaVbMqgnw4)

that is cool also! :slight_smile:
Next I got another button "Quick Join Lobby "

That is search for lobbies and connect to them. (I cant still find how to create if did not find, but I will look at this later after at least we can start game scene)

So other player on other PC or phone press - “ONLINE” - “ROOM LIST” - “QUICK JOIN LOBBY” and connected well! Its awesome,and even simpler that was in photon!

code of “quick join lobby” -

async public void JoinLobbyButton()
    {
        await joinLobbyTask();
    }

async Task joinLobbyTask() {

        Debug.Log($"Try to find lobbies");
         List<QueryFilter> queryFilters = new List<QueryFilter>
         { //DIFFERENT queryFilters   im not using them now
         }
         
         List<QueryOrder> queryOrdering = new List<QueryOrder>
         {
             new QueryOrder(true, QueryOrder.FieldOptions.AvailableSlots),
             new QueryOrder(false, QueryOrder.FieldOptions.Created),
             new QueryOrder(false, QueryOrder.FieldOptions.Name),
         };

        QueryResponse response = await Lobbies.Instance.QueryLobbiesAsync(new QueryLobbiesOptions()
        {
 
            Count = 20,
        });
     
         List<Lobby> foundLobbies = response.Results;
        if (foundLobbies.Any()) // Try to join a random lobby if one exists
        {
            Debug.Log("Found lobbies:\n" + JsonConvert.SerializeObject(foundLobbies));
            LobbyDebText.text = "Found lobbies:\n" + JsonConvert.SerializeObject(foundLobbies);
            var randomLobby = foundLobbies[Random.Range(0, foundLobbies.Count)];

            currentLobby = await Lobbies.Instance.JoinLobbyByIdAsync(
                lobbyId: randomLobby.Id,
                options: new JoinLobbyByIdOptions()
                {
                    Player = loggedInPlayer
                });
            Debug.Log($"Joined lobby {currentLobby.Name} ({currentLobby.Id})");
            LobbyDebText.text = ($"Joined lobby {currentLobby.Name} ({currentLobby.Id})");
        }
        else
        {
            Debug.Log($"Did not find any :( ");
        }
}

so something we take from example, something from documentation.
and then we stuck.

so we got 2 connected people in 1 lobbies, that’s good. What next? How to launch game?

We opened “lobby relay demo” and see what is “Player ready” button do, find that it created net Network manager and instantiate “game logic” prefab. We think that is normal because we need to create network and “press start host”(by code)

the code in "Lobby relay demo " was

  private void CreateNetworkManager()
        {
            m_inGameManagerObj = GameObject.Instantiate(m_prefabNetworkManager);  // ok this is good
            m_networkManager = m_inGameManagerObj.GetComponentInChildren<NetworkManager>();
            m_inGameRunner = m_inGameManagerObj.GetComponentInChildren<InGameRunner>();   // ok we make our game
       
            m_inGameRunner.Initialize(OnConnectionVerified, m_lobby.PlayerCount, OnGameEnd, m_localUser);

         
            // and here we stuck
            UnityTransport transport = m_inGameManagerObj.GetComponentInChildren<UnityTransport>();
            if (m_localUser.IsHost)
                m_inGameManagerObj.AddComponent<RelayUtpNGOSetupHost>().Initialize(this, m_lobby, () => { m_initializeTransport(transport); m_networkManager.StartHost(); });
            else
                m_inGameManagerObj.AddComponent<RelayUtpNGOSetupClient>().Initialize(this, m_lobby, () => { m_initializeTransport(transport); m_networkManager.StartClient(); });
        }

what is RelayUtpNGOSetupHost ? we try re create it, but it have many dependencies, “local lobby”, some other observers and actually this will not fit.

So now we have

  • lobbie;
  • 2 Connected players;
  • Dedicated server (may be we don’t need it anymore we really don’t know yet?);
    and we cant start game.

so

  1. can we use dedicated server and no relay system? If every physics and controls is on server it got zero lags. if not - ok, we will use relay.
  2. How create new lobby is quick did not find any?
  3. and how to start game ? :slight_smile:

that’s all we got now. Sorry for long thread again

I made it finally done. All working well. A create new project from zero and write code with experience, not from scratch. Without querry filters and so on. Got all works.

  1. Unity is simple yes, but i have great issues about documentation and why so many people stucking. Do I need to tell them here for improvement?

  2. should I show you new scripts?

  3. may be I need to create tutorial about “quick match” / “quick lobby join” system?

Thanks for the follow up – sorry I didn’t reply sooner.

I think this is all great info and I’ve passed it on to our teams to review and apply improvements in the future. (I can’t share exactly the exact improvements and their nature just yet – though I can assure you that your post had an impact!)

Like I said before, thanks a lot for sharing this type of feedback (the code snippets, as well as the entire journey you went through). And I encourage you to keep sharing your impressions as you progress in your journey!

1 Like