Home Memoirs of a Gamer Movies I watched Guidebook Code Projects Links

The Gorgon Engine

The Virtual Machine

At the heart of the engine is the virtual machine. The virtual machine is basically a collection of subsystems that are tied together via a bytecode interpreter. These subsystems are:

Beyond these subsystems there is the bytecode interpreter which has the following configuration

ObjectTable Count
Script File Segments10
Integer Variables256
Integer Stack256
String Variables16
Inventory Table128
Room Tracker Table1008

Script File Segments

Script files are block loaded into the appropriate segment as requested. When execution begins the VM tracks which segment is currently executing, the beginning and ending of the current script, and the current program counter. There is also a limited execution stack that is used to track when call instructions are executed.

Script File Format

We start with the script header which follows the following structure:

OffsetSizeValue
0002Should always be the hex value 6353h
0201Title Index
0301Variable Count
0401Event Count
0501Start Event Index
0602String Count
0802Events Table Offset
0A02Bytecode Segment Size
0C02Bytecode Segment Offset
0E02String Table Offset
1002String Data Size
1202String Data Offset
1401Array Size
1501Reserved
1602Array Data Offset

The Title Index identifies the entry in the String Table that contains the game's title. A value of -1 implies no Title.
The Start Event Index identifies the entry in the Events that defines the event to be executed upon loading the script. A value of -1 implies no Start Event.

The Events table is composed of 6 byte records following the format:

OffsetSizeValue
0002Bytecode Offset
0202Bytecode Length
0401Name Index
0501Reserved

The Bytecode segment contains all of the events' bytecode blocks strung together with no empty spaces between events.

The String Table is a simple array of 16 bit integers describing the offsets of each string in within the String Data segment. Strings are delimited by null terminator characters.

The String Data segment contains all strings with a null terminator character inserted after each string. All strings are stored as ASCII characters.

The Array Data segment is a simple array of 16 bit integers that can be referenced by the Bytecode instructions.

The GDK comes with a decompiler called Descriptor which is found in the same folder as the Scriptor compiler tool. Usage:

descriptor game.cns

System Registers

There are several system registers that can be accessed by using a series of pseudo variables that are dot notation extensions of the internal sys object. They are as follows:

IDNameAccessibilityCategory
0sys.ThisRoomReadRoom
1sys.LastRoomReadRoom
2sys.FirstTimeReadRoom
3sys.ScoreRead/WriteScore
4sys.MaxScoreRead/WriteScore
5sys.RandomRead/WriteMath
6sys.ControlledWriteFlags
7sys.TypingWriteFlags
8sys.PhysicsWriteFlags
9sys.SlowTypeWriteFlags
10sys.Spr_IdWriteSprites
11sys.Spr_XReadSprites
12sys.Spr_YReadSprites
13sys.Spr_DirReadSprites
14sys.Spr_PriorityRead/WriteSprites
15sys.Spr_MapReadSprites
16sys.Spr_CompletedReadSprites
17sys.Spr_SlotWriteSprites
18sys.Spr_PalWriteSprites
19sys.TimeReadMath
20sys.ShowScoreWriteFlags

Let's break these down by category.

Room Information

There's 3 Room related registers, ThisRoom, LastRoom, and FirstTime. They are read only and their purposes are fairly straight forward.

Then we have the score related registers for current Score and the MaxScore. They are exactly as their names suggest. An important note to bare in mind is that the Score register will force a refresh of the score marker on the screen if the ShowScore register is set. No such functionality is attached to MaxScore.

Next we have our 2 Math registers: Random and Time.

Now let's look at the environment flags. All flags are intended as simple write only boolean values. Like other parts of the engine, true is defined by what's not false and false is always defined as 0. Their behavior is mostly self explanatory, but for clarity's sake we'll list them here:

NOTE:Slow Type causes the printing subsystem to type one character to the screen at a time, allowing for a vsync event between each character. Disabled by default. Disabling this feature causes strings to be printed as quickly as possible.

The last set of system registers are for the Sprite subsystem and are discussed in detail here.