06 February 2011

An Architecture Overview

“All Gaul is divided into three parts.” So is King of Dragon Pass.

mTropolis code
What you see — the user interface — was all coded with mTropolis (a fine multimedia authoring tool that sadly was killed before King of Dragon Pass was released). mTropolis handled screen layout, responding to clicks, transitions, fading music and sound, and the like. mTropolis could build applications for either Windows or Mac.

The 500+ interactive scenes were all coded in our custom scripting language, OSL. This was designed to be easy for our writer, and to easily express the sorts of interactions we’d designed. OSL source files were compiled into bytecodes with the scene compiler. At run time, these were executed by C++ code.

Finally, there’s the game engine. This consisted of the OSL interpreter, as well as the economic model, which kept track of lots of information about each clan, including their relations with each other. This was all C++ code, and pretty much cross-platform.

Each system communicated only with lower-level ones for the most part. The mTropolis code could talk to the game engine by means of modifiers, special glue code that exposed most of the object properties. And the OSL language was full of functions to pick the least friendly clan, kill a random leader, etc. The OSL variables acted as a convenient shared system as well. For example, the mTropolis UI would set variables to indicate which heroquest and leader the user had picked. The OSL code for the heroquest would use these. The game engine would also set variables depending on the economic situation. And of course, since variables were persistent, one scene written in OSL could respond based on what an earlier one had tracked.

This flow worked for the UI, since the user was switching screens and performing actions. But interactive scenes were a special case, since what the user sees depended on what OSL code did. The original game had two C++ methods which let the game engine (typically on behalf of OSL) talk to mTropolis:  CScene::SendToCurrentScene, which passed along messages like NewChoice (see the chart here for details) or DoDefensiveBattle, and CScene::DebugMessageAlert, which displayed an error dialog.

Interface Builder connections
For the iOS port, the mTropolis code is replaced by iOS code, using UIKit (the high level user interface framework) written in Objective-C or hooked up using Interface Builder. None of the OSL scripts need to change, and only a very small part of the C++ engine needed updating (I did change file handling slightly). Instead of talking to the engine through an mTropolis modifier, the UI code can be written in Objective-C++, and can directly call engine code. And CScene::SendToCurrentScene and CScene::DebugMessageAlert are the only places that the engine talks to UIKit code.

So since two layers are cross-platform, almost all the work on the iOS version has been replacing mTropolis code with UIKit. Although I hope it all feels straightforward, the game’s interface is actually pretty complex, so it’s reasonable to say it’s about a third of the original development effort (not counting art and sound). And it’s a significant development effort for iOS as well.

And the UI layer would need to be recoded for other platforms (such as Android, or even Mac OS X). I expect it would be easier the third time, but it would still be a significant effort. And right now the focus is on getting the iOS version done.

No comments:

Post a Comment