
Hero of Allacrost: Engine Overview
Until today, I would have had to shamefully admit that I a have barely considered another person's code beside my own. I'm not talking about example code. Rather, I'm referring to looking at another person or group's large-scale program and attempting to figure out how they structured it at a high level. If you haven't done this yourself, I can say from my my recent experience that it's an eye opener for considering different ways of doing things. Most importantly it allows one to see how a successful program is designed.
Today I'll be reviewing Hero of Allacrost. It's an up and coming C++ RPG in the Open Source world. Although it's not a full game as of yet, a tech demo has been released and the team is well on it's way to expanding it into a full story-driven game.
Originally when I had decided to look into how an RPG game engine was designed, I thought it would require slogging through code multiple times in a chaotic attempt to understand the engine's structure. Thanks to the work by some easy to understand authors gaining insight into their engine turned out to be rather painless, much to my relief.
Allacrost makes extensive use of the singleton design pattern. The defining point of singleton classes is that they can only be instantiated once. Attempting to instantiate them again common returns a pointer to the already instantiated instance. Allacrost has audio, video, scripting, input, global, mode, and system singletons, among others. They are instantiated in main.cpp so that whatever uses them later on doesn't have to worry about setting them up. One can pretty much guess what these singleton's do, based on their names, except for the mode singleton, which leads us to the next defining point of the Allacrost engine.
Allacrost uses a concept of game modes. Example modes include map exploration, battling, shopping, paused gameplay, the menu screen, and even quit confirmation. Multiple modes can exist at the same time on a stack, with the mode at the top being the one that the game actually runs. Each mode requires three functions:
- Reset(): Prepares a mode, which has just reached the top of the mode stack, for use again.
- Update(): Allows a mode to do its processing.
- Draw(): Draws a mode.
Speaking of updating a mode, Allacrost uses time-based movement as opposed to fixed movement. This allows the game to take advantage of fast computers while at least running on older computers. From reading the Allacrost Quick Start Guide, I learned that the sleep function, which would be required with fixed movement on fast computers, has a varying accuracy across different operating systems. Besides any modern operating system will divide processing power between the running processes. Allacrost still makes use of the sleep function while in pause mode due to it's low use of the processor.
The input singleton accepts input from a keyboard or joystick and provides it to the rest of the engine in a queue of commands, such as move up. Each command has three accessors: pressed, released, and state. A command is pressed during the first main loop iteration that it is detected in. Released is similar. That leaves state, which is only true if the button triggering a given command is currently down.
The audio singleton makes use of the OpenAL and Ogg Vorbis libraries. It treats sound and music similarly, but distinctly and with differing features. While one song can play at a time, there may be a number of sound effects in use at once. To keep things simple, as all programs that are actually completed must, Allacrost refers to music and sound files by filename, excluding path and extension. All music files are stored in a single directory, while sound files are stored in another. There are no category folders for audio beyond that. Audio can be played, paused, stopped, and unloaded, among other things.
Next up, we have the video singleton. OpenGL is used for graphics, DevIL for images, and SDL_ttf for fonts. One common problem game programmers face is what the heck to do with different screen resolutions. Is a game's difficulty balanced really balanced when you can see more of the map just because you are using a higher screen resolution than someone else. Allacrost gets around this by dividing the screen with a coordinate system. The video singleton has a function that allows the programmer to choose the coordinate system, so for example, the screen can be 32 arbitrary units across and 24 arbitrary units high. The Allacrost team uses this to ease tile placement in map mode. Another point of interest with the video singleton is that it permits drawing on the screen using a cursor that can have it's location set absolutely or relatively, among other things. Relating to the video singleton, the GUI singleton uses unicode for displaying text so that the game can be translated to languages of other alphabets in the future.
What RPG would be complete without a scripting language? Allacrost wouldn't and that's why it uses the Lua scripting language. Of interesting note, Lua is also the Roman goddess whom soldiers would offer their seized weapons to. Anyway, the Lua scripting language can be bound with C++ allowing the Allacrost team to rapidly create game content to fill their engine with. Scripts can be stored in a binary or text mode. It makes no difference to the engine, although binary scripts will naturally run faster. The engine can read them using functions like bool readBool (const char *key) and int readInt (const char *key). The key just identifies what variable in a given table (as Lua calls a scope) should have it's value returned.
Finally, one more topic I feel is of merit in this summary of the Allacrost Getting Started Guide is error handling. The Allacrost team uses their own Exception class, upon which all other exceptions are derived from. If an exception unwinds the stack all the way back to the main game loop, the game crashes with a message. Smaller errors, such as failing to load a file, are handled immediately through the boolean return value of related functions.
With the above said, Hero of Allacrost is definitely a game to keep an eye on. Even if it goes nowhere, the existing documentation and code is something to learn from! Best of luck to the development team. You guys, and girls if there are any, rock!

No comments:
Post a Comment