GM Executables Explained

There has been a lot of interest regarding how Game Maker creates and runs executables, and some possible alternatives, as evidenced by numerous topics regarding this issue posted in the GMC.  In addition to a few knowledgeable and informative posts, there has been a lot of speculation and noise.  A large part of the confusion is a basic misunderstanding of the processes that happen between the pressing of the “Publish game” button and the start of the created game.

In this piece, I will attempt to explain GM’s handling of executables in as much of a non-technical, understandable fashion as possible.  In addition, I will list the pros and cons of compiling your game before runtime, or translating it automatically into an entirely different language.

GM Executables

A Game Maker executable currently consists of two items – your data, or what is actually interpreted and executed, and the runner (written in Delphi), which carries out the actual execution. This is why an empty game still takes up around 2 MB of space – the runner executable is automatically included in every GM .exe.  Without this, your games could not run.

Your data consists of all your code and resources in an encrypted format.  However, this encryption is liable to be cracked, which is what decompilers exploit when extracting your data.  Because your data is wholly contained in GM’s executable, and because it needs to be in a format that can be interpreted by the runner, it can also be “interpreted” by humans, with the help of an outside program.  Smarty explains:

Because the game executable always contains the game data, and because the runner must know how to decrypt that data, essentially a game executable will always be a case of “here is the locked box, and I’ve hidden the key somewhere under it”. YYG could provide a new encryption, but it would only be a matter of time before someone breaks it again.

So why include the data in the first place?

The current method that GM employs in creating an executable version of your game is designed to ease the development process as much as possible.  If you’ve ever had a syntax or other error that halted game operation, you were graced with a nice error message detailing not only what the error was, but where.  In order for this process to occur, the application must have its source code available and accessible.  Without the source code, GM could only tell you that an error occurred somewhere in your code.  Debugging then becomes a much more intensive process.

When a user first publishes their game, their encrypted data and the runner are combined into one executable file.  In order for the game to run quicker, the data is “first parsed into bytecode,” as Smarty explains:

There’s a lot to say for what that means, but let’s make an easy analogy: when I want you to “jump 3 times on your left foot and 3 times on your right foot” I could just shout that to you, or we could have an appointed signal, e.g. waving, so that we don’t lose time by you listening and intepreting what I just said. The engine works in the same way – at runtime it converts the GML script (scripts are always a method to give complex computer processes a syntax meaningful to humans, but computers do not need them) into bytecode, which are series of so-called tokens (the signals) and their parameters. At runtime, it’s faster at executing bytecode than trying to read the GML syntax.

But this is not the same as compilation, Smarty stresses.  Compiling an application involves parsing source code into a machine-readable bytecode, so that it is accessible at a lower level, and thus, slightly faster.  However, your machine lacks the error reporting abilities of a custom-built runner.

After your source code is parsed and your game begins, the runner starts interpreting your game code.

“A runner is basically a bunch of if-else statements. If it sees a particular token [instructions given by your code], it does something,” explains Yourself.

Alternative #1 – Compiling your entire game

A suggestion commonly put forth is to compile the entire game itself, as opposed to letting the already-compiled runner interpret your code.  Your resources would be protected, and it does lead to an increase in speed, but “[you’ll] lose all the ease of use,” as Yourself explains.  As mentioned above, the type of error reporting used by Game Maker would not be possible.

In addition, Game Maker would have to become “a compiler itself.”  This is an enormous and costly undertaking, requiring the writing of instructions that would parse every GM function into machine code.  The benefit/cost ratio would be minimal.

Alternative #2 – Compiling the runner in a different language

As mentioned above, the runner itself is written in Delphi.  When YoYo Games announced that it was being rewritten in C++, wild speculation arose as to whether enormous speed increases would be seen, or even if GM games would now be compiled.  However, both those claims have been debunked, as there is little speed advantage between Delphi and C++, and creating compiled games would not be possible if the runner was simply rewritten in C++.

So why is the runner being rewritten?

“Just portability. Compiled languages don’t have any significant advantages over one another when it comes to speed,” explains Yourself.  In addition, the Glog post announcing the move details YYG’s reasoning:

We’ve really done this work as a start of our program to have Game Maker apps running on other platforms….NOT to see if we can find advantages on Windows.

Alternative #3 – Parsing your game into another language’s bytecode

Another alternative that has been discussed recently is to compile your code into another language’s bytecode, and run your game as an application written in that language.  Among the many benefits put forth would be portability.  A program that compiles to JVM bytecode could be run on any program that has the Java Virtual Machine installed.

However, this is an extremely non-trivial process.  As mentioned above, a specific compiler would need to be written that takes into account every single GM function, and parses it into another language’s bytecode.  This is possible (along with a one-to-one translation of your code into another language), but the cost of undertaking such a project is extremely high.

Conclusion

Despite the speculation surrounding different methods of compiling GM games, one must always remember that, as with anything, there are always trade-offs.  In order to gain more speed, a game developer could program in C++ (or, according to the age-old meme at the GMC, in assembly).  However, a great deal of ease-of-creation is forfeited.  With C++, the drawing area must be rendered manually, as opposed to simply changing an object’s coordinates and seeing it dutifully move across the screen.  The reason Game Maker exists in its current form is to allow for easy, quick game creation or prototyping.  Sacrificing this ease of use makes Game Maker essentially useless, as making Game Maker games work could be as difficult as coding in C++.  At that point, one would be better off simply coding in C++.

Simply put, sure, it’s possible to make Game Maker run faster by compiling it before runtime, or by coding games in a format that makes the more conducive to increasing run speed.  But sacrificing this ease-of-use would be pointless.  If speed is enough of an issue, it may be time to learn another language.  But if you want to create games in a matter of hours instead of days and weeks, Game Maker is the best option.

Advertisements

5 Responses

  1. ahh, this is quite interesting. thanks for explaining.

    -Caniac

  2. There are some ways that have been missed. Parsing the game code to another language and then compiling that or converting it to bytecode both work and would take a lot less effort for the same benefits that have been listed for compiling or converting directly. This is actually what ENIGMA does and what G-Java did.

  3. “There are some ways that have been missed. Parsing the game code to another language and then compiling that or converting it to bytecode both work and would take a lot less effort for the same benefits that have been listed for compiling or converting directly. This is actually what ENIGMA does and what G-Java did.”

    In the case of ENIGMA, they have a team of at least 15 contributors listed on its homepage. I never argued that these methods wouldn’t be possible – they wouldn’t be cost effective for YYG, and you would lose a lot of the ease of use that Game Maker offers. I’m sure it took a lot of time to write the parser – and this is essentially identical to alternative #3. Instead of parsing directly into the language’s bytecode, G-Java, for instance, parses GML to Java, and then Java to Java’s bytecode.

    Here’s an excerpt from ENIGMA’s Readme:

    “Run “LateralGM***.jar”. Add as many code based, room, and sprite and resources as you like. This build does not include DND, or many resources.
    It has rooms, objects, and codem but is still at phase ALPHA.

    To denote that a piece of code is already C++, use cpp { /* Code here */ }”

    If you notice, DND actions are not included, thereby scaring off half of GM’s userbase. You’ve already lost some of the ease of use.

    In addition, if ENIGMA does produce an entirely compiled executable, then you lose the error reporting capabilities of GM.

    I’m not saying ENIGMA doesn’t have any applications – if you’re a fairly advanced programmer, it looks like you could gain some of the advantages given by C++ while keeping some of the higher-level features of GML. However, to do this directly with Game Maker (i.e., make a compiler), would be time-consuming and would essentially defeat what makes GM so useful in the first place.

  4. yeah, G-Flash also compiles the code, it takes the source and translates it into flash then compiles, and it seems to run about the same, but it is in such early stages that it is hard to tell, cause there is no ‘load’

    -Caniac

  5. You know, that “error reporting ease of use” is really a mistake. If you want to report errors in a pretty way, use debugging.
    It’s pretty much just a matter of time before ENIGMA can do almost anything GM can, with the exception of the execute_* and accessing variables as strings.
    DND actions are not included yet… once they have the core working, I am pretty sure ENIGMA will have almost as many – or even more – actions as GM.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: