GMLive - GML Cheat Sheet
GMLive - GML Cheat Sheet
cc%2Fdocs%2Fgm%2Fgmlive%2F
yal.cc
I also offer several archived versions of GMLive for use with old
GameMaker versions, such as GameMaker: Studio or
GameMaker Studio 2.2.x.
1 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
!"GameMaker: Studio
Using GMLive.gml
Using GMLive.gml
Initial setup
!"Import the GMLive asset the project:
!"If you bought the asset on itch.io, you can import it using
menu:Tools➜Import Local Asset Package, or by dragging and
dropping the .yymps file onto the workspace area (where the
resource editor windows show up) of the GameMaker window.
Note: .yymp is for GMS2.2.x, .yymps is for the current versions.
!"Import the assets (extension, object, and included files) from the
package.
Note: On Mac/Linux, omit importing Windows-specific exe and
ndll files.
Starting up (Windows)
!"Open your project directory using menu:Help ➜ Open project in
2 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
Explorer
(or navigate to it manually)
!"Open gmlive-server.exe
(you may also run it from Command Prompt/PowerShell/etc. if you
prefer)
!"Once the server window says "Project load took Xms", the server
is ready to go.
You can leave it running when recompiling the game - it will re-
scan the project directory whenever a new game instance
connects to it.
!"Change the "live" scripts/events as you see fit, save the file/project
(this is important) and see the changes in-game (if everything
was done correctly).
gmlive-server's window will report status updates.
Starting up (Mac/Linux)
!"Open your project directory using menu:Help ➜ Show Project In
Finder/File Manager
(or navigate to it manually)
3 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
Terminal at Folder.
On Linux, this depends on your file manager and/or desktop
environment.
I trust you to know how to open Terminal if you have chosen Linux
as your OS.
!"Once the server window says "Project load took Xms", the server
is ready to go.
You can leave it running when recompiling the game - it will re-
scan the project directory whenever a new game instance
connects to it.
!"Change the "live" scripts/events as you see fit, save the file/project
(this is important) and see the changes in-game (if everything
was done correctly).
gmlive-server's window will report status updates.
Exporting
GMLive extension works by communicating with gmlive-server
over network, which can be undesirable (or even forbidden,
depending on platform) in release builds of your game.
4 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
#macro Release:live_enabled 0
General functions
live_init(update_rate, url, password)
This function initializes GMLive and initiates the connection to
gmlive-server.
5 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
as a blank string.
live_log_script:script(debug_text, log_level)
You can assign a script into this global variable and GMLive will
call it whenever it wants to display some debug information (such
as notifications about scripts being reloaded).
For example,
live_execute_string(gml_code, ...arguments)➜ok?
Attempts to compile and run a snippet of GML code.
6 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
code.
var snip =
live_snippet_create(@'show_debug_message(argument0 * 2);');
if (snip != undefined) {
live_snippet_call(snip, 3); // -> 6
live_snippet_call(snip, 5); // -> 10
live_snippet_destroy(snip);
} else show_debug_message("Error: " + string(live_result));
live_snippet_call(snippet, ...arguments)➜ok
Executes a previously compiled snippet, returns whether
successful.
// ...
if (live_snippet_call(snip, 1)) {
show_debug_message("Result: " + string(live_result));
} else show_debug_message("Error: " + string(live_result));
live_snippet_destroy(snippet)
Destroys a previously created snippet.
7 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
Live functions
Live functions
live_call(...arguments)
Calls the "live" version of the current script/event with specified
arguments (if any).
function scr_test() {
if (live_call()) return live_result;
return "Hello!";
}
function scr_add(a, b) {
if (live_call(a, b)) return live_result;
return a + b;
}
live_call_ext(argument_array)
Same as live_call, but takes arguments in an array instead of a
list.
8 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
live_auto_call
In GMS2.3.x/GM2022+ version of GMLive, this macro is equivalent
to packing up arguments and calling live_call_ext (as shown
above).
function scr_test() {
live_auto_call;
// ...
}
live_defcall(...arguments, default_value)
Same as live_call but returns default_value instead of 0 if
execution fails.
For example,
/// scr_transform_string(string)
9 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
live_defcall_ext(argument_array, default_value)
A mix of live_call_ext and live_defcall - you can both pass
arguments as an array and a default return value.
live_result
Stores the returned value from the last live_call (or other "live"
group functions) if execution succeeded.
If the code did not return anything, holds 0 (GM default for exit).
live_name
In GMS2.3+, it can be hard for GMLive to tell apart nested
functions due to their automatic naming. To mitigate this, a
live_name variable is available and can be set to any unique
string prior to live_call for GMLive to know which function is
which.
For example,
live_code_updated:function(name, display_name)
You can assign a function/script to this global variable and it will be
10 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
So, for example, if you were to add the aforementioned code to the
end of obj_gmlive's Create event and changed something in a
live-reloaded Draw event of obj_test, you would see something
like the following in the Output:
11 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
!"If there's no compiled snippet for the location, the function will
return false and the original code will execute.
Resource functions
Resource functions
Apart of the primary feature of live-reloading code, GMLive can
also live-reload other resource types.
Sprite functions
Sprite functions
sprite_set_live(sprite, enable)
Enables/disables live reloading for a specific sprite.
Does not work for Spine/SWF sprites (as they cannot be reloaded
at runtime) and cannot do variable frame timings (since there are
12 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
For example,
sprite_set_live(spr_test, true);
While it might be tempting to call this for all the sprites, usually you
should not, as the server has to watch "live" sprites and their
subimage files for changes, and this can add up in disk access
time on larger projects.
Limitations:
!"Can't reload SWF sprites because there are no functions for doing
so.
!"Can't reload Spine sprites because I don't know much about these.
(but you might be able to do so yourself using file_set_live).
live_sprite_updated:function(sprite)
You can assign a function/script to this global variable and it will be
called whenever a sprite gets updated, like so:
live_sprite_updated = function(spr) {
show_debug_message("Reloaded " + sprite_get_name(spr));
// any extra logic
}
Path functions
Path functions
path_set_live(path_ind, enable)
Enables/disables live reloading for a specific path (the resource
type).
13 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
For example,
path_set_live(pt_test, true);
live_path_updated:function(path)
Like live_sprite_updated, but for paths.
For example,
animcurve_set_live(ac_test, true);
live_animcurve_updated:function(animcurve)
Like live_sprite_updated, but for animation curves.
14 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
changes.
The function's first argument will be the new contents (more on this
later) and the second argument will be the relative path (as
provided here).
Omit this argument or set it to undefined to disable live
reloading.
!".txt ➜ "text"
!".json ➜ "json"
!".bin ➜ "buffer"
!".csv ➜ "csv"
15 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
Disabling live-reloading:
file_set_live("test.txt", undefined);
Room functions
Room functions
Setting up
!"Create an empty object and name it, for example, obj_blank;
live_room_start();
live_blank_object = obj_blank;
live_blank_room = rm_blank;
16 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
room_set_live(room, enable)
Enables/disables live reload for a specific room. Don't forget to
setup helper resources first.
For example,
room_set_live(rm_test, true);
room_goto_live(room)
Transits to the specified room much like regular room_goto.
live_room_updated
If set, this script will be called whenever a new version of a room is
received.
live_room_updated = function(_rm) {
room_goto_live(_rm);
};
but you can also add your own logic this way.
Limitations
Limitations
Referencing "live" instances by name from non-"live" code
Since instance names are transformed into hardcoded instance
IDs during compilation, this will not work.
Consider assigning instances of interest into global variables in
room creation code if you need to - that way you'll assign IDs that
17 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
were given out to "live" versions as the "live" code would know the
"new" ones.
(anything else?)
This feature is relatively new and the topic of room loading is
relatively complex so it is possible that you'll encounter some
issues that I've not even thought of testing for. Make sure to report
things that break!
Shader functions
Shader functions
These are currently experimental.
Setting up
First, you will need an extension that can replace shaders with
new ones.
live_shader_updated:script(shader, hlsl_vertex_code,
hlsl_pixel_code)
A script should be assigned to this variable and will be executed
whenever a shader should be reloaded.
For example,
18 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
shader_set_live(shader, enable)
Enables/disables live reloading for a specific shader.
For example,
shader_set_live(sh_test, true);
API functions
API functions
The following functions are designed to add/override how GMLive
will compile code and are designed for rare cases where
something doesn't work right or to get around limitations with
calling extension functions.
Note that changing the API only affects newly compiled live code /
snippets - you should usually call these on game start / in
obj_gmlive's Create event.
live_function_add(signature, impl)
Registers a function for use in GMLive code / snippets.
!"clamp(a, b, c) (normal),
19 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
For example,
live_function_add("video_open(path)", function(path) {
video_open(path);
});
live_variable_add(signature, impl)
Registers a global built-in variable for use in GMLive.
For example,
20 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
live_variable_add("my_room_speed", scr_my_room_speed);
// and then in scr_my_room_speed
if (argument0) {
room_speed = argument1;
} else return room_speed;
or, in 2.3,
live_constant_add(name, value)
Registers a constant for use in GMLive.
live_constant_add("MATCHMAKING_SESSION",
MATCHMAKING_SESSION);
live_throw_error(text)
When ran from a function that is being ran by live code / snippet,
this passes an error message to GMLive, which will abort code
execution.
I cannot think of why you would want to unregister API entries, but,
just in case:
live_function_remove(name)
Removes a previously registered function.
live_variable_remove(name)
21 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
live_constant_remove(name)
Removes a previously registered constant.
GMS2.3+ functions
GMS2.3+ functions
live_method(self, func)➜method
Like the built-in method function, but supports re-binding functions
produced by GMLive code.
live_method_get_self(func)➜
Like the built-in method_get_self function, but returns correct
values for functions produced by GMLive code.
Technical topics
Technical topics
gmlive-server
Is a helper application for GMLive.gml. It does a few things:
22 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
on. You shouldn't need to touch this unless the default port (5100)
is being used by some other application or you desire to run
multiple gmlive-server instances on multiple project directories at
once.
neko gmlive-server.n
Error handling
Things that GMLive takes care of:
23 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
!"Missing variables/instances
!"Make a copy of GMLive folder so that you have one for Windows
(with EXE and NDLLs) and one for Mac/Linux (without NDLLs).
!"If using Git, delete the NDLL files, commit the deletion, add them
back on Windows machine, and also add them to .gitignore so
that they do not make it to Mac/Linux machines.
!"Install Neko VM on Windows so that you don't need the NDLLs nor
the EXE (and subsequently run neko gmlive-server.n from
24 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
Command Prompt/PowerShell)
Limitations
Limitations
Performance
On average, any time you add another layer on interpreted code,
performance degrades 5x..10x - YYC code is on average 5 times
slower than equivalent handwritten C++ code, non-YYC GML is
about 3..5 times slower than that, and GMLive, having runtime
compiled to GML, has roughly GM8.1 level of performance on non-
YYC and roughly regular GMS level of performance on YYC.
!"Using GMLive for ad-hoc modding support isn't a super good idea
That said, both GMLive and GameMaker are being worked on,
thus things will likely improve as time goes on.
25 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
!"catspeak
An open-source scripting language and compiler backend for
GameMaker. Pretty fancy.
!"Apollo
A native wrapper for industry-standard Lua, by me.
Similarly has sandboxing and full control over what executed code
can access.
26 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
API compatibility
API compatibility
Since GMLive reasonably needs to reference every function and
constant yet there is no way to go over constants nor get
information about function arguments at runtime, so the extension
has this massive script with function definitions and series of
live_function_add/live_variable_add/live_constant_add calls.
Here are the specific cases and instructions for getting around
them:
27 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
Constants
If a GameMaker update adds new constants, "live" code will not be
able to reference them until a GMLive update releases, but you
can also handle this yourself, like so:
live_constant_add("some_constant", some_constant);
Variables
On occasion, a GameMaker update might introduce a new global
variable that "live" code wouldn't be aware of. You can fix this like
so:
28 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
Troubleshooting
Troubleshooting
Code does not update
!"Make sure that you are saving the file (Ctrl+S or Cmd+S).
!"Check the output log for any compile/runtime errors with new
code.
!"You are calling the script with fewer arguments than you have the
code expect
(in which case GM would throw you an error as well).
29 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
with (some_instance_id) {
instance_destroy();
scr_some_instance_script();
}
30 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
function layer_tilemap_get_id_fixed(_layer) {
var els = layer_get_all_elements(_layer);
var n = array_length_1d(els);
for (var i = 0; i < n; i++) {
var el = els[i];
if (layer_get_element_type(el) == layerelementtype_tilemap) {
return el;
}
}
return -1;
}
<android:usesCleartextTraffic="true">
31 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F
The solution is to add a blank room in front of the rest, and add a
blank object to it which has a step event with something like the
following:
32 de 32 9/8/24, 15:56