|
Ultima IV:
Behind The Scenes
Would you like to know some of the workings behind this game? If so,
you're in the right place. In creating this site as well as the graphic
upgrade, I've had to uncover the details behind just about every file type
used by the game program.
Table of Contents
The
Original Graphics
The following information refers to
the original pre-patch data files, SHAPES.EGA, CHARSET.EGA, START.EGA,
STONCRCL.EGA, KEY7.EGA, RUNE_#.EGA, and virtuename.EGA.
Evaluating the Color Data
EGA palette (Netscape
might not show this table correctly. Too bad.):
| 0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
C |
D |
E |
F |
| 0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
In the 16-color PC
version of Ultima IV, each raw, unencoded byte holds two four bit color
values. For example, a byte value of 255 is
represented in binary as:
1 1 1
1 1 1 1 1
In order to see which
two colors will be assigned to the pixels, we break it into 4-bit halves
like this:
1
1 1 1 | 1
1 1 1
... and we see that
these two binary halves are equivalent to the decimal numbers 15
and 15. Therefore, a byte value of 255
means "white" followed by "white".
Similarly, if the byte
value were 142, then we would find it to mean
"dark gray" followed by "yellow" like this:
142
= 1 0 0 0 1 1 1 0
1 0 0 0 |
1 1 1 0
1 0 0 0 = 8
1 1 1 0 = 14
The "short
cut" is, of course, to just look at the hexadecimal value of the
byte. If we know that the 142 mentioned above
is 8E in base 16, then all we have to is know
that 8 is the first color and E
(or 14 in base 10) is the second color.
4F
means "dark red" followed by "white".
SHAPES.EGA (tiles) and
CHARSET.EGA (font)
SHAPES.EGA, the tile
graphics set, is 32,768 bytes. There are 256 tiles, and each one is
defined by 128 bytes of the file using the method described above. The
data is read left to right and top to bottom. Each tile is 16x16 pixels.
Thus, the top row (16
pixels) of tile #0 is defined by the first 8 bytes of the file, which
expands to color data for all 16 pixels. The next 8 bytes defines the
second row of tile #0, and so forth.
To find the offset of
any particular tile, use: offset
= tile * 128 where tile
is 0 to 255. To find the offset of a row within a tile, use: offset
= tile * 128 + y * 16 where y
is 0 to 15.
CHARSET.EGA is very
similar to SHAPES.EGA. It defines the game font and can hold data for 16
colors exactly as the tiles do (despite Origin's release using only the
light gray color for text). The file is 8,192 bytes, the last 4,096 of
which don't seem to be used at all. There are 128 characters in the font,
each defined by 32 bytes. Each character is 8x8 pixels.
The top row (8 pixels)
of character #0 is defined by the first 4 bytes of the file.
The formulas presented
above can be easily modified to find a particular character or row.
Click
here to see the ordering of the character set.
Remaining Applicable .EGA
Files (run length encoded)
To start, the
following table describes what these files contain:
| START.EGA |
the "border"
graphic that divides up the main game screen |
| KEY7.EGA |
graphic shown when you use
your key of 3 parts |
| RUNE_0.EGA |
the meditation vision for
valor |
| RUNE_1.EGA |
the meditation vision for
honesty, justice, and honor |
| RUNE_2.EGA |
the meditation vision for
compassion and sacrifice |
| RUNE_3.EGA |
the meditation vision for
spirituality |
| RUNE_4.EGA |
the meditation vision for
humility |
| RUNE_5.EGA |
displayed after answering
the final riddle |
| STONCRCL.EGA |
displayed at congratulation
screen |
| HONESTY.EGA |
the
remaining files are all parts of the codex symbol that is built
during the endgame. They are written to the screen with a logical
OR, so the pixel positions of their values cannot be allow to
overlap from file to file... among other things, our patch changed
this. We also use 9 RUNE files instead of just 6. That way, we
could have a unique vision for each virtue quest. |
| COMPASSN.EGA |
| VALOR.EGA |
| JUSTICE.EGA |
| SACRIFIC.EGA |
| HONOR.EGA |
| SPIRIT.EGA |
| HUMILITY.EGA |
| TRUTH.EGA |
| LOVE.EGA |
| COURAGE.EGA |
All of these files use
the same format, which differs from the tileset and font format. They are
run length encoded (RLE), meaning that a signifier byte tells the program
to start a "run" of one particular byte for a certain number of
repetitions. For example, if you had a run of 180 "black-black"
bytes (remember, each byte still holds information for two adjacent
pixels), this would be compressed to just three bytes in the file: first
the signifier, then the run length (up to 255), then the value to be
repeated.
The signifier byte in
ALL of these files is 02.
Therefore these 180
bytes mentioned above would be compressed to: 02 B4
00. This would mean 360 pixels of black.
For single values (not
part of a run), the file simply includes the value. It is only when you
want to have a run of 3 or more of the same value that it is economical to
encode it as a run using the signifier byte.
The only strangeness
occurs when you actually WANT to have a "black-darkgreen" byte
(or bytes), which you should realize by now is ALSO the byte value 02.
Even if there is only one of these, it must be encoded as a run, like
this: 02 01 02.
The maximum run value
is 255 (510 pixels in 16 color mode). If there are more than this a new run must be started.
Because of the RLE,
these files will all have varying lengths, and you must uncompress them to
edit them. Once uncompressed, they will all, invariably, be exactly
32,000 bytes.
No matter how small
the actual visible (non-black) part of the graphic, the entire 320x200
screen is represented by these files. In other words, even if the
meditation vision takes up a very small piece of screen, the image file
itself will be 320x200 and mostly black. The game knows not to overwrite the
screen with "black-black" bytes.
A run does not stop at
the end of a "row". That is to say, if you started a run of
black near the end of a row (say at coordinate x300,y0), it would
"wrap" around to x0,y1 and continue on.
The New Graphics
(VGA Patch)
While I'm not even
close to being able to explain Aradindae's programming genius in making it
all work, I can tell you how the graphics files were changed to accommodate
the 256 color palette.
Added,
Changed , and Unused
files:
| U4VGA.PAL |
768 byte color palette |
| RUNE_0.EGA |
displayed after answering
the final riddle |
| RUNE_1.EGA |
the meditation vision for
honesty |
| RUNE_2.EGA |
the meditation vision for
compassion |
| RUNE_3.EGA |
the meditation vision for
valor |
| RUNE_4.EGA |
the meditation vision for
justice |
| RUNE_5.EGA |
the meditation vision for
sacrifice |
| RUNE_6.EGA |
the meditation vision for
honor |
| RUNE_7.EGA |
the meditation vision for
spirituality |
| RUNE_8.EGA |
the meditation vision for
humility |
| SHAPES.VGA |
the 256 color tile set |
| CHARSET.VGA |
the 256 color character set |
| SHAPES.EGA |
old tiles |
| CHARSET.EGA |
old font |
| Other .EGA files
are still used but converted to 256 color: START, STONCRCL, KEY7,
and all virtues and principles (COMPASSN, LOVE, etc.) |
The Palette File U4VGA.PAL
This file is 768 bytes
and holds the color palette information used by the patched game. There
are 256 possible colors (out of 262,144), and each one is described by 3
bytes ranging in value from 0 to 63 (hex 00 to 3F). The byte order is Red,
Green, Blue.
Evaluating the Color Data
This couldn't be
simpler: 1 byte for 1 pixel. Breaking the information into two 4-bit pairs
is no longer necessary as it was in the 16 color mode.
SHAPES.VGA (tiles) and
CHARSET.VGA (font)
SHAPES.VGA, the tile
graphics set, is 65,536 bytes. There are 256 tiles, and each one is
defined by 256 bytes of the file. The data is read left to right and top
to bottom. Each tile is 16x16 pixels.
Thus, the top row (16
pixels) of tile #0 is defined by the first 16 bytes of the file, with 1
byte for 1 pixel. The next 16 bytes defines the second row of tile #0, and
so forth.
To find the offset of
any particular tile, use: offset
= tile * 256 where tile
is 0 to 255. To find the offset of a row within a tile, use: offset
= tile * 256 + y * 16 where y
is 0 to 15. To find any particular pixel within a tile: offset
= tile * 256 + y * 16 + x where
x is also 0 to 15.
CHARSET.VGA is very
similar to SHAPES.VGA. It defines the game font and can hold data for 256
colors exactly as the tiles do. The file is 8,192 bytes, all of which is
now used. There are 128 characters in the font, each defined by 64 bytes.
Each character is 8x8 pixels.
The top row (8 pixels)
of character #0 is defined by the first 8 bytes of the file, and so on.
The formulas presented
above can be easily modified to find a particular character, row, or pixel
offset.
Click
here to see the ordering of the character set.
Remaining .EGA Files (run
length encoded)
All of the remaining
files (indicated above) use the same format, which differs from the
tileset and font format. They are run length encoded (RLE), meaning that a
signifier byte tells the program to start a "run" of one
particular byte for a certain number of repetitions. For example, if you
had a run of 180 "black" pixels, this would be compressed to
just three bytes in the file: first the signifier, then the run length (up
to 255), then the color value to be repeated.
The signifier byte in
ALL of these files is 02.
Therefore these 180
bytes mentioned above would be compressed to: 02 B4
00. This would mean 180 pixels of black.
For single values (not
part of a run), the file simply includes the value. It is only when you
want to have a run of 3 or more of the same value that it is economical to
encode it as a run using the signifier byte 02.
The only strangeness
occurs when you actually WANT to have a "darkgreen" byte (or
bytes). Even if there is only one of these, it must be encoded as a run,
like this: 02 01 02. For this reason, I
duplicated the green color elsewhere in the palette file, and then wrote a
little utility to find and replace any occurrence of 02
in the raw image data with its equivalent. This way, we get maximum
efficiency from the RLE by sacrificing only one palette slot.
The maximum run length
is 255 pixels. If there are more than this a new run must be started.
Because of the RLE,
these files will all have varying lengths, and you must uncompress them to
edit them. Once uncompressed, they will all, invariably, be exactly
64,000 bytes.
No matter how small
the actual visible (non-black) part of the graphic, the entire 320x200
screen is represented by these files. In other words, even though the
meditation visions takes up only the portion of the screen on which your
party moves through the map, the image file itself will be 320x200 and
mostly black. The game knows not to overwrite the screen with black.
A run does not stop at
the end of a "row". That is to say, if you started a run of
black near the end of a row (say at coordinate x300,y0), it would
"wrap" around to x0,y1 and continue on.
Miscellaneous Changes
In order to make the
endgame prettier, the logical OR operation used to write each piece of the
codex symbol to screen was changed to an XOR operation. Therefore, it was
necessary when building each successive image to XOR it with the
previous image. It is not sufficient to simply draw and save each
"frame" of the codex symbol... the colors will "reverse
out" and look entirely unlike what you expected.
The World
Map (WORLD.MAP)
The WORLD.MAP is a
65,536 byte file, whose values correspond to the tile
list shown at the bottom of this page.
You might expect this
file to be a simple matrix of 256x256 tiles, which corresponds to the
world size. You would be wrong about that. Presumably to save memory, the
Ultima IV program will only load a small section of the map at a time, and
in order to facilitate this the world map is divided into smaller pieces.
It is in fact divided
into a total of 64 32x32 chunks, with the chunks arrayed as follows:
| 1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
| 9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
| 17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
| 25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
| 33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
| 41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
| 49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
| 57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
As far as actual byte
order in the file, chunk 1 will take up the first 1,024 bytes. Chunk 2 the
second 1,024, and so forth.
Within these chunks,
the byte order is as expected. That is, the first 32 bytes are row 1, the
second 32 bytes are row 2, etc.
The Town
Maps (.ULT)
These files are the
town maps. They also contain information about the people in the towns and
their starting positions.
Standard ULT File
Structure (1,280 bytes):
Map (1,024 bytes):
A 32x32 matrix
defining the tiles that make up the town. Values taken from
the tile list below. Only the physical structure of
the town is defined here. Characters and shopkeepers are NOT!
Population (256 bytes):
Series of bytes
defining the appearance, starting position, behavior, and dialog tree
for up to 32 characters.
Each series of 32
bytes within this 256 byte block represents a different type of data,
but they always come in the same character order. In other words,
population offset 0, 32, 64, 96, 128, 160, 192, and 224 all refer to the
same NPC, as do offsets 1, 33, 65, 97, 129, 161, 193, and 225.
If less than 32 NPC
characters exist in the town, then zeroes come FIRST in the sequence.
32 bytes =
tile to represent character ??? (guard, child, merchant, etc.)
Changing this value seems to have no effect. In order to alter the
graphic, you must change the similar value below. This value may have
something to do with the combat prowess of the NPC, but that is
unconfirmed and seems unlikely. Always, this number will be very close
or identical to the other similar value explained below. Let me know if
you are sure of the meaning of this byte.
32 bytes = X
position of character (0 to 31)
32 bytes = Y
position of character (0 to 31)
32 bytes =
tile to represent character (guard, child, merchant, etc.)
In some cases, this is a repeat of the first number. Other times it is 1
or 3 less depending on if it is part of a 2-frame or 4-frame animation.
If the NPC's graphic is part of an animated frame series, this number
should always be the first number in that series. Changing this number
will alter the graphic used to represent the NPC.
32 bytes = X
position of character (repeat of previous X value)
32 bytes = Y
position of character (repeat of previous Y value)
32 bytes =
character behavior:
| 0 |
Stationary |
| 1 |
Normal Wandering |
| 128 |
Follows PC closely (or
is Merchant) |
| 255 |
Tracks Player &
Attacks (as a monster does) |
32 bytes =
character identity (indexed in corresponding TLK file)
Value is 1 to 16 (as ordered in the town's TLK)
or 0 (no identity -- a silent character or a merchant has no TLK id)
The
Combat Maps (.CON)
These files are the
combat screens. For example, if you attack the shore from your ship, melee
combat will be carried out on the SHIPSHOR.CON map.
The exception is
SHRINE.CON, which DOES NOT have the same structure. Even if you melee over
a shrine tile, you will see grasslands. The SHRINE.CON is instead used
only when you meditate and has a different byte structure.
Standard CON File
Structure (192 bytes):
Header (64 bytes):
Defines starting
positions of player's party members and monsters.
Possible X and Y values range from 0 to 10 (A).
byte 0-15 =
starting X position of monsters (up to 16 monsters)
byte 16-31 = Y position of monsters
0 and 15 create a coordinate pair, as do 1 and 16,
etc. If fewer than 16 monsters, monster starting positions are randomly
chosen from among these coordinate pairs.
byte 32-39 =
X position of party members (up to 8 party members)
byte 40-47= Y position of party members
32 and 40 create a coordinate pair, as do 33 and 41,
etc. Positions are not random; they are always used in order no matter
how many characters in your party.
byte 48-63 = 08
AD 83 C0 AD 83 C0 AD 83 C0 A0 00 B9 A6 08 F0
Purpose unknown. Seems to be constant among all files.
Body (121 bytes):
An 11x11 matrix
defining the tiles on which combat will take place. Values taken from
the tile list below.
Footer (7 bytes):
Always seems to be 8D
00 00 00 00 47 09. Purpose unknown.
SHRINE.CON File
Structure (192 bytes):
Body (121 bytes):
An 11x11 matrix
defining the tiles on which the characters meditate. Values taken from
the tile list below. The Party Icon (1F) is
explicitly defined in this matrix.
Footer (71 bytes):
Purpose unknown. No
similar files exist for comparison.
The Dungeon
Files (.DNG)
These files are the 3D
dungeon maps. They also contain information about all the top-down view
rooms that you might enter, the creatures that inhabit them, any floor
triggers present, and starting positions for characters and monsters.
Please note that ABYSS.DNG is slightly different and will be explained
separately.
Standard DNG File
Structure (4,608 bytes):
3D Map (512 bytes):
Each dungeon level
is an 8x8 grid, and there are 8 levels per dungeon.
Thus the first 64
bytes are Level 1, and the first 8 bytes are "row" 1 of that
level. And so on through 512 bytes.
The choice of values
here is limited (values shown in hex):
| 00 |
Nothing / Corridor |
| 10 |
Ladder Up |
| 20 |
Ladder Down |
| 30 |
Ladder Up & Down |
| 40 |
Treasure Chest |
| 50 |
Ceiling Hole (not
used?) |
| 60 |
Floor Hole (not
used?) |
| 70 |
Magic Orb |
| 80 |
Winds / Darkness Trap |
| 81 |
Falling Rock Trap |
| 8E |
Pit Trap |
| 90 |
Plain Fountain |
| 91 |
Healing Fountain |
| 92 |
Acid Fountain |
| 93 |
Cure Fountain |
| 94 |
Poison Fountain |
| A0 |
Poison Field |
| A1 |
Energy Field |
| A2 |
Fire Field |
| A3 |
Sleep Field |
| B0 |
Altar |
| C0 |
Door |
| D0-DF |
Dungeon Room - in order
from later in the file |
| E0 |
Secret Door |
| F0 |
Wall |
Ladders DO line up
between levels, and the hallways wrap around left to right and top to
bottom (like Pac-Man's escape tunnels!)
Dungeon Rooms
(4,096 bytes, 16 rooms of 256 bytes each):
There are 16 rooms
per normal DNG file. The order in which these rooms appear in the file
determines what identifier is used to place it on the 3D dungeon map.
(See above.) The first room is D0, the second is D1... and the 16th is
DF. Each room is defined as follows and totals 256 bytes:
16 bytes =
floor triggers; changes that occur when you step on certain coordinates
in the room. There can be four such triggers per room, and each one is
defined by four bytes. If there are less than four triggers, 0's
(meaning no trigger) come LAST in the sequence.
trigger byte 1 =
tile you wish to PLACE (see tile list)
trigger byte 2 =
where you step to activate the trigger. Examples:
Hex value 85
means you step on coordinate x8,y5 to activate the trigger.
Hex value A3
means you step on coordinate x10,y3 to activate the trigger.
trigger byte 3 =
coordinate of first tile to change.
trigger byte 4 =
coordinate of second tile to change.
TRIGGER EXAMPLE:
46 85 75 65 - Places a Fire Field at (7, 5) and (6, 5) when you
step on (8, 5).
PRACTICAL TRIGGER
EXAMPLE: (Abyss Level 7 room)
16 44 06 05 | 16
44 04 40 | 16
44 50 60 | 16
88 51 15
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
| 0 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
| 1 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
| 2 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
| 3 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
| 4 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
| 5 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
| 6 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
| 7 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
| 8 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
| 9 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
| A |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
Stepping on the
secret door at (8, 8) replaces the walls next to each wisp (5, 1 and
1, 5) with tile floors so you can reach the monsters. [Trigger
#4]
Stepping on the
spot occupied by the gazer (4, 4) creates purple tile floor exits to
the north (4, 0; 5, 0; 6, 0) and west (0, 4; 0, 5; 0, 6). Notice that
stepping on a single coordinate (4, 4) can activate multiple triggers.
[Trigger #1, #2, & #3]
16 bytes =
master (first frame) creature tile, as seen in tile list.
Defines types of monsters that will be in the room. If there are less
than 16 creatures, 0's (meaning no monster) come FIRST in the sequence.
16 bytes =
Creature starting X positions (0 to 10 (A)).
16 bytes =
Creature starting Y positions (0 to 10 (A)).
8 bytes =
Party starting X positions (0 to 10 (A)) if entering from top.
8 bytes =
Party starting Y positions (0 to 10 (A)) if entering from top.
8 bytes =
Party starting X positions (0 to 10 (A)) if entering from right.
8 bytes =
Party starting Y positions (0 to 10 (A)) if entering from right.
8 bytes =
Party starting X positions (0 to 10 (A)) if entering from bottom.
8 bytes =
Party starting Y positions (0 to 10 (A)) if entering from bottom.
8 bytes =
Party starting X positions (0 to 10 (A)) if entering from left.
8 bytes =
Party starting Y positions (0 to 10 (A)) if entering from left.
121 bytes =
11x11 matrix defining the physical structure of the room.
Creatures are NOT included here; only walls, floors, rocks, fields, etc.
7 bytes = 00
00 00 00 00 00 00 (filler)
ABYSS.DNG File
Structure (16,896 bytes):
3D Map (512 bytes):
The Abyss is exactly
the same as the other dungeons in this regard (8x8 levels, 8 levels).
However, the Abyss
has 64 dungeon rooms instead of just 16. The dungeon rooms are still
specified with D0-DF, but with a twist:
Level 1 &
Level 2 share a single D# series. (8 rooms each)
Level 3 &
Level 4 share a single D# series. (8 rooms each)
Level 5 &
Level 6 share a single D# series. (Level 5 has 5 rooms, Level 6 has 11
rooms)
Level 7 &
Level 8 share a single D# series. (Level 7 has 4 rooms, Level 8 has 12
rooms)
The D# still refers
to the order in which the rooms are defined in the file; it simply
resets itself every two levels.
Dungeon Rooms
(16,384 bytes, 64 rooms of 256 bytes each):
There are 64 rooms
defined in the ABYSS.DNG file. The byte structure is exactly the same as
the other dungeon files. There are simply more rooms tacked on to the
end of the file.
The
Dialog Files (.TLK)
These define the NPC
character names, behaviors, and conversation trees (well, conversation twigs
in the case of this game). The presentation order of the characters (from
1 to 16) determines their "ID number", which is used in the ULT
town maps. (See Above.)
Standard TLK File
Structure (4,608 bytes):
Single Character
(288 bytes):
byte 0 = Yes
/ No branch trigger. This value determines which keyword will cause the
NPC to ask you a Yes or No question after his response.
| 0 |
Character has no query. |
| 3 |
JOB |
| 4 |
HEALTH |
| 5 |
KEYWORD 1 |
| 6 |
KEYWORD 2 |
It is possible
that 1 and 2
values would correspond to NAME and LOOK, but this does not exist in
the game and has not been tested.
byte 1 = Yes
/ No response affects Humility?
1
=The response affects Humility.
Answering YES to the NPC's question will cause a loss of 5 Humility
points. Answering NO will gain 5 Humility points.
0
= The response does not affect humility.
byte 2 =
Turns away?
This is the
possibility of the NPC turning away from you during a conversation. As
best as I can determine, it is something like a percent chance.
Example: Brigant
the Troll in Bucaneer's Den has a turn away value of 128
(80 hex), and he turns away about
50% of the time. (This is the highest one in the game.) He also will
attack you sometimes, but that's probably just because he's a
troll! Cricket the Bard in Britain has a turn away value of 32
(20 hex), so in my estimation he
will turn away about 13% of the time because he's busy playing the
lute.
byte 3-287 =
The rest of it. Each piece of information is separated by a value 0
byte. Line feeds are explicitly stated with a value 0A
(hex) byte. Leftover space at the end of the record is padded with value
0 bytes. If a piece of information does not
need to exist for this particular character, it is simply replaced by a
capital "A" (41 hex). If
eliminating a KEYWORD in this manner, the KEYWORD should be 41
20 20 20 (an "A" with 3 spaces).
Order of
Information:
-
Name
-
Pronoun (He,
She, It)
-
LOOK
description
-
JOB response
-
HEALTH
response
-
KEYWORD 1
response
-
KEYWORD 2
response
-
Yes / No
Question
-
YES response
-
NO response
-
KEYWORD 1 (4
characters, all capital letters)
-
KEYWORD 2 (4
characters, all capital letters)
The Saved
Game Files (PARTY.SAV, OUTMONST.SAV, MONSTERS.SAV)
PARTY.SAV File
Structure (502 bytes):
This file holds all
information about your characters, inventory, and current game.
Header (8 bytes):
4 bytes =
header, purpose unknown
4 bytes = #
of moves, reversed storage order
Example: EA
0C 02 00 = $00020CEA = 134,378 moves
Maximum presumably
4,294,967,295 moves.
Character Data x8 (39
bytes each character, total 312 bytes):
2 bytes =
current hitpoints, reversed storage order
Maximum should be
800 hp, or 20 03.
2 bytes = max
hitpoints, reversed storage order
Maximum should be
800 hp, or 20 03.
2 bytes =
experience, reversed storage order
Maximum should be
9999 xp, or 0F 27.
2 bytes =
strength, reversed storage order
Maximum should be
50, or 32 00.
2 bytes =
dexterity, reversed storage order
Maximum should be
50, or 32 00.
2 bytes =
intelligence, reversed storage order
Maximum should be
50, or 32 00.
2 bytes =
mana, reversed storage order
Maximums should be
determined by class as follows:
| Class |
Formula |
max DEC |
max HEX |
| Mage |
2 * INT |
99 * |
63
00 * |
| Bard |
INT |
50 |
32 00 |
| Fighter |
0 |
0 |
00 00 |
| Druid |
3/2 * INT |
75 |
4B 00 |
| Tinker |
1/2 * INT |
25 |
19 00 |
| Paladin |
INT |
50 |
32 00 |
| Ranger |
INT |
50 |
32 00 |
| Shepherd |
0 |
0 |
00 00 |
*
while the Mage formula would dictate a maximum of 100 mana, the actual
maximum is 99; it is likely that this was implemented for display
purposes. 49 INT will yield 98 MP, but 50 INT will yield only 99 MP.
2 bytes =
unknown, reversed storage order
The purpose of
these bytes is unknown.
2 bytes =
weapon carried, reversed storage order
Value is 00
00 to 0F 00:
| 00
00 |
Hands (no weapon) |
| 01
00 |
Staff |
| 02
00 |
Dagger |
| 03
00 |
Sling |
| 04
00 |
Mace |
| 05
00 |
Axe |
| 06
00 |
Sword |
| 07
00 |
Bow |
| 08
00 |
Crossbow |
| 09
00 |
Oil |
| 0A
00 |
Halberd |
| 0B
00 |
Magic Axe |
| 0C
00 |
Magic Sword |
| 0D
00 |
Magic Bow |
| 0E
00 |
Magic Wand |
| 0F
00 |
Mystic Sword |
If you're into
cheating a little, weapons can be assigned with an editor that would
normally be forbidden to a character's class. An armada of Magic Wands
works quite nicely.
2 bytes =
armor worn, reversed storage order
Value is 00
00 to 07 00:
| 00
00 |
Skin (no armor) |
| 01
00 |
Cloth |
| 02
00 |
Leather |
| 03
00 |
Chain |
| 04
00 |
Plate |
| 05
00 |
Magic Chain |
| 06
00 |
Magic Plate |
| 07
00 |
Mystic Armor |
16 bytes =
name
MAY be 15
characters and a terminator of 00.
The practical
LIMIT, however, is 8 characters and a 00
terminator. Any name longer than 8 characters will corrupt the
display.
Example:
Geoffrey
47
65 6F 66 66 72 65 79 00
Any values
following the 00 byte but within this 16
byte block may be considered "junk" data.
1 byte =
gender
0B
= Male
0C = Female
1 byte =
class
00
= Mage
01 = Bard
02 = Fighter
03 = Druid
04 = Tinker
05 = Paladin
06 = Ranger
07 = Shepherd
1 byte =
status (ASCII capital G, P, S, or D)
G = 47
= Good
P = 50 = Poisoned
S = 53 = Sleeping
D = 44 = Dead
Footer (182 bytes):
4 bytes =
food, reversed storage order
maximum = 999,999
or 3F 42 0F 00
For display
purposes, the last 2 digits of the decimal food total are truncated on
screen. Each "move" subtracts an actual amount of food equal
to the number of characters in your party.
When buying food,
each pack of "25 rations" is actually equal to 2,500 food in
the save file.
2 bytes =
gold, reversed storage order
maximum = 9,999
gold or 0F 27
16 bytes =
virtue levels, reversed storage order each 2 bytes
2 bytes for each
of 8 virtues, determines your virtuousness or partial avatarhood in
that virtue. Value may be 0 to 99.
00
00 = partial Avatar (partial ankh appears between Food and Gold
totals on screen)
01 00 through 63 00
= virtue level (99 is better than 0).
At 99 (63
00) Hawkwind the Seer would tell you to seek the elevation in
that virtue.
Virtue order is
standard: Honesty, Compassion, Valor, Justice, Sacrifice, Honor,
Spirituality, Humility
2 bytes =
torches, reversed storage order
maximum = 99, 63
00
2 bytes =
gems, reversed storage order
maximum = 99, 63
00
2 bytes =
keys, reversed storage order
maximum = 99, 63
00
2 bytes =
sextants, reversed storage order
maximum = 99, 63
00
But 01 00 will
suffice, since sextants do not disappear with use.
16 bytes =
reserve armor, reversed storage order each 2 bytes
maximum = 99, 63
00
8 types of Armor
ordered as in the armor table shown in the above section on character
data.
Note that you may
specify "reserve" Hands with an editor but this has no
effect on the game. A quantity will never show next to Hands, nor can
you sell Hands at a shop.
32 bytes =
reserve weapons, reversed storage order each 2 bytes
maximum = 99, 63
00
16 types of
Weapons ordered as in the weapon table shown in the above section on
character data.
Note that you may
specify "reserve" Skin (No Armour) with an editor but this
has no effect on the game. A quantity will never show next to No
Armour, nor can you sell Skin at a shop. =)
16 bytes =
reagents, reversed storage order each 2 bytes
maximum = 99, 63
00
8 types of
Reagents, ordered:
Ash, Ginseng, Garlic, Silk
Bloodmoss, Black Pearl, Nightshade, Mandrake
52 bytes =
spells, reversed storage order each 2 bytes
maximum = 99, 63
00
Quantity of mixed
Spells are saved in alphabetical order from A-'Awaken' to Z-'Z-Down'.
1 byte =
quest item storage #1
This byte stores
which quest ITEMS you currently possess or which quests have been
completed.
Each bit of the byte represents a different item:
Binary order: 7 6
5 4 3 2 1 0
0 = Skull of
Mondain (picked up from ocean)
1 = Skull of Mondain (thrown into Abyss)
2 = Candle of Love
3 = Book of Truth
4 = Bell of Courage
5 = Key part: T
6 = Key part: L
7 = Key part: C
Note that bit 0
and 1 should not both be set to ON...
Scenario:
1. You retrieve the Skull from the deep sea by searching with your
boat = Bit 0 set to ON. The Skull is now in inventory.
2. You use the Skull at the entrance of the Abyss, destroying it = Bit
0 set to OFF, Bit 1 set to ON. The Skull is removed from inventory,
but the game knows NOT to let you pick it up again from the ocean.
1 byte =
quest item storage #2
This byte stores
which quest ITEMS you currently possess or which quests you have
completed.
Each bit of the byte represents a different item:
Binary order: 7 6
5 4 3 2 1 0
0 = Silver Horn
1 = Wheel of The HMS Cape
2 = Candle has been Used at Abyss
3 = Book has been Used at Abyss
4 = Bell has been Used at Abyss
5 = unused
6 = unused
7 = unused
Note: to freely
enter the Abyss, you must have Used the Skull, Bell, Book, and Candle.
All the proper bit flags must be set, as described.
1 byte =
longitude location (X coordinate location)
Corresponds to the
two parts of the second given sextant coordinate (Longitude).
A' through P' = 0
through F
A" through P" = 0
through F
Example: E8
= Longitude: O'I"
May also be though
of as the absolute X coordinate on the 256x256 world map matrix.
1 byte =
latitude location (Y coordinate location)
Corresponds to the
two parts of the first given sextant coordinate (Latitude).
A' through P' = 0
through F
A" through P" = 0
through F
Example: E9
= Latitude: O'J"
May also be though
of as the absolute Y coordinate on the 256x256 world map matrix.
1 byte =
Virtue Stone storage
This byte stores
which colored Virtue Stones you currently possess.
Each bit of the byte represents a different stone:
Binary order: 7 6
5 4 3 2 1 0
0 = Blue
1 = Yellow
2 = Red
3 = Green
4 = Orange
5 = Purple
6 = White
7 = Black
1 byte = Rune
storage
This byte stores
which Runes you currently possess.
Each bit of the byte represents a different Rune:
Binary order: 7 6
5 4 3 2 1 0
0 = Honesty
1 = Compassion
2 = Valor
3 = Justice
4 = Sacrifice
5 = Honor
6 = Spirituality
7 = Humility
2 bytes =
number of Characters in Party, reversed storage order
01
00 = you are alone
08 00 = party is full (necessary to
complete the game)
00 00 = "No Party Formed!"
error at start up.
Example: 6
characters in party means that the first six character records (as
described above) represent the characters in the party.
2 bytes =
Vehicle / Party Icon, reversed storage order
This represents
the party's current mode of transport, as defined in the tile
list below.
Examples:
12 00 = you are in a boat facing east
14 00 = you are on a horse facing west
18 00 = you are aboard the hot air
balloon
1F 00 = you are on foot
2 bytes =
Balloon status, reversed storage order
00
00 = on ground, or not aboard balloon
01 00 = balloon is flying
TO BE CONTINUED...
OUTMONST.SAV &
MONSTERS.SAV Info forthcoming...
What
Didn't I Figure Out?
I covered a great deal
of information about the program, but there is much I did not bother to
work out.
I used to get a lot of
questions regarding the character creation sequence, most of which were
something like "Why didn't you update the title screen, the gypsy
carnival, or the abacus?"
The answer is that I
simply couldn't figure out how these files worked. I spent probably a
total of 6 hours looking at them, trying to make sense of the scheme,
until I decided that it is such a minor part of the game it wasn't worth
additional time. Believe me, I would have loved to redo to carnival graphics and
"tarot" cards, but in my opinion, it's really something you
spend a very small amount of time looking at compared to the rest of the
game.
The
Complete List of Tiles
| 0 | 0 |  | Deep Water | | 1 | 1 |  | Medium Water | | 2 | 2 |  | Shallow Water | | 3 | 3 |  | Swamp | | 4 | 4 |  | Grasslands | | 5 | 5 |  | Scrubland | | 6 | 6 |  | Forest | | 7 | 7 |  | Hills | | 8 | 8 |  | Mountains | | 9 | 9 |  | Dungeon Entrance | | 10 | A |  | Town | | 11 | B |  | Castle | | 12 | C |  | Village | | 13 | D |  | Lord British's Castle, West Wing | | 14 | E |  | Lord British's Castle, Entrance | | 15 | F |  | Lord British's Castle, East Wing | | 16 | 10 |  | Ship | | 17 | 11 |  | Ship | | 18 | 12 |  | Ship | | 19 | 13 |  | Ship | | 20 | 14 |  | Horse | | 21 | 15 |  | Horse | | 22 | 16 |  | Tile Floor | | 23 | 17 |  | Bridge | | 24 | 18 |  | Balloon | | 25 | 19 |  | Bridge | | 26 | 1A |  | Bridge | | 27 | 1B |  | Ladder Up | | 28 | 1C |  | Ladder Down | | 29 | 1D |  | Ruins | | 30 | 1E |  | Shrine | | 31 | 1F |  | Questing Party | | 32 | 20 |  | Mage | | 33 | 21 |  | Mage | | 34 | 22 |  | Bard | | 35 | 23 |  | Bard | | 36 | 24 |  | Fighter | | 37 | 25 |  | Fighter | | 38 | 26 |  | Druid | | 39 | 27 |  | Druid | | 40 | 28 |  | Tinker | | 41 | 29 |  | Tinker | | 42 | 2A |  | Paladin | | 43 | 2B |  | Paladin | | 44 | 2C |  | Ranger | | 45 | 2D |  | Ranger | | 46 | 2E |  | Shepherd | | 47 | 2F |  | Shepherd | | 48 | 30 |  | Column | | 49 | 31 |  | White SW | | 50 | 32 |  | White SE | | 51 | 33 |  | White NW | | 52 | 34 |  | White NE | | 53 | 35 |  | Mast | | 54 | 36 |  | Ship's Wheel | | 55 | 37 |  | Rocks | | 56 | 38 |  | Lying Down | | 57 | 39 |  | Stone Wall | | 58 | 3A |  | Locked Door | | 59 | 3B |  | Unlocked Door | | 60 | 3C |  | Chest | | 61 | 3D |  | Ankh | | 62 | 3E |  | Brick Floor | | 63 | 3F |  | Wooden Planks | | 64 | 40 |  | Moongate, Transient | | 65 | 41 |  | Moongate, Transient | | 66 | 42 |  | Moongate, Transient | | 67 | 43 |  | Moongate, Blue | | 68 | 44 |  | Poison Field | | 69 | 45 |  | Energy Field | | 70 | 46 |  | Fire Field | | 71 | 47 |  | Sleep Field | | 72 | 48 |  | Solid Barrier | | 73 | 49 |  | Hidden Passage | | 74 | 4A |  | Altar | | 75 | 4B |  | Spit | | 76 | 4C |  | Lava Flow | | 77 | 4D |  | Missile | | 78 | 4E |  | Magic Sphere | | 79 | 4F |  | Attack Flash | | 80 | 50 |  | Guard | | 81 | 51 |  | Guard | | 82 | 52 |  | Citizen | | 83 | 53 |  | Citizen | | 84 | 54 |  | Bard, Singing | | 85 | 55 |  | Bard, Singing | | 86 | 56 |  | Jester | | 87 | 57 |  | Jester | | 88 | 58 |  | Unfortunate | | 89 | 59 |  | Unfortunate | | 90 | 5A |  | Child | | 91 | 5B |  | Child | | 92 | 5C |  | Bull | | 93 | 5D |  | Bull | | 94 | 5E |  | Lord British | | 95 | 5F |  | Lord British | | 96 | 60 |  | A | | 97 | 61 |  | B | | 98 | 62 |  | C | | 99 | 63 |  | D | | 100 | 64 |  | E | | 101 | 65 |  | F | | 102 | 66 |  | G | | 103 | 67 |  | H | | 104 | 68 |  | I | | 105 | 69 |  | J | | 106 | 6A |  | K | | 107 | 6B |  | L | | 108 | 6C |  | M | | 109 | 6D |  | N | | 110 | 6E |  | O | | 111 | 6F |  | P | | 112 | 70 |  | Q | | 113 | 71 |  | R | | 114 | 72 |  | S | | 115 | 73 |  | T | | 116 | 74 |  | U | | 117 | 75 |  | V | | 118 | 76 |  | W | | 119 | 77 |  | X | | 120 | 78 |  | Y | | 121 | 79 |  | Z | | 122 | 7A |  | Space | | 123 | 7B |  | Right | | 124 | 7C |  | Left | | 125 | 7D |  | Window | | 126 | 7E |  | Blank | | 127 | 7F |  | Brick Wall | | 128 | 80 |  | Pirate Ship | | 129 | 81 |  | Pirate Ship | | 130 | 82 |  | Pirate Ship | | 131 | 83 |  | Pirate Ship | | 132 | 84 |  | Nixie | | 133 | 85 |  | Nixie | | 134 | 86 |  | Giant Squid | | 135 | 87 |  | Giant Squid | | 136 | 88 |  | Sea Serpent | | 137 | 89 |  | Sea Serpent | | 138 | 8A |  | Seahorse | | 139 | 8B |  | Seahorse | | 140 | 8C |  | Whirlpool | | 141 | 8D |  | Whirlpool | | 142 | 8E |  | Storm | | 143 | 8F |  | Storm | | 144 | 90 |  | Rat | | 145 | 91 |  | Rat | | 146 | 92 |  | Rat | | 147 | 93 |  | Rat | | 148 | 94 |  | Bat | | 149 | 95 |  | Bat | | 150 | 96 |  | Bat | | 151 | 97 |  | Bat | | 152 | 98 |  | Giant Spider | | 153 | 99 |  | Giant Spider | | 154 | 9A |  | Giant Spider | | 155 | 9B |  | Giant Spider | | 156 | 9C |  | Ghost | | 157 | 9D |  | Ghost | | 158 | 9E |  | Ghost | | 159 | 9F |  | Ghost | | 160 | A0 |  | Slime | | 161 | A1 |  | Slime | | 162 | A2 |  | Slime | | 163 | A3 |  | Slime | | 164 | A4 |  | Troll | | 165 | A5 |  | Troll | | 166 | A6 |  | Troll | | 167 | A7 |  | Troll | | 168 | A8 |  | Gremlin | | 169 | A9 |  | Gremlin | | 170 | AA |  | Gremlin | | 171 | AB |  | Gremlin | | 172 | AC |  | Mimic | | 173 | AD |  | Mimic | | 174 | AE |  | Mimic | | 175 | AF |  | Mimic | | 176 | B0 |  | Reaper | | 177 | B1 |  | Reaper | | 178 | B2 |  | Reaper | | 179 | B3 |  | Reaper | | 180 | B4 |  | Insect Swarm | | 181 | B5 |  | Insect Swarm | | 182 | B6 |  | Insect Swarm | | 183 | B7 |  | Insect Swarm | | 184 | B8 |  | Gazer | | 185 | B9 |  | Gazer | | 186 | BA |  | Gazer | | 187 | BB |  | Gazer | | 188 | BC |  | Phantom | | 189 | BD |  | Phantom | | 190 | BE |  | Phantom | | 191 | BF |  | Phantom | | 192 | C0 |  | Orc | | 193 | C1 |  | Orc | | 194 | C2 |  | Orc | | 195 | C3 |  | Orc | | 196 | C4 |  | Skeleton | | 197 | C5 |  | Skeleton | | 198 | C6 |  | Skeleton | | 199 | C7 |  | Skeleton | | 200 | C8 |  | Rogue | | 201 | C9 |  | Rogue | | 202 | CA |  | Rogue | | 203 | CB |  | Rogue | | 204 | CC |  | Python | | 205 | CD |  | Python | | 206 | CE |  | Python | | 207 | CF |  | Python | | 208 | D0 |  | Ettin | | 209 | D1 |  | Ettin | | 210 | D2 |  | Ettin | | 211 | D3 |  | Ettin | | 212 | D4 |  | Headless | | 213 | D5 |  | Headless | | 214 | D6 |  | Headless | | 215 | D7 |  | Headless | | 216 | D8 |  | Cyclops | | 217 | D9 |  | Cyclops | | 218 | DA |  | Cyclops | | 219 | DB |  | Cyclops | | 220 | DC |  | Wisp | | 221 | DD |  | Wisp | | 222 | DE |  | Wisp | | 223 | DF |  | Wisp | | 224 | E0 |  | Mage | | 225 | E1 |  | Mage | | 226 | E2 |  | Mage | | 227 | E3 |  | Mage | | 228 | E4 |  | Lich | | 229 | E5 |  | Lich | | 230 | E6 |  | Lich | | 231 | E7 |  | Lich | | 232 | E8 |  | Lava Lizard | | 233 | E9 |  | Lava Lizard | | 234 | EA |  | Lava Lizard | | 235 | EB |  | Lava Lizard | | 236 | EC |  | Zorn | | 237 | ED |  | Zorn | | 238 | EE |  | Zorn | | 239 | EF |  | Zorn | | 240 | F0 |  | Daemon | | 241 | F1 |  | Daemon | | 242 | F2 |  | Daemon | | 243 | F3 |  | Daemon | | 244 | F4 |  | Hydra | | 245 | F5 |  | Hydra | | 246 | F6 |  | Hydra | | 247 | F7 |  | Hydra | | 248 | F8 |  | Dragon | | 249 | F9 |  | Dragon | | 250 | FA |  | Dragon | | 251 | FB |  | Dragon | | 252 | FC |  | Balron | | 253 | FD |  | Balron | | 254 | FE |  | Balron | | 255 | FF |  | Balron |
|