Ultima III Internal Formats

Note: This file was originally found here.

SHAPES.ULT
This file contains 0x50 tiles. All tiles are 16*16 pixels^2. Each tile in stored in CGA-compatible format. The first 0x20 bytes of each tile contain the first bit plane, the following 0x20 bytes contain the second bit plane.

 
 * The Ultima III monochrome, CGA, and EGA tileset

The index within this character set is also used to index the XP table.

CHARSET.ULT
This file contains the 0x80 characters that make up the U3 font. All characters are 8*8 pixels^2. Each character in stored in CGA-compatible format. The first 0x8 bytes of each character contain the first bit plane, the following 0x8 bytes contain the second bit plane.

SOSARIA.ULT
This file contains the world map and information about the game world state.

Monsters, horses, ships, chests
U3 stores the location of these objects by writing them directly into the map.

Monsters
Monsters are stored as basetile_number*4. The map tile under the monster is stored in the table at 0x11A0.

Horses
Horses are stored as 0x28 == horse_tile*4. The tile under the horse can only be 0x1, because you can only dismount a horse on a grass tile.

Ships
Ships are stored as 0x2C == ship_tile*4. The tile under the ship can only be 0x0.

Chests
The map tile under the chest is encoded in the lowest 2 bits of the tile: 0x24 == chest_tile*4 + 0 --> chest on bricks (tile 0x8) 0x25 == chest_tile*4 + 1 --> chest on grass (tile 0x1) 0x26 == chest_tile*4 + 2 --> chest on forest (tile 0x2) 0x27 == chest_tile*4 + 3 --> chest on deep forest (tile 0x3) Monsters can't walk onto chests, so there can only be one chest per map square.

Moon phases and sub-phases
Each turn, both sub-phases are decremented. When a sub-phase reaches -1, it is reset to 0xB/3, and the corresponding phase is incremented. The phases are the numbers displayed on the upper border of the game world window.

DEMO.ULT
This file contains the 19*6 map displayed in the main menu. Each byte represents a tile.

MOVES.ULT
This file contains the animation script for the main menu map.

ROSTER.ULT
This file stores the infomation about all the characters the player has created.

Character record format
NOTE: BCD = binary coded decimal (two digits per byte).

Sub-morsels
This field contains 2 digits (those behind the decimal point) of the food field. On the surface, the game subtracts 10 from this field during every turn (remember that it contains a BCD). Everywhere else, the game subtracts 10 every 4 turns.

PARTY.ULT
This file contains information about the current party. BCD = binary coded decimal (two digits per byte).

Party location
Note: You can only save your game in Sosaria, so the party location field in the file is always 0.

.ULT files (town maps)
These files contain the map and "dialog" for each town. There are 32 NPC's in every town. (?)

Movement flag + dialog number
(byte >> 4) == 0 --> NPC walks around

(byte >> 4) == 4 --> NPC doesn't move

(byte >> 4) == 8 --> NPC is a merchant

(byte >> 4) == 0xC --> NPC attacks party

(byte % 0xF) == sentence number

Still unknown: 0x85, 0x86 (?)

.ULT files (dungeon maps)
These files contain the dungeon maps and sign texts.

Map format
There is at most one sign per dungeon level. To find out the text for a sign, use (dungeon_level-1) as an index into the table at 0x800.

.ULT files (conflict maps)
These files contain the 11*11 conflict maps.

CNFLCT_A.ULT

CNFLCT_B.ULT

CNFLCT_C.ULT

CNFLCT_F.ULT

CNFLCT_G.ULT   grasslands

CNFLCT_M.ULT

CNFLCT_Q.ULT

CNFLCT_R.ULT

CNFLCT_S.ULT

Map format
U3 uses the 8 bytes at offset 0x90 (in memory) to store the tiles under monster 1-8. U3 uses the 8 bytes at offset 0x98 (in memory) to store the hit points of monster 1-8. U3 uses the 4 bytes at offset 0xA8 (in memory) to store the tiles under PC 1-4. U3 uses the 4 bytes at offset 0xAC (in memory) to store the base tiles for PC 1-4. U3 doesn't use the values stored at these locations in the conflict files.

.IMG files
Each of these files contains an 11*11 tile image. Each byte represents a tile number.

Further Notes
I'm pretty sure that U3 doesn't save the wind direction.