Ultima IV Internal Formats

=Introduction= This is a reference to the various files comprising the DOS version of the game Ultima IV.

=SHAPES.EGA=

This file contains the bitmaps for each tile. Each tile is 16x16 pixels, and each byte represents two pixels. In other words, the first 8 bytes represent the 16 pixels on the first row of the first tile.

offset len  notes 0x0    128  tile 0 0x80   128  tile 1 0x100  128  tile 2 ... 0x7F80 128  tile 255

=CHARSET.EGA=

This contains the bitmaps for each character in the font. Each character is 8x8 pixels, and each byte represents two pixels. In other words, the first 4 bytes represent the 8 pixels on the first row of the first character.

The order is the standard ASCII mapping; 'A' is character 65, 'z' is character 122. The lowest 32 characters have the following glyphs:

=EGA files (RLE encoded)=

The following .EGA files are RLE encoded: START.EGA, KEY7.EGA, RUNE_x.EGA (where x is between 0 and 5), STONCRCL.EGA, HONESTY.EGA, COMPASSN.EGA, VALOR.EGA, JUSTICE.EGA, SACRIFIC.EGA, HONOR.EGA, SPIRIT.EGA, HUMILITY.EGA, TRUTH.EGA, LOVE.EGA, and COURAGE.EGA. Each of these files represents a 16 color 320x200 bitmap. Each pixel is encoded in 4 bits, like SHAPES.EGA and CHARSET.EGA. However, runs of identical *bytes* (not pixels) are encoded with a special run indicator value (0x02) followed by a one byte count and a one byte value. This allows a single run of up to 255 bytes (510 pixels) to be represented as three bytes. For example, the byte values "28 28 28 28" could be represented as "02 04 28". If the value 0x02 needs to be represented, it *must* be encoded in a run ("02 01 02").

=EGA files (LZW encoded)=

The remaining .EGA files are LZW encoded: ABACUS.EGA, ANIMATE.EGA, GYPSY.EGA, INSIDE.EGA, OUTSIDE.EGA, PORTAL.EGA, TREE.EGA, WAGON.EGA, HONCOM.EGA, SACHONOR.EGA, SPIRHUM.EGA, VALJUS.EGA, and TITLE.EGA. Also, the file SHAPES.EGZ is a LZW compressed version of SHAPES.EGA. Like the RLE encoded files, each of these files represents a 16 color 320x200 bitmap. LZW encoded files only seem to be used in the introduction sequence (title.exe); the images used by avatar.exe are RLE encoded instead. (Description of LZW algorithm to go here).

=WORLD.MAP=

This is the map of Britannia. It is 256x256 tiles in total, broken up into 64 32x32 chunks. The first chunk is in the top left corner, the next just below, and so on, until the last in the bottom right corner. Each tile is stored as a byte that maps to the tiles in SHAPES.EGA.

The "chunked" layout is an artifact of the limited memory on the original machines that ran Ultima 4. The whole map would take 64k, too much for a C64 or an Apple II, so the game would keep a limited number of 1k chunks in memory at a time. As the player moved around, old chunks were thrown out as new ones were swapped in.

=ULT files=

These contain town information. Specifically, a 32x32 map, plus the starting position, movement behavior, and conversation index of each NPC. The conversation index gives the starting position of the NPC's dialog block in the corresponding .TLK file. I'm not sure why some of the data is duplicated.

=TLK files=

These contain conversation information. The file has a 288 (0x120) byte block containing his or her dialogues, plus the words that trigger his or her responses (keywords). Most of the fields are variable length strings terminated by a single zero byte and the following field starts immediately after. The blocks are padded with zero bytes to 288 bytes.

0x0   1    NPC 0 question flag (0-no question, 3-job triggers, 4-health            triggers, 5-keyword 1 triggers, 6-keyword 2 triggers) 0x1   1    NPC 0 question type (0-should answer yes, 0-should answer no) 0x2   1    NPC 0 turns away probability 0x3   var  NPC 0 name (zero terminated) var   var  NPC 0 pronoun (zero terminated) var   var  NPC 0 description (zero terminated) var   var  NPC 0 job (zero terminated) var   var  NPC 0 response 1 (zero terminated) var   var  NPC 0 response 2 (zero terminated) var   var  NPC 0 question (zero terminated) var   var  NPC 0 yes answer (zero terminated) var   var  NPC 0 no answer (zero terminated) var   5    NPC 0 keyword 1 (zero terminated) var   5    NPC 0 keyword 2 (zero terminated) var   var  zero padding 0x120 3    NPC 1 question flag ...

=CON files=

These files contain the 11x11 battleground maps shown when combat starts. It has the map itself plus starting positions for up to 16 monsters and 8 party members.

offset len notes 0x0   16   start_x for monsters 0-15 0x10  16   start_y for monsters 0-15 0x20  8    start_x for party members 0-7 0x28  8    start_y for party members 0-7 0x30  16   ??? 0x40  121  11x11 map matrix 0xB9  7    ???

=DNG files=

These files contain dungeon information. The first 512 bytes are the 8x8 maps for each of the 8 levels. These are used for the dungeons 3D mode. The rest of the file is a set of 16 (64 in the case of the ABYSS.DNG) 256 byte blocks that define the dungeon rooms.

offset len notes 0x0   64   level 1 8x8 map matrix 0x40  64   level 2 8x8 map matrix 0x80  64   level 3 8x8 map matrix 0xC0  64   level 4 8x8 map matrix 0x100 64   level 5 8x8 map matrix 0x140 64   level 6 8x8 map matrix 0x180 64   level 7 8x8 map matrix 0x1C0 64   level 8 8x8 map matrix 0x200 256  room 0 data 0x300 256  room 1 data 0x400 256  room 2 data 0x500 256  room 3 data 0x600 256  room 4 data ... 0x1100 256 room 15 data

For ABYSS.DNG only: 0x1200 256 room 16 data 0x1300 256 room 17 data ... 0x4100 256 room 63 data

Dungeon Room format:

offset len notes 0x0   16   floor triggers (4 bytes each X 4 triggers possible) 0x10  16   tile for monsters 0-15 (0 means no monster and 0's come FIRST) 0x20  16   start_x for monsters 0-15 0x30  16   start_y for monsters 0-15 0x40  8    start_x for party member 0-7 (north entry) 0x48  8    start_y for party member 0-7 (north entry) 0x50  8    start_x for party member 0-7 (east entry) 0x58  8    start_y for party member 0-7 (east entry) 0x60  8    start_x for party member 0-7 (south entry) 0x68  8    start_y for party member 0-7 (south entry) 0x70  8    start_x for party member 0-7 (west entry) 0x78  8    start_y for party member 0-7 (west entry) 0x80  121  11x11 map matrix for room 0xF9  7    buffer

Trigger format:

offset len notes 0x0   1    tile to be placed (0 means no trigger and 0's come LAST) 0x1   1    2 nibbles indicating the (x,y) coords of trigger 0x2   1    2 nibbles indicating the (x,y) coords of 1st tile to change 0x3   1    2 nibbles indicating the (x,y) coords of 2nd 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).

=PARTY.SAV=

This file stores the information that is stored when the game is saved. It includes party-wide information like gold and food, plus a 39 byte record for each character.

offset len notes 0x0   4    counter (incremented regularly, probably every screen update) 0x4   2    moves (low word) 0x6   2    moves (high word) 0x8   39   player 0 record 0x2F  39   player 1 record 0x56  39   player 2 record 0x7D  39   player 3 record 0xA4  39   player 4 record 0xCB  39   player 5 record 0xF2  39   player 6 record 0x119 39   player 7 record 0x140 4    food (in units of hundredths) 0x144 2    gold 0x146 16   karma (2 bytes each for honesty, compassion, valor, justice,            sacrifice, honor, spirituality and humility; 0-partial avatar) 0x156 2    torches 0x158 2    gems 0x15A 2    keys 0x15C 2    sextants 0x15E 16   armor (2 bytes each for none (unused), cloth, leather, chain,            plate, magic chain, magic plate, mystic robes) 0x16E 32   weapons (2 bytes each for none (unused), staves, daggers,            slings, maces, axes, swords, bows, crossbows, oil, halberds,            magic axes, magic swords, magic bows, magic wands, mystic            swords) 0x18E 16   reagents (2 bytes each for sulfurous ash, ginseng, garlic,            spider silk, blood moss, black pearl, nightshade, mandrake) 0x19E 52   mixtures (2 bytes each for awaken, blink, cure, dispel,            energy, fireball, gate, heal, iceball, jinx, kill, light,            magic missile, negate, open, protection, quickness,            resurrect, sleep, tremor, undead, view, winds, x-it, y-up,            z-down) 0x1D2 1    items (1 bit each for skull, skull destroyed, candle, book,            bell, key part C, key part L, key part T) 0x1D3  1    items (1 bit each for horn, wheel, candle used at abyss             entrance, book used at abyss entrance, bell used at abyss            entrance, (3 bits unused)) 0x1D4 1    x coord 0x1D5 1    y coord 0x1D6 1    stones (1 bit each for BYRGOPWB) 0x1D7 1    runes (1 bit each for HCVJSHSH) 0x1D8 2    number of characters in party 0x1DA 2    transport (0x10-ship facing west, 0x11-ship facing north,            0x12-ship facing east, 0x13-ship facing south, 0x14-horse            facing west, 0x15-horse facing east, 0x18-balloon, 0x1f-on            foot) 0x1DC 2    on surface: balloon status (0-on ground, 1-flying) in dungeon: current torch duration 0x1DE 2    current phase of left moon (Trammel); range = 0-7 0x1E0 2    current phase of right moon (Felucca); range = 0-7 0x1E2 2    hull integrity of currently boarded ship if you x-it a ship, save, restart the game, and board the ship again, you will find that all damage to the ship has been mysteriously repaired. 0x1E4 2    introduced to Lord British (0-haven't been introduced, 1-introduced) 0x1E6 2    time of last successful hole up & camp The game stores ((moves / 0x64) & 0xffff) in this field when you successfully hole up & camp. If (moves / 0x64) < 0x10000: You can only hole up & camp successfully if the current ((moves / 0x64) & 0xffff) is different from the value in this field. If (moves / 0x64) >= 0x10000: Hole up & camp is always successful. 0x1E8 2    time of last mandrake/nightshade find The game stores (moves & 0xf0) in this field when you find mandrake/nightshade. You can only find mandrake/nightshade if the current (moves & 0xf0) is different from the value in this field. 0x1EA 2    time of last successful meditation at a shrine The game stores ((moves / 0x64) & 0xffff) in this field when you successfully meditate at a shrine. If (moves / 0x64) < 0x10000: You can only meditate successfully if the current ((moves / 0x64) & 0xffff) is different from the value in this field. If (moves / 0x64) >= 0x10000: Meditating at a shrine is always successful. 0x1EC 2    time of last virtue-related conversation The game stores ((moves / 0x10) & 0xffff) in this field when one of the following happens: 1) you give gold to a beggar           2) you answer a yes/no question from an NPC (doesn't have to               be a question where the answer affects your virtue) If ((moves / 0x10) & 0xffff) < 0x10000: Giving gold to a beggar or answering a virtue-related yes/no question only increases your karma if ((moves / 0x10) & 0xffff) is different from the value in this field. If ((moves / 0x10) & 0xffff) >= 0x10000: Giving gold or answering a virtue question always increases your karma. 0x1EE 2    if the party is in a dungeon: coordinates of this dungeon if not: coordinates of the dungeon last entered by the party 0x1F0 2    orientation in dungeon (0-west, 1-north, 2-east, 3-south) 0x1F2 2    dungeon level (starting at zero, 0xffff = surface) 0x1F4 2    current party location (see below)

The character record format:

offset len notes 0x0   2    hit points 0x2   2    hit points maximum 0x4   2    experience points 0x6   2    strength 0x8   2    dex 0xA   2    int 0xC   2    mp 0xE    2    ??? 0x10  2    weapon 0x12  2    armor 0x14  16   name 0x24  1    sex (0xb-male, 0xc-female) 0x25  1    class 0x26  1    status ('G'-good, 'P'-poisoned, 'S'-sleeping, 'D'-dead)

Party location: Since you can only save on the surface or in a dungeon, the only valid party locations are 0 and 0x11-0x18.

hex    location 0     surface 1     Lord British's castle 2     The Lycaeum 3     Empath Abbey 4     Serpent's Hold 5     Moonglow 6     Britain 7     Jhelom 8     Yew 9     Minoc a     Trinsic b     Skara Brae c     Magincia d     Paws e     Buccaneer's Den f     Vesper 10     Cove 11     Deceit 12     Despise 13     Destard 14     Wrong 15     Covetous 16     Shame 17     Hythloth 18     Abyss 19     Shrine of Honesty 1a     Shrine of Compassion 1b     Shrine of Valor 1c     Shrine of Justice 1d     Shrine of Sacrifice 1e     Shrine of Honor 1f     Shrine of Spirituality 20     Shrine of Humility

=MONSTERS.SAV=

Ultima 4 maintains a structure (in memory) that I've decided to call the "monster table." When you Journey Onward, U4 loads MONSTERS.SAV into the monster table. When you Quit & Save, U4 writes the monster table to MONSTERS.SAV. The purpose of the monster table fields depends on the current party location (surface, dungeon, settlement).

Surface: On the surface, the monster table contains information about monsters and inanimate objects (chests, horses, ships, balloon). A table entry is free if (previousTile[i] == 0). However, when u4dos deletes and entry, it sets both currentTile[i] and previousTile[i] to 0. Slots 0-7 are for monsters, while slots 8-31 are for inanimate objects. Non-empty entries don't have to be contiguous. Whirlpools and twisters are special cases; they must be placed in slot 0-3, or they won't swallow ships / damage the party. When you leave Hythloth, u4dos creates the balloon at (233 / 242). If there is more than one inanimate object on a tile, objects closer to the beginning of the table are drawn on top of those closer to the end. Monsters and the party are always drawn on top of inanimate objects. The current tile and previous tile values are used during runtime. However, when the game is saved, the previous tile must be set to the monster's base tile. The current tile can be any of the monster's tiles, except for pirate ships, where the current tile determines which direction the pirate ship is facing. If the previous tile is not set to the monster's base tile, it won't behave properly in u4dos: monsters with ranged attacks won't use them in combat, twisters and whirlpools will attack the party, and pirates will appear as pirate ships in battle. For transports with more than one tile (horse, ship), the previous tile determines which direction the transport is facing, while the current tile can be any of the transport's tiles.

0x0    32      current tile 0x20   32      current x coordinate 0x40   32      current y coordinate 0x60   32      tile for previous turn 0x80   32      x coordinate for previous turn 0xA0   32      y coordinate for previous turn 0xC0   32      not used 0xE0   32      not used

Dungeons: In a dungeon, the monster table contains information about the monsters in the dungeon. A monster stored in the monster table is *also* stored in DNGMAP.SAV. Inanimate objects are not stored in the monster table; they are stored
 * only* in DNGMAP.SAV.

0x0    32      not used 0x20   32      current x coordinate 0x40   32      current y coordinate 0x60   32      current tile 0x80   32      x coordinate for previous turn 0xA0   32      y coordinate for previous turn 0xC0   32      dungeon level; range = 0-7 0xE0   32      not used

Settlements: In a castle/town/village, the monster table is loaded from the settlement's .ult file, starting at offset 0x400. It contains information about the settlement's NPC's.

0x0    32      current tile 0x20   32      current x coordinate 0x40   32      current y coordinate 0x60   32      tile for previous turn 0x80   32      x coordinate for previous turn 0xA0   32      y coordinate for previous turn 0xC0   32      movement behavior for NPCs 0-31 (0x0-fixed, 0x1-wander, 0x80-follow, 0xFF-attack) 0xE0   32      conversation index (tlk file) for NPCs 0-31

=OUTMONST.SAV=

OUTMONST.SAV is a backup of the monster table, created when you enter a dungeon or settlement. When you leave a dungeon or settlement, the monster table is reloaded from OUTMONST.SAV.

Exception: when you enter Hythloth though the ladder in LB's castle, the game does not write the current monster table to OUTMONST.SAV, because it already did that when you entered LB's castle.

=DNGMAP.SAV=

When you Quit & Save in a dungeon, the game saves objects (orbs, chests) and monsters in DNGMAP.SAV. DNGMAP.SAV contains the 8x8 maps for all 8 levels. Every tile is encoded as a byte. The upper nibble of a tile determines the tile type (see below). The lower nibble encodes the monster standing on the tile, except for tiles 0x80 0x90 0xA0 0xD0 (see below).

0x00 = nothing 0x10 = ladder up 0x20 = ladder down 0x30 = ladder up/down 0x40 = chest 0x50 = hole (ceiling) 0x60 = hole (floor) 0x70 = orb (see below) 0x80 = trap (magic winds) 0x81 = trap (falling rocks) 0x8E = trap (pit) 0x90 = fountain (no effect) 0x91 = fountain (healing) 0x92 = fountain (100 hit points damage) 0x93 = fountain (cure) 0x94 = fountain (poison and 100 hit points damage) 0xA0 = magic field (poison) 0xA1 = magic field (energy) 0xA2 = magic field (fire) 0xA3 = magic field (sleep) 0xB0 = altar (stone color depends on dungeon) 0xC0 = door 0xDn = dungeon room #n 0xE0 = illusionary wall 0xF0 = wall

Monsters:

0 = none 1 = rat 2 = bat 3 = spider 4 = ghost 5 = slime 6 = troll 7 = gremlin 8 = mimic 9 = reaper A = insects B = gazer C = phantom D = orc E = skeleton F = rogue

Orbs: When a PC touches an orb, one or more attributes are raised by 5 points each. Which attributes are raised depends on the dungeon.

dungeon    attributes Deceit     I-- Despise    -D- Destard    --S Wrong      ID- Covetous   -DS Shame      I-S Hythloth   IDS

=TITLE.EXE=

This executable is launched by ultima.com to display the introduction and create new characters. When "journey onward" is selected from the intro menu, it exits and ultima.com passes control off to avatar.exe, the main game executable. This .exe has lots of the data necessary for the intro screens embedded in it.

offset len  notes 0x0   17445 ??? 0x4425 11088 text for introduction, gypsy dialog and gyspy questions (zero terminated strings) 0x6f75 1035 ??? 0x7380 184  list of frames sequences for beasties on intro screen 0x7438 54   ??? 0x746e 532  266 x/y pairs that are the coordinates for the pixels that make up the Lord British signature on the introductory title screen 0x7682 1    zero terminating byte 0x7683 95   tile values for the 19x5 map that appears on the introductory title screen 0x76e2 548  script data for the intro map animations 0x7906 ...  ???

=AVATAR.EXE=

This is the main game executable, launched from ultima.com (or run on its own to skip the intro). Lots of the special case data is embedded in this .exe.

offset len   notes 0x0    63843 ??? 0x0f963 1    volume on/off flag 0x0f964 27   13 two-byte code pointers to 13 sound generation routines plus one padding byte 0x0f97f 171  .ULT filenames; 16 zero terminated strings 0x0fa2a 48   stone colors; 8 zero terminated strings 0x0fa5a 91   .DNG filenames; 8 zero terminated strings 0x0fab5 28   ??? 0x0fad1 8    moongate x-coordinates (one byte for each moongate starting              at moonglow) 0x0fad9 8    moongate y-coordinates (one byte for each moongate starting              at moonglow) 0x0fae1 32   16 two-byte offsets to .ULT filenames (value + 62141 gives              file offset) 0x0fb01 32   area x-coordinates (one byte for each town, city, castle,              dungeon, shrine) 0x0fb21 32   area y-coordinates (one byte for each town, city, castle,              dungeon, shrine) 0x0fb41 16   8 two-byte offsets to stone colors (value + 62141 gives              file offset) 0x0fb51 16   8 two-byte offsets to .DNG filenames (value + 62141 gives              file offset) 0x0fb61 72   ??? 0x0fba9 8    pirates cove ship x coordinates 0x0fbb1 8    pirates cove ship y coordinates 0x0fbb9 8    pirates cove ship tiles 0x0fbc1 37   zero terminated list of tiles that are walkable 0x0fbe6 149  14 zero-terminated navigation strings ("North", "Sail              North", etc.) 0x0fc7b 539  Chamber of the Codex virtue questions 0x0fe96 78   ??? 0x0fee4 647  Chamber of the Codex dialog strings 0x1016b 28   ??? 0x10187 509  Chamber of the Codex dialog strings 0x10384 83   ??? 0x103d7 1280 abyss question dialog strings 0x108d7 22   11 two-byte offsets to abyss question answers (value +              62141 gives file offset) 0x108ed 80   ??? 0x1093d 169  .TLK filenames; 16 zero terminated strings 0x109e6 13   "OUTMONST.SAV" zero terminated string 0x109f3 32   16 two-byte offsets to .TLK filenames (value + 62139 gives              file offset) 0x10a13 659  ??? 0x10ca6 246  monster names; 36 zero terminated strings 0x10d9c 129  weapon names; 16 zero terminated strings 0x10e1d 77   armor names; 8 zero terminated strings 0x10e6a 64   weapon abbreviations; 16 zero terminated strings 0x10eaa 55   character class names; 8 zero terminated strings 0x10ee1 58   npc type names; 8 zero terminated strings 0x10f1b 81   reagent names; 8 zero terminated strings 0x10f6c 434  spell names; 26 zero terminated strings 0x1101e 292  castle/city/town/dungeon/shrine names; 32 zero terminated strings 0x11142 11   ??? 0x1114d 72   36 two-byte offsets to monster names (value + 62131 gives              file offset) 0x11195 32   16 two-byte offsets to weapon names (value + 62131 gives              file offset) 0x111b5 16   8 two-byte offsets to armor names (value + 62131 gives              file offset) 0x111c5 32   16 two-byte offsets to weapon abbreviations (value + 62131              gives file offset) 0x111e5 16   8 two-byte offsets to character class names (value + 62131              gives file offset) 0x111f5 330  ??? 0x1133f 26   mp required for each spell (one byte per spell) 0x11359 654  ??? 0x115e7 16   mask of which classes can use each weapon (one byte per              weapon) 0x115f7 8    mask of which classes can use each type of armor (one byte              per armor type) 0x115ff 134  ??? 0x11685 52   monster hp table 0x116b9 36   monster leader types (one byte per monster type) 0x116dd 36   monster encounter size table (one byte per monster type) 0x11701 2    ??? 0x11703 16   weapon value list (one byte per weapon type) 0x11713 8    armor value list (one byte per armor type) 0x1171b 16   weapon type list (one byte per weapon type; 0 = melee, 0xff              = missile) 0x1172b 154  .CON filenames; 14 zero terminated strings 0x117c5 28   14 two-byte offsets to .CON filenames (value + 62131 gives              file offset) 0x117e1 64   dungeon .CON filenames; 7 zero terminated strings 0x11821 164  ??? 0x118c5 12   altar room exit destinations 0-3 = truth (north, east, south, west) 4-7 = love 8-11 = courage 0x118d1 146  ??? 0x11963 8    ambush monster types 0x1196b 190  miscellaneous text strings 0x11a29 26   spell reagent masks (one byte per spell) 0x11a43 364  miscellaneous text strings 0x11baf 16   city/runemask pairs (city id, corresponding rune bitmask) 0x11bbf 12   miscellaneous text string 0x11bcb 120  24 five-byte item location records (see below) 0x11c43 288  ??? 0x11d63 250  companion dialog text 0x11e5d 16   8 two-byte offsets to virtue adjectives for companion dialogs (value + 62123 gives file offset) 0x11e6d 1404 ??? 0x123e9 3486 Hawkwind dialog text; the first 40 zero terminated strings are his responses for 5 levels times 8 virtues, plus some other miscellaneous dialog strings 0x13187 80   40 two-byte offsets to Hawkwind dialog strings (value +              62075 gives file offset) 0x131d7 564  reagent vendor dialog text; x zero terminated strings 0x133eb 16   reagent vendor index for each city (one byte per              castle/city/town) 0x133fb 8    4 two-byte offsets to reagent shop names (value + 62075              gives file offset) 0x13403 8    4 two-byte offsets to reagent shopkeeper names (value +              62075 gives file offset) 0x1340b 24   price for each of the first six reagents at Moonglow, Skara Brae, Paws, and Buccaneers Den respectively (one             byte per price) 0x13423 1274 weapon vendor dialog text; 28 zero terminated strings 0x1391d 12   6 two-byte offsets to weapon shop names (value + 62075              gives file offset) 0x13929 12   6 two-byte offsets to weapon shopkeeper names (value +              62075 gives file offset) 0x13935 24   which four weapons each of the six weapons vendors can sell (one byte per weapon) 0x1394d 32   price of each weapon (two bytes for each price) 0x1396d 16   weapon vendor index for each city (one byte per              castle/city/town) 0x1397d 28   14 two-byte offsets to weapon descriptions (value + 62075              gives file offset) for all weapons except hands and mystic 0x13999 522  more weapon vendor dialog text; 27 zero terminated strings 0x13ba3 646  armor vendor dialog text; 19 zero terminated strings 0x13e29 10   5 two-byte offsets to armor shop names (value + 62075 gives              file offset) 0x13933 12   6 two-byte offsets to armor shopkeeper names (value + 62075              gives file offset) 0x13e3f 20   which four types of armor each of the five armor vendors can sell (one byte per armor type) 0x13e53 4    zero padding 0x13e57 16   price of each type of armor (two bytes for each price) 0x13e67 16   armor vendor index for each city (one byte per              castle/city/town) 0x13e77 12   6 two-byte offsets to armor descriptions (value + 62075              gives file offset) for all armor types except skin and mystic 0x13e83 484  more armor vendor dialog text; 27 zero terminated strings 0x14067 318  horse vendor dialog text; 7 zero terminated strings 0x141a5 622  guild vendor dialog text; x zero terminated strings 0x14413 6    ??? 0x14419 8    price per unit of each guild item (two bytes for each price) 0x14521 8    quantity per unit of each guild item (two bytes for each              quantity) 0x14429 4    2 two-byte offsets to guild shop names (value + 62075 gives              file offset) 0x1442d 4    2 two-byte offsets to guild shopkeeper names (value + 62075              gives file offset) 0x14431 8    4 two-byte offsets to guild item inquiry responses (value +              62075 gives file offset) for torches, gems, keys, sextants 0x14439 702  inn dialog text; x zero terminated strings 0x146F7 16   inn index for each city (one byte per castle/city/town) 0x14707 8    inn sleep location x coordinate for seven inns plus zero pad 0x1470f 8    inn sleep location y coordinate for seven inns plus zero pad 0x14717 8    inn prices for seven inns plus zero pad 0x1471f 14   7 two-byte offsets to inn names (value + 62067 gives file              offset) 0x1472d 14   7 two-byte offsets to inn names (value + 62067 gives file              offset) 0x1473b 14   7 two-byte offsets to inn price dialogs (value + 62067              gives file offset) 0x14749 424  more inn dialog text; x zero terminated strings 0x148f1 266  healer dialog text; x zero terminated strings 0x149fb 16   healer index for each city (one byte per castle/city/town) 0x14a0b 20   10 two-byte offsets to healer shopkeeper names (value + 62067              gives file offset) 0x14a1f 20   10 two-byte offsets to healer shopkeeper names (value + 62067              gives file offset) 0x14b33 598  more healer dialog text; x zero terminated strings 0x14d89 978  tavern dialog text; x zero terminated strings 0x1515b 16   tavern index for each city (one byte per castle/city/town) 0x1516b 12   minimum price for information at each tavern (two bytes for              each price) 0x15177 12   6 two-byte offsets to tavern shop names (value + 62067 gives              file offset) 0x15183 12   6 two-byte offsets to tavern shopkeeper names (value + 62067              gives file offset) 0x1518f 12   6 two-byte offsets to tavern specialty names (value + 62067              gives file offset) 0x1519b 12   price for plate of food at each tavern (two bytes for              each price) 0x151a7 12   7 two-byte offsets to tavern information topics (value +              62067 gives file offset) (??? why 7, not 6) 0x151b5 12   6 two-byte offsets to tavern information responses (value +              62067 gives file offset) 0x151c1 598  more tavern dialog text; x zero terminated strings 0x15417 456  food vendor dialog text; x zero terminated strings 0x155df 16   food vendor index for each city (one byte per castle/city/town) 0x155ef 10   price for 25 units of food at each vendor (two bytes for              each price) for Moonglow, Britan, Yew, Skara Brae, and Paws, respectively 0x155f9 10   5 two-byte offsets to food shop names (value + 62067 gives              file offset) 0x15603 10   5 two-byte offsets to food shopkeeper names (value + 62067              gives file offset) 0x1560d 189  Lord British dialog keywords; 27 zero terminated strings 0x156ca 2968 Lord British dialog text; 25 zero terminated strings ("He              says", plus responses for last 24 of the above keywords) 0x16262 104  ??? 0x162ca 2037 Lord British "help" response dialog strings 0x16abf ...  ???

Each item location record has the following structure:

offset len notes 0x0   1    item location (same encoding as party location in PARTY.SAV,            e.g. 0 for surface) 0x1   1    item x coordinate 0x2   1    item y coordinate 0x3   2    ??? (a pointer?)

=External Links=


 * http://www.geocities.com/xenerkes
 * http://www.moongates.com/u4/Tech.asp
 * The original version of this page can be obtained here.