BDCFF: Peter Broadribb's binary format proposal

Proposal written by: Peter Broadribb
Last modified: about 11 Nov 1995
Supersedes: nothing
Superseded by: Leon Wennekers's binary format proposal (sorry, not online yet)

In this document:

  1. BNF-like specification
  2. English description

1.0 BNF-like description

Here's a sort-of-BNF kind-of specification of the file:
BDCFF ::= header cave* gameAttrib ; ie header followed by zero-or-more caves and then gameAttrib

header    ::= signature crc
signature ::= <a 6-byte fixed signature>
crc       ::= <a 4-byte CRC over the rest of the file>

cave       ::= recordSize width height caveData caveAttributes
recordSize ::= <a 4-byte length count of the width,height,caveData,caveAttributes>
width      ::= <a 2-byte integer>
height     ::= <a 2-byte integer>
caveData   ::= (objectType objectAttributes)* ; ie repeated (width*height) times

objectType       ::= <two-byte integer>
objectAttributes ::= <two-byte integer>

caveAttributes ::=
      (oneByteTag                    byte one-byte-padding)
    | (twoByteTag                    byte byte)
    | (fourByteTag                   byte byte byte byte)
    | (multiByteTagShort shortLength byte* [one-byte-padding]) ; ie padded to even number of bytes
    | (multiByteTagLong  longLength  byte* [one-byte-padding]) ; ie padded to even number of bytes
oneByteTag        ::= <two-byte integer in the range $0000-$03FF>
twoByteTag        ::= <two-byte integer in the range $0400-$07FF>
fourByteTag       ::= <two-byte integer in the range $0800-$0FFF>
multiByteTagShort ::= <two-byte integer in the range $1000-$1FFF>
multiByteTagLong  ::= <two-byte integer in the range $2000-$2FFF>
byte              ::= <one-byte integer>
one-byte-padding  ::= $00
shortLength       ::= <two-byte integer>
longLength        ::= <four-byte integer>

gameAttrib ::= caveAttributes ; ie same format but describes game attributes instead

2.0 English description

Now I'll describe what I mean in English. :)

A BDCFF file consists of:

  1. fixed length header
  2. zero or more caves
  3. game attributes

2.1 File header

The file header consists of:
  1. a 6-byte signature, used by downloading agents to identify the file type as a BDCFF file, and by other agents to ensure that the file is in fact a BDCFF file rather than something else
  2. a 32-bit CRC of the rest of the file (in specified format; sample code will be available to check and generate these CRCs)

2.2 Cave

An entire cave consists of:
  1. record length (4 bytes; see description below)
  2. cave width (2 bytes; excludes bounding wall)
  3. cave height (2 bytes; excludes bounding wall)
  4. cave data (layout of the cave; width*height*4 bytes). The cave is described left-to-right, top-to-bottom. Each cave position takes up four bytes:
    1. object type (2 bytes)
    2. object attributes (2 bytes)
  5. cave attributes (variable length). There may be zero or more attributes, and each attribute has the following format (described more fully below):

2.2.1 Record length

The cave starts with a 4-byte record length. This is the number of bytes taken up by the rest of the cave description (width, height, data, attributes), used to be able to determine where in the file the next cave begins, so you can quickly skip to the next cave.

2.2.2 Width and height

The cave width and height are 2-byte integers, indicating the size of the cave. I used 2-byte integers rather than 1-byte integers because potentially you might want a cave that is larger than 256 in one dimension. Shrug; why limit yourself? Anyway, the cave width and height exclude the bounding wall, meaning that you can assume that there is some boundary already in existance which will prevent objects from moving out of bounds. You can, of course, include your own boundary (eg of steel wall) in the cave data if you like, either for visual reasons (because you want the boundary to be of steel wall) or because you do actually use the boundary (eg put the exit box in the bounding steel wall).

2.2.3 Cave data

The size of the cave data can be found by multiplying the cave width by the cave height by 4 (because there are 4 bytes per cave position).

The cave is described by a simple "dump" of its contents; no fancy compression algorithms describing the cave in terms of lines, boxes etc. Each position in the cave is described by a 2-byte object type and 2 bytes of object attributes. Object types
The 2-byte object type permits 65536 different object types. Object types would be things like space, diamond, boulder, firefly, the player, steel wall, brick wall, magic wall, zonk, snik snak, bombs, explosion-to-space, explosion-to-diamond, etc. All these object types would be registered and described in the central BDCFF database on the Net, so you could look up the exact specification about what the object looks like, how the object behaves, and what the attributes field means for that object. Object attributes
The attributes field might be used as a number or as a bitfield. It would be used to describe the different states the object can be in. For example, a firefly can be facing in one of four directions; the magic wall can be inactive, active, or expired; a boulder can be falling or stationary, an explosion can be in one of several stages.

2.2.4 Cave attributes

The variable length cave attributes may describe either things that affect the cave as a whole (such as the amount of time available to complete the cave) or things that affect all objects of a specific type (eg slime permeability, magic wall milling time, amoeba growth factors). It would not include things that affect a set of games together, such as the sequence of caves which form a game; these are described in the Game Attributes. Attribute tags
Since some attributes may be present and others absent, and new attributes might be invented in the future, we need to have a variable structure. The way I propose is to have a tagged structure: tag, data, tag, data, tag, data, ...

For example, let's say we had the following tags defined in BDCFF:

In the file, the tags might appear in any order. For example, if the cave attributes consisted of: $0400 0015 0000 0700, this would be read as: Attribute length
The amount of space required to describe an attribute may vary. Some attributes might be able to be described in only one, two, or four bytes of data. Other attributes might take a variable amount of data (say, text describing the author's name, or a comment). It's even possible that an attribute might take more than 64K of data (perhaps if the attribute contained nested attributes inside?).

But because of the extensibility of the BDCFF specification, where new attribute tags might be defined from time to time, it's possible that some implementation of Boulder Dash might come across an attribute tag that it doesn't know about. Say, for example, that it doesn't know what slime is, and therefore the slime permeability attribute is unknown to it. The implementation needs a way of knowing how long the attribute is, so that it can skip on to the next one.

The way I propose to facilitate this is to group the tags into ranges:

That way, even if an implementation does not know that attribute tag $0000 means slime permeability, it knows that the tag is followed by one byte of data and one byte of padding, and so it can skip forward to examine the next attribute.

All registered attribute tags will be described in detail in the central BDCFF database, so you can update your BoulderDash program to be able to read and use new tags as they might be created.

2.3 Game attributes

Finally, following all the cave descriptions in the file, the file finishes with game attributes. These are in the same format as the cave attributes just described, but instead describe things that affect the entire set of caves as a whole, rather than just one cave. For example, maybe it might describe the sequence in which caves go to form a game, or something. I don't know, but I'm sure I'll find it useful to have a Game Attributes section sometime. :)
Webmaster for this page is Peter Broadribb