Unity I still don't think is ideal for Multiplayer FPS games...

What is the underlying purpose of multiplayer netcode? To update the position, rotation and state of all objects in the gameworld.

How many different ways can this be done? Does the sending and receiving of this information need to be native to Unity or is it possible to hand this off to say a custom written DLL? Is the authoritative source of this information the server, the client, or both? Is there a way to use flexible authoritative sourcing to address different networking situations and game object states?

“AAA” game developers know how to address these questions in any game - and there is always custom code that needs to written to address specific issue that the game engine doesn’t address. No matter how good an engine is perceived to be, there is only so much “out of the box” will do without customization. And either the game developer can address issues themselves, or they contact the engine developer to help address their issues, or they pay the engine developer to address their issue - or they take an issue that can’t be addressed out of the equation.

I’ve read in the forums where people have given up on dealing with certain multiplayer issues they are having with their game. Is it because Unity or their plug-in doesn’t “provide” for them - or is it because of their own limitation as a programmer? It’s really a personal decision based on how much of their own time and effort, or money [ buying a solution/expertise] they want to spend on the problem. Because if it’s possible to put a bunch of “smart people” in one room and figure out a solution to that person’s issue, then it’s not really about Unity.

Think about it.

one limitation i found in my limited experience with unity is that the game update() function cannot be set a fixed rate independent of the frame rate because by it is called before rendering a frame. I think this makes it very hard to implement any sort of client-side prediction and/or latency compensation.

  1. FixedUpdate.

  2. Workarounds are trivial.

Yes, we use it in our monster truck game. uLink fully supports it.

can you poll for user inputs in fixed update?

Of course, but that’s not what FixedUpdate is for.
Update() is for user input.

As i’m being right into netcoding a fighting game (which migh be the most unforgiving genre in term of lag management, as every milisecond counts), I can put my experience with unity here : nothing has been wrong so far.

  • I can connect two different OSes (been playing from my Mac against my Windows client)
  • Transfers are much faster than .NET udp
  • Network class is very reliable, I’ve yet to see a connection/disconnection not sent in time
  • as for lag predictability, it’s totally up to the coder to do that. Plus, it doesn’t need a fancy engine implementation imo, as it’s really no big deal to manage.
    Just create a coroutine WaitForSeconds(estimatedLag) each time you perform a local command that has to be sent on the network, so it’s synchronized. (this description is indeed vulgarized, in my case I’m sending the player command, and will not trigger it locally until I’ve received a distant validation. The distant player will not replicate that command locally until [estimatedLag] amount of time is elapsed.)

Anyway, every move I send is perfectly synchronized right now on both clients, I really don’t have any problem with Unity network features.

Also, the “feel”, whatever it is, is only up to the coder, not the engine. Plus it is imho a clear mistake to let the engine decide that feel, as it creates complete generic games (aka people saying “oh, one more Unreal Engine game … they all look/feel the same”).

p.s : I can’t see how any quite complex game netcode could not be homebrew. For optimization reasons, for starters. Or even for processing order management. For example, still in my case, I’ve put all the control processing right at the end of the visual update loop, so in case of lag, player won’t react on corrupted visual feedback. This custom cooking cannot be made with generic engine features.

As npsf wrote, FixedUpdate(). Even further : coroutines, so you can put on hold an update until “something” has finished.
Plus if I’m not mistaken, Update can be set as a coroutine. And anyway, without coroutines, it’s quite easy to just stop a FixedUpdate process if a condition is not met (like myCustomNetworkSync == false).

i see

ty for clarifying that, i have been wondering how it works for a while now.

the script reference for FixedUpdate() is kind of misleading

Is one option.

Between Timers, Threading, and Native Plugins you have a lot of control about how your networking and game logic works - and can relegate Unity to a glorified renderer if needed.

For our newest project, we chose Unity as engine. Not because it looks nice, or has lots of nice features other engines do not have. No, most other engines are actually 1000 times better than Unity.

We chose Unity because it is the perfect solution for multiplayer games. Together with Ulink and some self written code, you can achieve greater results than in any other engine. We are seriously thinking of a 500 player FPS game. Our first tests have proven that 350 players work perfectly fine, and we are still working on our netcode. No other engine could have offered playernumbers that are even close to that.

I apologize for the necro, but I would like to add two cents to the argument…
Source Engine is fantastic for FPS games. Why is this? Because it was forked from an FPS game, then modified for another FPS game, then iterated over many years for more and more FPS games. In short, everything about the Source Engine was DESIGNED for FPS games. That’s not to say it can’t do other games, but FPS are it’s specialty.
It’s also the same with UE, although a bit different. UE was designed originally to power Unreal Tournament, a Quake-style multiplayer FPS. While UE3 may have abstracted a lot of functionality to the point where you can really write any game, you can still clearly tell it was originally designed for a first person shooter.

Unity, on the other hand, was built from the ground up as a diverse game engine designed for any idea you could possibly think of, completely unlike these other two engines.
That being said, a great FPS is not impossible in Unity. There are plenty of articles on how Valve does their netcode, why would it be impossible to replicate that in Unity YOURSELF? It’s not impossible. It might take several FPS iterations to get to that perfect mix, but it’s not impossible. And this should be the responsibility of the developer, not Unity.

Valves net code is not really the best in the world though… It gives you some ideas but it certainly is not optimized for huge player counts.

Which, again, is yet more evidence that Source was designed primarily for FPS games - where typically you only see up to 32 players running around in the same game, MAYBE up to 64 but that’s pushing it.
Whereas Unity was designed to be flexible to do whatever the hell you want it to do. 1,000 player FPS? Sure, why not?

Yep, exactly. Could not agree more. :slight_smile:

http://forum.unity3d.com/threads/96339-FPS-Game-(WIP)-(-Weekly-Updates-)

nuff said.

Just a minor correction here; Unreal Engine was designed originally to power Unreal.

Ah, you’re right.

If you’re trying to do a good networked FPS in Unity (read: with proper rewind/replay networking that doesn’t melt your processor or framerate), the less of Unity’s time / physics / APIs / component / event model you rely on the better. The closer you get to Unity being a off beat metronome that knows how to raycast and draw the better off you’ll be.

I’m not sure I agree with some of those. I’m using plenty of Unity APIs just fine, and it’s actually turning out to be really easy.

If anybody’s curious, here’s my setup.

I have an EntityRewinder component. This component stores the transform’s position every frame up to a second. It has two functions: Rewind, and Restore. Rewind will store the entity’s position, and then rewind the entity to the given past timestamp. Restore does what it says on the tin: restores the stored position.
I then have each EntityRewinder register itself with a static List, and I have static versions of the two aforementioned functions that iterate over this list and call the corresponding function on the EntityRewinder. So basically I can call EntityRewinder.RewindAll and EntityRewinder.RestoreAll to perform entity rewinding on everything in the scene.

Now, I also have a HitscanManager. This manager has a networkView attached to it so that it can perform RPCs. From the client, when you want to shoot someone, it makes a call to HitscanManager to do a bullet raycast. The HitscanManager does an RPC on the server. The server performs the actual hitscan logic:

Find the difference between current network time and the timestamp of the message
Use the difference to rewind all entities
Perform the raycast (if it hits a player, send damage or whatever the raycast was for)
Restore all entities

And now I have entity rewinding. Easy as pie.
I would say it’s not about avoiding Unity’s API at all. It’s more being smart about using them.

That works if all you care about is rewinding for hitscan. I rewind actual projectiles, pawns, items, and potentially the entire game state and “replay” it forward tick by tick back to the current time, resulting in potentially different player / item positions / collisions / state, not just restore with modified health values. And this happens on both the (fully authoritative) server and clients to varying degrees.