Data-driven game engine

Hi all.



I've been playing with XML based data driven development. I'll not post an extended version of information here but here is the sumary:



Goal: fast prototype games by recombining reusable plug-and-play components;



The entire engine is a mediator pattern between gamestates, each one defined in XML and being composed of a collection of GameObjects. GameObjects are defined as types in XML, based of Components and declarative inheritance. The engine uses a lot of reflection in the parsing and gamestate building fases. In my blog there's a post with a bigger explanation of the architecture and examples.



One can download the engine source and examples: GCore Alpha.



Extracted from the blog entry:


My main idea is define a Game as a collection of GameStates, each one composed by a collection of GameObject instances. Each of these GameObject instances is by itself a collection of pluggable Components. This GameObject design is based on an article from the book Game Programming Gems 6 - data-driven game design. A GameObject can be anything like a player, with a 3D model, a static scene element or even a positional trigger of some type, it doesn't matter, all of them are just this: GameObjects with a collection of Components defining their looks and behaviors.

The goal is to develop fine grained reusable Components that can be combined in ways to express the desired game design and behavior. I've already developed a lot of these reusable components, some independent and some dependent on other to work:

    * VisualComponent - defines a 3D model to be imported, scaled, rotated and tranlated;
    * PhysicsComponent - plugs a static physics behavior for a GameObject with a VisualComponent;
    * DynamicPhysicsComponent - same as above, but with mass and dynamic physics;
    * PositionalAudioComponent - allows the attachment of a positional audio clip in declarative form;
    * TemporalTrigger - enables and disables child Components based on a timer;
    * TerrainComponent - permits the declaration of heightmap based terrain;
    * TerrainPhysics - for attaching physics to the terrain;
    * TerrainTexture - for composing and glueing splatts, color and detail textures.

These are just some examples since I've provided ~15 different components already, the vast majority being reusable in different game contexts.

Last but not least: You can think the game architecture as a big mediator (design pattern) between gamestates switchs (gamestates defined as collection of game objects in XML). GameObjects and Components implement the Composite design pattern since both can have collection of Components. The XML definitions use the concepts of inheritance. One can define a generic type, with a collection of components and refine their attributes in inherited declarations.

Multiple Components of the same type are allowed inside the same collection, the order of declaration is guaranteed in initialization and I used a LOT of reflection in the parsing and gamestates building fases. Too much blah blah blah? So lets see some action:


And some XML example:

From types-basic.xml:


  <type name="visualPhysics">
      <component class="gcore.component.VisualComponent">
      <component class="gcore.component.PhysicsComponent">
          <triangleaccurate value="true">
      </component>
  </type>


And from types-misc.xml:


  <type name="oldfence" extends="visualPhysics">
      <component class="gcore.component.VisualComponent">
          <model value="./sample/resource/oldfence.jme">
      </component>
      <component class="gcore.component.PositionalAudioComponent">
          <file value="/sample/resource/audio/cricket2.wav">
          <playrange value="25">
          <stoprange value="25">
          <maxvolume value="0.15">
      </component>
  </type>


As you can see, the oldfence type inherits the components and attributes from the visualPhysics one and spectializes some things, including a positional audio clip and using a specific 3d model.

How can we use this in a GameState? An extract from the gamestate definition file caating.xml:


  <object name="fence1" extends="oldfence">
      <component class="gcore.component.VisualComponent">
          <position x="40" z="10">
      </component>
  </object>


Some screenshots of the first example using the engine:



This is very interesting for me… I was going for a more modular plug-in-out type of setup for my game as well. I have not had much time to think about the details of how I could / should implement that, but my initial impression was that I might find lots of interesting tidbits from your code :slight_smile:

Links fixed. Feel free to use bits of the code, or even the entire engine, which would be better yet, since I'd like suggestions and new pluggable components.

I have a feeling of Deja vu and YAMMO while looking a the Screenshots.  :wink:

I have a feeling of Deja vu and YAMMO while looking a the Screenshots.

Public domain models and textures from the jmetest package.

And anyway, this "game" example is meant to be completely different. Some friends are modeling for me and then I'll show some really different screen shots. This game is a "Cowboy" one. Your goal is to make the cows get into the farm's fence.

Maybe I'll do a small SPACE GAME with the engine to show it's potential. Another space game... :D

Cool, looking forward… I hope this project makes good progress to modularizing features in jME… are you planing on having input controllers also modular?

They are already… The only thing you have to declare in XML is gamestates, types and objects (each one has a type). Types have components. In my example the "player" type has a ControllerComponent which is the module responsible for collecting input and updating the DynamicPhysicsComponent apropriately.



I've been developing this engine for the last 5 days only so I'm refactoring a lot of things but already quite happy with the results. Today I got rig of my hand made PlayerCameraComponent and replaced by a new one that encapsulates a ChaseCamera.

Really interesting. I stay tuned to get news about it.

Thanks perick! This answers my long search for a config driven "injection" based gaming architecture. Looking forward to test this out.



Does the Terrain Component support terrain engines such as jmeterra?



Wishlist: Modularised Server implementation could be really awesome (choice between JGN, Darkstar etc).

the trees (we modified them a bit) are also used in hhexen ;p

Oh yes, the tree models I'm using in this example are the same… I got them from the address you posted ages ago in the hhexen thread.



Thanks.

About the terrain components:



THe one I’ve implemented is based on terrain pages…

The texture splatting component is suitable for other types of terrain and it’s based on the hardware/fixed splatting examples you can find here in the forum.



The main goal until now was to build the injection based engine, so I could have two separate focuses: components programming and level design… This is already achieved.



You can download the sources and examples from the address below:

www.infoway-pi.com.br/erick/gcore.zip



Not sure if it’s updated but it’s a start.

hmm i think the links are broken

Checked and it's broken indeed. I'll check with the server admin what happened and probably host it somewhere else soon.

Moving the GCore discussiong from this thread…

http://www.jmonkeyengine.com/jmeforum/index.php?topic=7786.0



to here.


How could an component based object be copied after a program has been initialized?

Alternatively, is there a way to determine which components were used to construct an already initialized object?

Ok, let me explain two more bits…



The meta-data used to compose objects in XML is parsed to a run-time intermediate configuration. It is an object graph representing the same thing as the XML. One can see this meta-data config classes are found in the gcore.config package.



This runtime objects are the ones used by the game object builder to instantiate and populate these. Every game object keep a reference to it's meta-data config object… It's possible (not sure if already exposed, but trivial to do it) to use this config object to invoke the builder at runtime and create copies of any game object… One can even manipulate this config object and modify attribute values, but I do not recommend this.



It's also possible to compose the game objects programatically in Java or groovy instead of XML, but that's not exposed on the GameManager now.



To clone a game object from a component:



gcore.object.GameObjectBuilder.build(getOwnerObject().getConfig(),getState());



The build method takes two parameters: a TypeConfig carrying the game object meta-data and a GameState to put the built object in.



EDIT: I noticed that I removed the "config" attribute from the GameObject class. Put it again and will post the new version later today (in airport now - coming back home)