Ultima I Map Format

From ModdingWiki
Jump to: navigation, search
Ultima I Map Format
Ultima I Map Format.png
Format typeMap/level
Map type2D tile-based
Layer count1
Tile size (pixels)16×16
Viewport (pixels)304×144
Games

Ultima I has a single over world map file for all four of the game's lands. The map is 168×168 tiles, which yields 2,688×2,688 pixels. The tiles are drawn using the game's tile graphics, however, they don't tie up 1-to-1 because the tile graphics file includes animations.

File Format

The map data is a string of bytes. The file uses a nibble for each tile, or 2-tiles per byte. One row of tiles requires 84 bytes, and there are 168 rows.

Data type Name Description
BYTE tiles Binary representation of 2 tiles.

Tile Data

The tiles are as follows:

Value Tile Id Tile Description
0 0 Water
1 1 Grass
2 2 Forest
3 3 Mountain
4 4 Castle
5 6 Signpost
6 7 Town
7 9 Dungeon Entrance

The map file does not store which specific castle, town, dungeon, or signpost is at which location.

Source Code

Map Viewer

This FreeBASIC program displays the over world map with pixels made up of appropriately colored pixels.

' Draws the over world map of Ultima I.
 
Dim As UByte X
Dim As UByte Y
Dim As UByte Tiles
 
Screen 7
 
Open "H:\DOS\Ultima\Map.bin" For Binary As #1
 
Dim As UByte Colors(0 To 7)
Colors(0) = 1       ' Water
Colors(1) = 10      ' Grass
Colors(2) = 2       ' Forest
Colors(3) = 8       ' Mountain
Colors(4) = 15      ' Castle
Colors(5) = 6       ' Signpost
Colors(6) = 13      ' Town
Colors(7) = 0       ' Dungeon Entrance
 
Dim As UByte HiNibble
Dim As UByte LoNibble
 
For Y = 0 To 167
    For X = 0 To 83
        Get #1, , Tiles
 
        ' The EGA file stores 4 pixels per byte. The hi nibble is the first 
        ' color, the lo nibble is the second.
        HiNibble = Tiles SHR 4
        HiNibble = HiNibble And &h0F
 
        LoNibble = Tiles AND &h0F
 
        PSet(X * 2, Y), Colors(HiNibble)
        PSet(X * 2 + 1, Y), Colors(LoNibble)
    Next X
Next Y
 
Close #1
Sleep

Credits

This map format was reverse engineered by TheAlmightyGuru. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)