Mangalore
3D GUI
Entities & Persistence
Entity ID's
Mangalore level DB
 
Diverse Jme Mangalore Nebula Project1 Project2 Tabletop

A persitent world with entities

In managalore you have several components which define your game world. I will try to explain what I have learned about the mechanics in mangalore so far. But first some definitions. A world represents the environment where all gaming takes place. In this world you have objects, some moving, some static, which we call entities. Entities in mangalore have no specialized meaning, the only meaning they get is by attaching properties to them (like a gfx property for example). A property in managlore has certain attributes (active, resource, hitpoints, etc.).

In mangalore the physical elements you need to create a world is :

  • the database file storing your level information (db:world.db3)
  • the definition of your allowed entities (data/tables/blueprints.xml)
  • some graphics resources (gfxlib:examples/eagle.n2)
  • some collision meshes for static environment (meshes:examples/myEnvironment_c_0.nvx2)
  • or physics declarations for non static entities (physics:examples/myBox.xml)
  • some optional animations (these are the entity animations like elevator paths etc. not the animations within a gfx resource)
  • some optional navigation meshes
  • some optionalwaypoints

I will not talk about the last three ones here. I asume some models for the environment have been exported or created by hand. Note that level is not used by the managalore framework, but it might be helpful if you export levels to an xml file (mangalore early 2005 release) and then use the python tool to create your db file. Same goes for the entity definitions found in data/tables/db these are not used by the managalore framework as provided by radonlabs.

So how would I create a level with some environment graphics, some movable and destroyable objects and a player in managalore ?

I start from the bottom and will work up to explain what I know. A property is the lowest part you will need. Have a look in the Properties directory to get a grasp of what they look like and what the provide on functionality. Basically a property is a placeholder for information bits for an object in your game. Let's create a property. You can copy an existing one over to a LivingProperty, or create one from scratch. The decisive parts are the DeclareXYZ and RegisterXYZ macros. The first part is to declare the attributes of your property, for the LivingProperty I would add an int for hitpoints and an int for armorpoint:

 

namespace Attr 

{ 

        DeclareInt(Hitpoints); 

        DeclareStorableInt(ActualHitpoints); 

        DeclareStorableInt(Armorpoints); 

}; 


have a look at attr/attributes.h for the macros. Basically you state I want a variable of type X (int, string, float, matrix44, etc.) which is either storable or not. So hitpoints would be my high watermark, hitpoints are only loaded and on shutdown not persistet. ActualHitpoints are the working set which decreases on hurt or increases on healing, this is something I would persist so next time I resume the game my actual hitpoints are still the same. In my game armor also gets depleted so I would like to have it stored too -> DeclareStorable.
In my LivingProperty class I also declare I need runtime type information and more important I state that I will provide a factory to create new Livingproperties which is needed for assembley of entities via templates later:
 

DeclareRtti; 

DeclareFactory(LivingProperty); 


Next thing needed is a RegisterFactory(LivingProperty); entry to hook in our factory into managalore. That's all for the declaration of properties. Now comes the definition of the stuff.
For that we need a LivingProperty.cc file with some macros too. It goes the same way the declare macros went first we need the define mactros for our attributes. It is best to use copy & paste from the class file to avoid typo's and replace Declare with Define. But you get warned anyway on compilation time, so need not worry that much.
 

namespace Attr 

{ 

        DefineInt(Hitpoints); 

        DefineStorableInt(ActualHitpoints); 

        DefineStorableInt(Armorpoints); 

}; 


Then in the properties you define (here Implement) the rtti and factory macros as promissed in your class file:
 

ImplementRtti(Properties::LivingProperty, Game::Property); 

ImplementFactory(Properties::LivingProperty); 


The rtti macro needs your current class and the parent class as parameters to provide the correct runtime information. The factory just needs the current class as a parameter. That's nearly all you need to have a property with some attributes ready for compilation. Some other stuff you can add to your property is to have the SetupDefaultAttributes implemented which would do the initialization of attributes (like hitpoints and actual hitpoints are always 100 as a safety measure, armor is always 0, whatever you decide). Another point is to implement some logic processing like having your LivingProperty be the one to handle hurt or heal messages (which I will not detail here any further). Have a look at the other properties for inspiration.

Some important details you should know about your newly created properties:

  • Just creating the .cc and .h files and including them in your project for compilation will not make the properties available. The runtime macros will not get expanden until you also include your header file in one of your instantiated classes (setupmanager.cc, or something).

  • Another detail to look for is the decision on storable attributes. Only atributes marked as storable will also be written back to the database. So the transform (orientation of your entity) is sure a candidate for storing, but how about the name ? Not storable ? The answere is as always 'It depends'. If you want to create most of your entities by code for example like in a RTS game and not by loading pregenerated ones then the name atribute woud be a candidate for storable. Which also has consequences for level load/store times. So if your attributes will not show up in the database it could be very likely that the were not intended to be updated (storable).

Now let's create an entity and attach some properties. You can do this via different ways.

The 'mangalore' one is create an entity by loading it from the database, either by loading the entity instance. That would be the case if you resume your game. Or you load entities from the database based on template definitions. The last one I will describe a little bit in detail is creation of entities from scratch based on the allowed entity definition (data/tables/blueprints.xml)

Loading entities from the database is quite trivial and is used in the setupmanager. Set the current level, create a bare entity based on the db definition and set its properties to the values from the database. Have a look at FactoryManager::CreateEntityByGuid, CreateEntityByCategory for details.
Creating entities from scratch goes a similar way as described above. The main part is to define your new entity first in the blueprints.xml file. Here you specify a tag to identify your entity and which properties will be attached to the entity. I name my entity Alive and have the LivingProperty added.

 

    

    

        

        

        

    


This is the definition part of the entity, which just says an entity of type Alive is to be loaded in c++ with the Entity loader class and has the displaye three properties attached. To create an entity based on the template you call FactoryManager::CreateEntityByTemplate. This will create a bare entity with its properties attached and the attributes of the properties set to the values as defined in the SetupDefaultAttributes methods. This entity is not really usable. The next thing you need is to add some extra attributes to the entity like GUID, a name, a gfx resource and optionally some others like the orientation (transform), etc.
 

  gameEntity = FactoryManager::Instance()->CreateEntityByTemplate(

      "Alive", "Unit");

  matrix44 eMatrix;

  eMatrix.ident();

  //guid, name

  nGuid guid;

  guid.Generate();

  gameEntity->SetString(Attr::GUID, guid.Get());

  gameEntity->SetString(Attr::Graphics, "units/orks");

  gameEntity->SetInt(Attr::Hitpoints, 100);

  gameEntity->SetInt(Attr::ActualHitpoints, 100);

  gameEntity->SetMatrix44(Attr::Transform, eMatrix);

  EntityManager::Instance()->AttachEntity(gameEntity);


The last possibility is to create all from scratch, and not even use the template file. This is done via FactoryManager::CreateEntityByClassName to create a vanilla entity, followed by FactoryManager::CreateProperty to create vanilla properties. These are attached to the entity in the next step before you start setting your attribute values to the properties. The final step is again to attach the entity to the entity manager. Have a look at the code found in viewerapp.cc as shown below:



ViewerApp::SetupLightsInScene()

{    

    //create new Entity for light in scene, 

    //create lightProperty and attach it to the entity

    Ptr entity = Managers::FactoryManager::Instance()

    ->CreateEntityByClassName("Entity");

    Ptr lightProperty = Managers::FactoryManager::Instance()

    ->CreateProperty("LightProperty");

    entity->AttachProperty(lightProperty);



    //set position of lightsource

    matrix44 lightTransform;

    lightTransform.translate(vector3(100.0f, 100.0f, 100.0f));

    entity->SetMatrix44(Attr::Transform, lightTransform);



    //set Attributes of the lightsource

    entity->SetString(Attr::LightType, "Point");

    entity->SetVector4(Attr::LightColor,vector4(1.0f,1.0f,1.0f,1.0f));

    entity->SetFloat(Attr::LightRange, 1000.0f);

    entity->SetVector4(Attr::LightAmbient,vector4(0.3f,0.3f,0.3f,0.0f));

    entity->SetBool(Attr::LightCastShadows, false);



    //attach lightproperty to entity

    Managers::EntityManager::Instance()->AttachEntity(entity);

    return;

}

That's all. And remember, only storable attributes will be saved back into your world database.




Something missing? Mail to cc


2009-06-01
WoW Importer for Max
The World of Warcraft tool for 3D Studio has been updated. It now converts model files from WoW Client version 2.x (upto 2.7) and displays correct animations for multi mesh models. The script can be found here....
2007-03-07
nGUI explained
If you ever wanted some more details on the nebula2 nGUI System you can find it in the nGUI System article.
2006-10-17
Mangalore entity ID's
If you need information about the mangalore entity ID usage have a look here..
2006-08-06
Mangalore Articles
Added a new section about the mangalore game framework from radonlabs. The section contains some articles about my experience with mangalore. Read more here:
2006-03-10
Free models
Finally some free models for the Radonlabs SDK. You can download them here.