Architecture of an entire game.

Started by
26 comments, last by TiPiou 14 years, 1 month ago
Hi everyone. For ages, I've had aspirations to create games of many genres. Being myself a master-procrastinator, most of those projects didn't live past some drawings and writings over many lost-sheets-of-paper, sometimes a line of code or two, and from time to time some runnable engine test that was worth a screenie. Now, surprisingly, I've stuck to a single game-design idea for more than a week. In fact it has been nearly two years now that I've tried to polish this design (laugh it up, fuzzball !). Today, well... I'm craving to code. Before I run head-on into some concrete wall, however, I wanted to share some thoughts about the overall architecture of my software. I want the game to be a client-server (not MMO) RPG, code-named NeREIDS. The relationship I intend to have between my modules is something like this : I have the intention of using Qt for tools, String support, threading, signal handling, and networking, and D3D10 (or above) for rendering. Do you think this decomposition is too much split ? too coarse ? Do you think this organization is fine ? fubar ? Are the "operators" (shown in ellipses) between libs worth something ? should they be integrated directly into one of the libs ? This is my first attempt at this kind of design, please let me know :) - [Edit] for some rephrasing, I'm not so sure of my english. [Edited by - TiPiou on March 12, 2010 9:15:06 PM]

Follow NeREIDS development on my blog : fa-nacht.rmyzen.net/

Advertisement
if you've never made a game before I'd start off with just a non-networked game then move slowly into networking part of the game.
The design you laid out has very little do with a game. It all seems logic but it's very high level and broad. There's no way to tell whether you understand the details entirely. You'll just have to draft the whole thing up. It could be 100k lines of code before you see anything resembling what you've modeled here.

But the main point is, there's no game here. There's a box that says game mechanics but inside of that is a diagram far more complex than the one you have here. Not just specific game code but the mechanisms that you will use for making the game code. It's probably not going to work the first time, or the 3rd time. So you have to get those iterations out of the way before you can make progress.

Good luck :)

What i was going to post:
The thought of using signals and slots in a game makes me want to vomit.
You mentioned relations between modules but you actually don't define any relations, just a bunch of boxes that are far too general, don't say anything about what they can do, and have no real relation to each other (by the way, you probably want audio and physics in there somewhere, too). You should be way more specific than that if you don't want to end up with a tangled mess of spaghetti code. Some things you should think about:

You have no clear distinction between client and server application. I don't have experience with client-server games but if I were to do it I think I'd try to keep them more separate and define exactly what is client-only (graphics for instance), what is server-only, and what is shared.

You mention threading. Will the game be multithreaded? If so, how will it be multithreaded and how are you going to share data between threads? "Qt threading" is not an answer :)

What is the network protocol like? How are you going to handle security? What kind of updates are sent to the player? How is the client and server state kept in sync? Whose state is authoritative?

You mention SQL. What are you going to store in the database? What is the schema like? Will you use object-relational mapping? How are you going to sync the database and the in-game object model?

For each of those boxes, you want to think in detail about what it can do and how it interacts with the other boxes (it might be a good idea to sketch out the interfaces in pseudocode at least). Ask yourself questions like the ones above, and try to come up with very detailed answers.

I second the idea, that you should make a simple game without that kind of design first.
No matter how nice architecture-diagram you make, you will be just stunned, when it comes to implementation and coding.
Because of the diagram, you will tend implement those boxes/modules, so there is too much stuff to to before you can even see the program run. That's impossible to debug, I think it requires experience to develop an architecture from a simpler one. My point is, that I don't think that a(n inexperienced) programmer can build the final architecture for the first time in the life-cycle of the project, but has to "grow" the architecture somehow (but that's just a large IMHO, I'm not a programmer).

As the above post mentions, there are fundamental things you miss, because you haven't made a real game yet. And I also suggest you to finish your first game.
Hey, nice stream of replies when I wake up :) Thank you !

Though I have to say, I'm a bit "surprised" by those 4 first answers...

When the day comes that I'm showing an inheritance diagram between classes, I hope nobody replies "yea, fine, but you didn't show the implementation". Sure, but that was not the point of the diagram, was it ?

Now, I acknowledge the fact that from this diagram, I'm a very long way to a working release. Or even to a working black screen. And that it's too much work for a single programmer, and so on... But is this really what's making this diagram wrong ?

Quote:Original post by ARC inc
if you've never made a game before [...]

Despite being good at not finishing what I start when it comes to personal projects, I've made a living of programming and I have a degree of software engineering. Though I haven't had decades of experience, I've been employed as a programmer for some years, and even a couple of those in the game industry.

Quote:Original post by bzroom
The thought of using signals and slots in a game makes me want to vomit.

This is a reply I consider right on topic, even if I wouldn't have worded it that way ;) could you please give details as to why signals and slots are wrong ?

Quote:Original post by lightbringer
You mentioned relations between modules but you actually don't define any relations, just a bunch of boxes that are far too general, don't say anything about what they can do, and have no real relation to each other (by the way, you probably want audio and physics in there somewhere, too)

Right I didn't show any arrows, thought they would just mess up with the visibility. The "relations" are a top to bottom dependency. Physics is mentioned inside the NEntities lib. Audio would certainly be something to add, to a level similar to NGraphics lib.

Quote:Original post by lightbringer
You have no clear distinction between client and server application. I don't have experience with client-server games but if I were to do it I think I'd try to keep them more separate and define exactly what is client-only (graphics for instance), what is server-only, and what is shared

I suppose my lack of arrows deserved that answer, well the libraries on the left, under the client application box (NUserIntf, NGraphics), are used exclusively by the client side . Those on the right, under the server application box (NALife, NStorage), exclusively by the server side. Those on the middle (NMechanics, NEntities) and at the bottom (NCore, QtCore), by both. Those on the outside (D3D, QtNetwork...) are only visible to the lib they are linked to.

Quote:Original post by lightbringer
Will [...] How [...] What [...]

Those are implementation considerations, some of them I have thought about and are quite clear in my mind already (network, client/server sync & updates...) some I left aside (threading, database...). Are those really needed in that kind of diagram ?

I mean come on guys, when you cliqued on the post named "architecture", were you really expecting to see pseudocode ?


Well I hope I don't sound rude, thanks again to all who took the time to reply ;)

[Edited by - TiPiou on March 13, 2010 4:22:41 AM]

Follow NeREIDS development on my blog : fa-nacht.rmyzen.net/

Quote:Original post by TiPiou
When the day comes that I'm showing an inheritance diagram between classes, I hope nobody replies "yea, fine, but you didn't show the implementation". Sure, but that was not the point of the diagram, was it ?

Sure, but the diagram you posted is too general for any meaningful discussion IMHO. If you take out "NeREIDS", the letter "N", and "Qt", and add a bunch of stuff like audio, you could probably describe (very roughly) any multiplayer game with it. It doesn't say anything about your game in particular. In short, it's too high-level to talk about it. A class diagram is part of the architecture (on a lower level than the one you have right now) and is definitely something we could comment on.

For instance, we can all agree that almost every web application wiil have a service layer, a control layer, a presentation layer, and a database. You could draw those four as boxes above each other, and that would be correct in representing the architecture of a web application, but it's not particularly useful by itself.

Quote:Original post by TiPiou
Right I didn't show any arrows, thought they would just mess up with the visibility. The "relations" are a top to bottom dependency. Physics is mentioned inside the NEntities lib. Audio would certainly be something to add, to a level similar to NGraphics lib.

I was thinking more about the actual relations between the boxes - interfaces and coupling. It's a more lower level consideration but it is perhaps even more important than the higher level one.

Quote:Original post by TiPiou
Those are implementation considerations, some of them I have thought about and are quite clear in my mind already (network, client/server sync & updates...) some I left aside (threading, database...). Are those really needed in that kind of diagram ?

Some/many of those are fundamental architecture decisions. Especially threading. You have to plan for threading from day one if you are going to use it. What you want in the diagram is up to you, but presumably you wanted to make a diagram that says something useful about your game, and currently I don't think that's the case.

You also have some question marks in important parts of your diagram, which makes me think that you haven't thought things through. So I tried to come up with questions that would help you work out the architecture on a more fine-grained level, that is, the stuff inside and between those boxes. And partially the implementation, too. That doesn't mean that you have to cram it all into the diagram.

A high level diagram like this one has its place, to get a bird's eye view, and it makes for great presentation slides at executive meetings, but it's not enough to describe the architecture of your game. Currently you would probably get more mileage out of flowcharts for various use cases as well as class diagrams. Various UML diagrams are always an option, too.

Quote:Original post by TiPiou
I mean come on guys, when you cliqued on the post named "architecture", were you really expecting to see pseudocode ?

Take the advice that seems good to you and ignore the advice that doesn't seem good. I don't make quality guarantees about my advice, ether :). You did say that you've been at it for two years (not full-time, I presume). So it's not unexpected that we would think that you have something more concrete to talk about.

There is also something to be said for the iterative approach advocated by the posters above. You aren't gonna come up with a nice and clean architecture on your first try without actually getting your feet dirty in the code, so you might as well adapt a more agile development method.

[Edited by - lightbringer on March 13, 2010 7:56:01 AM]
Quote:Original post by lightbringer
Sure, but the diagram you posted is too general for any meaningful discussion IMHO. If you take out "NeREIDS", the letter "N", and "Qt", and add a bunch of stuff like audio, you could probably describe (very roughly) any multiplayer game with it.

OK that sounds right, you scored a point there.
To tell the truth, I've been thinking about this (too?) "high-level" organization only recently. I guess I could have asked "Is it truly a good thing to have each of those parts in a separate lib ?", I didn't mean "Do I need to have a render engine and some network protocols ?".

Until now, what inked all those sheets of papers I mentioned earlier were exactly solutions for very specific problems (game mechanics, rendering algorithms, editing interface, and so on). I simply wanted to take a step back and ask "OK, let's have a look at the bigger picture now, shall we ?". Thinking about how parts will be in relation together, how will I ensure that Server and Client side share common code and do not diverge, that kind of stuff.

Quote:Original post by lightbringer
For instance, we can all agree that almost every web application wiil have a service layer, a control layer, a presentation layer, and a database. You could draw those four as boxes above each other, and that would be correct in representing the architecture of a web application, but it's not particularly useful by itself.

That's assuming you were not shocked by the boxes themselves in the first place ;) (which is still good to know :p).

Quote:Original post by lightbringer
Some/many of those are fundamental architecture decisions. Especially threading. You have to plan for threading from day one if you are going to use it. What you want in the diagram is up to you, but presumably you wanted to make a diagram that says something useful about your game, and currently I don't think that's the case.

OK then, I come back when every part has full detail ;) But I had to make sure those parts were not silly.

Again, thanks for the answer

Follow NeREIDS development on my blog : fa-nacht.rmyzen.net/

Quote:Original post by TiPiou
I guess I could have asked "Is it truly a good thing to have each of those parts in a separate lib ?", I didn't mean "Do I need to have a render engine and some network protocols ?".

Perhaps not along exactly the same lines, but generally you do want to keep things separate and modular of course. This goes part of the way to promoting loose coupling. You also want to define strict rules about which modules any given module is allowed to talk to. You already have part of that formalized in the whole "top-down" approach, but it's more complicated than that.

If by "separate lib" you mean "separate DLL" then this would likely be unnecessary. Someone with experience with DLLs might provide a better answer.

You mentioned physics are part of the entity module. I would separate the entity code from the physics code. Especially because physics will generally be an external library that you will feed your game state into. You also don't have any resource management in place for loading and storing textures, models, wave files, and such - these things are usually entirely separate from the entity management.

Other than that I would just get started on a prototype - you'll quickly discover whether your design worked or not, especially that "game mechanics" box which is a bit of a mystery.

The diagram is nothing but a lot of boxes, each of which says "magic happens here".

Let's start at the beginning. Game simulation loop, and one of easiest to network is this:
while (running) {  readNetwork();  updateState();  if (isClient()) render();  sendNetwork();}


Qt however is event driven, which is the exact opposite of this design. So how exactly will those two interact?

The problems will start instantly, with when to update the GUI, how to handle accurate interpolation, how to trigger events fast enough so rendering isn't jerky, and so on....

How do you enforce rules? Where do they live? If a rule is enforced on server, how is it propagated across clients? How will clients roll-back the state, or correct invalid state.

NEntities - is cool, but how do you manage the distributed state? What does client have? Handles? Remote objects? Proxies? Shadow copies?

Where does the AI live? On server? On client? The diagram doesn't even show the distinction between server and client. Is it CORBA-based with fully shared state? What does the server look like? Is it a single machine? Is it a cluster? P2P?


The simplest diagram for this would be something like this:
+--------+ has +----------------+              +------------+         +----------+ | client |=====| object proxy 1 |              | simulation | updates | objects  |+--------+     +----------------+  { network } | server     |=========~~~~~~~~~~~~               | object proxy 2 |   async RPC  | loop       |   using                       .....                        +------------+=========+-----------+                                                                      | AI system |               +----------------+                                     +-----------+               | renderer for   |                                     | collision |               | object proxies |                                     +-----------+               +----------------+                                     | database  |               | physics and    |                                     +-----------+               | animation      |               | interpolation  |               | (past n states)|               +----------------+


Of course, any of the systems might or might not be needed, or would need to be different.

But at least now you can start structuring the design around the actual client/server architecture, since it gives at least a rough understanding of which part does what.

The libraries are not even remotely important at this point, especially since in case of C/S architecture the first thing you need to do is split them into shared, client and server portions. Unless the design is P2P, in which case the update mechanisms are more complicated, and responsibilities shared differently.

This topic is closed to new replies.

Advertisement