KEMBAR78
GMLive - GML Cheat Sheet | PDF | Finder (Software) | Computer File
0% found this document useful (0 votes)
224 views32 pages

GMLive - GML Cheat Sheet

Uploaded by

Manuel Madrid
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
224 views32 pages

GMLive - GML Cheat Sheet

Uploaded by

Manuel Madrid
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.

cc%2Fdocs%2Fgm%2Fgmlive%2F

yal.cc

GMLive.gml cheat sheet


34-43 minutos

This is a "cheat sheet" for the GMLive.gml extension by


YellowAfterlife.

The extension can be acquired from GM:Marketplace or itch.io.

For questions/support, use forums, or send me an email.

An up-to-date version of this document can always be found


online.

Click on sections to expand/collapse them.


Quick display controls: Categories · Sections · Everything · Toggle
night mode
A note on old GameMaker versions
This document is for the current version of GMLive, which works
with the recent GameMaker versions (GameMaker 2022 and
newer, including LTS).

I also offer several archived versions of GMLive for use with old
GameMaker versions, such as GameMaker: Studio or
GameMaker Studio 2.2.x.

These versions of GMLive are no longer actively supported and


have slightly fewer features than the latest ones, but still are fairly
stable and have been used in numerous games during their time.

1 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F

For convenience, archived documentation from these versions is


available separately:

!"GameMaker: Studio

!"GameMaker Studio 2.2.x

!"GameMaker Studio 2.3.x

Using GMLive.gml
Using GMLive.gml
Initial setup
!"Import the GMLive asset the project:

!"If you bought the asset on GM Marketplace, you can import it


using menu:Marketplace➜My Library.

!"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.

!"On Mac/Linux, install Neko VM if you haven't already.


Neko VM is a tiny (1.5 .. 3.2MB) runtime for cross-platform
applications that I use for GMLive's server application.

!"Place obj_gmlive in the first room of the project.

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)

!"Navigate to datafiles ➜ GMLive

!"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.

!"Add live function calls to scripts and events of interest.


Note that the event must be GML-type (not a DND space with a
GML block)

!"Run the game.

!"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)

!"Navigate to datafiles ➜ GMLive

!"Open a Terminal window in the folder.


On Mac, this is done using menu:Finder ➜ Services ➜ New

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.

!"Type neko gmlive-server.n and press Enter.


If all is well, you'll see "Starting up... (protocol version: ...".

!"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.

!"Add live function calls to scripts and events of interest.


Note that the event must be GML-type (not a DND space with a
GML block)

!"Run the game.

!"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.

For this reason I recommend disabling GMLive prior to exporting.

To do so, change the value of live_enabled macro in


obj_gmlive's Create event to 0.

4 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F

Doing so strips out majority of GMLive's code, leaving only a


handful of dummy functions that will return default values when
called.

After exporting you can set live_enabled back to 1.

If you are using configurations, you can set up a configuration-


specific macro to automate this, like so:

#macro Release:live_enabled 0

If you rely on live_execute_string and/or Snippet API, you may


want to instead disable server communication by passing
undefined instead of the URL in live_init.

General functions
live_init(update_rate, url, password)
This function initializes GMLive and initiates the connection to
gmlive-server.

update_rate is how often files should be checked for updates, in


seconds. 1 is a common value. Lower values can load changed
files faster, but will also cause file system to be polled more
frequently.

url is the URL that gmlive-server is running on.


Typically you'll want something like "http://127.0.0.1:5100"
to connect to the server on the same machine.
Passing undefined instead of the URL prevents the connection
while allowing to use GMLive's utility functions (e.g.
live_execute_string).

password is the password set via gmlive-server's --password


option, as a basic form of security if running the server in an
unprotected network. If you did not specify one, this should be left

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).

If not assigned, plain show_debug_message calls are used.

log_level can be 0 (info), 1 (warning), or 2 (error).

For example,

live_log_script = function(text, level) {


show_debug_message(text);
if (level == 2) {
// make a beep
}
}

live_execute_string(gml_code, ...arguments)➜ok?
Attempts to compile and run a snippet of GML code.

Returns whether execution succeeded. If it did, live_result


contains the returned value (if any). If it didn't, live_result
contains the error text.

if (live_execute_string(@'show_message("Hello!"); return 1')) {


show_debug_message("Result: " + string(live_result));
} else show_debug_message("Error: " + string(live_result));

Please keep in mind that much like the similarly-named GM<=8.1


function, this compiles code on every call, thus is not fast and
should only be used for debugging (e.g. if you want to be able to
type snippets of GML in-game for quick tests) - use
live_snippet_create if you need to repeatedly execute dynamic

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.

live_snippet_create(gml_code, name = "snippet")➜snippet


Creates a new "snippet" from a string of code.

Since this pre-compiles code, doing so is faster than


live_execute_string for cases where you would want to repeatedly
execute the same dynamic code snippet (in parallel with
object_event_add in legacy GameMaker).

If there is a compilation error, the function returns undefined and


stores the error text in live_result.

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));

Don't forget to destroy your snippets to free up memory when


you're done using them!

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

Using a snippet after it had been destroyed will generally error.

Live functions
Live functions
live_call(...arguments)
Calls the "live" version of the current script/event with specified
arguments (if any).

Returns whether the "live" version is already loaded and was


called.

If execution succeeds, live_result contains the returned value.

If execution fails, live_result contains 0 (also see live_defcall).

For example, if your script takes no arguments, you could do:

function scr_test() {
if (live_call()) return live_result;
return "Hello!";
}

If your script takes two arguments, you could do:

function scr_add(a, b) {
if (live_call(a, b)) return live_result;
return a + b;
}

If your script takes a varying number of arguments, see


live_call_ext or live_auto_call.

live_call_ext(argument_array)
Same as live_call, but takes arguments in an array instead of a
list.

You might use it like so:

8 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F

var argument_arr = array_create(argument_count);


for (var i = 0; i < argument_count; i++) {
argument_arr[i] = argument[i];
}
if (live_call_ext(argument_arr)) return live_result;

However, for specific purpose of passing all of the arguments to a


live_call, you can most often use live_auto_call in current
GameMaker versions.

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).

So, instead of one or other if (live_call... snippet, you can


just do

function scr_test() {
live_auto_call;
// ...
}

and that's it.

live_defcall(...arguments, default_value)
Same as live_call but returns default_value instead of 0 if
execution fails.

This is handy if live-coding a script that may only return values of


specific type (thus specifying a default value would allow to avoid
errors outside of "live" code).

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

if (live_defcall(argument0, "")) return live_result;


// (some risky manipulations with string)

would return "" if execution of the "live" code fails.

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,

function Greety(_name) constructor {


name = _name;
static greet = function() {
live_name = "Greety:greet";
if (live_call()) return live_result;
trace("A greet from", name)
}
}

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

called whenever a code snippet (script, event, etc.) gets updated,


like so:

live_code_updated = function(name, display_name) {


show_debug_message("Reloaded " + display_name + "(" +
name + ")");
// any extra logic
}

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:

Reloaded obj_test:Draw_0 (gml_Object_obj_test_Draw_0)

As you can see, display_name is a (relatively) human-readable


name and name is whatever GMLive uses to tell this snippet apart
(typically the script name or the name from
debug_get_callstack())

How does this work, anyway


You might be wondering what exactly do the different "call"
functions do and why you have to add them by hand to scripts/
events.

The way this works is:

!"When you change a file in your project, gmlive-server will note


the change and will send a new copy to the game when it asks for
updates.
The extension will then compile the new code to an easier-to-
execute form and store it.

11 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 first look up where they're being used from.


(either through live_name or debug_get_callstack)

!"If there's a compiled snippet stored for the location, it will be


executed, the return value will be stored in live_result, and the
function will return true.
This way the new code executes instead of the original code.

!"If there's no compiled snippet for the location, the function will
return false and the original code will execute.

That is also why the calls have to be added manually - there is no


way to add a bit of code to every single function during compilation
without changing every file in the project (which is a bad idea for a
variety of reasons).

Resource functions
Resource functions
Apart of the primary feature of live-reloading code, GMLive can
also live-reload other resource types.

As an opening note, set_live functions from this category can


be called whenever and have little to no overhead for repeated
calls, so you can set up the callbacks and make yourself a debug
console/menu for picking resources to live-reload, or even just
add-remove a line of code in a "live" script/event.

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

no functions for changing this)

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).

!"Can't do variable frame timings and broadcast messages. because


there are no functions for setting them up.

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);

Note that GameMaker stores path positions as a number in 0..1


range so making a path shorter/longer will cause instances
following it to jump around as they readjust.

live_path_updated:function(path)
Like live_sprite_updated, but for paths.

Animation curve functions


Animation curve functions
animcurve_set_live(animcurve_ind, enable, ?precision)
Enables/disables live reloading for a specific animation curve.

Optional precision determines bezier curve iterations.

For example,

animcurve_set_live(ac_test, true);

live_animcurve_updated:function(animcurve)
Like live_sprite_updated, but for animation curves.

file_set_live(path, ?callback, ?kind)


Enables/disables live reloading for a specific included file.

This can be used for live-updating game data, localization, or


anything else.

path is a relative path to the file (e.g. some.txt, or GMLive/


gmlive.html).
You may go out of the included file directory using ../ to read
other files inside the project directory (e.g. ../notes/mynote/
mynote.txt), but not files outside of the project directory.

callback is a function/script that will be called whenever the file

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.

kind is a string determining how to load the file. It can be one of


the following:

!""text": provides file contents as a string.

!""buffer": provides file contents as a buffer.


Note that the buffer will be automatically deleted later so you
should copy the data from it somewhere as necessary.

!""csv": provides file contents as a CSV grid (using load_csv).


Similarly, the grid will be automatically deleted afterwards.

!""json": provides file contents as a JSON value, provided that it's


valid JSON.

!""base64": provides file contents as a base64 string.


This is the format data is originally received in and is convenient if
you intend to decode it yourself as you please.

If kind is not specified or is set to "auto", it will be auto-detected


based on file extension:

!".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

!".b64, .base64 ➜ "base64"

If the file extension is not recognized, an error is thrown.

Example (assuming that you have a test.txt in your Included


Files):

file_set_live("test.txt", function(_text, _path) {


show_debug_message(_path + " has been updated: " + _text);
});

With a file type override:

file_set_live("test.txt", function(_buf, _path) {


show_debug_message(_path + " is now " +
buffer_get_size(_buf) + " bytes long");
}, "buffer");

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;

!"Create an empty room and name it, for example, rm_blank; If


using GMS2, remove the default instance and background layers;
Add the following to its Room Creation Code:

live_room_start();

!"Assign the two to live_blank_object and live_blank_room


in obj_gmlive's Create event:

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);

Can be called at runtime, including from "live" code.

room_goto_live(room)
Transits to the specified room much like regular room_goto.

If a "live" version of the room is loaded, transits to


live_blank_room instead and loads the new version of the
room there.

live_room_updated
If set, this script will be called whenever a new version of a room is
received.

By default this does an equivalent of

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.

As of 2024, the only such extension is seemingly my own, which is


Windows-only and has some limitations, but at least it doesn't
break often.

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,

live_shader_updated = function(shader, hlsl_vertex_code,


hlsl_pixel_code) {
// ... call your respective function to replace the shader
}

GMLive will automatically assign shader_replace_simple's


function if available.

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);

Can be called at runtime, including from "live" code.

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.

signature is function signature, including the name, such as:

!"clamp(a, b, c) (normal),

!"instance_destroy(?id, ?execEvent) (prepend optional


arguments with ?)

!"max(...values) (include ... for trailing arguments).

Trailing content (such as the various characters from fnames) is


allowed, but will be ignored.

impl (a script in 2.2, a function in 2.3) will then be called with


provided arguments as 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);
});

You may call live_throw_error to hand an error back to the


executing "live" code (such as noting that arguments are mis-typed
if this would result in a catastrophic error otherwise).

live_variable_add(signature, impl)
Registers a global built-in variable for use in GMLive.

signature is the variable signature in fnames format:

!"room_speed (a read/write variable)

!"fps* (a read-only variable)

!"view_xport[] (an array)

impl (a script in 2.2, a function in 2.3) will be called with the


following arguments:

!"argument0: whether writing (true) or reading (false) the variable.

!"argument1: if writing the variable, this contains the new value.

!"argument2: if the variable is an array, this contains the index.


Please note that, honoring how GameMaker (still!) works, a =
view_xport; is equivalent to a = view_xport[0];.

You may call live_throw_error to hand an error back to the


executing "live" code (such as preventing out-of-bounds array
access for fixed-size arrays or performing value validation on
write).

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_variable_add("my_room_speed", function(set, val) {


if (set) {
room_speed = val;
} else return room_speed;
});

live_constant_add(name, value)
Registers a constant for use in GMLive.

There isn't much to this one - name and value.

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.

In GMS2.3 you may instead use show_error or throw.

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

Removes a previously registered global built-in variable.

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:

!"Fetches resources from the project.

!"Watches "live" files for changes.

!"Sends updated files to the game.

Starting up without arguments (such as by double-clicking the


executable) has it automatically look for a GMS1/GMS2 project in
the parent directory.

Passing an argument (such as by dragging a file/directory onto the


executable) has it load up the specified project.

Starting up from command-line/PowerShell/terminal allows to


specify additional arguments:

!"--port <port number>: Sets a custom port to run the server

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.

!"--password <string>: Sets a custom password (to be passed


in live_init).

!"--timeout <seconds>: Adjusts connection timeout for clients.


In other words, how long it is without a response before a
connection is dropped and related data structures are cleaned up.
Default is 60 seconds and you wouldn't usually need to touch this
unless you have issues with the game disconnecting during a
step-by-step debug session.

!"--runtimePath <path>: If your GMS2 runtimes somehow don't


reside in the usual location and gmlive-server fails to detect them
as result, you can use this to force a path (which would end on
\runtime-a.b.c.d)

On the technical side, gmlive-server is a Neko VM application. For


Windows, the few DLLs it uses and an executable version are
packaged together with it. On Mac, you'll need to install Neko VM
binaries (~1.5MB) to be able to run it from terminal via

neko gmlive-server.n

Error handling
Things that GMLive takes care of:

!"Syntax errors in "live" code


(code will not be updated if the new version doesn't compile)

!"Value errors (e.g. trying to add a string to a number, dividing by 0)

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

!"Wrong argument types passed to common built-in functions

When a "runtime" error occurs, it is logged and the "live" script/


event halts execution. This does not prevent subsequent attempts
to execute the code.

Things that GMLive cannot take care of:

!"Runtime errors in non-"live" scripts

!"Fatal errors thrown by built-in functions (e.g. memory allocation


errors)

If you are using GMS1 or older versions of GMS2 (2.2.5 or earlier),


you can also use catch_error and a
"GMLiveForGMSX_and_catch_error" version of the extension to
prevent a number of crashes.

Using GMLive on Windows and Mac/Linux at once


If you have the same project directory shared between a Windows
and non-Windows machine (via cloud sync, network folder,
SyncThing, version control, etc.) and want to be able to use
GMLive without adding/removing files, you can do any of the
following:

!"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)

!"Copy the GMLive folder elsewhere and run it from Command


Prompt/PowerShell/terminal with a path to your YYP (see above).

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.

This has a few implications:

!"Enabling livecoding for too many performance-critical scripts at


once isn't a good idea.
GMLive versions from 1.0.48 onward will not compile-interpret
code until a script/event is changed after game start, but still there
is minor overhead in checking whether the script/event has a "live"
version loaded or not.

!"Using GMLive for ad-hoc modding support isn't a super good idea

!"both for performance reasons and because the interpreted scripts


would have complete access to GameMaker API and game's
resources.
You can look into tiny expression runtime

That said, both GMLive and GameMaker are being worked on,
thus things will likely improve as time goes on.

Use of GMLive for modding

25 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F

Although it may be tempting to use GMLive's


live_execute_string and Snippet API for ad-hoc modding
support, the consequences of that aren't unlike use of
execute_string - you would be executing code without any
security measures in place, meaning that scripts could crash the
game, corrupt save data or unrelated variables, and so on.

Better options would be:

!"catspeak
An open-source scripting language and compiler backend for
GameMaker. Pretty fancy.

!"tiny expression runtime


An open-source example project and accompanying tutorial on
writing purpose-specific scripting languages, by me.

!"Apollo
A native wrapper for industry-standard Lua, by me.
Similarly has sandboxing and full control over what executed code
can access.

!"For projects with higher requirements, I may occasionally be


available for contract work and have built all kinds of compilers
and interpreters for clients over years.

Calling functions in native extensions


GMLive by default has entirety of standard GameMaker API and
all game-specific resources exposed to it, but native extensions'
functions currently cannot be dynamically referenced, therefore
you would not be able to call them from "live" code by default.

As a workaround, you can either make a script that calls the


function, and then call that script, or use live_function_add to

26 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F

expose wrapped functions to GMLive, like so:

live_function_add("ext_func(a, b)", function(a, b) {


return ext_func(a, b);
});

Copy-on-write behaviour in arrays


NOTE: As of GM2022, copy-on-write has been deprecated and is
turned off by default in new projects.

GML itself has a particular feature (see "Advanced Array


Functionality") that has it so that passing an array as an argument
to a script, and then changing it via arr[index] = value
(rather than arr[@index] = value) would duplicate the array
prior.

The internal data for this is not exposed, however, so GMLive is


unable to do it in the same way, and only does "create-on-write"
(replacing a value with a new array if it isn't yet).

If this doesn't make immediate sense, it is unlikely that you rely on


this feature anywhere.

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:

Function signature changes

27 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F

As of GMS2022, GMLive will gracefully new functions appearing


(albeit with no argument count checks) or functions going missing,
but it cannot handle argument changes for existing functions - like
the infamous reduction of buffer_set_surface from 5 to 3
arguments, or introduction of an optional argument to
instance_create_depth.

When this happens, GMLive will refuse to compile code with


seemingly-incorrect argument counts, but you can fix this yourself:

live_function_add("instance_create_depth(x, y, depth, object, ?


vars)", instance_create_depth);

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);

But if a constant is removed, you'll get a startup error in


GMLiveAPI.
You can comment out the offending lines in the script, but it can be
easier to add an empty macro for each such constant, like so:

#macro some_constant undefined

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:

live_variable_add("some_variable", function(set, val) {


if (set) {
some_variable = val;

28 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F

} else return some_variable;


});

Troubleshooting
Troubleshooting
Code does not update
!"Make sure that you are saving the file (Ctrl+S or Cmd+S).

!"Make sure that gmlive-server is running.

!"Check the output log for any compile/runtime errors with new
code.

!"Check gmlive-server window for any project load errors.

!"Check if the time next to the client in gmlive-server window is


ticking.
If it's not ticking, you likely accidentally deactivated/destroyed
obj_gmlive.

"Argument index is out of range"


This usually happens for one of two reasons:

!"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).

!"You forgot to add script arguments to live_call/live_call_ext.

"Couldn't find live function"


There are generally two possible causes for this error:

1. You are trying to live-code a function-in-function (e.g. a static


function inside a constructor) or function-in-event (e.g. a function
assigned inside a Create event).
Depending on GameMaker version, debug_get_callstack()

29 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F

output can be unreliable for such cases, so use of live_name is


necessary for GMLive to know which function it should be taking
the new code from.

2. You are using a macro that has not been auto-detected as


containing a live-call.
Try using one of the default live_call functions instead.

"Can't call instance-specific function - instance does not exist."


You can occasionally get this error in output log when calling
scripts for instances after deactivating/destroying them - currently
the only way self/other instances can be set up for a call is via
with blocks, and these do not work with deactivated/destroyed
instance IDs.

GMLive uses a few workarounds to get around this in common


situations (applying to original self/other instances of the
event), but if you have something like

with (some_instance_id) {
instance_destroy();
scr_some_instance_script();
}

that may show that error.

As a workaround, you can either change your code not to attempt


to call scripts on freshly deactivated/destroyed instances, or move
the D/D+call branch into a separate script.

Problems with tilemaps in "live" rooms


If you are using layer_tilemap_get_id, you should be aware
(as per manual) that it does not work with "dynamically" created
tilemaps, including those made by GMLive.

30 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F

The workaround is to make a little function that finds the tilemap


on the layer, which might look as following:

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;
}

What is "GMLive - copy.gml"?


Occasionally I make a copy of one or other GMLive script to run a
text diff tool on them before publishing an update and forget to
remove them later. Such files are safe to remove.

"Failed to load library : no suitable image found. "


You can get this on Mac if you did not remove the original ndll
files - NDLLs that Windows uses are different from those for OSX.

"Cleartext HTTP traffic not permitted" on Android


You'll need to add

<android:usesCleartextTraffic="true">

to "Game Options ➜ Android ➜ Permissions - Inject to Application


Tag".

Running game in debug mode skips over create events


GameMaker versions prior to GMS2.3 have a curious bug that has

31 de 32 9/8/24, 15:56
GMLive.gml cheat sheet about:reader?url=https%3A%2F%2Fyal.cc%2Fdocs%2Fgm%2Fgmlive%2F

it that if your game has "enough" code in it and your computer


matches the unknown requirements, the debugger may choke for
a bit, causing the game to skip events for the first few frames.

Since GMLive adds about 900KB worth of GML code to your


game, it tends to tip off the issue for affected users.

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:

if (!debug_mode || ++x > xstart + 3) {


instance_destroy();
room_goto_next(); // or room_goto(real_init_room)
}

In worse cases, 3 may be increased until the issue is no longer


present.

The issue seems to be fixed as of GM2022.

32 de 32 9/8/24, 15:56

You might also like