Separate Unity projects for client and server?

Hello, I am developing a multiplayer game. I started developing the game before Unity started supporting multiplayer again so I have my own custom solution where the servers are just .NET console applications. The server app and the client app have a lot of shared code which I build to a shared .dll
I am running into an issue where I want to access some of these shared classes from a Unity C# job but I would need to use NativeContainers which would not work in a .NET application.

So I have a couple questions for anyone that’s made multiplayer games with dedicated server applications:
Do you have a separate unity project for the client and the server? Also how much of a pain is this? One unity project practically takes up all my PC’s memory I can’t imagine what it would be like to run two.
What do to share code between the projects and make sure that when you make changes to the shared code it’s immediately reflected in both projects?
if not, do you have both the server running from the same project? How does that work for you?

You can also consider for your jobs to either use a set of native collections that can be used by both .NET and Unity jobs or to just use managed objects in your job (you just need to be careful since you don’t get safety checks)
https://github.com/fholm/UnsafeCollections

1 Like

This question comes up a lot, respectively the intention to do so.

It is doable, yes. But the pain required to implement this and the pains of the resulting workflow make it a path you should only go along with if you ABSOLUTELY have to. Especially if you use Netcode for GameObjects and not just the Unity Transport, because keeping both project’s assets (specifically: networked prefabs) in sync is both essential and error prone.

What are the benefits of separating server and client projects?
Very little. Typically people look into separating projects out of these two concerns:

  • clients should not have server code
  • server should not have client assets

But: Both are achievable in a single project!

By properly separating concerns (here: client, server, and shared code) via Assembly Definition files you can “strip” the client build from server code. You can also quite simply #if SERVER any code that shouldn’t be in the client.

And then Unity has a “Dedicated Server” target platform which ensures that the server isn’t bloated with all the client’s assets. Have never used it so I’m not sure what is required to make it work, but it’s the option I would explore first and foremost.

If you keep everything in a single project, then you only need a single source control repository and you can work with Parrel Sync or Multiplay (host/join via multiple editor instances) to speed up testing and debugging issues.

What are the pains of having separate server and client projects?

  • You will typically have two instances of the editor open at all times.
  • You will spend more time on project maintenance, most importantly time spent making builds and testing.
  • You need to keep both project’s assets and scripts synchronized. Since they are separate projects, that requires a more elaborate source control setup with a third project that contains shared code and assets (possibly as a package).
  • It is not possibly to allow clients to host games if you separate server and client projects, because clients would need the server code in its exectuable to be able to host a game.
  • … probably a lot more. I’m sure others have more insight. :wink:

If you don’t have at least 16 GB of memory you will seriously need to upgrade one way or another if you want to develop multiplayer games. You WILL have to run at least two editors, or at least I wouldn’t want to work without it and while networking, I used to have 2+ editors open most of the time.

You cannot expect to be able to debug multiplayer issues with just an editor and a build all the time, let alone the time it takes to make a build for every test session. You HAVE to be able to use ParrelSync which will run additional read-only copies of the editor and project. This speeds up testing tremendously! Imagine you can basically hit playmode and test right away and inspect the game state on all clients because they’re all editor instances vs having to make a build instead and launch it multiple times and not being able to see what each client’s state is.

4 Likes