Sunday, November 21, 2010

Update on the game engines

Hi all,

It's been a while since my last blog posting, so I figure it was time to wax poetic on what I'm currently up to.

I've spent some considerable time working on the Broken Sword 2.5 engine with Sev. As has happened previously, what I originally intended as something else to work on alongside Rex Nebular, quickly overshadowed it, and I ended up spending most of my recent holiday just working on it. It's now available in the public SVN, and is running fairly well, so I'm going to leave any remaining work to any other interested parties, and have returned to work on my other engines.


Rex Nebular is coming along nicely. As I've mentioned in the past, I've been creating a custom script engine, based on the Tinsel script interpreter, to handle interpretation of game scripts. I've then created a custom script program that iterates over specified functions in the Rex Nebular disassembly, and converts them to a script text file. I then have a simple script compiler I've developed that compiles the scripts, and creates a new 'mads.dat' file.

As of right now, I've only converted the scripts associated with the first game room. The scripts associated with scene entry and 'scene tick/step' are working properly, so Rex is now waking up and standing entirely based on script execution, rather than the hard coded behaviour I previously had. I consider this a big step, since it validates the entire process of converting original executable instructions to script code, and final execution works properly.

The next step is to implement some remaining missing pieces of the action dispatch code so that Rex can actually do actions, rather than just walking about. Right now, I'm aiming for right-click Look actions to work properly. Then it should only be minor further changes to have other actions work as well. Soon Rex will be able to do all the various things in the first room. And I'm looking forward to the day when Rex will finally be able to take his first steps into a bigger world and finally leave the cockpit.. :)


Another game engine I'm currently working on is the tSage engine, which is used by the Ringworld game. Previously, the fact that it was so Object Oriented annoyed me, because it made it harder to understand the game flow since some classes, such as the event manager, had four descendant classes, making it difficult to understand what each class in the hierarchy did. Now, though, I'm actually starting to see some benefit from it.

The classes related to handling the game state are very clean. For example, there is a generic 'Scene' class, from which each game scene dervices a specific implementation class. So, there is a 'Scene30' class for the first scene in the game, and it has fields for the various hotspots and objects within the scene. Speaking of hotspots, there too is a hierarchy, with a base 'SavedObject' (used for object persistence), which subclasses to a 'SceneHotspot' (used for basic hotspots), which subclasses to a SceneObject (which is an object in the scene that is drawn into it, rather than being part of the background). From there, a SceneObject is sub-classed to the NPC class - this is where the encapsulation really helps, since all logic related to drawing NPC's is already handled by the SceneObject class, so didn't need to be disassembled multiple times for different kinds of things in the scene. The NPC class only has to implement the additional logic for moving character around the scene.

In fact, the NPC class also further sub-classes to the 'Player' class, which has extra logic to handle allowing the player to interact within the game. A lot of the logic for handling the player is thus already handled by the NPC class, so the Player class only has to add on the extra logic for allowing direct player control.

Because of this OO model, all the game logic is implemented by deriving new custom classes from these base classes, and then adding them into a particular scene. So, for example, the first scene in the game has the player having to ring a doorbell by 'using' a motion sensing beam. This beam is implemented as a 'SceneObject' derived custom class, which overrides the 'action' method to either provide a description on-screen for the 'Look' action, and start the 'kzin answering the door' sequence in response to a 'Use'.

I'm still undecided about whether I'll re-implement the game by manually converting all the game logic to C++ code, or try to create a process, as with Rex Nebular, to convert the game executable routines into equivalent scripts that could be interpreted. The OO nature of the game engine would make it trickier to convert to scripts. I'm planning to at least, eventually, converting the logic for the first scene to full C++, and see how it looks.