Sunday, December 19, 2010

tSage engine proceeding quickly

Hi all,

I've really been making some great strides forward with my implementation of the tSage engine. I offer the two screenshots below. One is from the first game scene when run in DOSBox, the other under ScummVM:







Hard to tell them apart, isn't it? :). The one on the left is from DOSBox, and the one on the right is ScummVM. All the initial hotspots in the first game room are now set up, are being drawn on the screen, and have correct look descriptions. The only exception is a minor graphic glitch with the doorway - the current drawing code doesn't yet support clipping objects based on priority calculations, so the top of the doorway isn't correctly clipped off.

One of the next major steps from here is to delve further into the movement classes and code. Whilst the player is now drawn on-screen, I don't yet have any code responsible for moving the player, such as when you manually walk somewhere, or when the computer moves the player to a set location, such as when you use the door beam.

From what little I've looked into the movement code so far, the game maintains a set of classes responsible for moving objects within the scene. For the player specifically, there's a lot of code that seems to make use of special 'walk regions', which indicate where on the screen the user can walk. The movement code is tied into this, and uses them to determine both where the player can move to, and for pathfinding to move the player to the given destination.

Given the pace I've been having recently in other areas of the engine, I don't anticipate that it will take too long. Hopefully, soon I'll be able to move the player about on the screen. Then I can start delving into implementing all the logic involved in the first cut-scene, where the Kzin comes to the door and speaks with the player. It's so much more fun working on an engine when you can almost day-by-day make visible progress in it's implementation.

PS: I've been making such rapid progress with tSage, I've been somewhat neglecting work on the MADS engine. I hope any fans of Rex Nebular will be patient with me.. I will get back to work on it eventually. :)

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.

Tuesday, July 27, 2010

Rex can now walk about on-screen

Here I was bracing myself for the imagined complexities of movement logic, and it turned out to be a whole lot simpler than I imagined. Probably blame it on the other two engines I've had experience with path-finding for: Lure, and Tinsel, both of which have their share of complicated logic. For Rex Nebular, though, the implementation was a lot more elegant than I'd expected.

What the MADS engine does for walkable areas is to have two parts. The first is a priority/depth surface, which had already been previously implemented. This is a surface which both specifies the walkable areas, and is also used to determine which parts of an object, at a given 'depth', should be drawn on-screen. In the first room, for example, the area comprising the chair has some varying levels so that the player gets drawn behind it.

The other part to the movement functionality is a series of 'scene nodes'. These are a series of points distributed across the scene to represent appropriate intermediate points in movement. If a straight line between the start and end point isn't possible, because of a marked obstruction, then the engine calculates the distance between each node in the scene, including both the start and end points as two extra nodes. It then calculates which series of nodes will take the shortest amount of time to traverse, and uses that as the basis for movement - the actual walking then moves the player from node to node until the destination is reached.

This works well for the game since, unlike in Tinsel or Lure, there aren't ever any moving actors that could interrupt the walking path. The only NPC character movement that ever happens is in cut-scenes, where the player is either not moving, or is being controlled by the computer (such as when Rex is taken to the cells).

Now that I've got Rex moving around on the screen, the next immediate step is to get the hotspot and selection code working. Somewhat ironically, this is turning out to be more complicated than the walking code itself. I'm currently working my way through disassembling the various routines and implementing comparable code. Hopefully, I'll soon have enough implemented that I can properly implement some actual actions in the first room.

Monday, July 12, 2010

MADS/M4 engine now has cutscene support

Well, it's been a very productive month for work on the MADS/M4 engine.

Since the last posting, I started working on the cutscene animation system. This is a separate module to the basic cycled animations that get loaded into a screen.. rather, the game uses an animation manager to handle so-called 'cutscene animations', such as that of Rex waking up in the first room. In this case, the animation manager handles the work of animating the sequence of frames of Rex waking up, looking around, and then getting up. Given that this was the fist major action in the game, it made sense to have that properly implemented first.

Above and beyond that, the animation manager is also used for handling all the full-screen animations done in both the introduction and ending sequences, so once I had Rex properly animated in the first scene, I moved onto implementing proper support for them. With some help from Md5 on the handling of digital voices during the intro, the introduction sequence now plays completely if you press 'F3' from the main game menu. There are only a minor few issues remaining with the introduction, in that:
  • The tempo of the intro isn't quite matched to the original yet; I'll need to properly calibrate the timing loops at same stage
  • I haven't implemented palette cycling, which is used by some scenes within the introduction sequence to simulate basic animation.
I consider the above minor things, and I'll get to them eventually. For now, I again got distracted from polishing up the remaining issues by making a breakthrough in my understanding of the code that controls the player (you) within the screen. Within the last week I've implemented a great deal of code associated with player control, and now Rex is corrected displayed when the wakeup animation is completed. Not only that, but the idle animations run for Rex, and you can even turn him around by using the Ctrl-T key.

The obvious next stage for me to look into is actually starting to give some movement control for Rex, and have him be able to walk around on-screen. This is where I'll need to worry about figuring out the pathfinding algorithm, and how actual movement is done. I've already identified some of the methods associated with handling Rex's movement but, as I expected, there's a lot of calls to unknown sub-methods that I'll need to figure out the purpose of. Since the MADS engine was designed to be generic for multiple games, there's a lot of complexity in both the movement and pathfinding code that I'll need to figure out.

I'm really looking forward to this. It'll be another major milestone reached when I can move Rex around the room. At that point the game will finally be properly interactive. I'll then be able to work on interacting with objects, which I already understand a lot about, and maybe even moving between rooms and/or teleporting.

Sunday, May 23, 2010

MADS engine reaches a milestone

Well, it's been a busy last month at work, but with things starting to settle down, I've finally had some free time to start working on the MADS engine again. And as of this weekend, I've just reached an important milestone in the development of the ScummVM engine implementaiton - the core graphics display framework is now working properly.

That's right.. the game logic for the first screen setup is still hardcoded, but the engine now properly implements all the necessary code to handle the calls to register a sprite sequence animation, and drawing elements on the screen; so animation sequences are now properly animated.

I consider that this reperesents a great step forward, since the entire game is based on the display of graphics - so I finally have a working core from which to build on further functionality with. This includes areas such as the logic for the player character itself.

The graphics core in the MADS engine has been more complicated then I've previously dealt with - the functionality is split between a main sequencing list for scheduling animations, graphics display logic, and various suppport classes, such as for dirty area handling. There's a whole mess of inter-relating code, which meant that I had to disassemble a lot of the code before I was able to implement something that works. There are still some fields that I've yet to figure out that handle certain special cases, such as the ability of dynamic hotspots to move their position, but that'll come in time.

If there's one thing that annoys me about the MADS engine it's the number of data variables that seem to get set everywhere. I'm presuming the original engine was designed to be generic for multiple games, but there seems to be a ridiculously large number of data values being set throughout the engine. It'll be interesting to find out whether the the majority of them are part of the 'core' MADS engine, or represent a whole lot of game-specific hacks for the Rex Nebular game.

I've included a screenshot from the first game room from Rex Nebular below. It may not be obvious from a still picture, but the various status displays now display flashing lights, and bubbles are escaping from the hull into the water.

Monday, March 1, 2010

MADS disassembly is back on track

Since it's been a month since my last posting, I thought it was time to post a status update. The work on disassembly of the MADS (Rex Nebular) engine has been going well.. I've made a lot of progress on various areas of the game logic.

I haven't actually added much code to the ScummVM engine yet, since I decided it would be better to fully understand a given area before I implement it. At the moment, my reverse engineering has been some undirected - it's obviously more effective to work on whatever areas you can find that are easiest to disassemble, which in turn may make other areas easy to disassemble later on. However, it does mean that there are bits and pieces across the entire engine that are now understood better.

One area of the game engine that's going to prove interesting is all the hard-coded game logic - each scene has several routines associated with it for scene loading, scene animations, and handling interaction with elements. Obviously it would be preferable not to completely reimplement these in code, since it would take a lot of code space, and there are two other games whose code would also need to be reimplemented.

What will probably need to be done is to create some kind of basic script interpreter engine, and convert the various scene routines to an interpretable script. Luckily, most of the routines seem to use a fairly simple subset of x86 instructions, so it shouldn't prove an impossible task. In any case, that's something for the future, when I fully understand all the various routines the methods call. For now, I've set a short term goal of manually implementing the logic for the first game room, and will return to the idea of scripts at a later date.

On a final note, for those of you who like pictures, see below for an example of the scene walkable areas for the fist scene of Rex Nebular. It also has a slightly weird sprite frame from Rex inserted into the picture - Rex isn't movable yet, though.. it's just a test from some of the loaded sprites:

Friday, January 29, 2010

Roadblocks in the path of tSage

Those of you who have been following the IRC channels will know that I made some real progress in the disassembly of the tSage engine, used by the Ringworld - Revenge of the Patriarch game, as well as several others. I hadn't really gotten into any of the game logic, but I'd made great strides in decoding the image formats and graphics display, so much so that my engine on Scummvm-misc could display test dialogs, as well as the right-click game dialog with proper highlighting and everything. Sample screenshots below:








However, given the perversity of life, I should have known better than to announce on the channel that I was making real progress. :(. Because as I was getting into the game execution logic, I began to realise just how complicated they made the engine. Whilst using C++ has it's advantages from the perspective of RE, since it does group related functions close together with the variables they use, in this case, they seemed to go overboard with it.

A preliminary look at the main event loop of the game shows they implemented a stack of "action objects" - multiple independent event handlers can be registered and control swapped form one to the other. I'm not sure, but I presume that this is to allow for things like cutscenes, where standard game operation is superseded.

For even more complexity, they went with a class hierarchy for the action objects which is at least four levels deep!.
The classes, as far as I've been able to determine, are as follows:
  • They have a core 'SavedObject' class, which has some internal logic for registering each object instance in a central list. I presume this is for automating saving and loading.
  • A child class which I'll call "SmartPointer". This class seems to encapsulate a pointer to a secondary object, and provides core logic for 'fixing' up the pointer reference. I can't be sure yet, but there's a lot of 'fixup' code in the engine, which I presume handles restoring pointer references between objects when a savegame is loaded, and all the objects are re-constructed. This class also implement a basic virtual table of processing and dispatch methods that automatically defer to the foreign object if one is set
  • Yet another child class which introduces basic event manager functionality amongst other things
  • A concrete fourth child class which seems to further override some of the event manager functionality, and is what gets added to the game's "action list".


As you can imagine, all this makes it somewhat different to understand what the blazes is going on. I've also examined the engine from some other points, such as scene loading, and even that seems to be overly complex, with method calling method - they really went in the direction of generalised/generic functionality, with the result that the code seems to be much more complex than it should otherwise need to be.

</whinge>

In any case, the tSage engine was only meant to be a part-time RE effort for when I needed a break from the MADS engine. I did somewhat get carried away with it for the last few weeks, but that was only because the areas I was looking at proved so easy to reverse engineer. Now that I'm running into more complex code, I've decided that the break's over, and I'm returning to work on the MADS engine again. For that, at least, the code seems somewhat simpler, even if it can be a pain to run in the DOSBOX debugger because the segments keep getting shifted around in memory. ;)

For those of you who are Ringworld fans, don't worry, I'll still be working on the engine. It's just there won't be as rapid a progress on it as I'd recently hoped.