question

rob avatar image
rob asked

Unity server

Soooo running a Unity instance on the server is not a good idea. This whole time I've been developing a game wanting to run Unity on the server and worrying that maybe it wasn't a good idea, maybe it wouldn't be possible due to performance issues. And now I've finally tested it and it's worse than I ever imagined. Even a barebones Unity project running in -batchmode -nographics eats up 30MB of memory. That seems like a lot. The default t2.medium server barely managed to run 2 or 3 instances of my game before it became impossible to launch new instances.

So what should I do? Is anyone using TNet with PlayFab? That looks like it might be more appropriate. Photon doesn't seem like an option - no custom server code in the cloud hosted option and the standalone server licenses are expensive considering I don't want to use most of their features. I just want a simple lightweight messaging service where I can customise the server. DarkRift seems like another good option but the developer is currently working on DarkRift2 so there's no point using the old one and the new one isn't ready yet.

I would love to hear what anyone else is using for their server builds (with Unity clients)!

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Joshua Strunk avatar image
Joshua Strunk answered

Maybe this could turn into a centralized discussion on dedicated server setups for Unity projects? Mainly because this is a massive subject and decent answers are really case specific.

First off if your game uses even a single thing in UnityEngine for its logic you either have to reimplement it without UnityEngine or run a Unity exe on the server and I mean anything. Physics is the huge elephant in the room in regards to this. This means you are only using Unity for rendering, resource management, and input management.

Lowest Level sockets:

HTTP : Not actually a socket basically web requests has no push ability from the server. Rest API

TCP : Turnbased - can be fairly simple

UDP : Realtime or Mobile - complicated will need a library to work with it.

Websocket : Basically the only option for web builds really simple and similar performance as TCP

Libraries/Frameworks:

DarkRift: (I know nothing about this)Being phased out for DarkRift2 ?

Forge Networking Remastered (FNR) : Abandoned and recently open-sourced networking solution.

Lidgren : Old school c# library for handling basics of UDP socket networking. no longer maintained?

LiteNetLib: A newer more focused (less tested) reimagining of Lidgren with a sharp focus on the Unity platform.

RakNet : A granddaddy battle-tested C++ networking library which can be wrapped for use in Unity. It has now however been abandoned. (Rust which is written in Unity uses this ( source))

Unet: The built in Unity solution requires running a Unity build on the server. Playfab provides an example project here.

Services

Nakama: Immature Open-source(written in Go with Lua scripting) real-time BaaS with very similar lobby/matchmaking capabilities to Photon with the added bonus you can control the code running on your server.

Photon: Major networking service offering primarily a slick API, matchmaking, and relay server lobby management.

There is also tons of room to get crazy. For example the title I am currently working on (Unity) uses a NodeJS matchmaking server. The matchmaking server uses WS to communicate with our clients while our clients use the transport layer from the Nakama Unity client. They both are just wrappers around low level websockets and the logic is completely different on server and client so no need to share the code.

I am just getting started on this but fleshing this out will take time if anyone has additions/edits/ etc I highly encourage for you to comment.

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

dragonfoundry avatar image
dragonfoundry answered

I'll lay out what we're doing here. We're a real time CCG, so somewhere between turn based and real time (not many messages going back and forth, 1/s/player or less). All our gameplay logic is on the server; the client is effectively a display terminal (though it does do some prediction, so players don't always have to wait for a server response before seeing the results).

Language: Server is C#, just like our Unity project. This lets us reuse code pieces easily; it also means less switching context during development (we don't share any game code, but we do share the messaging/sockets code, and we have moved code pieces between client and server in the past). Game data is zipped json; player data is human-readable json in PlayFab.

Sockets: We use TCP connections for everything. Adding a reliable UDP connection for gameplay is on our long-term to do list. We're running on a home-grown scalable tcp sockets implementation. There was about 2 weeks of implementation work here getting things working perfectly, making message queues scale, making performance good enough. If I were recommending something now, I'd recommend implementing using WebSockets if you can (or just reliable UDP if you're running on PlayFab's server hosting).

Messages: We're using Protobuf for all client-server messages (and all server-server messages too). Protobuf is awesome, but be careful when using it on iOS/Android, as you have to precompile, and that can make changes a little more tricky (it handles versioning very well, though). I'd still recommend protobuf, but the big thing I've learned is to not make it do everything. For example, our keyword abilities and subtypes each have a lookup dictionary in our data files, so we can add a new one without having to recompile the protobuf.

Servers: There's a lot of startup & memory costs with starting a server executable. For us, loading & parsing all the data and booting up etc is approx 100x more CPU expensive than running a single game, and the memory usage is ~30x more memory for the base data & executable running than what's required for each incremental game. So our server is designed to run multiple games on a single instance. This means it doesn't work nicely with PlayFab's custom servers, so we're hosting ourselves (still on AWS). I could go into a giant post just on hosting and devops for this stuff...

Architecture: We've got edge servers (client connections, client data, PlayFab calls), a single matchmaker server (player list and matchmaking), and game servers (just handle gameplay, no external communication). It's all auto-scaling on AWS. This is a LOT of work to put together; if you don't have our efficiency concerns, and can use PlayFab's server system, I'd highly recommend it. One big advantage - we have persistent client-server connections, so we can cache player data, and that's a huge performance boost over Cloudscript.

Automation: We're not as automated as I'd like, but we're better than I've had on other projects. Logging errors/info to Loggly or similar is vital; having some kind of tool that can review the status of running servers is vital (we have a simple html-based admin page that lets us review what's going on and do some simple actions); having a push-button system for putting up a new server stack is vital*10. We use CloudFormation to automate the AWS stack creation, PowerShell to push server builds and automate startup tasks, and a custom tool to pull game data from Google Sheets and package it up for clients and servers. It's a lot of work to set up, but means we don't make as many mistakes.

Photon: We use Photon for chat, and that's about it. We do overload the chat messages for a few special functions, such as player-to-player challenges (though if I were doing it again, I'd run all that through the server messages)

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

rob avatar image
rob answered

Thank you both for these extremely detailed posts, I'll spend some time looking through these options (and some others like TNet, uLink? SmartFoxServer?)

Ideally I want to write in C# so that I can reuse existing code.

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.