Menu

Format_info

Hugh Greene

This has been copied from a text document with only minor modifications
to wikify it. It may still need some more wikification.

Hex

Most GM files are in a binary format, meaning that you cannot use a text
editor to view/modify them by hand, and attempts to do so will most
likely corrupt your file.

You are encouraged to instead use a hex editor to examine GM files
and/or make modifications. For Windows, I would strongly recommend
XVI32
and for Linux I would recommend Okteta, although GHex tends to be
sufficient for most purposes.

Legality

I have thoroughly reviewed the License Agreement of Game Maker, and have
a general knowledge of copyrights and such. These activities are legal,
as long as I do not tamper with the compiler and as long as I maintain
credit to Mark Overmars for the original Game Maker, which I will make
sure to revere and worship greatly in this product. A note from Mark
Overmars himself regarding this
activity:

Sorry for not replying earlier. I was first was on holidays and then trying to catch up. I don;t think this is an important issue. Actually .gm6 files are not really protected. And even though I prefer people not to hack them, I cannot see a reason to be worried about this.

Mark

sic

Version

From time to time, you'll see some bytes documented as "GM Version
needed for the following info". For resources, first GM version tells
when the resource type was added, while the second GM version tells when
the last update of the resource type was.

  • 800 for GM8.0 (notice, GM8's GMKs are zlib compressed. Please see
    Note About GM8 below)
  • 702 for GM7.0 (notice, GM7's GMKs are obfuscated. Please see the
    GMKrypt Documentation)
  • 701 for GM7.0 as well.
  • 620 for GM7.0 in some places. This may be because Mark was planning
    on calling it 6.2
  • 600 for GM6.1 and GM6.0 (cross-compatible)
  • 530 for GM5.3 and GM5.3a (bug-fix version. cross-compatible)
  • 520 for 510 for GM5.1
  • 500 for GM5.2 and GM5.0 (forward compatible)
  • 430 for GM4.3

and so on. Other numbers may pop up as well, as in-between versions. For
example, 542 means that 530 cannot read it, but 600 can. Software
usually does this for format changes during development. Also see Angle
Brackets below.

Longint / Numbers

GM uses primarily 32-bit (4-byte) little-endian signed integers, which I
choose to call "longints", for most of its data. Even basic things like
True/False and Radio Buttons etc. each tend to be stored in their own
4-byte/32-bit set, rather than merging 8 of them to make a single byte
or merging 32 of them to make that same 4-byte.

I will display any dates as Gregorian ISO standard (yyyy-mm-dd).

Dates are stored in 64-bit (8-byte) signed doubles representing the
number of days that have passed since 1899-12-30. Fractional parts are
used to represent fractions of days (hours, minutes, seconds, etc).

Colors are stored in a 32-bit integer, usually only using the first 3
bytes as R G B respectively, with the 4th byte as 0. Sometimes they'll
make use of the 4th byte, so handle carefully. We're not yet fully
certain what the 4th byte represents, but it may be Alpha.

Unless otherwise denoted by a preceding (<byte size="">bytes) note,
all data is stored in 32-bit integers or 32-bit preceded 8-bit character
sequences (as denoted by insertions, explained below).</byte>

Insertion and Curly Brackets { }

Insertion will take 2 normal forms, and a third special form (see Angle
Brackets). Both normal forms will almost always have a longint before
the insertion to indicate how much information is contained in the
insertion. If this number is 0, no additional data will be inserted. The
data is then surrounded by curly brackets { }.

Data Insertion

The first kind of insertion is Data Insertion. This is when the data is
a series of length-prefixed bytes. My documentation will show these by
having all the information (the length longint, the curly brackets, and
the data) on one line. The most common example of Data Insertion is
String Insertion

Example of data insertion

Length of Name { Name }

which would turn out as something like 07 Sprites ...

or just 00 ...

Structured Insertion

The second kind of insertion is Structured Insertion (although you
needn't remember the name). For this, the documentation format will
start with a longint which will indicate how many times the structural
contents actually appear, and then the first curly bracket { on a new
line, followed by the data on its own lines separate from the curly
brackets, and then concluded with an end curly bracket on a new line.
See the examples below.

Two common forms will arise. One is the true/false Structured Insertion.
This determines simply whether or not the insertion will appear.

Example of a true/false

Object exists
{
Object ID
}

The other is the Repitition Structured Insertion. This means that the
first longint will indicate *how many times* the data within will be
inserted. The data itself is not actually repeated - only the structure
format is.

Example of repetition

Number of Objects
{
View ID
Followed Object
}

In this case, supposing there's 8 views, each with increments of ID, and
each following no object (-1).

The result would be: 08 00 -1 01 -1 02 -1 03 -1 04 -1 05 -1 06 -1 07 -1 (replacing each of those numbers with the longint equivelent)

Conditional Insertions and Angle Brackets \< >

Conditional Insertions are when a certain condition (e.g. the value of a
prior longint) must be met in order for the data to be inserted. This is
set apart from normal insertions because that longint may not be
adjacent, or because the longint value may not be an obvious indicator
of the repetitions (e.g. 0 may indicate that data is indeed inserted,
while 1 may indicate that it is not). Angle Brackets are placed around
this conditional expression.

A very common example of Conditional Insertions is the Version Number,
as this weighs heavily on what data appears in which version. Each
section has its own version number - there's one for Game Information,
one for each resource, and a separate one for the format of each
resource. Thus you should keep an eye on which version number is being
used for that section - and also keep an eye on the scope of that
version
number.

Example of Version Numbers

GM version needed for the following info (440/600/800)
<440 only> Kind (-1*=None, 0="Wave", 1="Midi", 2="Mp3", 10="Unknown")
<600+> Kind (0=Normal, 1=Background, 2=3D, 3=Multimedia)
<440-600> Preload (1)

Here we see something specific to 440, followed by something which only
appears in 600 and up (and does not appear in 440), followed by
something specific to versions 440 to 600 (and does not appear in 800)

When different versions get grouped together, I try to group the older
versions first and the newer versions later.

Of course, Conditional Insertions aren't solely dependant on a version
number. Here's an example of Special Case insertion (one which does not
denote how often the data is repeated)

10 or -1
<if not -1> Size of Image data { Image Data }

This frequently occurs in Sounds and Images. At this time we do not
understand why this odd conditional is there - why use 10 instead of 1,
and -1 instead of 0?

Default Values in Parenthesis ()

I've also included default values and value ranges to my format
documentations, for your convenience. When the default value is not
obvious by the format, I will put an asterisk (*) next to it.

Here are a few examples of the formats used;

(

<default></default>

) e.g. (0)

(<lower>-<upper>,</upper></lower>

<default></default>

) e.g. (0-100,10)

(<lower>to<upper>,</upper></lower>

<default></default>

) e.g. (-1 to
100,-1)

([Range,]<val1>=Name1,<val2>=Name2[,<val3>=Name3[,...]]) e.g. (0-2,0*=Yes,1=No,2=Cancel)</val3></val2></val1>

Category:Formats


Related

Wiki: Category:Formats
Wiki: GED_format
Wiki: GEX_format
Wiki: GMKrypt
Wiki: GM_format
Wiki: LGL_format
Wiki: LIB_format

MongoDB Logo MongoDB