Skip to content
Vadym Diachenko edited this page Jun 18, 2023 · 13 revisions

Welcome to the GMEdit wiki!

Check out the sidebar on the right side for a categorized view.

Here's a small breakdown of additional language features that GMEdit offers on top of GML:

Feature name
What you can do Instead of what
#args (named argument shorthand; mostly superseded in GMS2.3+)
#args a, b
// optional arguments:
#args a, b = 4, ?c
 
 
var a = argument0, b = argument1;
// optional arguments:
var a = argument[0];
var b = argument_count > 1
    ? argument[1] : 4;
var c = argument_count > 2
    ? argument[2] : undefined;
Null-conditional operators (??, ?., ?[; mostly superseded in GM2022+)
var h = instance_nearest(x, y, obj_enemy)
    ?.cur_health ?? 0;
// (split into two lines to fit GitHub)
var e = instance_nearest(x, y, obj_enemy);
var h = e != noone ? e.cur_health : 0;
 
Null-conditional assignment (??=; superseded in GM2022+)
a ??= b;
if (a == undefined) a = b;
Template strings (with expression insertion; superseded in GM2023+)
draw_text(5, 5, `health: $hp/$maxhp`);
 
draw_text(5, 5, my_script(
    "health: %/%", hp, maxhp));
#import (aliases / packages)
#import variable_instance_get as v_get
var v=v_get(id,"x");
// multiple items:
#import scr_some_package.* as Pkg
Pkg.one(1);
return Pkg.two(2);
// [transformed to in saved file]
var v=variable_instance_get(id,"x");
// multiple items:

scr_some_package_one(1);
return scr_some_package_two(2);
Typed local variables (method shorthand)
var v:Grid = new Grid(4, 4);
v.set(0, 0, "hi");
var r = v.get(0, 0);

enum Some { one, two, sizeof }
var v:Some = Some();
v.one = 1;
r = v.two;
var v = ds_grid_create(4, 4);
ds_grid_set(v, 0, 0, "hi");
var r = ds_grid_get(v, 0, 0);

enum Some { one, two, sizeof }
var v = array_create(Some.sizeof);
v[@Some.one] = 1;
r = v[Some.two];
inline functions (superseded in GMS2.3+)
on_click = #lambda { trace("hi!"); }
on_destroy = #lambda { trace("bye!"); }
 
 
 
 
on_click = scr_obj_test_on_click;
on_destroy = scr_obj_test_on_destroy;
// ... in scr_obj_test_on_click:
trace("hi!");
// ... in scr_obj_test_on_destroy:
trace("bye!");
arrow functions (for GMS2.3+)
array_sort(arr, (a, b) => a - b);
 
 
array_sort(arr, function(a, b) {
    return a - b;
});
#mfunc (macros with arguments)
#mfunc swap(a, b) { var _z=a;a=b;b=_z;}
var a = "1", b = "2";
show_debug_message(a + " " + b); // 1 2
swap(a, b);
show_debug_message(a + " " + b); // 2 1
Scripts or manual insertion,
depending on the macro.
coroutines (scripts that can be suspended/resumed)
/// array_foreach(array)
#gmcr
var arr = argument0;
var len = array_length_1d(arr);
for (var i = 0; i < len; i++) {
    yield arr[i];
}

// used like:
var iter = array_foreach(0, myarray);
while (array_foreach(iter)) {
    show_debug_message(iter[0]);
}
For practical reasons,
you wouldn't do this to yourself

FAQ

What do GameMaker versions mean?

GameMaker has changed its naming convention a few times through the years, which can make it hard to make sense of if you didn't keep watch. Here are some notable GameMaker versions and what they mean in context of external editors:

  • 1999-2011: GameMaker 1.0 .. 8.1
    The older versions could only target Windows and used a simple sequential numbering scheme.
    Projects were stored as a single compressed file, for better (load/save time on small projects) or worse (save time on big projects, hard to run diffs on)
  • 2011: GameMaker: HTML5
    Quickly superseded by GameMaker: Studio, this version introduced ability to export games for web browsers.
  • 2012: GameMaker: Studio
    GM:S introduced most of the target platforms that we see to this day (desktop, mobile, console) and slightly updated the IDE.
    Project format was updated to a directory-based one with XML metadata files and resources stored as separate text/media files.
  • 2016: GameMaker Studio 2
    Initial GMS2 release featured a brand new IDE and some programming language+API updates.
    Project format was updated to a directory-based one with JSON metadata files and resources stored as separate text/media files.
  • 2020: GameMaker Studio 2.3
    GMS2.3 significantly updated the syntax (introducing anonymous objects, function literals, constructors, exception handling, and more).
    Project format was updated to a slightly off-spec JSON with trailing commas and cleaner formatting for version control.
  • 2022: GameMaker 2022+
    In 2022, GameMaker switched to a year.month.minor.build version format.
    Minor project format changes and new syntactic features are regularly introduced.
What's "superseded"?

There is a particular pattern where GMEdit features and syntax extensions eventually make it into GameMaker itself.

Most of it is likely due to using similar sources of inspiration (many of GMEdit linter features and syntax extension mimic ECMAScript or Haxe, GML typically borrows from ECMAScript or C#), some seems a little more inspired by GMEdit (like # color literals or upcoming code editor updates in GM2023).

Features that have been completely superseded are disabled for newer GameMaker versions, while partially superseded ones can still be manually enabled to use them if there's an advantage over the built-in implementation.

Some things are less likely to be superseded - for example, the linter's design substantially differs between GMEdit and GM IDE (with GMEdit relying on flexible user-provided type annotations and GM IDE trying to deduct type information from the code).

Are syntax extensions safe to use?

The premise behind most of the GMEdit's syntax extensions is simple enough:

When you save a file with a custom syntactic feature (say, an (err)=>{} arrow function), it is converted to a form that GameMaker IDE and the compiler can understand (which is function(err)/*=>*/{} for arrow functions).

When you load a file, GMEdit converts these back into nicer-to-look-at shorthands.

Most of the GMEdit's syntax extensions look like perfectly regular GML code with an occasional annotation comment. You could write it yourself, but that would take a little longer, and that's the point.

Exceptions from this rule are:

  • Inline functions/literals for old GameMaker versions, which move the function contents to its respective file and display the name instead.
  • Macro-functions, which replace a macro "call" with its arguments separated by "segment" macros.
  • Coroutines, which stick the original script code in a comment and place the generated one below.

Better workflow:

Syntax extensions:

  • `vals: $v1 $v2` (template strings)
  • #args (pre-2.3 named arguments)
  • ??= (for pre-GM2022 optional arguments)
  • ?? ?. ?[ (pre-GM2022 null-conditional operators)
  • #lambda (pre-2.3 function literals)
  • => (2.3+ function shorthands)
  • #import (namespaces and aliases)
  • v:Type (local variable types)
  • #mfunc (macros with arguments)
  • #gmcr (coroutines)

Customization:

User-created:

Other:

Clone this wiki locally