C64 Dungeon Layout Exposed

Any developer realated stuff
Post Reply
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

C64 Dungeon Layout Exposed

Post by Darendor »

After much conferring with ZeroZero we have managed to more or less completely decipher the makeup of dungeon levels.

One lousy byte escapes my comprehension. :?

Still.

We know that the dungeon levels are stored on the DUNGEON disk from NMA0 to NMAF.

The entry level to each dungeon contains the following: Exit co-ordinates on the Skara Brae map, which levels allow use of the APAR spell, and the style of walls used for the dungeon (out of 4). Direction of the dungeon is set by the entry stairs orientation (so that if there are stairs leading UP to Skara Brae, it goes downwards; stairs leading down to Skara Brae means the dungeon is skyward)...

Here is a comprehensive breakdown of the dungeon as stored on disk:


Bytes Meaning
=====================================================
000 - 001 Load Address of file
002 - 201 Wall Map, one byte per cell
202 - 401 Event Map, one byte per cell
402 - 409 Level flags, relate to NMAx file (8 levels)
40a - 411 APAR(teleport) (00 = allowed, FF = disallowed)
412 Monster difficulty (00 to 07)
413 PHDO (00 = allowed, 01 = disallowed)
414 wall set style: 0 = sewer, 1 = Cellar, 2 = catacomb, 3 = Mangar
415 N co-ordinate of dungeon entrance on Skara Brae map
416 E co-ordinate of dungeon entrance on Skara Brae map
417 ???
418 - 421 dungeon name (9 chars and dc)(spaces padded with a0)
422 - 431 coordinates for up to 8 special events
loaded from files (8 coors)
432 - 441 indices into file load table to evaluate file
number to be loaded from there
442 - 461 anti magic (16 coors)
462 - 471 teleport FROM coors (8 coors)
472 - 481 teleport TO coors (8 coors)
482 - 491 Spinners (8 coors)
492 - 4a1 Smoke (8 coors)
4a2 - 4c1 HP damage zone (16 coors)
4c2 - 4d1 SP regeneration zone (8 coors)
4d2 - 4e1 Stasis chambers (8 coors)
4e2 - 4f1 cells with messages, same sequence as following texts (8 coors)
4f2 - 501 forced encounters, inavoidable fights (8 coors)
502 - 511 type and number of opps from 4f2
512 - 521 -20h = offset of text (8 pairs)
522 - eof texts
_______________________________________________________

The level flags means that the NMAx levels that this dungeon belongs to. For instance, NMA0, NMA1, NMA2, and NMA3 are the Wine Cellar, Sewers 1, Sewers 2, and Sewers 3. A dungeon can have up to EIGHT levels assigned to it, and unused level flags are padded with FF.
What follows that is eight bytes set to either 00 or FF; this determines whether the level allows teleportation. In the case of the Wine Cellar/Sewers, the bytes read 00 00 00 00 FF FF FF FF to show all four levels can be teleported into/through/out of.

The monster difficulty is a "level" that determines how difficult random (and set) encounters will be. Setting this beyond 07 has not been tested significantly.

The byte at 0413 determines whether the Phase Door (PHDO) spell functions. 00 = yes, 01 = no. Contrary to what I previously thought, the PHDO and APAR spells are independently allowed/disallowed.

The byte at 0414 determines which style of wall is displayed in the dungeon levels. 00, 01, 02 or 03.

Bytes 0415 and 0416 are the N and E co-ordinate of their location on the map of Skara Brae. Think of Skara Brae as on a 30 x 30 oversized dungeon map. These bytes are determined by the entry dungeon level only.

Byte 417's purpose is undetermined yet.

Each dungeon level has its own custom name, 9 characters long maximum terminated by the value DC with unused spaces represented as A0.

The coordinates for special events is two pairs of bytes indicating where on the map events that load from the disk are positioned. For instance, in the Sewers level 1 the Spidergod statue is at 9N, 4E. Unused bytes are padded with FF.

There is a jump table loaded from the BOOT disk that contains the offset for which NMxx file to load in the event of a "loadable special":

:1b2c 00 1b 0c 0d 0e 0b 00 0f
:1b34 10 1c 1d 1e 11 12 14 13
:1b3c 1f 20 21 22 23 24 25 15
:1b44 26 27 28 29 2a 2b 2c 2d
:1b4c 2e 2f 16 18 17 30 31 32
:1b54 33 34 19 35 36 37 38 39
:1b5c 3a 3b 3c 3d 3e 3f 40 41
:1b64 42 43 44 1a 91 1b 6c 1b

The spidergod event above has 11 FF, which translates from hex into 17. Starting at 1b2c in the table above (from 0), we count up to 17 and end up with a hex value of 20. So, the game loads NM20.PRG.
Note that the offset (XX FF) must be in the same order that the co-ordinates appear at for it to work correctly. For instance, the first loaded program is at 09 04, so the first offset must be set to 11 FF. If there was a 2nd loaded special at say 12 19 then the 2nd offset would be for instance 12 FF, which would have to come after 11 FF...get it?

From 0442 to 0461 are up to 16 pairs of co-ordinates for antimagic zones. Unused bytes are padded with FF.

0462 to 0471 has up to 8 pairs of teleportation co-ordinates; these are the FROM set. Unused bytes are padded with FF.
Immediately following these are the TO set of co-ordinates (0472 to 0481); these are in the same sequence as the FROM set.

0482 to 0491 holds the coordinates for up to 8 spinners. Unused bytes are padded with FF.

0492 to 04a1 holds coordinates for up to 8 "Smoke in your eyes!" zones. Unused bytes are padded with FF.

04a2 to 04c1 holds coordinates for up to 16 hitpoint leech zones. We found no way to adjust the damage done each movement. Unused bytes are padded with FF.

04c2-04d1 are the coordinates for up to 8 magic point regeneration zones. Appears to be a fixed rate. Unused bytes are padded with FF.

04d2 to 04e1 are co-ordinates for up to 8 "stasis chambers". Unused bytes are padded with FF.

04e2 to 04f1 are co-ordinates for up to 8 static text messages. Unused bytes are padded with FF.

04f2 to 0501 are co-ordinates for up to 8 preset battles. Unused bytes are padded with FF.

0502 to 0511 are the monster ID and # for preset battles (04f2 to 0501). Same sequence. Unused bytes are padded with FF.

0512 to 0521 are the offsets for the actual text messages set up at 0522 onwards (and co-ordinated from 04e2 to 04f1). For message #1, you subtract the value at 0512 from the value at 0522. For message #2, the value at 0514 is subtracted from the value at 0512, then the remaining number is added to 0522 to get the beginning of that message. And so on.

I had a hard time grasping it when ZeroZero explained it to me. :?





What follows is random comments and notations used during the trial and error process.


Mytery bytes

412 - 417 A0: 00 00 01 05 1c 00 Cellar

I think I know how to read 512 to 521
Mike says:
How?
Martin says:
substarct 20 fhex from each value
Martin says:
except the fd's
Mike says:
Er.
Martin says:
texts start at 522
Mike says:
0510: FF FF 20 FD 6D FD...
Martin says:
20 => 0, 6d => 4d, 98 => 78
Martin says:
then that number points to the start of that text
Mike says:
HOw did you come to figure that?
Martin says:
text 1 starts at 522 + 0
Martin says:
text 2 starts at 522 + 4d
Martin says:
text 3 at 522 + 78 all hex
Mike says:
And the FDs?
Martin says:
bs, filling stuff
Martin says:
unless there is more text than 256 chars
Mike says:
How did you know to even look for that?
Martin says:
experience


Mike says:
09 04 is 9N 4 east, our first loaded special?
Martin says:
dungeon name sewers
Martin says:
yes spidergod
Martin says:
only one here
Mike says:
11 FF is our offest.
Mike says:
Offset.
Martin says:
yes
Mike says:
11 being 17, so...
Mike says:
NM17?
Martin says:
no
Mike says:

Martin says:
the 17th value in the file list at memory 1b2c

:1b2c 00 1b 0c 0d 0e 0b 00 0f
:1b34 10 1c 1d 1e 11 12 14 13
:1b3c 1f 20 21 22 23 24 25 15
:1b44 26 27 28 29 2a 2b 2c 2d
:1b4c 2e 2f 16 18 17 30 31 32
:1b54 33 34 19 35 36 37 38 39
:1b5c 3a 3b 3c 3d 3e 3f 40 41
:1b64 42 43 44 1a 91 1b 6c 1b
:1b6c c9 ee f3 e5 f2 f4 a0 c4
:1b74 d5 ce c7 c5 cf ce a0 e4
:1b7c e9 f3 eb a0 e1 ee e4 a0
:1b84 f0 f2 e5 f3 f3 a0 e1 a0


412 - 417 A0: 00 00 01 05 1c 00 Cellar
A1: 01 00 00 00 00 00
A2: 01 00 00 00 00 00
A3: 02 00 00 00 00 00
A4: 02 00 02 0f 12 00 Catacombs
A5: 03 00 02 00 00 00
A6: 03 01 02 00 00 00
A7: 03 00 01 18 04 03 Harkyn's
A8: 04 01 01 00 00 03
A9: 04 00 01 00 00 03
AA: 05 01 01 1b 1b 13 Kylearan's
AB: 05 00 03 02 02 03 Mangar's
AC: 06 00 03 ff ff 03
AD: 06 01 03 ff ff 03
AE: 07 01 03 ff ff 03
AF: 07 01 03 ff ff 03

Byte 417
User avatar
Marco
Posts: 81
Joined: Mon Dec 10, 2007 7:45 pm
Contact:

Post by Marco »

Very interesting stuff. How/where are the darkness squares stored? Maybe the "mystery byte" has something to do with those? Though it seems to me that info would take a lot more disc space. Are the darkness squares included in the wall map?

EDIT: I just had a thought -- maybe that mystery byte is a flag related to the 4th level of Mangar's Tower when the walls turn to doors and doors turn to walls. It might be easier to accomplish that trick using a flag, rather than rewriting the entire dungeon level grid in the computer/emulator memory.

Marco.
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

Marco wrote:Very interesting stuff. How/where are the darkness squares stored? Maybe the "mystery byte" has something to do with those? Though it seems to me that info would take a lot more disc space. Are the darkness squares included in the wall map?

EDIT: I just had a thought -- maybe that mystery byte is a flag related to the 4th level of Mangar's Tower when the walls turn to doors and doors turn to walls. It might be easier to accomplish that trick using a flag, rather than rewriting the entire dungeon level grid in the computer/emulator memory.

Marco.
The "level flags" include darkness.

Specifically: Stairs up, stairs down, traps, specials, darkness, portals up, portals down, and forced encounters.
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

The special that transforms doors to walls and vice versa is a loaded event, so it's not a flag.


As an aside, I came to the realization that it'll be impossible to add more dungeon levels unless we alter the game engine code. I think. :?
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

Nevermind the bit about not adding more levels, I just added a sixth level to Mangar's Tower! :shock:

The Dungeon Disk with the modifications:
http://www.mediafire.com/?sharekey=2273 ... f6e8ebb871

Explore Mangar's Level 5 and see if you don't find anything different. 8)
Last edited by Darendor on Tue Mar 17, 2009 5:18 pm, edited 1 time in total.
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

It seems that I need to give pause to my dungeon editor program and reconsider how to make it work.

So far, it just writes directly to the sectors, but it would be a lot less of a headache in the end if it just knew to make a new dungeon file and write the data that way.


So...does anyone here have any experience with making a BASIC program that makes other .PRG files based on data that is either inputted from the keyboard and/or existing files?
brideck
Posts: 11
Joined: Wed Oct 19, 2011 7:48 am

Post by brideck »

This seems as good a thread as any. Does anyone know what determines the set of possible traps in a dungeon and/or what the different sets are? I guess I'm talking about both in chests and in the dungeon itself.

There's clearly something that prevents you from tripping a Basilisk snare in the wine cellars, etc. Maybe it's just tied to the same index as monster difficulty.
User avatar
Darendor
Posts: 1502
Joined: Wed Jan 14, 2009 1:53 am
Location: Red Deer, Alberta, Canada

Post by Darendor »

brideck wrote:This seems as good a thread as any. Does anyone know what determines the set of possible traps in a dungeon and/or what the different sets are? I guess I'm talking about both in chests and in the dungeon itself.

There's clearly something that prevents you from tripping a Basilisk snare in the wine cellars, etc. Maybe it's just tied to the same index as monster difficulty.
I imagine that the game code itself is hard-wired for two types of random trap types that go off. I think ZeroZero managed to decipher that bit of the engine 2 years ago.
User avatar
ZeroZero
Posts: 286
Joined: Tue Mar 10, 2009 9:10 pm
Location: Germany

Post by ZeroZero »

Trap fields are set by a flag in the dungeons event map.

The type of trap is fully randomly, but limted by the dungeons monster level.

There is also an event for chests that I disassmebled long ago, works similar.

Spinners, smoke, darkness are *not* traps, but special fields. Traps are things like pits etc.
drifting
Posts: 153
Joined: Wed Dec 07, 2011 10:21 pm

Re: C64 Dungeon Layout Exposed

Post by drifting »

Darendor wrote: One lousy byte escapes my comprehension. :?

Bytes Meaning
=====================================================
000 - 001 Load Address of file
414 wall set style: 0 = sewer, 1 = Cellar, 2 = catacomb, 3 = Mangar
415 N co-ordinate of dungeon entrance on Skara Brae map
416 E co-ordinate of dungeon entrance on Skara Brae map
417 ???

The byte at 0414 determines which style of wall is displayed in the dungeon levels. 00, 01, 02 or 03.

Byte 417's purpose is undetermined yet.
From my disassembling of the MSDOS version, there are some differences:
000-001 Load Address of file
This field does not exist on the MSDOS version.

414 - This is the direction the party is facing when they exit the dungeon.
0 - North
1 - West
2 - South
3 - East
The wall set style is hardcoded in the program itself.
417 - This is a flag for the orientation of the dungeon. If this flag is zero, the levels go down as in the sewers. If it is non-zero, then the levels go up as in the Castle.

The Scry Site spell uses it like this:
If (417 == 0) then
print("and are X levels below")
else
print("and are X levels above")
User avatar
ZeroZero
Posts: 286
Joined: Tue Mar 10, 2009 9:10 pm
Location: Germany

Post by ZeroZero »

See here:

2010-04-16 Dungeon map file format

In fact only byte 414 differs between C64 and DOS versions.

E D I T

Of course the events that are loaded from file in C64 will be evaluated in
a different way, however the meaning of the bytes in the level file is
the same.
Desmet Irkm
Posts: 35
Joined: Fri Nov 11, 2011 2:50 pm
Location: .de
Contact:

Post by Desmet Irkm »

@drifting I can't believe that 414 is the direction the party is facing when they exit the dungeon. In the msdos version they exit exactly where they entered the dungeon, facing the same dircetion they had entered. Bytes 415 and 416 are also ignored. This is the same for the Amiga version. In the Apple IIgs version 415 and 416 are used, e.g. when you exit the catacombs you always face the center of grand plaz.
drifting
Posts: 153
Joined: Wed Dec 07, 2011 10:21 pm

Post by drifting »

Well that's irritating. I have that byte marked as the exit direction in my notes. Looking through the disassembly I don't see any references to that byte in the level data. So now I have no idea how I came to the conclusion that it is the exit direction...
Post Reply