Search Unity

Feedback My experience with netcode for GameObjects thus far

Discussion in 'Netcode for GameObjects' started by MaskedMouse, Mar 24, 2022.

  1. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,092
    Background
    I'm a developer for about 7-8 years. I got a bachelor degree in IT. My study was called "Game Technology and Production". Most of my experience is in XR and UGUI due to my daily job.
    So as a challenge I started development of a hobby project. A multiplayer Tower Defense game using Netcode for GameObjects. I have no experience with other multiplayer API such as Mirror. So I wouldn't be able to compare them in terms of ease of use.


    The network manager
    The singleton pattern. Everytime you want to access anything you have to write
    NetworkManager.Singleton

    Want to access the NetworkSceneManager?
    NetworkManager.Singleton.SceneManager.LoadScene


    It would've been easier if the
    NetworkManager
    was a static class and the configuration of it in the inspector as a component that communicates with the static
    NetworkManager
    class.
    That way you can write
    NetworkManager.StartServer()

    NetworkSceneManager.LoadScene
    just like many other Unity based API.
    If you need the MonoBehaviour lifetime of Unity that could be done in a proxy component instantiated at the start of the server.


    Switching scenes
    I've setup a Main Menu and Lobby UI using UI Toolkit. Selecting multiplayer and a submenu 'Host' I start the NetworkManager server and switch the scene to the Lobby Scene.
    Upon entering the Lobby scene, I have a lobby controller that keeps track of the connected clients and their ready status. For every client connected I need to sync up their username, ready status and character / race in the UI. So I called a server rpc from the client to add themselves to the connected list with their username and last preferred character / race. I got an error telling me that the RPC was called on a NetworkObject that is not in the spawned object list. After quite some time debugging why, I found out that I switched the scene the regular way using Unity's SceneManager and not the NetworkSceneManager.

    It would've been nice if I had a warning / error message that I changed scenes with the regular API.
    Or it would've been even better if you can use the regular SceneManager API.
    There is a
    SceneManagerAPI.overrideAPI
    perhaps you can hook in the required functionality through that. So you wouldn't need to call
    LoadScene
    through the
    NetworkManager.Singleton.SceneManager
    .


    Documentation
    Some pages are already out of date. Like the NetworkVariables still mentions NetworkDictionary which has been removed in 1.0.0.


    Missing Features
    A lobby controller component with connection UnityEvents and a client ready UnityEvent.
    It would make prototyping a lot faster that handles these.
    ClientConnected, ClientDisconnected, ClientLostConnection, ClientReconnected, ClientReady

    Addressables support, this is something I've already mentioned in another thread. It's on the roadmap.
    Having a list of prefabs on a NetworkManager loads them all into memory even when you don't use them.
    In my case if I were to have 20 different towers per race and have 4-5 different races. That'd mean I have to load 80-100 towers into memory at all times. Even though one of those races may not be chosen or a large selection of towers would not be available. But they're still being loaded into memory at the Bootstrap scene.
    Addressables in this case would be nice to load in the prefab only when it is required.


    Unclear
    Ways of referencing choices made by the player. Choosing a character, choosing a tower. In single player I'd have a scriptable object with a list of player selected towers as AssetReference. Instantiate them when selected through the UI.
    In multiplayer I somehow need to synchronize the selection into a List. Which is something I can't wrap my head around how since you can't reference prefabs.
    I have looked at the Boss room example but that project feels like a code spaghetti to me. Finding a needle in a haystack. Which is why I looked at the bitesize examples but that case doesn't seem to be in there. It does have a lobby but no client based selections.


    I'm learning slowly but I could use some more bitesize examples on how to mess around with data and references. I find 'to the point' examples easier to follow than the boss room project.
    The post turned more into a bit of a rant but I really want to try to create a multiplayer game with it.
    I just need to learn more before I can really use it to create a game with it.
     
    Last edited: Mar 25, 2022
    yonatanab1, NotaNaN, emredesu and 5 others like this.
  2. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    660
    I'm working on a lobby, it's a little different to what you're after as it's a lobby with multiple rooms but follows the same principles. Here's an over-simplified version of part of the workflow taking rooms out of the equation:
    • On client side
      • Client enters lobby
    • On server side
      • Create new player
      • Add player to lobby
      • Spawn new player
    • On client side
      • On each player network spawn
        • Display player details in UI
    • On client UI selection (character, tower, ready)
      • RPC selection to server
      • Server updates player selection (NetworkVariable)
      • Selection propagates to all players in lobby
    The lobby keeps a list of all the players. I do also spawn the lobby as well but I've removed functionality from it so it's not doing so much right now, but I have the players as children of it as it's easy to see who's in it.

    I had a conversation with one of Unity's product managers and one of the things I mentioned was having more small real world examples. It's good to have the Boss Room example but it's a bit overwhelming for the uninitiated.

    That page has been updated but it's under the develop tab for some reason.
     
    GilbertoBitt likes this.
  3. CreativeChris

    CreativeChris

    Unity Technologies

    Joined:
    Jun 7, 2010
    Posts:
    457
    @MaskedMouse Thank you for taking the time to write up your experiences on using NGO.

    I have shared this with our engineering team and I will take some action on your feedback.

    I did want to focus on the samples area you mention:

    I have looked at the Boss room example but that project feels like a code spaghetti to me. Finding a needle in a haystack. Which is why I looked at the bitesize examples but that case doesn't seem to be in there. It does have a lobby but no client based selections.

    I'm learning slowly but I could use some more bitesize examples on how to mess around with data and references. I find 'to the point' examples easier to follow than the boss room project.
    The post turned more into a bit of a rant but I really want to try to create a multiplayer game with it.
    I just need to learn more before I can really use it to create a game with it.

    We are doing a lot of clean up on the spaghetti code as you describe it, we know this isn't as accessible as it should be considering it is an educational tool - more on this soon.

    There are many ideas to expanding our bite-size sample library as well, currently we have three small examples, but we are looking at potentially building more - what would you like to see us prioritise?
     
  4. CreativeChris

    CreativeChris

    Unity Technologies

    Joined:
    Jun 7, 2010
    Posts:
    457
    @cerestorm thank you for sharing as well.

    I had a conversation with one of Unity's product managers and one of the things I mentioned was having more small real world examples. It's good to have the Boss Room example but it's a bit overwhelming for the uninitiated.
    This is actually why we created bite-size, we realised Boss Room can be very overwhelming to someone unfamiliar with Netcode programming. We have initiatives this year that refactor and simplify the Boss Room codebase and a video series to go alongside it, to teach the theory and practical of NGO with Boss Room.

    I think there is more we can do with Bite-size samples, I would love to hear your ideas.
     
  5. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,092
    Bitesize samples could be as simple as several different scenes doing different things.

    Setting up the network manager to host and load the game scene.
    To get familiar with starting the network manager and getting from a menu screen to a game scene.

    Have a small uGUI / UI Toolkit setup where there is a float number and a button to randomize this number.
    You get to learn how to do a ServerRpc and use a NetworkVariable<float> to set a random value server side.
    side note: UI Toolkit setup is a bit different because it doesn't have a GameObject hierarchy unlike uGUI.
    side question: Can a NetworkVariable be on a Scriptable Object instead of a GameObject with a NetworkBehaviour component containing the NetworkVariable?


    You can expand on this example by making each player have their own random number and their own button to click.
    You get to learn how NetworkVariable ownership works. Players can only change their own number.

    Have a small uGUI / UI Toolkit setup simulating a chat window. Starting off with a input field to set your player name.
    Then have a window with a ScrollView / ListView and an input field for chat input.
    You get to learn how to do a ServerRpc with user input and a ClientRpc to update the client's ScrollView / ListView.

    You can expand on this example by announcing that a player joined / left the chat room.
    You get to learn how to disconnect as a client and to subscribe to the Client Connected / Disconnected callbacks. Though I don't know how this goes with player names. Setting them before connecting or after connecting, like a profile.
    Upon connecting you can't immediately instantiate a player instance without knowing their name. Or you'd wait until you get their name and then instantiate it.

    With all previous knowledge you can setup a lobby room with uGUI / UI Toolkit.
    Starting the network manager as host or as client depending whether you host or join. Going from the main menu to the lobby. Upon joining you take a slot and have your profile name displayed with a ready button you can click. Upon all being ready the Start becomes available, transitioning from Lobby to Game scene.

    You can expand on this example by having the player choose their character i.e. a cube, capsule or sphere.
    You learn how to set a reference to a prefab that should be used as model for the player and instantiate it upon entering the game scene.

    Then going from the Game Scene back to the lobby, people may change their character. Go for another round or disconnect.

    In the end it is about setting scenes up, transitioning between them, connecting / disconnecting, getting data from one scene to the other, synchronizing data, changing data based on player input / choices.

    Personally I use UI Toolkit, Scriptable Objects and Addressables. I'm mostly struggling with how to set references of prefabs per player. i.e. a character selection, a subset selection of tower prefabs. To set this reference server side and do a ServerRpc to instantiate that prefab with ownership for that player. But you can't reference that prefab directly in the ServerRpc method. Prefabs aren't value types whilst normally in single player you'd just reference the prefab (or AssetReference). I'd keep the list of towers in a Scriptable Object containing a List. With Netcode the workflow isn't entirely the same due to Server / Client communication.
     
    Last edited: Mar 30, 2022
    PutridEx likes this.
  6. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    660
    I've not used it for a while but I have a test project where I tested particular aspects of Netcode by running them at a click of a button. It got pretty messy over time but a more modular approach demonstrating different aspects like connect, disconnect, network callbacks, network variables, onChange calls etc with nicely separated code that's easy to dig into would aid understanding.

    While you're here there's a few issues I'd like to mention.

    The Hello World videos were made pre v1 so some information on them like parts of the NetworkManager are out of date.

    I've seen a few of the documentation pages have been updated under develop which leads having to check two places to find the latest version. The documentation could do with a pass putting the latest pages in the correct place and removing any remaining pre v1 references. The develop section doesn't seem to be serving much purpose at this point in time.

    Some bug fixes only work with Unity transport and you wouldn't necessarily know about them unless you know where to look. This may cause some confusion while UNet remains the default transport.

    It would be handy when there's a new preview release that it gets a mention in the Release Announcements thread.
     
  7. CreativeChris

    CreativeChris

    Unity Technologies

    Joined:
    Jun 7, 2010
    Posts:
    457
    Just a quick reply to say the NetworkVariables page is updated for 1.0.0.

    And thanks to @cerestorm @MaskedMouse for your thoughts on Samples. I'm planning a proper reply tomorrow.
     
    MaskedMouse likes this.
  8. CreativeChris

    CreativeChris

    Unity Technologies

    Joined:
    Jun 7, 2010
    Posts:
    457
    Our immediate priority is developing Boss Room further to consider it a production-ready sample vs early access, which is its current status. We know large parts of this sample are spaghetti-like and need refactoring and made more straightforward. However, we didn't want to abandon Boss Room - I want it to be a sample game that continues to live on, thrives, and helps us educate the community and dogfooding our features before our users do. I know samples Unity has created in the past have had a very short shelf life, and I don't want Boss Room to share a similar experience; it has been built for 1-year plus in the open through our GitHub repository.

    We haven't had too many gaps/cycles to focus on other materials yet, between dogfooding and writing a game for educational purposes.

    I want Boss Room to be in a state where we can be proud of how simple our code is to show users how RPCs can work, how you handle connection management, how to use NetworkRigidbody, an excellent example of NGOs scene management etc. Currently, it is spaghetti-like, it does need refactoring, and some aspects have too many classes for what should be simple things. I guess this is the fun we have had to endure while building this with experimental software :) - I hope to get there towards the end of this year, but no promises.

    The bite-size samples are built to show modularity, simpler code, and features in isolation - I believe there is a lot more we can do here. A direction we are pursuing today is what can we recycle from Boss Room and build small diorama style scenes with. Think the archer is shooting a projectile to hit an Imp with just a click of a mouse button (or tap on a mobile screen) - showing a small example of how to set this up with RPCs.

    Another question with bite-size samples is "do we create bite-size scenes within one bigger project file or is each scene its own project?" At what point would one bigger project then start to suffer from being overwhelming again?

    I really resonate with your ideas and examples and I can say these are things we have identified we want to build.
     
  9. CreativeChris

    CreativeChris

    Unity Technologies

    Joined:
    Jun 7, 2010
    Posts:
    457
    Thanks - I will check in with the docs team re: HelloWorld - regarding the use case for develop version - which should contain the latest and greatest documentation for upcoming releases, but I think some of that content was not backported to v1.0.0 which is the problem - please correct me if I am wrong.

    There is a plan to switch the default transport to UTP (don't hold me to when though). Considering the confusion - is it because you see in the release notes fixes for transport and because it wasn't made clear it was UTP only? I will see if there is anything we can change to avoid the confusion in the interim.
     
    Last edited: Mar 31, 2022
  10. cerestorm

    cerestorm

    Joined:
    Apr 16, 2020
    Posts:
    660
    That all sounds promising, I've barely looked at Boss Room as I prefer to see examples in isolation but it's good to know the code will be improved so it's easier to go through when I need it.

    In an ideal world when looking for information and examples I'd like a workflow approaching this:
    • Google search
    • Link to Netcode documentation
    • Description of functionality
    • Code examples, use cases
    • Link to practical example, where it can be found in a bitesize / Boss Room project
    • Link to video (and time) where the subject is being covered.
    I'm all for less effort on the user's part (ie me). :)

    I missed this part:
    I tend to only look at the release notes if a preview release breaks something, which isn't often. I mentioned it as I think major improvements or fixes should get a mention on the forums in case it's missed elsewhere. It does raise the point of are there use cases for staying with the UNet transport or is it recommended to switch over?
     
    Last edited: Mar 31, 2022
    CreativeChris likes this.
  11. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,092
    Having project samples around is certainly a good thing. It is not only for the purpose of educating others but also for validating the package itself. Can things be done easier? What can we do to improve? If you would scale up the boss room, what problems would you face? (looking at the NetworkManager's Networked Prefabs list :rolleyes: that list would probably explode).
    What are / were your biggest problems with the Boss Room project and how would you solve them?
    How do you keep things modular?
    Many questions can be asked as validation, improvement could be a result.

    As for the Boss Room project and its size, any developer that would enter a mid or late stage of a project would be overwhelmed by all existing code and how it all hangs together. You don't know what the thoughts were of the team and how it progressed over time. You have to dive in and get to know how it all works together. It could be an entire different workflow than your own. (Which in my case it is or a mix of it.)
    I didn't totally get where data was stored, changed or how/where it got synced together. I mean I used Rider to F12 my way through. Search for what accesses / changes certain fields had. Or just look in playmode what components were attached to the game objects. I would probably understand it eventually, but I would've had to spend a lot more time into it. Which I decided not to do and go for more bite sized samples to get a quicker understanding. I do occasionally have a peek at the Boss Room project though.

    It would most certainly help understanding the Boss Room project as a whole or to be able to learn how you can solve the same problem in your own project. So making bite-size samples from the boss room makes sense to do. A lot of it is already there.

    I'd be very much looking forward to more bite size samples and more explanation of how things work together.
     
    CreativeChris likes this.
  12. hoesterey

    hoesterey

    Joined:
    Mar 19, 2010
    Posts:
    659
    I'd actually like Unity to take on bigger projects. Boss room is a great example of the type of tech demo Unity is great at making. Unity always struggles more and more the bigger a project gets. Unity features would benefit greatly from being developed against a "real" project with whatever team size Unity is trying to optimize for. Currently Unity works best with tiny teams, though I don't think that is the intent. Maybe?
     
    ZYMA123 and CreativeChris like this.
  13. Fressbrett

    Fressbrett

    Joined:
    Apr 11, 2018
    Posts:
    97
    I get your point, although the bigger the project the more specialized the solutions and approaches get, and one might find themselves even more lost. As for an example/educational project I believe simplicity is the way to go. A few scenes, each illustrating some feature (one lobby scene, one in-game scene where players perform some actions, one scoreboard...).
     
  14. CreativeChris

    CreativeChris

    Unity Technologies

    Joined:
    Jun 7, 2010
    Posts:
    457
    We are hearing a rather balanced approach to learning, some users want a vertical slice game and others want a simplistic approach like our bite-size samples. I believe there is space for both, which is why we have both at the moment.

    We also have some ideas for other approaches as well, but more on that in the future.
     
  15. AnomalusUndrdog

    AnomalusUndrdog

    Joined:
    Jul 3, 2009
    Posts:
    1,553
    Honestly, even the bite-sized projects that I saw (Invaders, ClientDriven, 2DSpaceShooter) the ones mentioned in the documentation, were also equally obtuse. As someone completely new (or rather, last time I worked on multiplayer was on Unity 4.x), I didn't know where to start. Didn't know which piece of code would run first. Trying to read through the scripts, it was like, too many new concepts being introduced at the same time.

    The script naming was also different from each other, one had a "BootstrapManager", another had a "MenuControl", and one had a "NetworkManagerHud". Mind you, they all do more or less the same thing (after a lot of back-and-forth checking), which is to handle starting the server/client/host. So trying to "grok" each project was like starting again from scratch, because they all name things different.

    The HelloWorld and GoldenPath tutorials were the only ones useful (guess my main complaint was that they were under "Walk-Throughs" at the bottom of the Table of Contents, when I kept searching for something like "BasicTutorials" at the top or some sort of tutorials near the "Getting Started" section and couldn't see any). Ultimately I understood more from Youtube videos (Tarodev, Dilmer Valecillos) than the sample projects.
     
    CreativeChris likes this.
  16. CreativeChris

    CreativeChris

    Unity Technologies

    Joined:
    Jun 7, 2010
    Posts:
    457
    @AnomalusUndrdog thank you so much for your feedback. Yes, that lack of consistency between each Bite-size sample is an area we are looking to improve for the full release. We also want to improve our documentation for each bite-size sample which will do a much better job of guiding users through each sample. Appreciate your feedback, and we are by no means finished on all of our sample and educational content, a lot of improvements are still to come.
     
  17. slambingo_

    slambingo_

    Joined:
    Jun 8, 2022
    Posts:
    3
    I have the same issue and i can't find a way to reference an object that is spawned on the server. Any advise?
     
  18. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    440
    Talking about the example you mentioned, you just need to send the ID of the item in the list from the server to the client (or viceversa) and use it to retrieve the item from a list
     
  19. slambingo_

    slambingo_

    Joined:
    Jun 8, 2022
    Posts:
    3
    I know i can get the id of the object but there are no functions like GetGameObjectByID(id)
     
  20. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    440
    @slambingo_ What I meant is that you need to add an ID field (could be an uint) to your Item's class, and use it to identify the item when it is in a list/array that you store "offline" (I.E: in a ScriptableObject).

    So your item's class becomes something like:

    Code (CSharp):
    1. class Item : ScriptableObject
    2. {
    3.     public uint ID;
    4.     //other data
    5. }
    then you have a:

    Code (CSharp):
    1. class ItemsDatabase : ScriptableObject
    2. {
    3.     [SerializeField]
    4.     List<Item> items;
    5.  
    6.     public Item GetItemByID(uint ID)
    7.     {
    8.         for (int i = 0; i < items.length; i++)
    9.         {
    10.             if (items[i].ID = ID)
    11.             {
    12.                    return items[i];
    13.             }
    14.         }
    15.         return null;
    16.     }
    17. }
    And you use GetItemByID() to get the item when you need it. Is this clearer now?
     
  21. slambingo_

    slambingo_

    Joined:
    Jun 8, 2022
    Posts:
    3
  22. Fressbrett

    Fressbrett

    Joined:
    Apr 11, 2018
    Posts:
    97
    For a lot of items and in case all item IDs are unique (which they should be), you can also use a Dictionary instead of a List to reduce lookup times. This is because the lookup complexity of a Dictionary is O(1) and the lookup compexity of a List is O(n), which bascially means that the more items there are in a List the longer finding an item will take, while it will take the same amount of time for a Dictionary, no matter the amount of items in it.

    Code (CSharp):
    1. class ItemsDatabase : ScriptableObject
    2. {
    3.     public Dictionary<uint, Item> items;
    4.  
    5.     public Item GetItemByID(uint ID)
    6.     {
    7.         if(items.ContainsKey(ID))
    8.         {
    9.             return items[ID];
    10.         }
    11.         return null;
    12.     }
    13. }

    The only problem here is that by default, Unity isn't able to serialize your
    items
    Dictionary. However, there are Assets like Odin Inspector as well as custom attribute drawers that allow you to serialize Dictionaries in order to expose and edit them in the Inspector. You could also keep storing all Items in a List and generate a Dictionary for lookups once at the start of your application, that you could use for runtime lookups.
     
    Last edited: Mar 19, 2023
  23. ViktorMSc

    ViktorMSc

    Joined:
    May 28, 2022
    Posts:
    14
    I agree about the Boss Room example, it is useless to get started.

    The documentantion on Netcode and the Gaming Services is also need a complete re-write.

    Sometimes it's just a few paragraphs without any explaination on how to write the code.

    Other examples include way too much code and do not explain how to do simple things.

    One example, the documentation does not explain how to implement player names and sync them accross the network.

    Another example, a new developer needs to bang his head a lot of times before he accidentally stumbles across ClientNetworkTransform and ClientNetworkAnimator. Such basic things should be included inside Netcode when you install the package in my opinion.

    Third example, NetworkVariables. Why doesn't Unity start explaining how to do simple things like player health? You could combine the example with the "toggle open door" but that is not even explained either. How is ToggleServerRpc() used? Who calls it? How can I implement a health bar that way?

    I know the answers now, but imagine being new to Unity and reading this wall of text: https://docs-multiplayer.unity3d.com/netcode/current/basics/networkvariable/
     
    Last edited: May 21, 2023
  24. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    440
    Hey @ViktorMSc , thanks for the feedback. I've got something that might be interesting for you and whoever shares your point of view:
    There's an unreleased (but public) NGO sample on this branch. It's temporarily called APIDiorama and is supposed to provide what you're asking for: practical NGO examples for real-life situations, without the complexity of BossRoom, each in their own scene.

    its UI/polishing development is paused at the moment, but the sample is complete feature-side.

    Maybe you can give it a try and see if it provides better guidance?
     
    MaskedMouse and ViktorMSc like this.
  25. ViktorMSc

    ViktorMSc

    Joined:
    May 28, 2022
    Posts:
    14
    Sounds great and exactly like something that would solve these problems!

    I will give it a go, thanks for the feedack.
     
  26. RikuTheFuffs-U

    RikuTheFuffs-U

    Unity Technologies

    Joined:
    Feb 20, 2020
    Posts:
    440
    Thanks Viktor, much appreciated! We're also trying to udnerstand if this is a format people want, so if you have feedback to share we'll take good care of it <3
     
    ViktorMSc likes this.
  27. ViktorMSc

    ViktorMSc

    Joined:
    May 28, 2022
    Posts:
    14
    Just got time to have a look :) @RikuTheFuffs-U

    The BiteSize / ClientDrivenExample is exactly what I am talking about!

    Integrating it to the ThirdPersonController template is very clever.

    Great addition to the docs. Thanks and keep up the good work.
     
    CreativeChris likes this.