RMB File Fixed Length Data (FLD) (6776 bytes total) Record Counts (3 bytes) Block Positions (640 bytes) Section1 (832 bytes) Section2 (128 bytes) Block Data Sizes (128 bytes) Small Maps (520 bytes) Automap (4096 bytes)) Filenames (429 bytes) ...RMB Block Data... (Variable) Outside Header (17 bytes) 3D Object Data (66 byte records) Flat Object Data (17 byte records) Data Section3 (16 byte records) People Data (17 byte records) Door Data (19 byte records) Inside Header (17 bytes) 3D Object Data (66 byte records) Flat Object Data (17 byte records) Data Section3 (16 byte records) People Data (17 byte records) Door Data (19 byte records) Extra Byte (1 byte, optional) ...RMB 3D Objects... (66 byte records) ...RMB Flat Objects... (17 byte records)Note that in the RMB block data section there are two repeating sections. The first section contains data for the outside, or main, object, such as the exterior of a house or tavern. This section usually just has one 3D Object Data section which is the main 3D object for locations. The following section holds the data for the interior object, such as inside a house or tavern. Typically this section holds much more information than the previous one.
FLD Record Count (3 bytes) FLD SubBlock Positions (640 bytes) FLD Section1 (832 bytes) FLD Section2 (128 bytes) FLD Block Data Sizes (128 bytes) FLD Small Maps (520 bytes) FLD Automap (4096 bytes) FLD Filenames (429 bytes)In general, each of these subsections can be subdivided into 32 further subrecords as described in each section below.
[Bytes 0 - 3] long XPos1; [Bytes 4 - 7] long ZPos1; Unknown what these coordinates are for. Possibly the subblock size? [Bytes 8 -11] long XPos2; [Bytes 12-15] long ZPos2; Give the position of the subblock in map coordinates. [Bytes 16-19] long YPos2; Unknown.
[Bytes 0-127] long Sizes[32];
[Bytes 0- 7] char Header[8]; [Bytes 8-263] char TextureInfo[16][16]; See description which follows. Contains modified texture image indices to use. [Bytes 264-519] char ObjectInfo[16][16]; Currently unknown.The first 256 bytes after the header shows some interesting designs when viewed as a 16x16 image and probably indicates the textures to display on the land under the block. The format for the texture info bytes is a bit field described as follows:
[Bits 0-5] int TextureIndex; (6 bits) This value, ranging from 0-63, gives the new texture index to display. The texture file to use will depend on the current location (desert, temperate, etc...) and the time (raining, summer, winter, etc...). [Bit 6] int RotateTexture; (1 bit) Might be a flag indicating that the texture should be rotated 90 degrees so that the width becomes its height and vice-versa. This allows reuse of textures rather than duplicating them in the texture file. [Bit 7] int FlipTexture; (1 bit) Appears to be a flag indicating that the texture should be flipped in both the X and Y directions so that its last pixel becomes its first.The last 256 bytes looks more like a starry night and could indicate how to place scenery around the block, but its purpose is unknown currently. It may be a bit field like the first 256 byte section.
0x00 Background, transparent 0x03 Store? (orange) 0x10 Taverns (green) 0x12 Residence? (gray) 0x13 Residence (gray) 0x14 Residence? (gray) 0xE0 Special Item? (not displayed) 0xFA Object (not displayed) 0xFB Object (not displayed)It is not known what the three types of residences represent. The bitmap probably does not control where things appear but was most likely used as as development tool.
[Bytes 0- 12] char BlockFilename[13]; [Bytes 13-428] char Filenames[13][32];
Header (17 bytes) } Exterior data like that 3D Object Data (66 byte records) } for a house or tavern. Flat Object Data (17 byte records) } Usually contains just Data Section3 (16 byte records) } one 3D object People Data (17 byte records) } Door Data (19 byte records) } Header (17 bytes) } Interior data like 3D Object Data (66 byte records) } that for the inside Flat Object Data (17 byte records) } of a house or tavern. Data Section3 (16 byte records) } Contains much more People Data (17 byte records) } data than the previous Door Data (19 byte records) } section. Extra Byte (Optional 1 byte, 0x96)Some RMB files do not have any subrecords, they simply end after their FLD Filenames. In some subrecords there is an extra byte, 0x96, after the end of the record. It can be identified by the length of the subrecord1 as given in the fixed length data section for the RMB file.
[Byte 0] unsigned char Num3DObjectRecords; [Byte 1] unsigned char NumFlatObjectRecords; [Byte 2] unsigned char NumSection3Records; [Byte 3] unsigned char NumPeopleRecords; [Byte 4] unsigned char NumDoorRecords; The number of records in each of the data sections which follow. [Bytes 5- 6] short Unknown1; [Bytes 7- 8] short Unknown2; (always non-zero) [Bytes 9-10] short Unknown3; [Bytes 11-12] short Unknown4; (always non-zero) [Bytes 13-14] short Unknown5; (always non-zero) [Bytes 15-16] short Unknown6; (always non-zero) The data suggests 3 pairs of shorts but it could be something entirely different.
[Bytes 0- 1] short ObjectID1; Always non-zero in the range 1-511. [Byte 2] char ObjectID2; Ranges from 0 to 63. The required 3DObject to load from Arch3D.BSA can be calculated from: ObjectID1 * 100 + ObjectID2 This appears to give the directory ID for the appropiate object. It may be done this way if the objects are grouped by type in some fashion. [Byte 3] char Unknown1; Always non-zero, ranges from 3 to 67. [Bytes 4- 7] long Unknown2; Non-zero only in 1297 of 236250 records. Seems to repeat within the same file. Could be two or four seperate fields. [Bytes 8-13] long Unknown3; [Bytes 14-17] long Unknown4; Non-zero only in 272 of 236250 records. Seems to repeat within the same file. Could be two or four seperate fields. [Bytes 16-19] long NullValue1; [Bytes 20-23] long NullValue2; Always 0 (confirmed). [Bytes 24-27] long XPos1; ( -896256 to 761856 ) [Bytes 28-31] long YPos1; ( -59136 to 273152 ) [Bytes 32-35] long ZPos1; ( -815360 to 705536 ) Usually 0s, but some (370) records have what look like coordinates here with the given ranges. [Bytes 36-39] long XPos2; ( -1088 to 1096 ) [Bytes 40-43] long YPos2; ( -579 to 518 ) [Bytes 44-47] long ZPos2; ( -512 to 1536 ) Looks to be a coordinate of some form. Values range as indicated above and is usually non-zero. [Bytes 48-51] long NullValue3; Always 0 (confirmed). [Bytes 52-53] short Angle; Almost always non-zero. A value of 0x200 specifies that the object should be rotated 90 degrees about the Y-Axis (vertical). [Bytes 54-55] short Unknown5; Always zero. [Bytes 56-59] long NullValue6; Always 0 (confirmed). [Bytes 60-63] long Unknown8; Only non-zero 16 times in one file (CUSTAA45.RMB) where it is 0x200 (512). [Bytes 64-65] short NullValue5; Always 0 (confirmed).
[Bytes 0- 3] long XPos; [Bytes 4- 7] long YPos; [Bytes 8-11] long ZPos; Looks like coordinate of some form. [Bytes 12-12.6] int SubImageIndex; (7 bits) The subimage in the texture file to use for the flat. [Bytes 12.7-13.7] int TextureIndex; (9 bits) The texture file index to use. [Bytes 14-15] short Unknown1; Usually non-zero (50%) and ranges from 0 to 65535. Might indicate whether or not to display the flat. The 'debuging' icons usually have a value of 0x0000 or 0xFFFF here. [Byte 16] char Unknown2; Usually non-zero (90%) and ranges from 0 to 105.
[Bytes 0- 3] long XPos; [Bytes 4- 7] long YPos; [Bytes 8-11] long ZPos; Looks like coordinate of some form. [Byte 12] char Unknown1; Usually zero (99%) and ranges from 0 to 15. Repeats mostly in each file where it is present. [Byte 13] char Unknown2; Almost always non-zero and ranges from 0 to 45. [Bytes 14-15] short Unknown3; Usually zero and ranges from 0 to 1292. Lower 8 bits are always zero and upper 8 bits range from 0 to 7.
[Bytes 0- 3] long XPos; [Bytes 4- 7] long YPos; [Bytes 8-11] long ZPos; Looks like coordinate of some form. [Bytes 12-12.6] int SubImageIndex; (7 bits) The subimage in the texture file to use for the person. [Bytes 12.7-13.7] int TextureIndex; (9 bits) The texturefile to use for the person. [Bytes 14-15] short NPCType; Seems to indicate the type of PC such as weaponsmith, barkeep. etc... 0x0000 - Common person 0x01FE - Barkeep [Byte 16] char Unknown3; Always non-zero and ranges from 1 to 45.
[Bytes 0- 3] long XPos; [Bytes 4- 7] long YPos; [Bytes 8-11] long ZPos; Looks like coordinate of some form. [Bytes 12-13] short Unknown1; Usually non-zero in the range 0 to 1536. [Bytes 14-15] short Unknown2; Always non-zero in the range 90 to 98. [Bytes 16-17] short Unknown3; Almost always non-zero in the range 0 to 7173. [Byte 18] char NullValue1; Always 0 (confirmed).
RDB files are archived in Blocks.bsa. Each BSA filename begins with a letter and is followed by a 7-digit decimal integer. (For example, "N0000019.RDB") These files are referenced in the dungeon records of Maps.bsa.
Each RDB file describes one dungeon 'block' in detail. Each block of dungeon is fits on a 2D grid with other blocks. There are two connecting passages in each of the four cardinal directions, so there are eight paths leading out of each block.
[Header] [3D Models Section] [3D Model Records] [Additional Data] [Object Section] [Object Header Section] [Object Roots Section] [Object Data Section]
[Byte 0] char Unknown1; [Byte 1] char Unknown2; [Bytes 2-3] short Unknown3; [Bytes 4-7] long GridWidth; The width of the Object Root Section [Bytes 8-11] long GridHeight; The height of the Object Root Section [Bytes 12-15] unsigned long objectOffset; The offset from the beginning of the RDB file to the Object Root Section [Bytes 16-19] long Unknown4;
[Bytes 0-4] char modelID[5]; a string containing the five-digit decimal representation of the object's model ID as seen in Arch3D.bsa (not null-terminated) [Bytes 5-7] char objectType[3]; a short string possibly describing the type of object (not null-terminated)Next is another list of 750 records, but of only 4 bytes each. They seem to correspond to the 3D Model Records. The format of these bytes is unknown. Unused records are filled with 0x00.
[Object Header Section] [Object Roots Section] [Object Data Section]
[Bytes 0-3] long UnknownOffset; An offset from the beginning of the RDB file to a linked list of unknown purpose and format. [Bytes 4-7] long Unknown1; [Bytes 8-11] long Unknown2; [Bytes 12-15] long Unknown3; [Bytes 16-19] long FileSize; The length of the RDB file, in bytes. [Bytes 20-51] char Unknown4[32]; Seem to always be 0xFF [Bytes 52-55] char TagDAGR[4]; Seem to always be the character array "DAGR" [Bytes 56-511] char Unknown5[456]; Seem to be 0xFF
[Bytes 0-...] long Offsets[]The number of longs in the list is GridWidth*GridHeight. Each entry is an offset from the beginning of the file to an Object Record. Any negative value indicates that no object data is present. The meaning of the grid layout is unknown.
Each Object Record is a node of a doubly linked list. Use the Object Roots Section to find the head of the list, and iterate using the offsetNext and offsetPrev fields.
Object Record (25 bytes): [Bytes 0-3] long offsetNext; The offset from the beginning of the RDB file to the next Object Record. Any negative value indicates that there is no next item. [Bytes 4-7] long offsetPrev; The offset from the beginning of the RDB file to the previous Object Record. Any negative value indicates that there is no previous item. [Bytes 8-11] long xLoc; [Bytes 12-15] long yLoc; [Bytes 16-19] long zLoc; These three values define the object's location in space. [Byte 20] char objectType; This can take on only these three values: 0x01: The object is a 3D model. 0x02: The object is a light source. 0x03: The object is a flat (including markers and monsters). [Bytes 21-24] long postRecordOffset; The offset from the beginning of the RDB file to the object's type-specific data.Each object has a variable length post record, pointed to by postRecordOffset. The format of this record depends on the objectType.
Object Post Record, type 0x01 (3D Object) (23 bytes):
[Bytes 0-3] long xAngle;
[Bytes 4-7] long yAngle;
[Bytes 8-11] long zAngle;
the rotation angles about each axis
[Bytes 12-13] short ModelIndex;
Indexes one of the 750 entries in the 3D Models Section.
This model is used for the object.
[Bytes 14-17] long Unknown3; (ranges from 0 to 240)
[Byte 18] char Unknown4; (ranges from 0 to 108)
[Bytes 19-22] long ActionOffset;
Offset from the beginning of the RDB file to an Action
Record, which contains additional information about how this
object behaves. If this value is -2 then no such record exists
for this object.
Object Post Record, type 0x02 (Light Source) (10 bytes):
[Bytes 0-3] long Unknown1;
[Bytes 4-7] long Unknown2;
[Bytes 8-9] short Unknown3;
(Presumably, these values determine light intensity, range, etc.)
Object Post Record, type 0x03 (Flat Object) (11 bytes):
[Bytes 0-1] {
[bits 0-6] int SubImageIndex; (7 bits)
[bits 7-15] int TextureIndex; (9 bits)
}
The texture to use, formatted as in the "RMB Block Flat
Objects" section of an RMB file. The TextureIndex identifies
the texture file and the SubImageIndex identifies the image
within the texture file.
[Bytes 2-10] char Unknown1[9];
[Bytes 0-4] char DataEntry[5]; [Bytes 5-8] long TargetOffset; The offset from the beginning of the RDB file to the Object Record describing this action's target, negative if there is no target. [Byte 9] char Type; Probably affects how the DataEntry field is interpreted. Ranges from 0 to 100, but most entries use these values: 0x00: Probably used to indicate no action. 0x01: Object Translation 0x08: Object Rotation
The target object (and the target object of its action, etc.) is activated simultaneously with this object. In this way targets can be chained together for several simultaneous effects.
Both Rotation and Translation actions format the DataEntry field in this way:[Byte 0] char Axis; Takes on values ranging from 1 to 99, but most entries use these values: 0x01: negative x 0x02: positive x 0x03: negative y 0x04: positive y 0x05: negative z 0x06: positive z (Maybe a bit field?) [Bytes 1-2] unsigned short Duration; Determines how long the object takes to reach its destination. [Bytes 3-4] unsigned short Delta; The amount to move along/around the specified axis.Rotations rotate about the Axis while translations move along them.
Doors do not appear to use the Action Record. It is not known whether teleporting walls use it. Switches, levers, and moving platforms appear to use it.
For example, in Privateer's Hold there is a switch next to a platform with a throne on it. Flipping the switch invokes the switch's action, which rotates it into the flipped position. That action targets the platform, which makes it rise. The platform's action targets the throne, which also rises. All these are performed simultaneously.