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

Started by
20 comments, last by Norman Barrows 10 years, 7 months ago

what would be the C++/OOP way to implement this architecture ?

gallery_197293_613_19742.jpg

audio would play music and sound effects stored in the databases. it would be told what to play and when by the simulator.

input would get input from the keyboard, mouse, and other input devices, and send it to the simulator as needed/requested.

video would produce everything seen on the screen, as directed by the simulator. so it would include the renderer and gui components.

the databases would store all the game info. meshes, textures, materials, models, animations, sfx, music, the world map, the entities list, databases of entity types, object types, etc. databases would be of 3 basic types: static databases would not change during one run of the game/level/mission. they would be read only - a database of target types for example. dynamic databases would be expected to change every frame. an entities list would be an example of this. semi-static databases might change, but usually not every frame. a list of dropped objects, or a changeable world map might be examples of this. other game specific databases might also be used. for example, CAVEMAN has action type and skill type databases.

the simulator would run the show. it would contain the main game loop. it would receive input and process it, updating databases as needed. it would perform all the update functions (IE run the game for one "frame" or "turn") or dispatch commands to the appropriate databases to update their contents. It would also dispatch commands and parameters to the audio and video units to do sound, music, and to render the screen. So its largely a controlling unit.

needless to say, this diagram is high level in the extreme, and each unit in it would in turn be composed of a number of sub units.

i'm pretty familiar with the non OO way this would be done, basically a bunch of adt APIs. but i was wondering what form a c++/oo implementation might take.

so before / while i start to slice this thing into classes and such, i thought i might get some suggestions from folks who do this everyday.

my natural approach would be to simply convert ADTs to classes. but i'm not sure if this would be considered the "usual" way to slice things or not.

for example, the entities list:

apparently in C++/OO, its common to implement an entities list as some sort of array or linked list of pointers to objects, where each object contains the info for one entity. furthermore, its also apparently common to create and destroy entity objects on the fly as needed.

in the non-OO world, this is a flat file database. a simple array of structs, nothing more. anyone who implemented an array of structs as a linked list of pointers to structs allocated on the heap would be thought to be "odd" at the least, if not "crazy".

so converting an entities list ADT to a C++/OO entities list in a straight forward manner, one would get and array of structs data structure with methods that operated on structs. the entire array would be one object. there would be an entitylist class, with a single instance, one entity list object.

but this doesn't seem to be the usual way its done in OO/C++.

i'm sure there are other places where this situation arises as well. I think it stems from the OO vs non-OO way of looking at data. Apparently, in OO, it not uncommon to take "everything is an object" literally, and to the extreme. To the point where individual records in a database become objects, and perhaps even fields in those records. The result would/could/might be a proliferating tree of objects on the heap. Add in creating and destroying objects on the fly, and you have a constantly changing giant rats-nest tree of objects possibly/probably fragmenting the heap.

i'm thinking there's a way to slice things in an OO/C++ style with out the usual difficulties encountered, perhaps by using objects primarily as higher level modules / units.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Advertisement
Wouldn't the simulator be the layer over the database and the Input, Audio, and Video would only interact with the simulator? As far as methodologies, I would think that MVC would be a contender.

Beginner in Game Development?  Read here. And read here.

 


Wouldn't the simulator be the layer over the database and the Input, Audio, and Video would only interact with the simulator?

my original response was getting long winded, <g> so i'll keep it short:

audio and video need access to the data to do their job. the simulator tells them what to do, but the data required to do it is in the database. so either the simulator gets all the data, then passes it all to the audio and video units (yuk!), or it just lets them do it themselves directly (sweet!) <g>. Think DMA transfer and microchannel architecture.

input doesn't really need access to the game's databases. it just gets queried by the simulator as needed.


As far as methodologies, I would think that MVC would be a contender.

model - view - controller. hmm... lemme wiki that to refresh my memory.

just looked it up. its an architecture designed for business apps. i'm not looking for a different architecture, i'm wondering how to implement this one in oo/c++.

the layout as presented may be too high level. i may need to specify the different part of the units (such as video), then ask for recommendations on implementations of those parts using oop/c++.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

There's a major difference between live data (in RAM, workable) and storage data. The concept of serialization is the bridge between the two things and I don't really suggest to even try doing it in a different manner.

Truth is even OOP is a buzzword. Yes, it gave us much more than many other methodologies, but don't take for granted it's the only thing in existance. When sending stuff over the wire (or to storage, for that matter) OOP does not hold much. You must send bits and will get bits, trying to convince yourself otherwise is trying to live in an abstract world. It's just numbers and conventions. The hardware will send you numbers, you will work with numbers. Period.

I think the main fallacy in your line of thinking is to draw a single "databases" block while there are clearly different databases involved. I strongly believe you didn't get the whole point of what OOP is, consider:


i'm sure there are other places where this situation arises as well. I think it stems from the OO vs non-OO way of looking at data. Apparently, in OO, it not uncommon to take "everything is an object" literally, and to the extreme. To the point where individual records in a database become objects, and perhaps even fields in those records. The result would/could/might be a proliferating tree of objects on the heap. Add in creating and destroying objects on the fly, and you have a constantly changing giant rats-nest tree of objects possibly/probably fragmenting the heap.

The inference OOP-->objects on heap is wrong. OOP itself does not mandate heap usage, much less heavy usage fragmenting the heap.

The point is that you have "blobs" of data which you don't modify directly but use specific functions instead. In many OOP languages, the functions are "near" the data they manipulate. But they don't have to be! OOP is possible in C and even ASM.

Previously "Krohm"

The diagram is so trivial and high level, containing only general categories of functionality, that even Krohm's criticism that there is only one "database" box is premature (the single "database" box means only "database-related stuff is layered below the simulator", without implying that databases are improperly consolidated into one Database component). I suggest, after thinking of your requirements, to start design from efficient and convenient algorithms and data structures; particularly in a very general purpose language like C++ you'll be able to fit classes to what your program really does, instead of hacking arbitrary class structures and inappropriate interfaces to make them behave acceptably.

Omae Wa Mou Shindeiru


There's a major difference between live data (in RAM, workable) and storage data

it appears my diagram has caused confusion.

first let me fix that, (by posting a better one right quick) then i'll reply.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

hopefully this will be a little clearer.....

gallery_197293_613_85237.jpg

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php


There's a major difference between live data (in RAM, workable) and storage data

as you can see in the updated diagram. the "databases" are only that data currently in ram or on the video card. not stuff on the hard drive, or received via network, etc.

sorry for the confusion!


a single "databases" block while there are clearly different databases involved

obviously - or at least i thought it was obvious. <g>. lack of precision - my bad!

yes, the "game data" represents multiple data structures of different types, holding different types of data.

here's what the list might look like for CAVEMAN:

* a list of active players (like an entities list, but for multiple player characters).

* an entities list (vector, list, component-entity system, etc).

* a list of world objects (basically static entities like dropped inventory items)

* the world map data structure

* a list of known npc's and their data.

( CAVEMAN generates npc's on the fly, so it only needs to track npc's you've met. a game like Oblivion would have a large "database" of NPC's, although the data might be split up between many levels or cells. in such a case, the equivalent would be the npc's active in the currently loaded level / cell / area. )

* entity type definitions

* object type definitions

* action type definitions

* skill type definitions

plus others that don't come to mind.


The point is that you have "blobs" of data which you don't modify directly but use specific functions instead. In many OOP languages, the functions are "near" the data they manipulate. But they don't have to be! OOP is possible in C and even ASM.
yes. this is what i do now. basically ADT's in C.


you'll be able to fit classes to what your program really does

over the years, i've noticed that what most games "really do" is something similar to the above diagram.

i suspect that the layout as presented is still too high level, and lacks sufficient detail to elicit responses on implementation recommendations for different parts.

i should probably take it one unit at at time.

i'll reformulate my question to be multiple specific implementation questions, instead of "so what would be some cool classes for this architecture?" <g>.

please stay tuned, as i was hoping you guys would chime in with some advise.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

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

Some of the data is persistent, some is transitory. Some is stored in specialized locations, some is stored in general collections. Some is stored as individual pieces in small game objects, some is stored in resource caches, some is stored on disk, some is stored in video memory, some is stored in the renderer, some is stored in scene graphs, some is stored in physics engines, some is stored in audio memory, some is stored in network buffers, and on, and on, and on.

Attempting to bundle all that up as "databases" or "Game data" is so big of an abstraction that you couldn't really implement anything from it.

Have a look at the C4 Engine overview:

architecture.png

Even that diagram is an EXTREME simplification. Although some games are simple, most are complex and intricate architectures.

Generally the simulator is a process that schedules processing on individual game objects. The simulator schedules when physics get updates, when objects get updated, and when alarms should fire.

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.

Audio generally does not generally work with the simulator either. 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. It also has a connection to one or more resource caches. The broad simulator itself generally has nothing to do with audio, unless perhaps you are modifying the sound when on 'fast forward' or 'pause' modes.

The network is a way to keep multiple simulators in sync. Exactly how that happens is game dependent.

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

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. It can be convenient to have a database (or multiple databases) since you can do queries and possibly even perform some logic in a stored procedure when its desirable (really, if you use a database, you should do this for any action which might leave the database in an inconsistent state if it were to fail mid-way, because the database can make sure the entire action is atomic -- that is, all or nothing).

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 -- You could, in alternative, combine flat-files with a database if you really want the ability to query over binary data (with associated metadata), by storing the files path in the database, rather than the data itself.

throw table_exception("(? ???)? ? ???");

This topic is closed to new replies.

Advertisement