How JavaScript beats GameMaker Language (GML)

15
Official Construct Post
Ashley's avatar
Ashley
  • 1 Sep, 2021
  • 2,593 words
  • ~10-17 mins
  • 13,204 visits
  • 5 favourites

Construct supports JavaScript coding in addition to its block-based approach. JavaScript is an industry-standard language used widely across browsers, servers and more, and is one of the most popular programming languages in the world. Some tools choose to go their own way and develop their own programming language used only in their tool. We think this has few upsides and major downsides. To illustrate this, here's a case study in how JavaScript compares to GameMaker Language, aka GML - the language used in GameMaker Studio 2.

Performance

First up, let's examine performance. For games, fast performance is an essential feature to ensure a smooth framerate. To compare the performance of the raw language, we built a simple number-crunching test that just counts how many prime numbers there are between 1 million and 2 million. The key function is IsPrime, and you can see how close the code is for each in the code sample below.

We ran this test in four ways:

  1. In JavaScript, in a Construct 3 project - download C3 project
  2. In GML, via the VM (an interpreter) - download GameMaker project
  3. In GML, via the YYC (a C++ compiler), which is only available with a subscription
  4. And despite not being a text-based language, also an equivalent in Construct's event blocks for comparison - download C3 project

In both GML cases we used the newer 64-bit runner/compiler, which performs better on this test. Modern browsers have all been 64-bit for some time already, so this also helps ensure a fair comparison. We tested with GameMaker Studio 2 v2.3.3 and C3 r260 in Chrome 92 on a Windows PC. All the files used in this test are linked above, so you can check them out and replicate results yourself. The results may surprise you! The time taken to calculate how many primes there are between 1 million and 2 million is summarised below (after a brief warmup period to ensure CPU caches and JITs are operating at peak performance).

JavaScript is far faster than GML on this test. The VM proves much slower - in fact, over 40x slower. Even if you pay for a GameMaker subscription and use YYC to compile to native code, it still comes out over 5x slower. Modern JavaScript JIT (just-in-time) compilers are incredibly sophisticated and have been fine-tuned by entire teams of dedicated engineers at the biggest tech companies for years. This also dispels the myth that just because something is compiled to C++ it's fast. JavaScript is not just 10% or 20% faster, but several times faster. Further, JavaScript JITs are also tuned for fast startup, so there's no need to sit around waiting for code to compile. It just starts running with an interpreter right away, compiles code in the background, and then switches over to it as soon as it's ready - all of which happens surprisingly quickly. And all this raw performance comes for free with the very browser you're reading this in!

Perhaps there are some obscure tricks or performance hacks that can improve the result somewhat for GML. However this still proves the point that JavaScript is super fast with straightforward, idiomatic code, and you don't need to resort to time-consuming experimentation and research to get an excellent result.

In fact, JavaScript is so fast that even our equivalent made in Construct's drag-and-drop event block system clocks in relatively close to the result for the YYC. In intensive benchmarks like this, the event system has quite a high performance overhead compared to text-based programming languages since it's essentially interpreted by JavaScript code; despite this, thanks to JavaScript's extreme performance it ends up surprisingly close to the C++ code compiled by YYC, and also far ahead of the VM interpreter. So Construct's event blocks are no slouch either.

Many games run intensive code for purposes like pathfinding, bullet hell games, and more, and high performance is key to maintaining a smooth framerate no matter what your player is battling through. This test result shows that if you want peak performance, choose JavaScript.

Ease of learning

One reason sometimes cited to develop a separate language is to customise it to be easy for beginners to learn. However the fundamentals of GML and JavaScript are very similar. They're both languages with a C-like syntax, a dynamic type system, and garbage collection to simplify memory management. Just take a look at the code samples for IsPrime above - the syntax is pretty close, and so it's likely both are about equally approachable for beginners.

Being such a widely-used language, JavaScript has several advantages for beginner learners though. There are free coding tutorials and learning resources for it all across the web, such as the MDN Learn JavaScript guide and The Modern JavaScript tutorial, some also with interactive samples where you can edit and run the code. Further there are schools, colleges, coding "bootcamps" and other educational institutions that include teaching JavaScript coding, providing more options to learn in the wider world.

Finally JavaScript is a highly transferrable skill, being widely used in industry both in browsers and on servers, and with plenty of jobs available around the world for a promising career. Learning a language only used by one tool throws extra hurdles in your way if you want to go further, having to learn the new aspects of an industry-standard language, and unlearn the quirks and bad habits that you may have picked up with the the previous language.

So overall JavaScript should be just as easy to learn, but offer a much better path onwards in future.

Language features

New JavaScript features go through a rigorous standardisation process, where proposals are thoroughly reviewed and consensus achieved before implementing and releasing them. In theory a single organisation could move quicker. However JavaScript still has many major features that are limited or entirely missing in GML. In this section we review some of them. The standardisation process also helps ensure features are designed well, with thorough reviews from technical experts across the industry.

While JavaScript has a great many language features, beginners can pretty much just ignore the more advanced parts, so this should not have any impact on how easy it is to learn the language basics. It's a great benefit to more experienced coders though, providing a wide range of tools to help you best express what you want to do, and ensuring you can go a long way without running in to limitations or missing features.

Modules

JavaScript Modules provide a useful way to write code in isolated modules, only importing and exporting what they need. It helps keep code clear with separated concerns, and helps make it easy to re-use code and third-party libraries across projects. The syntax is shown below.

// In utils.js:
export function add(a, b)
{
	return a + b;
}

// In main.js:
import * as Utils from "./utils.js";

console.log(Utils.add(2, 3)); // logs 5

There are many more ways to import and export functions, objects and variables in JavaScript, including with dynamic imports. GML does not appear to have any equivalent to this.

Promises & async functions

Some tasks, such as loading textures, or fetching resources over the network, are fundamentally asynchronous: they take some time to complete, so they happen in parallel to code continuing to run, and then they finish at some later time. JavaScript makes this convenient with Promises and async functions. A short example is included below.

async function LoadDataFromURL(url)
{
	const response = await fetch(url);
	const blob = await response.blob();
	return blob;
}

There's a wide range of related features here, such as using Promise.all to conveniently wait for multiple parallel tasks to all complete, and various error-handling mechanisms, but there's too much to easily cover here. Suffice to say, JavaScript has this well covered.

GML supports asynchronous events, but has no special syntax for it, requiring looking up in a special async_load variable to establish the result. JavaScript provides many more language features to make it easy and convenient to write asynchronous code.

Arrow functions

Arrow functions are a convenient shorthand for functions based around the => arrow syntax, which helps make code clear, especially in cases like event listeners. They also carry over the this scope from the containing scope, which is especially useful in class methods. Arrow functions can even be async as well. A simple example is shown below, with both versions working equivalently.

// Using normal function:
async function onStartup(runtime)
{
	// do startup stuff...
}

runOnStartup(onStartup);

// Using arrow function:
runOnStartup(async runtime =>
{
	// do startup stuff...
});

GML does not support arrow syntax for functions.

for..of & generators

This is another area of JavaScript with too much to easily cover here, but in summary the related features for..of and iterators and generator functions provide useful tools for iteration. In its simplest form, for..of is a simplified syntax for iterating collections like Array, Map and Set:

for (let i of myArray)
{
	console.log(i);
}

You can also use generator functions to easily define your own iterator:

function* oddNumbersUpTo(limit)
{
	let n = 1;
	while (n < limit)
	{
		yield n;
		n += 2;
	}
}

for (let i of oddNumbersUpTo(10))
{
	console.log(i);
}

As you might expect, this logs 1, 3, 5, 7, and 9. This and many other capabilities allow you to do far more sophisticated things than the usual for loop. You can even use for await..of with async generators! GML appears to have no equivalent to these features.

Class syntax

JavaScript has a full class syntax for declaring classes, including with inheritence, constructors, public and private methods, setters and getters, static methods and properties, public and private field declarations, super calls, and more. GML appears to support constructor functions and inheritence, but not a full class syntax like the JavaScript sample shown below.

class Rectangle {
	constructor(width, height)
	{
		this.width = width;
		this.height = height;
	}
	// Class method
	setSize(width, height)
	{
		this.width = width;
		this.height = height;
	}
	// Class getter
	get area()
	{
		return this.width * this.height;
	}
	// ... and many more syntax features ...
}

Destructuring

Another feature only to mention in brief that GML is missing, destructuring allows for unpacking values from arrays and objects. It's useful for things like returning multiple values from a function, as shown below.

function getTwoValues()
{
	return [10, 20];
}

const [firstValue, secondValue] = getTwoValues();
// now firstValue is 10 and secondValue is 20

Much more

JavaScript is a mature and sophisticated language with many syntax features, tools, standard library features, and more. Here's just a few more things there isn't space to go in to more detail on:

From all this, one thing is clear: JavaScript has far more language features than GML. It even seems unlikely GML will ever catch up - far more resources are being poured in to the development of JavaScript, as it's backed by the likes of Google, Apple and Microsoft, who all have their own teams working on it, and there are plenty more proposals in the pipeline. So if you want the best features in your programming language, choose JavaScript.

Cross-platform consistency

JavaScript engines are rigorously tested with an industry-standard test suite to ensure they all implement the specification exactly correctly across every platform. This kind of thorough testing process helps ensure the same code runs identically across a wide range of platforms, whether it's Windows, iOS or Raspberry Pi.

The GML manual indicates various places where the language does not work the same across platforms. These include:

  • Function argument evaluation order can change across platforms (ref)
  • The precedence of operators can change across platforms (ref)
  • Code as simple as obj_ball.speed = 0 works on different instances between HTML5 and other platforms (ref)
  • Changing gml_release_mode can improve performance but produce unexpected behavior like memory corruption bugs. JavaScript always works reliably and at maximum performance.

Quirks like these throw hurdles in your way when trying to port your game to another platform. JavaScript is thoroughly tested to ensure all cases like these are clearly defined in the specification and work consistently across engines. And Construct uses JavaScript on all platforms, ensuring its own engine is equally consistent. So if you want cross-platform consistency, choose JavaScript.

Independently developed

JavaScript engines like V8 are developed by the big tech company heavyweights like Google. With their dedicated teams on the job, there's no need for us to spend our limited resources designing, developing and optimising a separate language for Construct. This frees up our time to focus on making a better product, introducing cool new features like scene graph, mesh distortion, and some new 3D features. Browsers also auto-update bringing the latest performance improvements and language features, so JavaScript keeps getting better even within the same version of Construct!

Conclusion

JavaScript beats GML in multiple ways: it performs much better on our benchmark; it has far more language features and many more in development; and it is more consistent across platforms. It's probably just as easy to learn as GML, but has a major advantage in being an industry-standard language that better prepares you for a future career. And the fact it is independently developed allows us to focus on what we do best: making a great game creation tool. We picked GML for comparison as it illustrates the point well in another game creation tool, but these benefits are likely to apply relative to any tool that develops its own non-standard programming language. It's extremely difficult to get anywhere close to the vast development resources that industry-standard languages like JavaScript have had poured in to them for years, and so many of the same pitfalls are likely to come up.

So why does GML exist? There may be some minor benefits around novel language features or integration with the tool, but these hardly seem worth losing so much in language features and in the performance results we observed. The main reason is probably simply the fact GameMaker is old, having been originally released over 20 years ago in 1999. At the time there may have been a better case for going with a non-standard language since languages like JavaScript were still in their early days. But over the years JavaScript has overtaken GML by a considerable distance. Improving GML to compete with JavaScript may well be infeasible, and changing to a different language would be difficult and disruptive. It's the kind of legacy of an early decision that very old software tools can end up lumbered with.

You can avoid the pitfalls though! If you're just starting out and wondering which to choose, it's an easy choice: jump in with JavaScript. In Construct you can also mix and match event blocks and JavaScript code, providing an easy transition from blocks, to your first lines of code, to full JavaScript files. So get started with Construct today.

Update 12:41pm BST: the original post incorrectly identified which subscription tiers the YYC came with. The post has been edited to correct this. Apologies for any confusion.

Subscribe

Get emailed when there are new posts!

  • 67 Comments

  • Order by
Want to leave a comment? Login or Register an account!
  • It's impressive that C3 events being interpreted by JS are almost as fast as a C++ compiler benchmark. Hopefully you continue to find ways to improve performance.

  • This is all very interesting, but when it comes down to it GMS doesn't need third-party tools to get games running on consoles or PC.

    Meanwhile Construct needs NWjs or Electron for PC (both of which are not easy to setup for Steam, with tons of issues such as breaking Steam overlay, apps not closing properly, games not being able to get recorded unless you add certain args, OSX and Linux versions breaking and more), I believe Cordova for phones? (I haven't been keeping up with phone development but I heard it's just as annoying as PC), and for consoles you have to be lucky enough to find a publisher or anyone who has written their own interpreter to port your game.

    I love Construct because it's so easy to use and get started, and it's absolutely great for web games, but as soon as you need to publish your game you start to see its flaws. In my opinion GMS is way far ahead in this aspect.

      • [-] [+]
      • -1
      • Ashley's avatar
      • Ashley
      • Construct Team Founder
      • -1 points
      • *
      • (11 children)

      What's actually wrong with using third-party tools? No technology is perfect, everything has its quirks, but in general they work out great. And if there's no significant downsides, it's a great way to speed up development. With tools like Cordova, you're still getting much faster performance with JavaScript, so there are big wins too. And Construct provides services like the mobile app build service that help make it easier to publish to Android without needing to install and configure loads of developer SDKs.

      Edit: I'd add the whole reason JavaScript has so many benefits, is because we rely on third parties to provide the programming language. The point of the post is that if we made our own programming language it would likely have several major pitfalls. So there's big upsides to relying on third-party tools too.

      • The problem with third-party tools is that as soon as something doesn't work properly, we have to rely on other people to fix it, as it has been happening for the last few years with NWjs. Sometimes bug takes years to fix, or aren't fixed. Every serious developer that uses Construct faces this, you have to either Google or ask around something as simple as adding "--in-process-gpu" to your args just so your game can be captured by streamers.

        Performance is very important, but being able to publish your game also is - otherwise why are we even making games? Just look at how many GMS games have been published on consoles and PC to this date - even if GML is over 5 times slower.

        Load more comments (7 replies)
      • Sorry but there are issues with huge dependency on 3rd party tools

        1.) You have to always rely on them to solve their bugs. Only option available is just to wait for them to solve the bugs. Regarding 1st party tools, situation is in your hand. Just surf the code & solve that damm bug

        Example:- there was a bug in webview. It affected many apps & soon new version was offered by Google. But still you are at someone's else mercy

        2.) For mobile platform,it is dependent on Cordova. But issue is that rarely it is used & very few developers maintain it now. And that's too on charity. And javascript based solutions are available. See cocos creator

        Load more comments (2 replies)
  • Ashley Nice Article ! I think construct 3 needs more examples in javascript , a game like kiwi story in javascript will cover a lot of usage of scripting , because some people knows a litle bit of javascript ( like me ) but dont know how to implement the codes using construct 3 , Thanks

    • I agree completely with this! It's inspiring to read this blog post and I feel very competent with C3, but I do wish I could poke around with javascript directly in a C3 project, rather than need to learn javascript from the beginning and slowly try to understand how to migrate that knowledge over to C3's javascript blocks (I.E. I would be eager to first learn javascript fundamentals that are very common if you were trying to use scripting within C3, rather than learning absolutely everything about javascript).

  • While you are still not delivering native APKs, all of this is meaningless. WebView runs like a dog with 2 legs. Yes, blazing fast while developing….

      • [-] [+]
      • -1
      • Ashley's avatar
      • Ashley
      • Construct Team Founder
      • -1 points
      • *
      • (3 children)

      Do you have any actual benchmarks? The benchmark in the post shows JavaScript outperforming YYC, which uses native code, by over 5x.

      • I don't need a benchmark to see it running janky as hell. I raised an issue with the chromium team a while back on your advice, it was being blamed on GPU blacklists etc. etc. etc. End result is, it is unusable via WebView so I pulled it from the store. It runs fast on Chrome fine on the Android device, just not when packaged up in WebView inside an APK.

        Load more comments (2 replies)
  • This is a long message so, (thread)

    I love Construct and have used it since like 2014, never used Game Maker. But still, uh... surely there's a couple of things wrong with this picture?

    For one, I believe that few people who actually use C3 to develop games really write anything in JS. What we should actually be comparing is GM's subscription YYC performance to the event blocks everybody uses in C3 (which is also a paid subscription service, so it seems fair to compare the two). Your own graph clearly shows that GML outperforms C3 blocks (not by a lot, but it does).

    Now, I don't really care about that per se - C3 performs well enough for my purposes. But it does make me wonder why I'm supposed to care that JS is supposedly faster than GameMaker when that really has nothing to do with what I and most other C3 users are actually getting. What is the point of my knowing that pure JS, which I'm not using, is better than Game Maker? Who is this post for?

    • For two, to give GML a fair shake somebody really ought to point out that HTML5/JS games have a MAJOR disadvantage in that you can't export to consoles, and every time anybody points this out to you they just get a shrug and a "sorry, it's up to the console manufacturers to sort it out" or "there are third party porting services" (and naturally it's not your problem that they all charge a bazillion dollars to do anything, or otherwise simply won't reply to emails).

      Of course, Game Maker does allow you to build games suitable for use on the XBox, Playstation, and Switch (admittedly only from the most expensive subscription tier, but still, the option is there for a serious developer). I don't know how this can still be up for discussion whether or not it's a downside for a game creation system to be incompatible with almost all of the most popular game playing outlets.

      • I'm not particularly trying to advocate for Game Maker or anything (I've never used it and don't care if it's better or worse than C3). I'm just saying that this sort of borderline trash-talk post ("Here's Why We're Awesome, And The Competition Sucks") seems a little tacky and shortsighted. Pointing out the flaws in somebody else's game making software while conveniently overlooking the shortcomings of your own... is that really a good look for you?

        • [-] [+]
        • -4
        • Ashley's avatar
        • Ashley
        • Construct Team Founder
        • -4 points
        • (3 children)

        Lots of people - and increasing numbers - do use JavaScript coding in Construct. And while there isn't built-in console support in Construct, lots of people publish to other platforms like Android, iOS, web, desktop apps and so on. There's a much more diverse usage out there than you seem to suggest, and we'd like more people to know about the strengths of Construct!

        Load more comments (3 replies)
  • As it goes with these things, there is always some sort of a catch:

    • Although GML is not very best nor very fastest (VM is just a bytecode interpreter, YYC is AST compiled to variable-typed C++), it does win in size by more than an order of magnitude - a brand new GameMaker game is mere 2.5MB when zipped, while NWJS is 100MB and Electron is only slightly less than that.
    • As andreyin pointed out, C3's reliance on third parties ultimately costs developers a lot when coming to consoles - many stop using C3 for future work.
    • It is not entirely fair to speak of inconsistencies of GML without mentioning the JS type system ('5'+5 vs '5'-5 vs '5'- -5 etc.)
    • Ultimately, to say "you could be using these advanced JS features in a C3 game!" is not unlike "you could be doing unthinkable things by compiling GML from haxe!" - you could, but majority of people won't, as they'd probably just use the language then - without your engine.
      • [-] [+]
      • 0
      • Ashley's avatar
      • Ashley
      • Construct Team Founder
      • 0 points
      • (3 children)

      I'd point out the new Windows WebView2 exporter is just ~650kb for a zipped empty project - even smaller than GameMaker. Also the cross-platform inconsistencies were about whether things work the same across platforms - JS may have its quirks, but at least they're exactly the same on all platforms so they don't become porting hurdles.

      • I wouldn't see WebView2 as too much of a victory at this time - although the bootstrapper is tiny, the user will still have to download those 100MBs on first interaction, and use of evergreen version means that your application may eventually break into pieces once the web standards move on or bugs are introduced to Chromium. As result, I've not seen non-fixed version used in any complex (read: WebGL, WebAudio, Shadow DOM, etc.) applications.

        In what can be seen as comical lack of improvement over the last time GM performance was compared here (was that in 2011?), the post ceases to mention Construct's objective advantages over GM - use for rapid prototyping and the Remote Preview with live reloading (which is something that as of yet takes a $30 asset to somewhat replicate in GM).

        Load more comments (1 replies)
      • Honestly just sounds like you are extremely biased against GameMaker. Others point out its strengths and weaknesses vs C3 and you simply harp back with well C3 does this or that better. Just acknowledge while both products are great each is much superior and better to use in one aspect or the other over each other.

  • I love Construct - been using it a long time. I get what the blog post accomplishes and I appreciate being able to see this. I do agree with the skills learned with Javascript can help develop a career as a web developer. However, one look at the GameMaker showcase page vs Construct's showcase page is enough to tell you that this argument (about speed) is pretty moot in the real world. Yes speed is important but amazing games have been developed by GameMaker that is very intense, physics, projectile and effects heavy and they run very well everywhere, including consoles. I would also argue that if you know GML very well you will easily find work helping others develop games. Of course not in the same league as JS but quite a bit. As others have said - JS is not what many Construct users are using Construct for - it's fantastic to have the ability to use JS but the speed and coding brought up versus GameMaker and GML is as I said moot. Gamemaker definitely has a lot less to prove.

  • I think it might make more sense to compare Gamemakers HTML5 export to constructs blocks and JavaScript performance. I do wonder where it would fall on that chart considering it’s not 100 percent perfect and does have issues that I’ve to be taken into account when exporting using gamemakers web export.

    • of course Construct is better on HTML5, GameMaker still has some major problems on HTML5, touch input still doesn't work well on mobile devices on HTML5 export!

      In my opinion all engines have pros and cons, unity is powerful multiplatform engine, it can handles more than 100k instances easily using ecs, but when it comes to HTML5 it's terrible!

  • Is there any plans to narrow the gap between the speed of event blocks and JavaScript?

    The reason gml exists is likely the same reason event blocks exists. It’s a simple way to code a game without all the complexity of programming languages like c/c++/c#/java/javascript/etc. there are pros and cons to using an existing language or a custom one.

    No language isn’t without its quirks. JavaScript has many. Even the event blocks have some quirks with picking. Although I will say events are what keeps me using construct. The editor is nice too but really, there are many many other options if I want to code in JavaScript.

      • [-] [+]
      • 1
      • Ashley's avatar
      • Ashley
      • Construct Team Founder
      • 1 points
      • *
      • (0 children)

      We've done a ton of work to optimise event blocks already - I've written some past blogs covering work done on that (e.g. compiling expressions to JS). We've done so much that it's probably quite difficult to make any significant further improvements.

      The blog post covers several major disadvantages of using a custom programming language. The benefits of JavaScript are so big I think it's clear it outweighs any benefits there may be of a custom language.

  • Many of us who use Construct do it because we don't know how to program in traditional way.

    Now, how would Javascript blocks compare with if you ran exact same thing but constructed through events. This is probably the way most would use Construct for.

    • One thing to consider -

      If you worked for years on a project and found a bottleneck with your event blocks, you have a possible option to try and implement javascript with any of the more cpu-heavy parts of your event blocks. Sure, most will think "uhh but I don't know javascript" BUT, you are not stuck at a dead-end, you could ask community members or post on the forums explaining what you're trying to do, and some javascript god might end up offering suggestions or a path to go down in order to achieve what you want.

      It may be that not a lot of people will not utilise this, but if someone finds themselves needing to eek out some more performance somewhere for their huge complex multi-system RPG project, then it's amazing we have the option to go to the core and try to gain even more performance.

      • [-] [+]
      • 1
      • Ashley's avatar
      • Ashley
      • Construct Team Founder
      • 1 points
      • (0 children)

      The blog post includes both a JavaScript and event block based version of the performance benchmark. You can try them both out yourself.

  • Load more comments (26 replies)