what's the C++/OOP way to implement this architecture ?

Started by
20 comments, last by Norman Barrows 10 years, 7 months ago
I'm not really sure how you would accomplish what you think you're trying to accomplish here.

For instance for the audio you would have to retrieve the data from the database, even if database is just a buzzword of abstraction meaning a variety of long term storage the audio can't just "grab" it from the database. I'm assuming database just means "data" because getting audio from a database sounds like a terrible idea other than as a reference to where files are.

There's no "audio program" or something either, your simulator is going to get the data from somewhere and use the audio code to play it, what your chart shows is basically expecting data and a subsection of the simulator to work without the simulator actually doing it, and there being some performance difference with it, I really don't understand.

DMA transfer is not even remotely in the same category of what you're talking about because DMA transfer relies on hardware units, hardware may not be the CPU but it still has intelligent processing of data, it has the capacity to access other parts of the system and that isn't at all akin to your "audio and video units" it would always be a section of your user running code.
Advertisement


The overbroad "Game data" in your new graph is still not very useful.


Have a look at the C4 Engine overview:

my diagram only covers the "system managers" and "large scale architecture" portions of the C4 diagram. "low level library" and "base services" are assumed, and not included in my diagram.

each unit in my diagram in turn would have a diagram of its parts. all those diagrams, plus the diagrams of the assumed low level stuff would add up to something similar to the C4 diagram.

obviously i need to provide additional lower level detail.


From your diagram, "input" generally does not directly send input to the simulator. Generally it gets converted into events and handled by the UI or by an object picker that navigates the scene structure, which in turn gets generated into more events that potentially get forwarded to various other systems and game objects for processing. Those events are usually picked up by individual objects, not by the general simulator.

input is received. its converted to events. then i use an input handler to process the events and any additional events generated thereby. the input handler would be part of the simulator. the input unit would simply provide raw keystrokes, mouse actions, controller buttons, network packets, etc. network packets might be converted to keystroke or whatever first, as soon as they were received from a remote computer.

the diagram definitely needs more detail. i'll improve it.


Audio is generally triggered by UI code, or (rarely) directly by game object code, or (most often) by animation events. Audio is best when kept in sync with animations, hence the strong link between audio and animation.

my "audio" unit is a low level playback module. the simulator would tell it what to do, and when. for example, the input handler would trigger weapon fire sfx when a "fire weapon" event was received as input.

but your point about having the animation player trigger footfalls is excellent. exactly the kind of insights i was hoping to get by starting this thread. thank you!

so that means there will need to be a connection either from the part of the simulator that controls the animation player, or from the animation player itself, to the audio unit. that is one link i overlooked. but easily added.


It also has a connection to one or more resource caches

those would be the "audio data structures" in the "game data". hence the link from "game data" to "audio".


Interconnection between systems is much more complex than your diagram demonstrates.

i'll work up a more detailed one. thanks for the help so far!

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php


In general, I follow an MVC or MVVM pattern for the general architecture. Whether the data lives in a flat file or in a database doesn't have much of a bearing on the design, other than choosing one, the other, or both from the get-go.

over the years, i've discovered that perhaps as many as half of the major data structures in a game tend to be some sort of implementation of some type of relational database system.

a player "record" in the player "database" for CAVEMAN has links to the following databases: models, animations, animation players, textures, and entity types. one field in the player record is an entire inventory database.

the animation player record links to the model and animation databases.

the entity type record links to the model database.

an inventory item record links to the object types database.

an object type record links to the mesh and texture, or model and animation databases.

a model record links to the mesh, texture, and material databases.


Storing binary information (like audio or images) can get a little hinky unless its a fixed size shared in common with other files of its type

this is where i combine C and C++ syntax. i'll usually use a static C array of COM object pointers, big enough to get the job done. i use DirectX, and it stores audio, meshes, and textures as COM objects.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php


DMA transfer is not even remotely in the same category of what you're talking about

the direct link to data was the part i was referring to, not the multi-processor part. probably a bad analogy. forget i mentioned it.

i'll work up a more detailed diagram.

i've already written a snippet of example code, so we have something concrete to work with. i'll post that for inspection, then start on a better diagram.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

I worked up this example code snippet as a test.

it implements a simple flat file read only database. I find this type of database to be very common in games. i use this type of data structure for meshes, textures, models, animations, materials, sfx, music loops, etc.

the code is generic in nature, and can be adapted to any appropriate data type, such as those listed above.

basically its just a straight translation from C to C++ syntax.

.

.

 
  #define MAX_STRUCTS 10  
struct my_struct                    // a "database record"
{
int data;    // representative data
LPDIRECT3DTEXTURE9 tex;   // use texture data as an example
};  
 
class my_class                // a "database"   
{
public:
my_struct list[MAX_STRUCTS];
int num_structs;  
 
void load_struct(char *filename)        // load single mesh, tex, wav, etc from file
{
// load code goes here
filename[0]=0;     // suppress compiler warning by using filename somehow
}  
 
void load_structs(char *filename)       // load multiple meshs, texs, wavs, etc from a list contained in a file 
{
// load code goes here
filename[0]=0;     // suppress compiler warning by using filename somehow
}  
 
};  
 
void test2(int texID)     // test some syntax for setting a texture, and getting a value from the "database"
{
my_class a;
int b;
Zd3d_device_ptr->SetTexture(0,Ztex[texID].tex);            //     set texture, C version
Zd3d_device_ptr->SetTexture(0,a.list[texID].tex);          //     set texture, C++ version  (example call)
b=a.list[4].data;                                          //     get a value from the "database"                            
}  
 

.

.

so, how bad does it look ? <g>

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

ok, version 3 of the diagram.

data structures, low level libraries and services, and network output are omitted. animation playback of audio is included.

gallery_197293_613_16548.jpg

details on the renderer unit are next.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

the renderer unit:

I've tried to make this as generic as possible, i will give concrete examples as well.

renderer unit API:

render all

the drawlist:

i use a data structure (a scene graph ?) that i call a "drawlist" to store a list of all the meshes to be drawn, sorted on texture. the API consists basically of: clear, add, and draw. it draws all meshes in the list in texture order, using a state manager.

render all:

set lights

set camera

clear drawlist

begin scene

render environment to drawlist

render objects to drawlist

draw drawlist

end scene

at this point, things start getting game specific.

render environment:

this will depend on the type of environment to be rendered. for an outdoor scene, it might consist of drawing the sky, the ground, rocks, vegetation, etc, and any man made objects like buildings. for an indoor scene its would consist of drawing the current level / cell / area based on camera location. caveman actually renders three types of environments: indoors, outdoors, and underground. rendering an outdoors environment in caveman consists of rendering a skybox or clearing the screen, then rendering the sun or moon, clouds, rain or snow, and the terrain (ground mesh, vegetation, rocks, etc ). generally speaking, render environment will use the "world map" or "level map" and related data structure(s). caveman has a world map, four pattern maps for rocks and plants, and a database of caves, rock shelters, and huts. these are used to generate terrain chunks on the fly as needed for drawing (with LRU caching of course <g>).

render objects:

games tend to have lists of things. lists of entities, lists of static objects, lists pf projectiles, particle lists, etc, etc. so render objects is basically:

list1.renderall

list2.renderall

...

listN.renderall

where of course list.renderall is simply: for each item in list, item.render.

item.render:

rather game specific. i'll give an example from caveman.

1. get basic drawing information (meshID, texureID, modelID, scale, primitive type [mesh / model / 2d billboard / 3d billboard ] ) from appropriate data structure (entities list, enemy type definitions, or object type definitions). entities, enemy definitions and object definitions all have basic drawing information in them.

2. set any additional variables necessary such as current position and rotation.

3. for human models: set skintone texture set used by the model

4. for animated models: set current animation frame for the model

5. add drawing info to the drawlist.

still, generally, speaking, a game will have basic "how to draw it" info for all objects in the game. it will then apply instance specific data such as location, orientation, animation frame, etc. then it will use all this info to actually draw something, using meshes, textures, models, and animations stored in data structures.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

As a side note, you might want to try out DoxyGen (eventually with some dummy code). It can do the graphing for you albeit it's fairly stupid in what decides to draw and what not IMHO. At a certain point it becomes just easier to write the code rather than trying hard at design.

Implementation brings you knowledge, which leads to good design. I think you should start writing something if you haven't already.

Previously "Krohm"


I think you should start writing something if you haven't already.
well, lets see, i've done let's say a dozen, probably more, published games over the years. i'm guessing here. its like girls i've dated. each time i try to remember them all, i remember one i forgot the previous time i tried to remember them all! <g>.
i got back into game development seriously for the 4th time about Jan 2012. since then, i've gotten a RTT game to alpha, a FPS/RPG to beta, and early prototypes of a flight sim, a city builder, and a RISK - type turn based strategy game going. I've also done the de-regeur low level library for audio, graphics, timers, etc already.
recently i did a generic "entities list" library, sort of as an experiment - searching for patterns for use in games. soon after, i re-designed it, and added a basic "game engine" framework. In parallel with this work on the entity list and game engine code, i've been revisiting the topic of using traditional c++/oo for games. I actually used to make and sell game development libraries and tools, and have been considering perhaps releasing some of Rockland's in-house libraries or writing some articles or journal entries, but most folks would probably want to see them with a c++ api. i've been a fulltime indie since before C++ was invented. when it came along, it didn't offer that much for the single developer working on a single game project. its was mostly about reuse of code in enterprise level development with large teams, etc (which AAA game development has practically become these days). recently i thought i might give it another look-see. however, despite it having been around for years now, there doesn't appear to be much consensus on how to write a game in c++. i would have thought that by now someone would have figured it out, given the popularity of both C++/OO and computer games compared to back then.
the most recent thing i wrote was tonight. i took the combo game engine / entities list module, and made a new version that can be used as a stand alone library, without requiring any user defined callbacks, like the game engine version has. then i used this new version to rapid prototype a runtime module for a high level p-code game programming language virtual machine. then i wrote a little 40 byte program in the language's virtual machine code that starts directx, loads all graphics and audio content, then goes into a loop where it clears the screen, displays the name of the programming language, displays the framerate, and checks for ESC being pressed. when ESC is pressed, it shuts down directx and quits.
so as you can see, recently I've been playing around with game architecture, game library, game engine, and game module design a bit - and now, dedicated game programming languages too.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Going defensive much?

You don't need to.

I think you should start writing something (regarding this) if you haven't already.

Previously "Krohm"

This topic is closed to new replies.

Advertisement