Search Unity

Woo-hoo - Simplifying the server gives me 900 FPS :-)

Discussion in 'Multiplayer' started by jashan, Feb 17, 2008.

  1. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    Hi there,

    hm... someone suggested to remove all unnecessary stuff from the server. That was a very cool idea ;-)

    I had disabled all cameras on the server, so the minimum FPS I got when "going really crazy" (switching on the smoke and shooting as fast as I could hit the X-key in TRaceON) was 115 FPS (average in normal gameplay is about 900 FPS). Notably, on my Mac Pro with the game running on the same machine as the server (I didn't really have time to test this in a cleaner setting with separate machines right now). When I have the cameras switched on, on the server, I'm getting it down to 30 FPS. Here, average in "normal game play" is 300 FPS.

    So, today after being a bit frustrated with creating a rock-solid "seems-like-lag-free" networking even with 0.3 or 0.4s lag (by having both client and server in the editor both with networking emulation set to dial-up) - I'm not finished with that, yet - I decided to write a little magic script:

    The call to DisableMe() from the Update is just to be super-safe and should actually never be called... but you never know... and if it's called, it's only called once ;-)

    I attached this script to each and every game object that's not relevant for the gameplay-logic. I only needed to "refactor" one prefab, because I made the mistake of putting colliders and scripts on the same game object on which I also had the particles (don't do that, when you're planning to do networking ;-) ).

    Well, that was all done in one quick hour... And now guess what: No matter how hard I try, I can't get the FPS below 950, no matter what I try (and the game goes down to 15 FPS in these "harsh conditions").

    Now, when I use this optimization, even when I leave the camera switched on on the server (which is quite useful for testing), I'm still struggling to get the server FPS below 700...

    Feel free to use this "little trick" - it might save you some headaches... All you need is some "NetworkManager" script that you attach to some game object in your first scene and that you use with the "Unity singleton pattern" (DontDestroyOnLoad but do destroy when multiple instances are created)...

    The numbers above were with server and one client on the same machine. I just did another test with 4 clients + 1 server on my Mac Pro. The worst FPS I get on the server is still 300 FPS. I think that's really nice... Can't wait to test this on the "real server" with 20 players (I still need to find 20 players, though ;-) )

    Ahhhh - now all the frustration is gone ;-)

    Sunny regards,
    Jashan
     
  2. WarpZone

    WarpZone

    Joined:
    Oct 29, 2007
    Posts:
    326
    Interesting.

    What are the implications? Does this mean we could leave an instance of our Unity executable running on a server for days at a time with lots of players joining and leaving constantly, and performance would be better than if we didn't use this script?
     
  3. jashan

    jashan

    Joined:
    Mar 9, 2007
    Posts:
    3,307
    Well, that totally depends on your whole setup. In the game I'm using this for, there's some objects required for the game logic, and other objects that are basically just "eye-candy". This is probably true for almost all games. On the server the "eye-candy" is what wastes a lot of processing power, especially when it involves a lot of particles (and it's a true waste because no one ever sees that).

    You'd generally want to switch off the cameras on a server (actually, you'd want a headless server running as a system service, but you can't have that with Unity, yet, at least on Windows - and I would not put a Mac server out on the Internet because it's a ridiculously easy target for hackers). However, the objects (that no on ever sees) still are moved around, consume memory etc. etc.

    By correctly configuring and attaching this script to every game object that just does "eye-candy", you may get significant performance improvements which supports hosting more players on a single game-server executable instance. Once everything is set up, it's just a matter of going through your hierarchy (in every level), and saying "you live on the server, you sleep on the server".

    Of course, the server also has to be designed to take many players. If the server is just designed like the client (more or less in a peer-to-peer-type fashion), this script probably doesn't make too much sense, unless you want to run multiple server instances on one server machine (which may have funny effects, I haven't tried this - but running multiple game instances on my local machine here works smooth, so it probably works smoothly). I'm not sure why one would want to do that with a game that's designed for peer-to-peer networking (it's not really peer-to-peer, but almost ;-) ), though... There probably are situations where you would want to do that, but I haven't spent time thinking about those...

    In my case, the idea is in fact, having one game server executable instance running permanently on a dedicated server machine, and having all players use that specific server. So, I *have* to make sure I don't waste *any* cycles, because the more performance I waste in my server game executable, the fewer players can play on one server machine, the more server machines I need, the more money I have to spend per player. One costing me between EUR 50,00 and EUR 200,00 per month, depending on the hosting provider. If I can only host 30 players per server, that's severe. If I manage to host 1000 or more players per server (simultanuously), that's not even worth mentioning ;-)

    So that means: Bad performance on the server = waste of my money. There's another reason for that: If I can take 1000 players on a single machine, that means I only need to implement load-balancing stuff into my system when the game is a success and there's more than 1000 players playing simultanuously. I've designed it in a way that load-balancing should not be too hard to implement once I need it, but I'm sparing that for the second version after the initial release. So that saves some of my time, too (which is much more expansive than dedicated servers) ;-)

    You can still enhance this script by optionally destroying the game objects it is attached to. This way, you would also reduce the memory consumed by your game server instance. That, however, requires that you do not access the objects at all from any scripts (which is the case only with very few objects in my case, but it might be different for you). Otherwise, you'll get a lot of unpleasant exceptions which will degrade the performance and make the logs really big ;-)

    As always (and especially with network multiplayer), you have to understand what you're doing ;-) but when you do, this can be a nice performance increaser and design- and implementation-time saver ;-)

    Sunny regards,
    Jashan