Unity Networking in version 4.x

Hi guys,
At UCT, we have just started our final year games capstone project. My team is planning on creating an asymmetric shooter which pits military drones against a small guerrilla force. Naturally this requires networking.

We are restricted to using Unity 4 in our projects. The tricky part is ensuring that the states on each machine retain consistency with one another, and this in a physically simulated environment.

I was wondering if anyone on the forums has had any experience with networking in Unity and could perhaps offer a bit of advice.

Thanks in advance.

Comments

  • Even with advise you're in for a tough challenge. But I suspect the person you might want to talk to is @tbulford who is writing Battle Arena Drones in Unity3D.
    Thanked by 1NickCuthbert
  • Hey @NickCuthbert

    State management in multiplayer can be achieved in several ways. Using Unities multiplayer tools the easiest would be to own that state on one machine and only act on the others.

    So to clarify. Each bot that is spawned is managed and controlled on the machine that originally decided that the bot is needed (could simply be the host machine, that is the machine that started the game). You can then send that bots animations movements to the client machines through the RPC calls. We handle this by adding a control script on the machine that hosts and an acting script that simply acts out the orders on the other machines. (I am assuming you know how to spawn objects across the network and do RPC calls).

    For projectiles this is too slow. So we generally spawn each projectile on all machines. The projetiles are not networked and we allow the projectile hit/damage to only be calculated on the machine that "owns" the target object. (There are a few nice ways to make sure the spawned projectile looks correct on each machine but still represents a high level of similarity to the originating machine. One example is to allow adjusting the spawn point to match the position on the spawning object but to target at a distance the same location.)

    One thing I really suggest is you get used to the idea that each machine will be playing a slightly different game. The worlds will not be 100% perfectly aligned. For a FPS multiplayer game its too disruptive to force the world view to all match. Its rather ideal to make sure all critical experiences happen everywhere and slight differences in where each play is are assumed too be insignificant to the game experience.

    I hope that helps, its a bit high level. Feel free to ask more specific questions.
    Thanked by 2NickCuthbert Tuism
  • edited
    Thanks @tbulford. This is great advice.

    At the moment we're still in pre-production, but as networking is so fundamental to the game, we'd like to ensure that we get this aspect architected right from the start. I'm sure that we'll have a rather a lot of questions once we begin. =)

    Your approach is quite interesting, it seems to be a hybrid of a master server and peer to peer. Would you recommend the use of a headless server? We have access to the pro version of 4, so we'd have the feature available.

    Also is there any Unity specific oddities you'd need to take into account?
  • You may want to consider a headless server. I think that really up to you on how you want to manage the game state. It may be easier to just let one machine create the game and the others play though. I would suggest the headless master server if you wanted to have some sort of persisted world.

    In Unity watch for serialization issues. We have had issues with serializing nulls (This was with uLink we had dropped the Unity multiplayer libraries by then, but I suspect the same issue may exist for both). Plan your games state management, such as player score colour name, who owns this list how is it distributed. How do you expect to create games objects when players spawn and so on. If players drop out what does the process of them coming back in and getting all the current game data look like, How do you make sure that list is complete and that any changes to it are processed in order.

    I am a huge fan on UML Process diagrams for planning the state of these things. I have seen comments that UML is dull not game like enough etc. But seriously I really on it to help visualize the timed events of things and plan recovery when any one point should fail.

    I should point out I am actually not a fan of the RPC method of communications, well perhaps to be more specific I don't like seeing 50-60 small RPC calls all over various games object. It makes refactoring your multiplayer system very hard. We are currently moving to a Command Pattern approach. Its easier to manage and you can discard commands when you receive newer ones before process the old etc. This might be overkill for your project though and require you learn too many new things. I would say though plan your RPC's carefully.

    One thing I do recommend is to experiment in an empty project before you decide on processes. Test your process model before implementing it in your game. It might sound like it will take longer, I assure you it will be quicker in the end.

    Your approach is quite interesting, it seems to be a hybrid of a master server and peer to peer. Would you recommend the use of a headless server? We have access to the pro version of 4, so we'd have the feature available.
    Unity Multiplayer forces the concept of a Master server on you. But as I understand it your peer-peer communications should be delivered directly to that peer. That's why online games with the Unity multiplayer library are a bad idea. It relies on NAT breakthrough on routers to reach each peer, NAT breakthrough is not really supported by most routers any more for security reasons.
  • edited
    I'd recommend against unities old networking engine, it's buggy as hell and poorly documented. I implemented it for broforce and it was a pretty terrible experience. For robustness and ease of use I'd recommend Photon. It's cloud based though, so it has some extra latency. I think it is possible to run a local server.

    [edit] It is probably fine if you just want to get something up and running quickly for a project.
    Thanked by 1NickCuthbert
  • edited
    Okay, so I pretty-much always do this, but it's time for me to pop up again and talk about networking from a game-logic perspective...

    It honestly doesn't matter what low-level networking stuff you use (provided it's responsive enough for your particular kind of game) if you don't understand the fundamental problems of networking. You need a solution for the timing problem. You need to know how to solve identification issues. And you need to make sure you have determinism locked down.

    Timing:
    You have to ensure that your games across multiple machines all have the same game time. For a turn-based game, this means broadcasting state transitions super-reliably (seriously, multiple broadcast and ack setups, trust me). In a real-time game, this means accurate timing solutions (do not trust frame times), lag estimation between machines and bi-directional heartbeat ticks to make sure that machines don't go out of sync if there are connection hiccups. Timing gates how all your messages get handled: If you're using dead-reckoning or computed movement, you need accurate timing to know when a movement started so that you can replicate it correctly; Every single ingame state change or message needs to be tagged with a time so that you can ignore delayed messages or detect lag-spikes early. Don't do anything that is going to be framerate dependent. Ever.

    Identification:
    This is all about making sure that messages and state changes don't get crossed or confused. Replicated message setups are pretty good at handling object-level identification (provided you're not doing strange things with controller objects that gate all your game logic, ew) but you need some sort of plan to handle what happens if object create messages are lost or if an important state change is ignored/discarded. Identify who messages are from, where they're going and what they're supposed to do. Never have side-effects from your networking - you'll cry for weeks if it's possible for messages impact the gamestate in small or order-dependent ways. A huge part of identification is being able to track who owns what in your game, where the authority for the gamestate of a particular object lies. One of the major reasons for robust identification is so that you can backtrack when and how something was created - if it turns out that you have to step back and undo an entire series of gamestates because something arrived out of order, you kinda need to know what to change and what not to...

    Determinism:
    So, once you've got those two things down, this is what you use them to give you: Determinism. This dictates the information that you need to send between connected machines. Send the bare minimum required to make sure that the same gamestate will always progress to the next, 100% predictable gamestate, given the same network messages. @tbulford has touched on this briefly by pointing out that effects aren't important things to broadcast, provided your main gamestates are deterministic already. As an example: Chess is deterministic given the progression of grid squares (identification) that a move starts on and ends on, odd or even moves dictate which player's move it is (timing) - if you had explosions when things were taken, you could just leave the game to simulate that on each machine without broadcasting the exact state of each explosion. A realtime game needs player input state information at the exact time it changes on a player's machine in order to at least replicate a basic gamestate. If you get more complex and decide that player damage is owned by player machines (like TF2 does), then damage done becomes part of the player input for the player dealing the damage (this is why you can die behind walls to laggy TF2 snipers). A great way to test the robustness of your determinism is to simply save network messages to disk and then play them back, see if the game progresses the exact same way... Things to look out for are state-impacting random numbers (never do this, always use broadcast random-lists or put all random calls on the server to maintain reliability) and - again - message side effects. State machines are your friend.

    You're going to need to know exactly what you want your game to be like before you can make it deterministic over a network. I strongly recommend you build a single-player prototype to understand your game-feel and movement options/controls and only once you've got that going should you start trying to do any networking at all. And be aware that you'll probably need to rewrite your game from scratch to integrate your networking properly, this is pretty standard, you'll have a really hard time if you try to shortcut this... Prepare for it! ;)

    P.S. Come to the meetup on wednesday! Use the community's knowledge on this stuff...
  • edited
    To add to the excellent post above, to make your state and lag management a lot easier, for server-client games it is to your serious benefit if you can engineer your game state to simulate in EITHER direction. That is, both forwards and backwards, interpolating or extrapolating (dead-reckoning) where necessary. This makes it much easier for clients to correct their game state when packets drop or latency is high, effectively rewinding their state to the newest authoritative known state and then resimulating from there based on what they know.

    And as a minor correction, this is actually what TF2 and other Source engine games do (damage is not owned by clients and is always confirmed by the server). It's just that both the server and the client are capable of rewinding their states to say that actually, that really laggy sniper killed you 300ms ago, BEFORE you moved around the corner. You just didn't know about it yet. Valve actually document, both at that link and elsewhere, a lot of their network multiplayer architecture, which is strongly based on the same systems used by Epic in Unreal Tournament 2k4 (but improved with better client prediction), which was also publically documented but I can't seem to find it anymore.
  • This appears to be similar to the old Unreal networking documentation that I learned from 10 years ago - https://udn.epicgames.com/Three/NetworkingOverview.html
  • edited
    Thanks mgsaers for the all the great resources. I've got some free time (for a given value of free), so I'll pull on the old blast goggles.

    All this talk about determinism reminds me of this excellent talk by Jonathan blow:
    http://www.gdcvault.com/play/1012210/The-Implementation-of-Rewind-in
  • I found this great talk the other night:
    Physics for Game Programmers Networking
    It was a talk made during this year's GDC and enumerates the various approaches quite nicely.
Sign In or Register to comment.