I'm working on a rather small project where we will be developing a small engine, a client, a server and an editor of some kind. It's a component-based 3D engine with basic systems like Rendering, Simple-Physics, etc.

So far, after a fair amount of thought I've decided to structure the engine as a library. It'll contain the classes for all of the components and the sub-systems, but will not run them. Instead it will be included into another project that will initialize the engine and run the game loop. I've started calling that second project the "host application."

I see the host application as the "game" or the "editor" with the engine kind of looking like a strap-on jetpack of goodies.

The reason for this (in my mind) is to allow the engine to be reusable, and so I can develop our editor, game, model viewer, etc. using the engine without having duplicate code every which way.

This is all working out well thus far, however when considering the typical client/server model for a multiplayer game a few questions come up.

In one respect I can treat the client and server as separate projects, both referring to the engine, in the other respect I could develop the client and server as one project with a bunch of switches and a command-line argument to denote which "mode" the game should be in.

Could one of you insightful awesome people shed some light on the pro's and con's of these methods, or perhaps suggest a better way?

Is there any potential for a final application that acts as both client and server? Often in multiplayer games, It's useful to do so. (E.g., one player is acting as both client/server, others are just clients, but if server disconnects, another player takes up the server role). If so, the "series of switches" may be worthwhile.
–
Cameron FredmanFeb 12 '13 at 2:41

1

gafferongames.com provides a sufficient amount of material on structuring multiplayer communications and physics synchronization. If you haven't read it end to end already, I'd highly recommend it before proceeding any further. Good luck, and I'm looking forward to the final product.
–
Shotgun NinjaFeb 12 '13 at 3:47

1 Answer
1

Ok I am taking a stab at the issue, because I am in exactly the same situation.

Engine vs. Libraries

This is one thing I often come across. Sure when you build a game you need an "engine". And many novice developer will look at the Quakes and Unreals and think that a engine is a monolithic piece of software that is multiple of millions lines of code. But these engines come from large companies and large companies tend to build large systems.

Over the years I have found that when I write a library that does exactly one task and knows nothing about an "engine" as the most useful. The reason is because the library can be used in any context. Years later I tend to reuse a library unaltered from a previous project, but any code that was in the Engine is basically impossible to extract.

It may be sensible to build libraries (or use third party libraries) that solve one task and then integrate them into an "engine". The engine is then only glue between the bits and serves to implement a consistent handling and the almighty run method.

Simulation vs. Presentation

It makes sense to think about simulation (i.e. game logic) and presentation (rendering, sound), before asking about client and server. The reason being, that the server needs only to handle simulation, but the client needs to handle simulation (for local prediction) and presentation. You don't want to have code for visual effects running on the server, just because you think the physics are only done on the server.

It makes sense to package the engine into a central library or multiple libraries and have the client and server link that, since they are going to share much code. But you want to keep is somewhat modular, so you do not need to install presentation bits on a dedicated server setup. (But you can get away with it though.)

My Design

Ok this is my current approach and it works quite well, but it is my approach and may not fit your needs.

The meat of my engine is implemented in libraries that are fully independent from the engine. I use some common libraries such as ODE for features that are fully realized by other people.

The engine is structured in the way that you have a central Engine class, but that does nothing meaningful. It is extended by Services, each service doing one special task, such as rendering or physics simulation. The systems are actually encapsulating a library. Entities, that are very specific to the actual game then use the systems to do anything non trivial. The important bit here is that, entities are expected to properly behave in the absence of a service. This enables one code stack to live in the server, client and editor.

The code is then separated in a base module that defines the basics, such as the Engine, Service and Entity base cases. Each service then lives in it's own module. The client and server then only load and link against the services they actually require.

I implemented the editor as a optional service in the client, that is loaded on demand when a specific command line argument is set. But this is a matter of taste and it clearly could be done as separate executable or the Engine class ditched completely and only the entities used directly.

Thank you Sean, great post. Seeing how similar the client | server and client | editor are, it's making me think that command-line flags are a good way to denote between client | dedicated-server | editor but that the server itself should be it's own class and be capable of running in a client.
–
Cody SmithFeb 12 '13 at 18:12