Using Native DLL’s in Managed Code
Having developed what felt like quite a flexible system for entities (using Lua for behaviours) I decided I wanted an easier way to construct entities & place them in the world. The flexability of irrlicht allows users to define custom nodes which can be saved/loaded into the scene graph xml thus I looked into how i might save entites to the irrlicht scene.
Using a sample on creating custom scene nodes I was able to create my own entity scene nodes which was saved as a child to a mesh scene node. This entity scene node stored the filename to a separate xml file which defines the entity itself.
For the editor, I used C# to create a windows forms application. The editor allows the creation and modifcation of entity properties on a mesh instance placed within the scene. The editor uses the familiar format of separate viewports to view the scene from different angles (aka 3D Studio Max/Maya)
In order to link the C# interface to Irrlicht rendering the application is split into three sections. First is the C# project which handles all the front end interface. Next is a C++ DLL which wraps all the required functionality in Irrlicht (such as adding/removing meshes to the scene) and finally there is a C++/CLI form which bridges the two projects (performing tasks such as converting System.String to native char pointers, for instance). My choice to use CLI came purely from a curiousity of seeing how C++ works with .NET. I have had some issues with this setup to say the least.
The biggest problems I have had are when I had run time errors in the native dll, causing the application to crash. Due to running the C# debugger, a crash in the C++ DLL didnt yield any information as to the cause. Also for some reason I was unable to step directly into the native C++ code from the C# (From what I understood, Having the platform set to mixed mode in visual studio should have allowed this). I eventually found a work around to this problem through running the native debugger from the dll project and specifiying the target executable to be the output from the C# project. This way debugging throught managed code was not supported, but any crashes in the native dll, provided the callstack information for the native calls, allowing me to see where in the native dll the exection was encoutered.
C++ Lua Integration
In order to combat the issue of having many small behaviour classes for my entity system. I spent some time investigating the integration of a scripting system in order to delegate behaviour execution to scripts.
I choose to look into Integrating lua with C++ and came across the following codeProject article. Prior to reading this article, I had seen a small program which implemented Lua in C and thus I was a little dissappointed at the extra word required to integrate the system with C++.
However Getting into it, I discovered the bulk of the work was ensuring lua had the correct object state pushed onto the (lua) stack for the particular executing script object.
The main issue is when a new LuaScript object is created, the current top value of the lua stack is stored and replaced with the this pointer for the particular class object.
With access to the script object, through the stored this pointer. Member functions of the class can be registered with Lua, which when called are passed to a ‘ScriptMemberCall’ function in the script class, which handles the mapping of the function id to the actual function to execute.
The key change I made was here, where as the system from the codeProject sample, switched on the function Id to execute member functions in the script. I added a function object (a class with an execute parameter) to represent the functions. This way instead of switching on an id and hard coding each function. I used a map to index function id’s with function objects. e.g.
m_mpFunctions[m_iMethodStartIndex] = new FuncRemoveFromScene();
then my ScriptMemberCall function simply became
With the above I was able to modify my entity system so that the BehavourRemove class was replaced with mapping a script filename to an event, which, when fired, executed the script. The behavourRemoves script simple calls a function in C++ RemoveFromScene
this:RemoveFromScene()
end
The lua filename is then stored in the entity xml along with the event which determines when the script should execute
I hope to extend the lua system to support general functions such as playing sounds/particle effects. However a current issue i’m contemplating is how to expose different irrlicht engine functionality (such as generating particle effects) to the lua scripts
Entity System
As part of my videogame middleware module, I was tasked with implementing an entity system. The result I had worked well but presented me with some ideas on expanding the system. Now that I’ve finnished my final year, I have found the time to experiment with some personal projects thus have worked on expanding my entity system.
The inital system was developed for use with the Gamebryo engine, however due to not having access to that outside of my course, I have first had to re-target the system to another engine, in this case I chose Irrlicht (http://irrlicht.sourceforge.net/) a free, open source 3D engine (I also feel its significantly nicer to use than gamebryo).
To give some background, the entity system developed was component based, as opposed to a class hierarchy of entities, to allow flexibility in adding new entity types.
Below is a (sorta) UML that demonstrates the overall layout of the system
The EntityManager’s role is mainly just to store the created entity so they are all located in one place, & to release all the entities at the end, keeping the release code in one place helped to avoid memory leaks. Additionally the EntityManager is able to create Entity objects from an XML file.
The xml file defined an entity through specifying the behaviours and properties for a particular entity. For example, a coin pickup entity with a goldValue property and a behaviour to be removed on a collision event is defined using the following xml
<Event="EVENT_COLLISION" Behaviour="BehaviourRemove"/>
<Event="EVENT_COLLISION" Behaviour="BehaviourAddGold"/>
<Property Name="GoldValue" Value="5" />
</Entity>
The defined properties are stored as strings in a map, with another string acting as a key. So a coin pickup entity may have a GoldValue property with the value of 5. By storing all data as strings abitary types can be stored. In order to access the data template functions for getting & setting properties are available. Using the functions any datatype can be stored as a data member, the only requrement is that the data member supports the input (>>) and output (<<) operators to strings.
Acompaning the properties are behaviours, these are implemented as pointers to a class inheriting from a behaviour interface. Each behaviours is mapped to a game event (such as ON_COLLISION) which are fired from various points in the game code. This way when the game encounters a collision between two objects, the game code does not need to be concerned about the behaviour of the two entities involved in the collision, the reponse is simply delegated to the entities through the event system. Upon the occurance of an event which triggers a behaviour, an execute function on the behaviour is called. For example the coin pickup entity has a behaviourRemove mapped to the collision event which performs the logic of removing the coin from the scenegraph.
One thing that has become quickly apparent is the number of classes needed to implement the range of behaviours, my gamebryo project had around 20 behaviour classes, to implement 5-10 minutes of gameplay. My intention is to replace the behaviour system with a scripting system by encorperating a scripting platform such as LUA to implement the behaviours.



