Sign in to follow this  
TiPiou

Architecture of an entire game.

Recommended Posts

TiPiou    192
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]

Share this post


Link to post
Share on other sites
bzroom    647
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.

Share this post


Link to post
Share on other sites
lightbringer    1070
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.

Share this post


Link to post
Share on other sites
szecs    2990
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.

Share this post


Link to post
Share on other sites
TiPiou    192
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]

Share this post


Link to post
Share on other sites
lightbringer    1070
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]

Share this post


Link to post
Share on other sites
TiPiou    192
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

Share this post


Link to post
Share on other sites
lightbringer    1070
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.

Share this post


Link to post
Share on other sites
Antheus    2409
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.

Share this post


Link to post
Share on other sites
TiPiou    192
Hi again ^^

Well, although that was not my intent at first, everyone here seems to need a totally different view of the architecture so here it is.



Environment computing is kept in a separate thread because my map data (which is being stored on the server and sent over the network) is meant to be quite small as compared to the resulting meshes, using a form of "editable procedural-generation" in between :p

Feel free to ask for some more details on specific parts if you need them.

Quote:
Original post by Antheus
Where does the AI live? On server? On client? The diagram doesn't even show the distinction between server and client.

Please have a look at the messages lightbringer and I had about it :
[quoting myself :] "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."

Thanks for the detailed answer :)

Share this post


Link to post
Share on other sites
lightbringer    1070
That looks more like what I imagine when the word architecture is invoked. Some comments / things to think about:

My gut feeling (not based on experience) is that you have far too many threads. With this many, I imagine that synchronization will be excruciatingly complicated. Especially the entity clusters - do they really need a separate thread each?

Game mechanics / physics in client loop - are you going to be using that for prediction? Are correction messages included as part of entities update?

Is user input validation taking place somewhere?

What about entities that are not in proximity of players? Are those not updated at all? That could be problematic.

To some extent your design reminds me somewhat of Dungeon Siege - there are a couple of papers and presentations out there about it that you should read if you haven't already.

Share this post


Link to post
Share on other sites
TiPiou    192
Quote:
Original post by lightbringer
My gut feeling (not based on experience) is that you have far too many threads. With this many, I imagine that synchronization will be excruciatingly complicated. Especially the entity clusters - do they really need a separate thread each?

IMHO I'm well below a problematic thread number with this, but this needs to be tested. About the entity clusters, well, that's the way I would think of it as the most efficient when the server is running on a multi-core processor, but ofc it would be a whole lot simpler without any cluster management. Let's pretend that after some tests I could decide whether to keep this idea or to switch the whole simulation code inside the main loop.

Quote:
Original post by lightbringer
Game mechanics / physics in client loop - are you going to be using that for prediction?

I intend to have some prediction mechanism so basically yes that's a reason they're here, although I fear prediction code on the client side is not very "secure" in terms of client hacking. But hey I'm not even thinking about going commercial here so let's put this out of my mind.
Another reason to have game mechanics here is that a genuine client will perform a first check of whether a player action is allowed or not.

Quote:
Original post by lightbringer
Are correction messages included as part of entities update?

indeed

Quote:
Original post by lightbringer
To some extent your design reminds me somewhat of Dungeon Siege - there are a couple of papers and presentations out there about it that you should read if you haven't already.

Thanks for the tip, I'll have a look :)

Share this post


Link to post
Share on other sites
_the_phantom_    11250
Quote:
Original post by TiPiou
IMHO I'm well below a problematic thread number with this, but this needs to be tested.


You are also well below scalability; your client would be using 4 threads on my system, two of them probably pretty idle in the grand scheme of things. So over half the computing resources of my machine are laying idle. (for the record I have an i7 920, which has 4 cores and 8 threads, Intel have just released a 6 core/12 thread cpu which makes your resource usage even worse)/

Hardcoding things against threads just isn't a good way to go these days, certainly not with a new system; task based systems are going to provide much better scalibility.

Share this post


Link to post
Share on other sites
TiPiou    192
Quote:
Original post by phantom
Hardcoding things against threads just isn't a good way to go these days, certainly not with a new system; task based systems are going to provide much better scalibility.

Do you mean having a thread pool scaled to the number of cores and simply passing any task to it ?

Share this post


Link to post
Share on other sites
_the_phantom_    11250
Basically, yes.

There are other considerations in the design (work stealing, locality of work to threads, grouping of work and progression through it) but that's the general thrust of it.

Intel's Threading Building Blocks and MS's Concurrency Runtime are good places to look even if you don't end up using them.

Share this post


Link to post
Share on other sites
bzroom    647
Here's a very oddly worded post of mine about signals and slots: http://www.gamedev.net/community/forums/viewreply.asp?ID=3390739

I hate those little bastards. Not to mention the fact that it's not compile time checked and that it needs cumbersome preprocessing and IDE specific build parameters per file.

The first last only project i used with signals and slots was a build nightmare. I dont know how much of that was attributed to the signals and slots, i'd say not much, but it definitely left a sour taste in my mouth.

Besides signals and slots, my main point on your topic is that you can't make a useful engine without knowing how to make a game first. The high level architecture which doesn't mention any gameplay mechanics leads me to believe that you dont.

The reason i'm concerned is because these are the details that haunt my life. :P trying to save you some pain. but if you like pain then by all means proceed

Share this post


Link to post
Share on other sites
EJH    315
If this is non-mmog (i.e. people hosting servers on home connections), the number of threads you have is unnecessary. The average MP RPG (Diablo -> NWN) supports maybe 8-32 players max? Users will run out of bandwidth waaaay before you even come close to using all CPU resources of any reasonably current gaming hardware.

The client probably needs no threading at all (most sound, network, and databases do all that automatically behind the scenes) unless maybe you have advanced physics or a seamless world streaming scenario. The server needs maybe a server process and a separate GUI process.

For non-MMOG RPG bandwidth is the wall you will hit way before CPU. Just trying to save you some trouble syncing 4+ threads for what possibly will be little gain if any. =)

Share this post


Link to post
Share on other sites
EJH    315
Server GUI is extremely useful for admin and debugging. You can have multiple logs up at once (combat, chat, error etc) and settings and statistics menus. A chat interface so the admin can talk to players is nice. Real-time player data with all relevant info, so stuff like kick/ban by ip is simply a click. Sure its all doable by console, but in a much less user friendly manner. =)

Share this post


Link to post
Share on other sites
Rattrap    3385
Quote:
Original post by AverageJoeSSU
more importantly... why does the server need "physics"....


Because you pretty much have to assume the clients as being unreliable, else you're promoting a high probibility of false data. It'd be too easy to hack the system if you client data was always assumed to be correct and safe. The server needs to be the final autority on what is happening, and the only way it can do that is by running stuff like physics itself.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this