Advantages of sharing code between client and server

Back to index

When a game client and server communicate they need to be able to talk to each other in a common language. This means both ends need to have common knowledge about the data that is transferred in-between. In general projects choose different back-end programming languages because some people prefer those languages over the ones that have to be used to develop the client project, or they may be accustomed to develop the server in certain languages instead of others. Here I will go through why I think it is better to have a shared codebase and compare the advantages and disadvantages of different approaches.

The worst: non-shared language architecture

When both your client and back-end needs to know about a game object, you need to define them in the both codebases. To achieve this you first define it either in the client or back-end, and then in the other. Essentially you have to write the object definition and behaviour twice. That means every time you need to change something, you need to change that twice. You also need to keep track of the modifications to achieve properly working code.

The advantages:

  • You can write the back-end in your favorite language
  • Straight-forward codebase. Not much boiler-plate or enterprise code. Some people prefer this "no-nonsense" approach

The disadvantages:

  • Your team needs to have expertise in both the client and back-end languages
  • You have to keep both codebases in sync manually with duplicated code
  • You need to make sure both ends know about the current protocol
  • You need to write duplicated tests for both ends
  • The "no-nonsense" approach does not scale well to larger projects

The better: non-shared language with defined protocol

To help with defining the common language the server and client talk to each other you can use tools like protobuf or OpenAPI/Swagger. These tools are designed to generate some code for you so you don't have to constantly keep updating both codebases by hand. Of course you might still need to update the behaviour, but that's not as much code duplication as the previous approach. This is generally the best approach if you don't develop the client or don't even know who does. But I'm talking here in the context of game development where you generally also develop the client in-house, so that's why while certainly it is a good one it's not the best method in my opinion.

The advantages:

  • You can write the back-end in your favorite language
  • You define the common data structures and protocol in one place

The disadvantages:

  • Your team needs to have expertise in both the client and back-end languages
  • You need to generate code every time the protocol or data changes
  • You still might need to write duplicate code to get the same behaviour to happen on both ends
  • You need to write duplicated tests for both ends

The best: shared language architecture

In my opinion the best way to handle this is to have the server and the client being written in the same language. This allows you to have a shared common codebase that defines the network protocol, data types and behaviour. This of course needs some special care to not include client-only or server-only code in the common library, but the result is that you don't have to write duplicated code. It is easier to maintain and understand and people who are able to write client code are as well able to write the behaviour for the server. This lessens the burden and need for programmers.

The advantages:

  • No code duplication required
  • The whole programming team knows how to work with majority of the codebase
  • Less server-specialized people required to write server code
  • No need for expertise in multiple programming languages
  • Writing behaviour tests is easier since no code is duplicated

The disadvantages:

  • You may not get to use your favorite language unless it happens to be the one in use by both the client and server
  • Some minor care is needed to not include client-only and server-only code in the common library. A CI server or git hooks can help to test this
Back to index