Lords of Midnight : Tower of the Moon
by mike singleton

LORDS OF MIDNIGHT DATA FORMAT
this document contains the data format for Lords of Midnight, it is not complete but gives a good start and understanding. for further information download LOM source this may help fill in some of the blanks. should you find any errors with this document or indeed have any information to add, please send me an email.

 

address 0x5cb0 token dictionary
The tokens are stored using 5 bit bytes compressed together.
the format is [length][length * char] you have to decode all the tokens until you find the token you require
00 The 01 Lothoril 02 Gloom 03 Moon 04 Mirrow 05 Glorim 06 Korkith 07 Lost
08 Dead 09 Weird 0a Ugrak 0b Death 0c Doom 0d Despair 0e Vorgath 0f Ushgarak
10 Ugrorn 11 Kor 12 Toomog 13 Ogrim 14 Dodrak 15 Gorgrath 16 Valethor 17 Coroth
18 Ashimar 19 Ithril 1a Shadows 1b Blood 1c Thrall 1d Torkren 1e Gard 1f Mitharg
20 Moon 21 Iserath 22 Shimeril 23 Odrark 24 Ishmalay 25 Brith 26 Silence 27 Elenil
28 Rorath 29 Morning 2a Thimrath 2b Corelay 2c Rathrorn 2d Lorgrim 2e Lor 2f Fadrath
30 Droon 31 Grarg 32 Dreams 33 Ithrorn 34 Whispers 35 Xajorkith 36 Herath 37 Kumar
38 Marakith 39 Targ 3a Utarg 3b Athoril 3c Dregrim 3d Dawn 3e Trorn 3f Coom
40 Of 41 Mountain 42 Citadel 43 Forest 44 Henge 45 Tower 46 Village 47 Down
48 Keep 49 Snowhall 4a Lake 4b Waste 4c Ruin 4d Lith 4e Cavern 4f Army
50 Plain 51 Frozen 52 Domain 53 A 54 In 55 He 56 Stand 57 North
58 South 59 East 5a West 5b Looking 5c To 5d At 5e On 5f Beside
60 Less 61 Than 62 Hour 63 One 64 Two 65 Three 66 Four 67 Five
68 Six 69 Seven 6a Eight 6b Nine 6c Ten 6d Remain 6e Day 6f It
70 Is 71 Night 72 Luxor 73 Morkin 74 Corleth 75 Rorthron 76 Fawkrin 77 Farflame
78 Korinel 79 Lord 7a Fey 7b Wise 7c Skulkrin 7d Dragon 7e Moonprince 7f Press
80 Choose 81 Key 82 Save 83 Others 84 Game 85 Start 86 Tape 87 And
88 Enter 89 Being 8a Has 8b Been 8c Do 8d You 8e Want 8f Sure
90 Was 91 Quit 92 Continue 93 Failed 94 Again 95 An 96 Old 97 Try
98 Ing 99 Horse 9a Wolf 9b Ice 9c Troll 9d Wild 9e Guard 9f Free
a0 Dark a1 Midnight a2 Welcome a3 Land a4 Must a5 First a6 Between a7 New
a8 Or a9 Fear aa Load ab Fallen ac Foul ad Abroad ae Are af Found
b0 Nothing b1 Search b2 Many b3 Eleven b4 Twelve b5 Thir b6 For b7 Fif
b8 Teen b9 Twenty ba Hundred bb Thousand bc No bd Have be Pass bf War
c0 Solstice c1 Began c2 Since c3 Battle c4 Rider c5 Warrior c6 Alone c7 Slew
c8 Enemy c9 Thinks ca Victory cb Went cc None cd Men ce But cf His
d0 All d1 Utterly d2 Very d3 Slightly d4 Quite d5 Tired d6 Invigorated d7 Command
d8 Cannot d9 Guidance da Voice db Calls dc Shelter dd Refreshed de Which df Drain
e0 Fill e1 Vigour e2 Life e3 With e4 Hand e5 Brings e6 Sword e7 Slayer
e8 Waters e9 Cup ea Crown eb Destroy ec Leads ed Can ee Hide ef Hidden
f0 Seek f1 Killed f2 Afraid f3 Bold f4 Cold f5 Mild f6 Recruit f7 Fight
f8 Wolves f9 Him fa Ring

 

message format

all messages are stored in a token-ised format. as each byte is read then it is first checked if it is a special code or the word is looked up from the token dictionary this word is used in all lowercase. the next token is read to check if it is either CONNECT or LITERAL, if it is then this new text is added to the current word and the next token is check again. otherwise the word is printed with a space at the end
type description
0xfb NEWLINE start a new line
0xfc UPPERCASE next token is displayed with uppercase first character
0xfd CONNECT do not add a space before this token
0xfe LITERAL next byte is an ascii character and not a token
0xff TERMINATOR end of message
0x00-0xfa [tokens] lookup ascii token from the token dictionary

 

address 0x676e save game area
type offset description
WORD 00 days - days since the start of the game
BYTE 02 char - current selected character
BYTE 03 unused
BYTE 04 unused
BYTE 05 unused
TABLE 0x0006 garrisons
TABLE 0x00d2 special places
TABLE 0x0292 regiments
TABLE 0x0492 characters
TABLE 0x0892 terrain map
TABLE 0x17d2 area map
the area map is only partially included in the save game; this is because the area map isn't required for saving but the terrain map is saved as if it was 64x64 and not 64x61.

 

address 0x6774 garrisons
the 102 entries in this table correspond to the garrisons assigned to the 102 keeps and citadels
Ushgarak is element 0x06
Xajorkith is element 0x60
type offset description
BYTE 00
unused type race
7 6 5 4 3 2 1 0
race - see race table
type - 0 = warriors, 1 = riders
BYTE 01 total - size of this unit / 5

 

address 0x6840 special places
the 112 entries are the special places, the first 102 are keeps and citadels and have a corresponding entry in the garrisons table. the remaining are just in for extra routing. the left and right routing branch is used to randomly pick another location to head to. when an army of type 3 gets to a location in this table, they
randomly pick the left or right branch and then goto the location specified
in the table for that number.
type offset description
WORD 00 location - map location
BYTE 02 left - left branch special place
BYTE 03 right - right branch special place

 

address 0x6a00 regiments
128 entries for the free wandering armies of doomdark.
type offset description
BYTE 00
order x coor
7 6 5 4 3 2 1 0
BYTE 01
t   y coor
7 6 5 4 3 2 1 0
t = type - 0 = warriors, 1 = riders
BYTE 02 total - size of this unit / 5
BYTE 03 id - either special place or character

 

order description
0 go to special location [ID] and stay there.
1 wander around
2 follow character [ID] and kill him. then pick Luxor or morkin.
3 go to special location [ID] then pick new location.

 

address 0x6c00 lords
type offset description
WORD 00 location - current location
BYTE 02 direction - currently looking
BYTE 03 time - time of day
BYTE 04 first name - first name token
BYTE 05 title - see title types
BYTE 06
            m r
7 6 5 4 3 2 1 0

m =0 Moonring worn, 1 otherwise
r   =0 if not recruited, 1 otherwise.

m = moon ring toggle, this is set when luxor or morkin do not have the moon ring. while this is set then the character is unavailable.
r = recruited

BYTE 07 graphic - see graphic types
BYTE 08 riders - total riders / 5
BYTE 09 riders_energy - riders energy
BYTE 10 warriors - total warriors / 5
BYTE 11 warriors_energy - warriors energy
BYTE 12 battle_area - area currently in battle in
BYTE 13 riders_lost - number of riders lost in battle
BYTE 14 warriors_lost - number of warriors lost in battle
BYTE 15 killed - number of the enemy killed by the character in battle
BYTE 16 riders_killed - enemy killed by riders
BYTE 17 warriors_killed - enemy killed by warriors
BYTE 18 battle_status, 0xff no batle, 0 - battle continues, ?? - who won
BYTE 19 alive - 0 or 1
BYTE 20 energy - current energy
BYTE 21 strength - current strength
BYTE 22 cowardess
BYTE 23 recruiting_key
BYTE 24 recruited_by
the character who is doing the recruiting, recruiting_key is anded with the recruited_by from the character he wished to recruit and if it is not zero then recruiting can take place.
BYTE 25 courage
BYTE 26 unused
BYTE 27 hidden - 0 or 1
BYTE 28 race - see race table
BYTE 29 horse - 0 or 1
BYTE 30 object - object carrying - see object table
BYTE 31 deathby, 0 - in battle, otherwise the value is the object that killed him

 

graphic types
0x00 Targ on horse 0x01 Free on horse 0x02 Doomdark riders 0x03 Wise on horse
0x04 Morkin on horse 0x05 Wolf 0x06 Dragon 0x07 Ice Troll
0x08 Free 0x09 Doomdark Warriors 0x0a Wise 0x0b Morkin
0x0c Skulkrin 0x0d Wild Horse 0x0e Targ 0x0f Fey on Horse
0x10 Fey

 

races

0x00 doomdark
0x01 free
0x02 fey
0x03 targ
0x04 wise
0x05 morkin
0x06 skulkrin
0x07 dragon
titles
0x00 FirstName "the Moonprince"
0x01 FirstName
0x02 FirstName "the Fey"
0x03 FirstName "the Wise"
0x04 FirstName "the Dragonlord"
0x05 FirstName "the Skulkrin"
less than 0x0A "The Lord of" FirstName
else "Lord" FirstName

 

address 0x7000 terrain map
64x61 byte map running x - y
type offset description
BYTE 00
object terrain
7 6 5 4 3 2 1 0
terrain - see terrain table
object - see object able

 

address 0x7f40 area map
64x61 byte map
type offset description
BYTE 00
s d area
7 6 5 4 3 2 1 0

The area relates to text tokens 0 - 63, see area table
The d ( Domain )  bit decides how a location is described
eg: 0 - A keep in the domain of the moon
    1 - Moon Keep
The s ( Special )  bit is only used during the game for processing. If an army of character is at a location, this bit is set. This does not require pre-setting.

 

objects

0x00 None
0x01 Wolves
0x02 Dragons
0x03 Ice Trolls
0x04 Skulkrin
0x05 Wild Horses
0x06 Shelter
0x07 Guidance
0x08 Shadows Of Death
0x09 Waters Of Life
0x0a Hand Of Dark
0x0b Cup Of Dreams
0x0c Sword of Wolf Slayer
0x0d Sword of Dragon Slayer
0x0e Ice Crown
0x0f Moon Ring

terrain types

0x00 Mountain
0x01 Citadel
0x02 Forest
0x03 Henge
0x04 Tower
0x05 Village
0x06 Downs
0x07 Keep
0x08 Snow Hall
0x09 Lake
0x0a Frozen Waste
0x0b Ruin
0x0c Lith
0x0d Cavern
0x0e Army
0x0f Plains

 

 

 

The art of Landscaping
a description of the landscaping process is described in detail in The Art of Landscaping

 

address 0x9000 Start of Terrain Graphics
this is a general description of the draw format of the terrain graphics.
see the drawfeature function source code detailed elsewhere for a better description.
type offset description
BYTE 00 height
[ while height ]
BYTE 00 ... scan line data follows
 
o i c
7 6 5 4 3 2 1 0

o - further operations to follow
i - ink or paper
c - items to follow in this operation

        [   do ]
BYTE 01 start x of line
BYTE 02 end x of line
draw line on in [i] from startx-endx
draw a point at the start and end of line in ink
reverse [i]
                [ while c ]
BYTE 00  
t d
7 6 5 4 3 2 1 0

t - type 1 = line, 0 = point
d - data

if line then [d] is start x of line,  get next byte which is end x of line and draw a line in [i] from startx to endx
otherwise
[d] is the x coordinate to draw a point in [i]

BYTE 01 end x of line
                [ wend ]
        [   loop until [o] == 0 ]
[ wend ]

 

Miscellaneous
Lake Mirrow is hard-wired to location 0x1209 in routine 0x8F15

Tower of Despair is hard-wired to location 0x051A in variable 0xDCF8, 0xDCF9

The following Areas have THE prefixing them. 0x07 - Lost 0x20 - Moon 0x39 - Targ