Well, after Jon Hylands created the RDL specs for Descent
I, I decided to write the RL2 specs! As I wrote the initial versions of the Descent
Manager, I had to find out these informations stated here for the Level-Reporter.
Since Rel. 2a these specs have a very special feature, and
Im proud that such a feature was never released before in any games specs! Its
named "Developer Report". Look below for it!
This document was written by
Heiko Herrmann alias HH-Software Images and
Chris Becker alias Topher of the Descent Network.
Download Descent Manager for DOS Beta 06f with RDL/RL2 Developer Reports (390 kB)
Download DCheck tool by Peter Runge
RDL specs - Descent 1 Level format
eMail authors: Heiko Herrmann, Chris Becker
- Rel. 1a (Released 12/30/96): initial release
- Rel. 1b (Released 01/03/97): added internal level name
- Rel. 2a (Released 01/27/97): added switches information, introducing "Developer Report", added Vertigo Series Robots and Type 08 levels, some minor corrections
- Rel. 2b (Never released): minor fixes and additions
- Rel. 2c (Released 06/24/97): new design, now online viewable here at Descent Network - expect updates for the missing parts soon!
- Rel. 2d (Released 07/08/97): revised it again
- Rel. 3a (Released 12/18/98): revised by Chris Becker
- Rel. 3b (Released 01/05/99): revised again by Chris Becker
RL2 is the short form of "Registered Descent Level
2". You can use those only on the Descent 2 Registered Versions. The Shareware
Version, the OEM Version (called Destination Quartzon) and Descent 1 will just ignore
those levels! The RL2 is normally in a Descent archive file with the extension .HOG!
2-byte and 4-byte Integers are saved in normal PC style, so
that the minor byte comes first (so 12 80 23 33 will mean hex $33238012!). In case you are using a hex editor, for quick reference 255 decimal
is viewed as FF in a hex editor and 65535 is viewed as FF FF in a hex editor.
|
Descent Manager's Developer Report feature
|
This is a very special feature. Well, I thought to
understand the complex RL2 format it would be best to make you able to look at some
practical guide on some of your levels. How is this released?
Well, first of all you need the Descent Manager in the current version. As of releasing
this document, V1.0 Beta 03a is the actual version. Download it here...
Now, search for a level, which you want to analyse. Any working RL2 level is okay. Then
start the Descent Manager like this:
DESCMAN
/DEV C:\DESCENT\DEVIL\LEVELS\MYLEVEL.RL2 |
After pressing RETURN a special Developer report will be
created. It is stored in the same directory and has the same name as the Level, but uses
the extension ".DEV"! It is a simple ASCII file, which you can look at with any
text editor like EDIT, NOTEPAD, Norton Commander or even Word.
Now for the contents of this file: It contains lines like
Mine data pointer #MINEDATA 5666=$1622 points to 45991=$b3a7 |
The first column is the description of this file. The
second column (here "#MINEDATA") is the connecting piece to this spec!
Okay, now when you read this spec you will come to an point
with [#MINEDATA] for example. Now you want to know, where this point is in your
specific level. Then you will make the Developer report like above (if you didnt
already do it...) and look in the second column for #MINEDATA. You will find it and then
you see in the third column, where this thing is (or starts if the caption is more than
one byte!) in decimal and hexadecimal numbers! The fourth column does contain some
information as an addition, in this case it displays, where this pointer actually is
pointing to (short: the evaluated contents of this data). Isnt that a) easy and b) a
great thing?
Now to some syntax to the names I took!
-
If a name starts with "#" (like #MINEDATA), it
indicates NOT the point, where the MINEDATA is actually, but where the pointer to this
data is (short: where you can get the exact file offset to the data you want!)
-
All things, cubes and walls are listed seperatly. In this
spec there only stands a (e.x.) [#CUBE_xx], where xx stands for the number.
-
All those names are in brackets and in bold style in this
spec!
Note:
You should use Beta 03b or higher of the Descent Manager, because 03a has some bugs here
and some information was even missing!
The first 20 bytes are the header. Here is the explanation:
from start of the file:
| 0-3 |
ascii-chars
"LVLP" which means "Level Parallax". |
| 4-7 |
version number [VERSION] |
| 8-11 |
mine data
offset [#MINEDATA] |
| 12-15 |
game data
offset [#GAMEDATA] |
| 16-26 |
Palette file
(GROUPA.256) Terminated with 0A. |
| 27-31 |
Reactor time |
| 32-35 |
Reactor life |
| 36-39 |
Number of
flashing lights |
| 40-43 |
Secret Cube? |
| 44-78 |
Secret Cube
orientation? (3x3 matrix) |
The bytes 4-7 [VERSION] indicate the version number.
The following versions are out till now:
| 1 |
Descent 1
Shareware and Commercial Levels |
| 5 |
Descent 2
Interactive Demo Levels |
| 6 |
Descent 2
Commercial Levels |
| 7 |
Descent 2
Commercial Levels with V1.1 light extensions |
| 8 |
Descent 2
Commercial Levels with new robots (Vertigo Series levels!)(The Vertigo Series added the support for V-HAMs which let you add
custom robot weapons to a level as well as textures, models, ect.) |
We will only discuss version 6-8 here. Version 1 Commercial
are here.
The bytes 8-11 indicate the mine data offset. That is the
start of the data for the mine structures (cubes and vertecies) in the mine. The following
numbers are offsets from that address!
from minedata-offset [MINEDATA]:
| 0-1 |
Number of
verticies [NUM_VERTICIES] |
| 2-3 |
Number of cubes
[NUM_CUBES] |
| from
4 |
Verticies
information (number of verticies*12 bytes) [VERTICIES] |
| after |
Cubes
information (variable length) [CUBE_xx] |
The Vertex Data defines all of the points used by every
cube in the level. Each vertex is defined as follows:
| 0-3 |
X coordinate
value |
| 4-7 |
Y coordinate
value |
| 8-11 |
Z coordinate
value |
First of all there are two 2-byte integers with the number
of vertecies and the number of cubes. Following that the vertecies information with 12
bytes each: Each vertex is stored as three 16:16 coordinates (x, y and z). So you can get
the exact x-coordinate with the following: byte0+256*byte1+(byte2+256*byte3)/65536. Same
with bytes 4-7 for the y-coordinate and 8-11 for the z-coordinate.
A vertex's number is determined by the order it was in
minus 1. For example, the third set of X,Y and Z coordinates defines vertex number 2 (you
have to account for vertex number 0). You can skip the vertex infos and get directly to
the cube data with: minedataoffset+number of vertecies*12 bytes+4 from the beginning!
Okay, every cube package starts with the neighbor bitmask.
This is one byte containing the information where the cube is connected with another cube
and where the cube is an outer wall.
| Bit
0 |
left neighbor
cube |
| Bit
1 |
top neighbor
cube |
| Bit
2 |
right neighbor
cube |
| Bit
3 |
bottom neighbor
cube |
| Bit
4 |
back neighbor
cube |
| Bit
5 |
front neighbor
cube |
| Bit
6 |
special cube?
(not used anymore!) |
For each bit 0-5 is set to one, there will be a following
2-byte integer with the number of the cube connected to that side. Lets say, the actual
cube has on the left and on the back side neighbor cubes. Then the neighbor mask will be
set to 17 (16+1) and this means there will be 2*2 bytes=4 bytes following with the number
of the neighbor cube on the left side and on the back side (respectively). But here are
also some exclusions: If the neighbor cube is 65534, then that side is the special
"end wall", placed at the end of the exit tunnel, which was only used in Descent
I levels for the escape tunnel flight. And the second exclusion is that Parallax itself
usually sets ALL bits in the neighbor bitmask and then where not really a neighbor cube is
the number is set to 65535. This is important if you want to support both DEVIL levels and
the original DESCENT levels. This was also forgotten in the RDL specs by Jon Hylands,
although in Descent 1 this is the same, so it took me some time to figure out why DEVIL
levels were already working with the Descent Manager but the Parallax didnt...
For short: Save the bitmask of the actual cube in an
boolean array! When the neighbor bit is 1, set the corresponding array element to TRUE, if
not to FALSE. Then look at the neighbor cube info for each array element=TRUE and when
this is equal or higher than 65534, then reset the element to FALSE. You will need this
below!
Note to
Descent 1-RDL: Bit 6 of the neighbormask tagged a special cube in Descent 1! This is not
neccessary in the new file format anymore, so ignore bit 6!
After that the vertex info [CUBE_xx_VERTEX] comes.
Each cube is defined by its eight verticies! The information now following are the numbers
of the corresponding vertex number in the verticies data explained above:
from the point after the neighbor cube information:
| 0-1 |
vertex
left-front-top |
| 2-3 |
vertex
left-front-bottom |
| 4-5 |
vertex
right-front-top |
| 6-7 |
vertex
right-front-bottom |
| 8-9 |
vertex
left-back-top |
| 10-11 |
vertex
left-back-bottom |
| 12-13 |
vertex
right-back-top |
| 14-15 |
vertex
right-back-bottom |
Note to
Descent 1-RDL: In Descent 1s RDL format there would now be the special data for the
cube when Bit 6=1 in the neighbor bitmask and the cubes static light value (2
bytes). In RL2 this information does NOT stand here, but at the end of the cube
information! Note that difference if you write a tool which supports both Descent 1 and II
level files!!!
Next comes the wall bitmask [CUBE_xx_WBITMASK]. Bits
0-5 are once again if the corresponding side is a wall (doors, walls, switch to shoot,
illusion walls, ...). For each bit set there will be one byte with the ID of the switch.
So if the number is set to 34, then two Bits are set (Bit 5 and Bit 1), which means there
will be 2*1 byte=2 bytes following the switch bitmask containing the IDs of the switch.
The switch type and action itself is saved extra in the game data field, which is
explained later. If the ID is 255, then it would be like the corresponding bit is set to
0, meaning no switch on that side!
So, now for every side, that doesnt have a neighbor
(the corresponding bit in the neighbor bitmask is set to 0 or the neighbor cube is equal
or greater than 65534) or does have a switch (the corresponding bit in the switch bitmask
is 1 and the switch ID is not 255) there follows the texture information for that side.
This consists of the primary texture (2 bytes), optionally the secondary texture (2 bytes)
and the UVL-Data (24 bytes) shown here:
| 0-1 |
X
coordinate value |
| 2-3 |
Y
coordinate value |
| 4-5 |
Brightness |
The UVL data consits of 4 sets of X,Y and Brightness
values, one for each corner of the side. Not sure how to extract the values as of yet...
If bit 15 is set to one in the primary texture (greater
than 16384 decimal), there will 2 bytes follow after that with the secondary texture. The
UVL structure defines, for each vertex on the side, the offset of the texture, and the
light value of that vertex on the side. UV is the texture offset at that corner, and L is
the light value for that corner. The texture offset is a pair of short fixed point values,
which define how the texture is stretched.
Now the whole information you see above within the
"cube datas" subscription is repeated for every cube.
After the cube information follows the information on the
cube properties [CUBESPEC_xx]. This data is exact: number of cubes*8 bytes long!
The first byte contains the cube type:
| 0 |
Normal cube |
| 1 |
Fuel Center |
| 2 |
nothing (at first this was planned to be a "Repair Center"
but it wasnt included in the final Descent 1 version, neither D2 later...) |
| 3 |
Control Center
(Reactor) cube (only important for Descent 1, if
you forgot to set the cube containing the reactor there, Descent 1 didnt start the
countdown properly!) |
| 4 |
Materialisation
(Producer) Center |
| 5 |
Blue Home
(Capture-the-Flag) and Hoard-Station |
| 6 |
Red Home
(Capture-the-Flag) and Hoard-Station |
The other bytes descripe the the cubes static
light value and some other things, which I dont know till now...
The game data [GAMEDATA] starts at the offset which
is stated in the header (look at the beginning). The game data itself is divided into some
pieces. I did not get all structures till now, so there will be more to come in the
next versions of this spec!
The first is the game data header (143 bytes), which is
structured in the following way:
from gamedata offset:
| 0-1 |
Identifier
(6705 hex) |
| 2-3 |
Version (31) |
| 4-7 |
Size of header
(143) |
| 8-22 |
Filler (0) |
| 23-26 |
Level? |
| 27-30 |
Editor Offset(Just some comments about the maker of the level) |
| 31-34 |
Editor Bytes? |
| 35-38 |
Offset of
THINGS data (*1) [#THINGS] |
| 39-42 |
Number of
THINGS [NUM_THINGS] |
| 43-46 |
Thing bytes
(264) |
| 47-50 |
Offset of WALLS
data (*1) [#WALLS] |
| 51-54 |
Number of WALLS
[NUM_WALLS] |
| 55-58 |
Wall bytes (24) |
| 59-62 |
O-Door data
offset |
| 63-66 |
Number of
O-Door data entries |
| 67-70 |
O-Door data
bytes (16) |
| 71-74 |
Offset of
SWITCHES data (*1) [#SWITCHES] |
| 75-78 |
Number of
SWITCHES [#NUM_SWITCHES] |
| 79-82 |
SWITCHES bytes
(52) |
| 83-94 |
Filler (0) |
| 95-98 |
Offset of LINKS
data (*1) [#LINKS] |
| 99-102 |
Number of LINKS
[NUM_LINKS] |
| 103-106 |
LINKS bytes
(42) |
| 107-110 |
Offset of
PRODUCERS data (*1) [#PRODUCER] |
| 111-114 |
Number of
PROCUDERS [NUM_PRODUCER] |
| 115-118 |
PRODUCERS bytes
(20) |
| 119-122 |
Turn off data
offset |
| 123-126 |
Number of turn
off data entries |
| 127-130 |
Turn off data
bytes (6) |
| 131-134 |
Light data
offset |
| 135-138 |
Number of light
data entries |
| 139-142 |
Light data
bytes (8) |
(*1) all offsets are stated as offsets from the game data
offset on, so you must add them to get the real position within the file!
Directly after these 143 bytes (the game data header) there
is the name of the level, terminated with either the byte 0 or the byte 10 (hex A). After
the name is a list of all the POF files in Descent 2. Then comes the Editor comments. The
comments are 116 bytes long and NULL terminated and filled.
The following captions now descripe each of the known
sections.
The THINGS section [THINGS] contains full
information on each of the things in the mine. Things are not only items like weapons, but
also robots, reactors and starting places. The number of things are can be read of the
game data header [NUM_THINGS].
We start with the first byte of a thing [THING_xx].
This first byte indicates the type of the thing and the size of the package following
which descripes the thing in detail. 7 thing types are known. The following table will
show you the number of the types and how big a package of each type is (including the
first thing-type-indicator!):
| 2 |
235 bytes |
Robot |
| 3 |
92 bytes |
Hostage |
| 4 |
215 bytes |
Start place |
| 5 |
223 bytes |
Mine |
| 7 |
92 bytes |
Item (Weapon,
Key, Powerup, Accessories) |
| 9 |
151 bytes |
Reactor |
| 14 |
215 bytes |
Coop start
place |
I know very little of the information from every thing type
till now. Here is the information I know of each thing type and which was neccessary for
the Level-Reporter of the Descent Manager. I will add the missing information as soon as I
find out (if ya have further information send them to me, please!):
Thing-Type 2: Robot (235 bytes)
| 0 |
Thing-type (2
for Robot) |
| 1 |
Robot-type
Table of ROBOT_TYPES |
| 2 |
Control |
| 3 |
Movement |
| 4 |
Render |
| 5 |
Flags |
| 6-7 |
Cube |
| 8-19 |
Position |
| 20-55 |
Orientation (The orientation is stored in a 3x3 matrix of floating point
variables. Not sure what they mean as of yet.) |
| 56-59 |
Size |
| 60-63 |
Shield |
| 64-75 |
Last position |
| 76 |
Drop type
0=normal
2=drops Robots
7=drops items |
| 77 |
Dropped
robot(s) (if drop type=2) or item(s) (if drop type=7).
Table of POWERUP_TYPES
Table of ROBOT_TYPES
|
| 78 |
Number of
dropped robots (if drop type=2) or items (if drop type=7) |
| 79-82 |
??? |
| 83 |
Texture
override (Used to overide all textures on a robot.
This is how you get a robot to look like it's carrying a key) |
| 79-234 |
??? |
Thing-Type 3: Hostage (92 bytes)
| 0 |
Thing-type (3
for Hostage) |
| 1 |
Nothing (Usually a subtype but since H ostage has no subtype this should
be NULL) |
| 2 |
Control |
| 3 |
Movement |
| 4 |
Render |
| 5 |
Flags |
| 6-7 |
Cube |
| 8-19 |
Position |
| 20-55 |
Orientation (The orientation is stored in a 3x3 matrix of floating point
variables. N ot sure what they mean as of yet.) |
| 56-59 |
Hostage size |
| 60-63 |
Shield
(Probably ignored) |
| 64-75 |
Last position |
| 76-78 |
Nothing |
| 79-91 |
??? |
Thing-Type 4: Start / Thing-Type 14: Coop-Start (215 bytes)
| 0 |
Thing-type (4
for Start place or 14 for Coop start place) |
| 1 |
Start number (0
for Single-Player-Start) |
| 2 |
Control |
| 3 |
Movement |
| 4 |
Render |
| 5 |
Flags |
| 6-7 |
Cube |
| 8-19 |
Position |
| 20-55 |
Orientation (The orientation is stored in a 3x3 matrix of floating point
variables. N ot sure what they mean as of yet.) |
| 56-59 |
Size |
| 60-63 |
Shield |
| 64-75 |
Last position |
| 76-78 |
Nothing |
| 79-214 |
??? |
Thing-Type 5: Mine (223 bytes)
| 0 |
Thing-type (5
for Mine) |
| 1 |
Nothing (Usually a subtype but since Mine has no subtype this should be
NULL) |
| 2 |
Control |
| 3 |
Movement |
| 4 |
Render |
| 5 |
Flags |
| 6-7 |
Cube |
| 8-19 |
Position |
| 20-55 |
Orientation (The orientation is stored in a 3x3 matrix of floating point
variables. N ot sure what they mean as of yet.) |
| 56-59 |
Size |
| 60-63 |
Shield |
| 64-75 |
Last position |
| 76-78 |
Nothing |
| 79-222 |
??? |
Thing-Type 7: Item (92 bytes)
| 0 |
Thing-type (7
for Item) |
| 1 |
Item type
Table of POWERUP_TYPES
|
| 2 |
Control |
| 3 |
Movement |
| 4 |
Render |
| 5 |
Flags |
| 6-7 |
Cube |
| 8-19 |
Position |
| 20-55 |
Orientation (The orientation is stored in a 3x3 matrix of floating point
variables. N ot sure what they mean as of yet.) |
| 56-59 |
Size |
| 60-63 |
Shield |
| 64-75 |
Last position |
| 76-78 |
Nothing |
| 79-82 |
??? |
| 83 |
Texture (*2) |
| 84-91 |
??? |
(*2) Every item has a texture. But you neednt use the
right texture for that item. So it is possible to let a Mega Missile look like a
concussion and make it a surprise for the one who collects the
"pseudo"-concussion! Just use the texture number of the Concussion instead of
the Mega! I personally dont like those surprise games, so the Descent Manager will
soon have a repair option which resets those texture informations to the corresponding
ones. This texture number was also the reason for the Devil bug in version V2.1a and
V2.1b: Achim has set the wrong texture numbers to the flags which resulted in two funny
flags: one looked like a reactor shot and one like a fusion explosion... The Repair
Function of the Descent Manager will fix this one, too... The right texture numbers are
also stated in Appendix B - Items
Thing-Type 9: Reactor (151 bytes)
| 0 |
Thing-type (9
for Reactor) |
| 1 |
Reactor type
Table of REACTORS
|
| 2 |
Control |
| 3 |
Movement |
| 4 |
Render |
| 5 |
Flags |
| 6-7 |
Cube |
| 8-19 |
Position |
| 20-55 |
Orientation (The orientation is stored in a 3x3 matrix of floating point
variables. Not sure what they mean as of yet.) |
| 56-59 |
Size |
| 60-63 |
Shield |
| 64-75 |
Last position |
| 76-78 |
Nothing |
| 79-150 |
??? |
After the package of one thing comes the next, also with
the first byte containing the thing-type [THING_xx]...
A wall [WALL_xx] is more easy defined than things,
because it is not important which wall-type it is: each wall contains exact 24 bytes, so
the WALLS section [WALLS] is: number of WALLS*24 bytes big!
Here is the information of each wall:
| 0-9 |
Cube and Side
number |
| 10 |
Hitpoints (only if wall-type is blow door) |
| 11-15 |
Linked wall |
| 16 |
Wall type |
| 17 |
Flags
Bit 3: Door is locked (only if wall-type is normal
door)
Bit 4: Door closes again (only if wall-type is normal door)
Bit 7: Robots wont pass |
| 18 |
Wall state |
| 19 |
Switch
If the wall contains a switch, this byte contains the
number of the corresponding switch. If the wall has no switch, this byte is set to 255. |
| 20 |
Texture (only
Doors) |
| 21 |
Locked with
keycard
Bit 0: blue
Bit 1: red
Bit 2: yellow |
| 22 |
??? |
| 23 |
Flags
Bit 7: Door opens at end (after reactor/boss robot is
destroyed!) |
There are 6 known wall types in Descent 2:
| 1 |
Blow Door (Hostage and Guide-Bot doors) |
| 2 |
Normal Door |
| 3 |
Illusion Wall (e.g. the sparkles in the energy centers...) |
| 4 |
Only switch (a switch triggered by you flying through it, cannot be seen) |
| 5 |
Wall (to look through) |
| 6 |
Switch to shoot (the new Descent 2 control panel switches) |
A switch [SWITCH_xx] is also defined within a fixed
number of bytes. Every switch takes 52 bytes (Descent 1-RDL needed 54 bytes!). So
the SWITCHES section [SWITCHES] is exactly SWITCHES*52 bytes big!
Here is the information of each switch:
| 0 |
Switch type |
| 1-51 |
??? sides
affected? |
There are 14 known switch types in Descent 2:
| 0 |
Open door(s) |
| 1 |
Close door(s) |
| 2 |
Activate
Producer(s) |
| 3 |
Normal exit |
| 4 |
Secret exit |
| 5 |
Illusion off |
| 6 |
Illusion on |
| 7 |
Unlock door(s) |
| 8 |
Lock door(s) |
| 9 |
Open wall(s) |
| 10 |
Close wall(s) |
| 11 |
Wall(s) to
illusion |
| 12 |
Turn off
light(s) |
| 13 |
Turn on
light(s) |
No information on the other sections (LINKS and PRODUCERS) yet...