Building AdventureKit

Having decided that I’m building a 2D adventure game engine, it’s time to give it a name and figure out what I want out of it.

The Name

Following in the grand tradition of Apple frameworks, I’m calling it AdventureKit.

Whew. That’s enough for today, I think. Time for a beer…

Engine Goals

I had a specific idea I was exploring with the prototype. I wanted to see how viable it would be to use JSON as the format for scene data and dialogue as I want to be able to rapidly iterate the game while it’s running on an iPad.

(JSON is an easy to read, plain-text data format. This means that it can be edited in any text editor on the iPad.)

Say I’m developing a scene and think of an additional object that the room needs to make a puzzle more interesting. I’d like to be able to:

  1. Export the room JSON file from the app bundle
  2. Add the object parameters (name, position, sprite filename, dialogue for verb actions such as look or use, object limitations, etc.) in a code editor on the iPad (such as Textastic)
  3. Export this file from the text editor back into the game’s Documents directory
  4. Open up a drawing app, such as Procreate, and sketch out the object
  5. Export this image file from Procreate into the game’s Documents directory
  6. Return to the game, and tap a reload button

Tapping the reload button would cause the engine to refresh the scene and show the new object, which would be immediately interactive—depending on the object parameters, the player could pick it up, put it in their inventory, use it with other objects, give it to other characters, etc., without restarting the game.

All of this would happen entirely on the iPad.

Scene 1, Take 2

As assets or edited files cannot be added to the game bundle of an installed game (as its read only), here’s how the engine would find them:

Tapping on the reload button would cause the engine to look in the game’s Documents directory first for all scene and dialogue data, as well as assets (such as images or sounds), before falling back to the defaults in the bundle itself (if they exist).

If an asset such as a character or object image doesn’t exist in either the Documents folder or the bundle itself, then placeholders would be automatically created. These placeholders would allow testing to continue without having to wait for finished assets.

Development Mode

This workflow would only happen while the game is running in a special development mode. Other features of this development mode would include:

  • Being able to export all the new or edited assets in the Documents folder
  • Being able to manually assign imported assets to objects, characters, and scenes
  • Being able to assign dialogue data files to characters
  • A basic text editor to quickly make changes to the JSON data files within the game itself
  • A reset dialogue button that would conversations with characters to be restarted from the very beginning

Once I’m happy with how everything looks and works, then any files created or edited on the iPad would be exported to my laptop. They would then be polished and optimised as necessary (e.g. incorporated into a sprite atlas) and added to the bundle, ready for the next build.

Extending the Format

This process could extend beyond simply adding objects into existing scenes. It could allow me to add entire new scenes without a new build of the game.

One of the core attributes in a given scene file will be defined exit areas. These exit areas will have a reference to the filename of the next scene. When the player character enters that exit area, the engine would look for the scene file and load it if it exists.

This means that, between editing existing scenes to add new exit data and creating new scene files, it would be possible to add entirely new scenes solely on the iPad.

I already have this system working with character dialogue and it’s super fun. Being able to quickly fix typos or add whole new dialogue branches on the iPad itself without returning to Xcode is amazing.

I can only imagine how great it would make me feel to be able to add whole new scenes and characters on the fly. Somewhere close to God-like, I expect.

The Agnostic Engine

All adventure games need to be able to do basic things like show a title screen, have volume control settings, save and load games, handle inventory management systems, and so on.

The UI for these systems might have different designs for different games, but the fundamental functionality will be the same.

There’s no reason why JSON files couldn’t be used to define the assets for these UI elements as well.

This means that the engine could be created as a framework. My vision is to have the game bundle be nothing more than the engine (installed as a CocoaPod) and a big pile of assets: game data, scene data, character dialogue, image files, and sound files.

Any updates to the engine could then apply to all games at once and should help keep my entire (future) library of (hopefully many) games up to date. I could even add new features (better controls, or improved inventory management) that older games get the benefit of for with no additional work.

That’s the dream, at least.

There’s Always a Catch

The biggest potential problem I can see so far with this approach is that the number attributes required to define a believable scene might become too high, making working with JSON impractical. There are subtleties to adventure games (especially around animation) that might be tricky to model in this format without dozens of attributes, making it more confusing than if I had just modelled them some other, less abstracted way.

Another issue is performance. While reading JSON data files is lightning fast these days, loading all the sprite data they reference just in time might be too much even for modern devices.

However, the basic engine I already have built has shown that this direction has promise. Some of the scene data (like walkable areas and NPCs) and the dialogue systems are in place and are working well.

Right now there doesn’t seem to be any performance penalties to doing it like this, although my tests have been limited to single scenes so far.

If performance does become an issue, then there are things I can try. Most scenes will only have exits to one or two other scenes, so loading up all linked scene data in the background so everything is ready when the player selects an exit (at which point the unneeded assets are discarded) is a possibility.

I’m excited about the potential for AdventureKit to make developing adventure games on iOS quick and easy. Next up is trying to wrangle this excitement into a realistic roadmap for development, lest I find myself working on advanced esoteric features that would only be needed for a single specific scene in a single game (based on my past history, a not unlikely scenario).