more /root/File Formats/GM File Format (v8).thread
2009-04-15 02:13:53IsmAvatar
Game Maker File Format Documentation
The name is fairly self explanatory. If you've ever seen a *.gmk, *.gm6, or *.gmd file, here's the [3rd party] documentation behind its format.

This will probably continually be a work in progress, although I'm practically done. I'm just marking it as a Finished Product now (as well as the other file format documentations), and any updates will be version updates.

Everything - including resources, path data, and the mystery bytes not covered before - should be documented.
If I missed anything or if you see a spelling mistake or a byte that you know what it does that I missed, tell me or I may never know. Of course, redownload before reporting it, as I may have already updated it without saying anything.


Changes for Version 8
* Documents GM8.0 (gmk) files (which are not obfuscated, but utilize zlib compression)
* Some information about prior versions is removed (please refer to version 7 for those documentations). This was necessary due to some significant changes in the format (such as applying zlib to entire resources)
* Now broken into sections
** Introduction
** Main Format
** Resource Format
** Tree Documentation

Changes for Version 7
* Now accounts for GM7.0 (gmk) files in addition to the other versions. The 7 in the version number was purely coincidental, really.
** Modifies Game Settings a little
** Adds Extensions (and a Tree entry)
** Adds Include Files
* Some small corrections in the Game Information and Tree
** Mostly just using the right version numbers
* See also the Changes for Version 6, below

Changes For Version 6
* Now accounts for GM5.3 (gmd) files AND GM6.0 and GM6.1 (gm6) files. Support for other versions coming soon.
* Due to the new file format support, I changed the filename.
* Changed the documentation style a bit.
** New terminology (nothing official, just for name's sake)
** Removed the Inclusions version. Thus "ni" will be left out from now on
** Default values documented for most data where applicable.
** Angle brackets < > used for version differentiation and such.
** Other small semantics.
* Documented the mystery bytes before the Resource Tree
** Library Creation Code and Room Execution Order
* Some things were outdated, and are now up to date (e.g. Sounds and Images are now documented as zlib compressed in the heading info)

Vertion 7:
Please notice, for version GM7 (*.gmk), an obfuscation has been applied overtop of the format. Fortunately, we understand the obfuscation as well, and it has been documented here:
GMKrypt Obfuscation Documentation
So you can either de-obfuscate it in 1 pass and read the format in a second pass, or make it de-obfuscate the file as its reading it - either way would work, though the latter is probably more efficient. GM8 removes the obfuscation.
Version 6:
In versions older than 6, "ni" stands for No Inclusions, whereas the other file accounts for Inclusions. See the note below about Inclusions.
Version 5:
Version 4:
Version 3:
Version 2:
Version 1:

No Inclusions
I used to keep 2 separate forms - an Inclusions and a No Inclusions form. I no longer do this, since I have found better ways of notating things, and absolute file position is utter nonsense. But the older versions may still use this, so here's what it is:
To the left of some of the stuff is a hex number. This is the position that the data will appear in an empty file. Inclusions are when certain extra data is accounted for that appears when you just save a new file - for example, the Icon Image Data is already there in a new file, and this will offset the location of the next piece of data. Although it is a "String" if you will, prefixed by a 32-bit integer. Therefor, NI was created to set that 32-bit integer to 0 and have no string, thus the next data to appear is immediate, rather than offset. In this respect, NI would be better for the programmer, and Standard would probably be better for someone who just wants to read through the file with a hex editor, perhaps to get acquanted with it.
2009-04-26 19:14:23Bob the BlueBerry
There's no link for "GMKrypt Obfuscation Documentation"
2009-04-26 22:13:42IsmAvatar
There is now.
2009-05-30 16:34:31Kyle_Solo
I'm trying to use your excellent documentation to look at a gmk, but I'm having some problems. I can't seem to deobfuscate it successfully.

I have java code taken from your encryption documentation, it builds and runs fine, and even produces a new, supposedly deobfuscated file. The problem is that the file isn't actually deobfuscated, it's just messed up (as far as I can tell). After the first few bytes (which aren't touched, I know) everything looks like gibberish.

Here's a link to the code I'm using (copied from your documentation):

I apologize in advance if this is due to my extreme inexperience.

Thanks! Kyle_Solo
2009-06-10 03:21:31IsmAvatar
It seems that you're using the left half of the table to decrypt, when you should be using the right half.
writeByte((table[1][readByte()] - tell()) & 255)

Since you are using Java, you may consider cracking open the LGM source code to see how we do it. The section of interest here is of course org/lateralgm/file/GmStreamDecoder.java
2010-06-29 02:36:50Rusky
In case anyone's reading this, here are two problems I've discovered with the gm8 format:
-Each trigger is zlib'd, from "Whether Trigger of this ID exists or not" through the constant name
-Global Game Settings' "<702 only> Length of Version (3) { Version ("100") }" line applies to 800 as well, so it should be <702+>.
2010-07-03 16:17:17medo
Will files saved in GM8 ever contain resources with old formats? For example, could a valid .gmk with version 800 realistically contain a sprite with version 542?

I'm working on a tool to split .gmk files into a directory tree of data and .xml files and put them together again, so knowing that this can never happen would somewhat simplify my code.
2010-07-03 23:38:19IsmAvatar
I can't say anything about GM8, but I have seen it happen with older versions, especially with some of the example games and very old games converted to the latest format. Obviously keeping old formats for legacy support makes compatibility and conversion easier.

As for your XML files, I've already been working on a project that does that as a plugin to LGM, meaning it already has said legacy support.
2010-07-04 00:57:08medo
Maybe I was a bit hasty then, but as far as I can tell LGM currently can't write GM8 files and will ignore several data fields that were added in the new format.

I had planned (and have started) to write new model classes that are suitable for version 7.0 and above and that can also be used as beans for the XML mapping. Also, I have started adapting the GmlFileReader to work with the new classes.

Do you think it's worthwile to continue with this? If LGM gets improved support for the newer formats in addition to your plugin, it would probably be redundand.
2010-07-04 02:49:26IsmAvatar
Depending on your definition of LGM. We have an SVN, which is where development occurs. What you see here on our website and forum is really just releases and betas, and doesn't cover unstable development. Please see our latest announcement for more info on that.

That said, we have a branch called "Versioning" which is intended entirely for GM7 and GM8 write support. There are some aspects of GM8 that it doesn't support yet (like Triggers), but they are on the way. If you know Java, it'd be more than awesome if you want to help with dev of LGM itself as we add better support of these versions, as well as trying to accomplish some old tasks that we never got around to. Right now, I'm the only one developing LGM, which makes progress very slow, so more hands would really help get LGM rolling again.
2010-07-20 15:23:28Rusky
Found another problem with the gm8 format- each include file is zlib'd from the modified date through the 'remove at game end' option.
2010-07-21 20:07:50IsmAvatar
-Each trigger is zlib'd, from "Whether Trigger of this ID exists or not" through the constant name

Confirmed and corrected. Also corrected in LGM.

-Global Game Settings' "<702 only> Length of Version (3) { Version ("100") }" line applies to 800 as well, so it should be <702+>.

Corrected. Did not effect LGM.

-Each include file is zlib'd from the modified date through the 'remove at game end' option.

Confirmed and corrected. Also corrected in LGM.

For those of you following LGM, this is corrected is r447 under the Versioning branch only.
2010-07-23 06:50:38TrieBr
IsmAvatar I've seen this documentation for a very long time and I have finally found a use for it. The documentation format is very easy to read and understand. I can't thank you enough for providing this! Awesome work!
2010-12-02 06:27:31antidote
IsmAvatar, I believe the 16 unknown bytes are the DirectPlay GUID, I've done a bit of research and GUID's are dun dun dun, 16 bytes long.
2011-04-12 09:44:37Quadduc
I believe the 16 unknown bytes are the DirectPlay GUID, I've done a bit of research and GUID's are dun dun dun, 16 bytes long.

I have tested and confirmed this. Using chat.gm6 from the GM6 multiplayer tutorial:
$ xxd chat.gm6 | head -n 2
0000000: 91d5 1200 5802 0000 6b6f 0000 914b ab9e  ....X...ko...K..
0000010: 87a3 d445 b9fb 2ec3 cbc5 c354 1e02 0000  ...E.......T....

The 16 "unknown" bytes, starting at 0xc, are: 914b ab9e 87a3 d445 b9fb 2ec3 cbc5 c354. Running the game and connecting to a host that's listening with netcat, I get:
0000000: 3400 b0fa 0200 167d 0000 0000 0000 0000  4......}........
0000010: 0000 0000 706c 6179 0200 0e00 914b ab9e  ....play.....K..
0000020: 87a3 d445 b9fb 2ec3 cbc5 c354 0000 0000  ...E.......T....
0000030: 0100 0000                                ....

The same "unknown" bytes can be seen here starting at 0x1c. According to the dplay headers, this is a lobby broadcast packet, which contains the dplay game GUID at this position.

Because a dplay game GUID of 0 has special meaning, it should probably not be set to 0 in the game file, but rather to 16 random/unique bytes. The format documentation should be updated to reflect this.
2011-04-15 22:57:16medo
After some testing it looks like the only thing that changed in the new 810 format is the main version number. Strange that they would change it without any extra reason, but attempting to read a game with all types of resources works fine if you make LGM accept the 810 version number.
2011-04-17 06:45:59IsmAvatar
If you look through the list of changes, you'll see that it's mostly UI changes and some small improvements to their runner. There is only one backend change - but it is a change nonetheless: Fonts now support different Extended Ascii Charsets. The resulting file format is essentially completely backwards compatible, because they squeezed this information in with an existing integer: That of the font range min, which previously only used 1 of its 4 bytes. Now, the first 2 bytes are the font range min (little endian), and the next 2 bytes are the charset identifier (Documentation for the different identifiers is forthcoming).

As for the DPlay GUID, thanks for that info. I've added it to the documentation, and updated LGM to account for this.
2011-04-20 21:55:09medo
The recent update to 8.1.69 changed the file format again, to include a flag on the Global Game Settings / Errors tab which controls whether script parameters are checked or not. See here: http://store.yoyogames.com/downloads/gm4win/release-notes.html

The flag is apparently included as bit 1 in the (previously) boolean value for the "Treat uninitialized variables as 0" flag.
2011-04-27 00:42:46IsmAvatar
Already handled in LGM. I've documented the changes here: