Level File Format 1.0
This format is the binary format used by the Level Editor for the OMGDC.
The Level File Format is based upon the LCLib Binary IO Specification, and uses exclusively the Big-Endian Byte Order Mode. The LCLib Binary IO Specification can be found here.
Regular Expressions
Various strings in the file MUST match a certain regex. The string MUST match the entire regex exactly once. Otherwise it does not satisfy the requirement.
Rejecting files
At given points Implementations MUST, SHOULD, or MAY Reject a file.
Files which are Rejected MUST NOT be loaded and SHOULD be discarded by the Implementation.
If an a MUST/MUST NOT requirement is broken by a file, then the Implementation MUST Reject that file.
If a SHOULD/SHOULD NOT requirement is broken by a file, then the Implementation SHOULD reject that file.
Implementations MUST NOT generate files which it would reject.
It MUST be possible for at least one Level File to be created for any given Implemenation, such that the Implementation would not reject that file.
Structure of a Level File
A Level file consists of 4 parts and a hash. The 4 parts are its head
, layer_info
, sprite_list
, and trigger_list
.
A Level file can be described by the following structure:
struct level{
level_head head;
layer_info layers;
sprite_list sprites;
trigger_list triggers;
byte sha256[32];
};
sha256
is the SHA-256 hash of the rest of the file. If the hash does not match, then the file MUST be rejected.
Level Header
The level header describes basic information about the format, as well as some limited information about the level itself.
The level header is described by the following structure:
struct level_head{
byte magic[4];
version ver;
string levelid;
string unused_levelName;
byte unused_flags;
ushort levelLength;
ushort levelHeight;
};
magic
must be exactly the 4 bytes [EE AB DC 0B].
ver
indicates the version which is supported. The Current version of the specification is 1.0 (indicated by the bytes [00 00]). Implementations MAY support any number of released versions of the specification, and MUST support all versions previous to each of those versions in the same Major Version. Implementations MUST reject files that indicates an unsupported version or a version which has not been released.
levelid
is the identifier of the level. It MUST match the regular expression [A-Za-z_][\w_]*
.
unused_levelName
is to be the name of the level in a future version. This field is unused and reserved. It MUST be an empty string.
unused_flags
is to be a set of flags which apply to the level in a future version. This field is unused and reserved. It MUST be set to [00].
levelLength
is the length of the level in tiles. levelHeight
is the height of the level in tiles.
Layer Information
A Level is made up of multiple Background layers which consist of an image and other information about that layer.
The Layer Information of a level can be described by the following structure:
struct layer_info{
byte numLayers;
layer layers[numLayers];
};
Implementations MAY impose any limit on the number of Layers, but it must be able to support at least 1 layer.
Levels MUST have at least 1 layer.
Where each layer can be described by the following structure:
struct layer{
byte unused_layerFlags;
string layerImagePath;
float layerScrollSpeed;
};
unused_layerFlags
is to be a list of flags which apply to the level in a future version. It MUST be the byte [00].
layerImagePath
is the path to which the level image can be found. It MUST match the regex [^/ ]*(/[^/ ]*)*/?
.
layerScrollSpeed
is the speed which the level scrolls.
Sprites
Levels can have 0 or more sprites which have special properties.
The Sprite List can be described by the following structure:
struct sprite_list{
ushort numSprites;
sprite sprites[numSprites];
};
Where each sprite can be described by the following structure:
struct sprite{
string id;
ushort initialX;
ushort initialY;
byte spriteFlags;
ushort dataSize;
byte data[dataSize];
};
id
is the id of the sprite. It MUST match the regex [A-Za-z_-][\w_-]*:[A-Za-z_-][\w_-]*(\/[A-Za-z_-][\w_-]*)*
.
The sprite named by id SHOULD exist.
initialX
is the initial x position of the sprite. It SHOULD be less than the length of a level.
initialY
is the initial y position of the sprite. It SHOULD be less than the height of the level.
spriteFlags
contains information about the initial state of the sprite.
The following flags are well defined in the current version of the specification.
All other flags MUST be clear.
Flag | Name | Description |
---|---|---|
0x01 | DrawDisable | If set, the sprite is not drawn by default |
0x02 | CollisionDisable | If set, the sprite has no collision by default |
0x04 | AIDisable | If set, the sprite's AI and update clock are disabled by default |
0x08 | InteractDisable | If set, interaction triggers with this sprite are disabled |
0x10 | Persist | AI and Interaction applies as long as the level is active |
0x40 | Remove | If set, the sprite is removed (but can be re-inserted) when loaded. Implies CollisionDisable, DrawDisable, AIDisable, and InteractDisable |
0x80 | Destroy | This flag MUST NOT be set in a level file. |
data
indicates any data which is specific to the named sprite type. Each named sprite type may enforce its own structure for the bytes in this array.
This structure SHOULD be based upon the LCLib Binary DataIO Format in Big-Endian Byte Order mode, but does not necessarily have to be.
Triggers
In addition to sprites, various triggers may appear in a level. These triggers are different to sprites in that they do not have a position in the level. Instead they may be called upon by other sprites to
struct trigger_list{
ushort numTriggers;
trigger triggers[numTriggers];
};
Each trigger can be described by the following structure:
struct trigger{
string id;
ushort dataLen;
byte data[dataLen];
};
id
MUST match the regex [A-Za-z_-][\w_-]*:[A-Za-z_-][\w_-]*(\/[A-Za-z_-][\w_-]*)*
.
The trigger named by id
SHOULD exist.
data
is the data associated with the trigger. The structure of the data in this array is defined by the trigger named by id
.