1. Building a scene
I opted to go with a simple xml file to define a scene but there's no reason you couldn't go with any old format. There are just so many different XML parsing libraries out there already it just made sense to re-use instead of starting from scratch. The actual schema is also fairly arbitrary. Just go with something that makes sense to you. In the following example I have a complete scene setup. It's got basic camera data for a view frustum along with three different objects with a variety of different components. As I add more functionality and components to my engine the schema will grow with them.
[xml]
../../data/SimpleRotation.v.glsl
../../data/EngineTest.f.glsl
../../data/duckCM.tga
../../data/hello2.tga
../../data/duck.dae
../../data/HelloWorld.lua
../../data/SimpleRotation.v.glsl
../../data/EngineTest.f.glsl
../../data/test.png
../../data/hello2.tga
../../data/test.x
../../data/SimpleRotation.v.glsl
../../data/EngineTest.f.glsl
../../data/hello1.tga
<2dlocation x="0" y="0" width="1" height="1">
<2dtexture u1="0" v1="0" u2="1" v2="1">
[/xml]
2. Implementing game logic
In the past I have done most game logic in native code. It was separated out from the main engine code but still had to be compiled any time a change was made. On this project I've gone the route of using Lua for all logic. At least that's the goal. In the following test example I set the object rotating around the Z-axis while also fading between a pair of textures loaded for the object. I have everything exposed to Lua through the parent GameObject which just does a simple call through to any individual component that a method acts upon.
a = Parent:GetElapsedTime()
Parent:SetFadeFactor((math.sin(a) *0.5) + 0.5)
b = Parent:GetRotationZ()
b = b + 1.0
if b > 360.0 then
b = 0.0
end
Parent:SetRotation(0.0, 0.0,
3. Bonus area: Unit and Functional testing
While it's not actually part of the final game product testing is still an important function to insure the final product is a quality product. Being data driven makes it easy to be able to setup tests for all of your functionality using a bunch of data files instead of having to write a bunch of unit test code. While I was implementing my model importer I had a number of different scene files that would attempt to load models of different types and styles. It made things easy when it came to testing functionality as well as making sure I didn't have any ugly regressions.
All of this means less time compiling things but more importantly less churn in my testing applications. As I keep adding functionality to my engine library I'll be able to test them out by adding new data to my data files and my core test app will still only be the same few lines of code:
int main (int argc, char *argv[])
{
CSimpleEngine *Engine = NULL;
// Create and initialize the engine
Engine = new CSimpleEngine();
Engine->Init(800,600,32,"Tester");
// Create our scene and load a scene file
CScene *Scene = Engine->RequestScene("../../data/TestScene.xml");
Engine->SetCurrentScene(Scene);
Engine->MainLoop();
Engine->Shutdown();
delete Engine;
}