[insert links here]

Project OpenMortal

Toplevel Design Document

1. Introduction

1.1 Purpose of this Document

This document describes the design of OpenMortal.

OpenMortal consists of two main parts: the frontend and the backend.

1.2 Revision History

This table will be appended whenever this document is changed. Description of the nature of changes will be stored here.

Initial version. Describes the program's state after release of version 0.3

1.3 Definitions

Here are the definitions of terms used in this documentation.


Player refers to one of the two persons playing the game. A player chooses a fighter. The two players are referred to as "Player 1" and "Player 2", even though the C++ and perl code count arrays from 0.

Fighter is one of the many available characters. Usually there are only two fighters loaded at any time. Fighters are static: their properties never change. Maybe Fighter should be renamed to Character?

One game is the part of the program in which the players actually compete. The game consists of a number of rounds. The player selection, and gameover screen are not part of this definition.

One round starts with both players at full health, and ends either with a timeout or with a ko.

A graphical element on the game screen that is not the background or the characters. E.g. the "3x combo" text or a thrown projectile are doodads.

A tint is a methodical change in a palette. There are many ways to tint (e.g. grayscaling, darkening, green chroma, etc). Usually when two players choose the same fighter, the fighter of player 2 is tinted.
The description of a frozen moment in the course of a game. The Backend is responsible for calculating each consecutive scene. The number of scenes calculated per second is constant (except for the "hurry up mode", or if the computer is too slow).

Frames Per Second. The FPS indicator on the screen during a game indicates the number of scenes drawn, not the number of scenes calculated by the backend.

1.4. C++ Coding Conventions

Unfortunately two coding conventions are mixed in OpenMortal. The older style is somewhat Qt-esque (method and variable names starting with lower caps), the other is a new coding style that I adapted to at work. I plan to convert the entire codebase to the new style eventually in small steps. Here I will describe the new conventions:
The prefixes used are:
SomeExampleClass: public SomeBaseClass
void SomeMethod( int& a_riOutSomething );
int m_iSomething;
char* m_pcSomethingElse;
static enum SomeThingEnum
} mg_enWhatever;

2. The Frontend

The frontend is a C++ program. It uses SDL for hardware access such as screen drawing, music, sound effect and keyboard input. For information and documentation of SDL, SDL_image, SDL_ttf and SDL_mixer, please look at the SDL homepage.

The Frontend divides responsibilities into a number of classes:
Some utility methods and structures are imported from the SGE library. Yet some more are in gfx.cpp and common.cpp. There pieces are of less importance, and will not be discussed in this document.

2.1. State and Menus

State, despite it's name, stores global program configuration and state. It is a singlular object, and is accessed with a global pointer, g_oState. All other frontend modules access the state through this object. The state is made persistent through it's methods, Load() and Save(). Load is called on program start, Save is called when the program exits.

The State is the way the menus communicate with the rest of the system. For example, if the user chooses "Quit" from the menu, the m_bQuitFlag is set to true, and the program will react accordingly.

The state's most important properties are:

2.2. RlePack

The RlePack is an array of images, compressed with runlength encoding.

OpenMortal stores the character graphics (and eventually, the doodads too) in RlePacks. The reason is simple: RlePacks give an acceptable tradeoff between memory usage and blitting speed. Also the RlePack allows the sprites to be draw horizontally flipped.

The sprites in the RlePack are always paletted (8 bits per pixel). The size of the palette is between 0 and 256. The RlePack stores two copies of its palette: one is the "base" palette, as it was read from disk, the other is the "tinted" palette. The TintEnum contains values that can be passed to RlePack::SetTint. This is used for two things:
Additionally, the RlePack allows the color range to be shifted. This is necessary: if we want to load two characters with different palettes, both cannot occupy the same physical color range. Since all player RlePacks use 64 colors, the first pack will be shifted use colors 112-175, and the second will use colors 176-239. (The rest of the system palette

RlePack doesn't concern itself with concepts such as "player" or "doodad", it merely stores the palette and sprites. This part of OpenMortal can be reused in any project with little changes.

2.3. PlayerSelect

This class implements services that allows players to select their fighters. It also stores info about which fighter is available, and allows other parts of the program to programmatically assign a fighter to a player, and set fighter tints (this is used by e.g. the aqua-colored "frozen" effect).

Most important methods are:

2.4. Audio

2.5. Backend Connection

The Backend has two distinct functions: providing a connection to the embedded perl interpreter, and providing the frontend with variables that describe a scene of the game.

The backend can
  1. Read the scene from the Perl backend.
  2. Read the scene from a string.
  3. Write the scene to a string.
The string conversion routines are used for replays and instant playback. There are plans to add network read/write support to the backend which would allow OpenMortal to be played networked. This is a feature planned for version 0.5 or later.

Most important methods of the Backend are:
The public members of Backend describe the scene which was last read. The meaning of these should be mostly obvious and I will not detail them here. For more information about the scene and the working of the perl backend, see the chapter on the perl backend.


3. The Backend

3.1. Overview

3.2. Fighter

3.3. PlayerInput

3.4. Damage

3.5. Collision

3.6. Doodads

3.7. Fighter Data


4. The Game Workflow 


5. Game AI