This is a function "cheat sheet" for Apollo extension by YellowAfterlife.
+The extension can be acquired from GM:Marketplace or itch.io.
+For questions/support, use forums (itch.io, GM forums), or send me an email.
+A most up-to-date version of the manual is always available online.
+The extension is currently available for Windows, Linux, and Mac (experimental).
+ This also causes newly made states to have IDs start at 0 again.
+
+
lua_state_reuse_indexes()➜count
+ Here's the deal: As you might know, reusing indexes can cause some really mysterious bugs
+ if your code accidentally continues to use an index (which is now taken up by something else).
+
+ So, by default, Apollo will not do that. Which, in turn, means that after states are destroyed,
+ 4 bytes worth of data (which were onece the state's address) will continue to be reserved per state.
+
+ While it would take about 500 000 states to run out of memory this way,
+ you might prefer not to have that anyway.
+
+ So, calling this function will mark that memory as available again, causing Apollo to reuse the
+ destroyed indexes for newly created states. This will only affect indexes of states that are
+ destroyed as of calling the function.
+
+ In other words, while developing your project, you would not call this at all
+ (so that if you use a destroyed state, you get an obvious error), and for final release
+ version you would call it once in a while (such as during room transitions - to further
+ reduce the odds of anything going strange).
+
+ The function returns the number of indexes that will be reused as result.
+
+ Attempts to load and run a snippet of Lua code from the file at the given path.
+
+ The function mimics GMS' file handling rules, preferring files in game's save directory over the files in game's installation directory.
+
+ It will, however, also accept absolute paths, bypassing sandbox restrictions.
+
+ So, if you added an included file called "some.lua", you could then load it with
+
+lua_add_file(state,"some.lua");
+
If chdir is left at true, the function will automatically call lua_chdir when given a relative path so that the Lua code would work with files in that directory.
+
+ Returns the type of a state's global variable as a constant.
+
+ Possible values are as following:
+
lua_type_none: placeholder for type ID 0
+
lua_type_nil: an equivalent of GML's undefined. Not-yet-set values are nil.
+
lua_type_bool: a boolean value (true or false).
+
lua_type_number: a numeric type, same as GML's real.
+
lua_type_string: same as GML's string type.
+
lua_type_table: a Lua table (array or dictionary).
+
lua_type_function: a Lua function (that can be called via lua_call group).
+
lua_type_thread: a Lua "thread"/coroutine.
+
lua_type_userdata: an external reference (see Lua doc).
+
lua_type_lightuserdata: an external struct (see Lua doc).
+
lua_type_unknown: unrecognized type (never returns with normal Lua library)
+
+ If the state does not exist, an error is thrown.
+
+if(lua_global_type(state,"test")==lua_type_function){
+ lua_call(state,"test");
+}elseshow_debug_message("The state does not have a function called `test`!");
+
+ Returns the type of a state's global variable as a string.
+
+ Outside of debugging, you should prefer to use lua_global_type, as numeric comparisons are much faster than string comparisons.
+
+ The usual returned values are as following:
+
+
"nil": an equivalent of GML's undefined. Not-yet-set values are nil.
+
"boolean": a boolean value (true or false).
+
"number": a numeric type, same as GML's real.
+
"string": same as GML' string type.
+
"table": a Lua table. You currently can't do much with these from GML side.
+
"function": a Lua function - as such, a thing that could be called via lua_call.
+
"thread": a Lua "thread"/coroutine (more on these later).
+
+ So you could use a snippet like this to check if a state has a function named "test":
+
+if(lua_global_typeof(state,"test")=="function"){
+ lua_call(state,"test");
+}elseshow_debug_message("The state does not have a function called `test`!");
+
+ Like lua_call, but allows to pass in the arguments as an array.
+
+lua_add_code(state,"function add(a, b) return a + b end");
+varargs=array_create(2,7);// [7, 7]
+show_debug_message(lua_call_w(state,"add",args));// 14
+
+ A combination of lua_call_w and lua_call_xm - takes arguments as an array, writes results to another array, and returns the number of results written.
+
+ Same as aforementioned lua_return, but returns the contents of an array as a value list instead.
+ Note this will not work for nested arrays, however.
+
The last line with an empty lua_return_add is needed to return 0 values if loop matches no instances (as runtime would otherwise assume that you are going to return something with a regular return).
+
+ While Lua has a separate boolean type, GameMaker uses 1 as true-value and 0 as false-value.
+ This makes it hard to tell whether you were meaning to send 1 or true.
+
+ So there's this function, which returns either a lua_true or a lua_false depending on argument, which can be told apart by the extension explicitly, and will become the according Lua values once sent to Lua.
+
+ When a Lua state calls the exposed GML script, this variable holds the ID of the "caller" state. Can be used if you want to do anything aside of just returning value(s).
+
+ Sends an error message to the currently executing Lua state.
+
+ This should only be used inside scripts exposed via lua_add_function.
+
+/// scr_variable_global_get(name)
+if(is_string(argument0)){
+ returnvariable_global_get(argument0);
+}elselua_show_error("Expected a variable name to be a string.");
+
+ If you are using GameMaker Studio 2 or an Early Access version of GameMaker: Studio 1, you can have Lua directly read and write variables on GameMaker instances.
+
+ To do so, you would add three scripts to your project:
+
(exposes the above scripts to a Lua state and sets it up to use them when trying to read/write a field on a numeric value (id)).
+
+ Then you can use them as following:
+
+// create a Lua state:
+state=lua_state_create();
+// allow the state to work with GM instances:
+ref_variable_instance_init(state);
+// add a test function to the state -
+// function takes an instance and modifies it's `result` variable.
+lua_add_code(state,"function test(q) q.result = 'Hello!' end");
+// call the test-function for the current instance and display the result:
+result="";
+lua_call(state,"test",id);
+show_debug_message(result);
+
+ If you are building a medium-scale scripting API, you may find yourself needing to expose a large number of scripts (and/or built-in functions), as well as introducing argument type checking to prevent GML-side errors.
+
+ To save you from having to deal with that, Apollo includes a small utility that generates wrapper and loader scripts.
+
+ It accepts function definitions in funcname(arg1:type1, arg2:type2, ...):rtype,
+
+
arg1, arg2, ...: argument names. Will be shown in errors returned to Lua.
+
type1, type2, ...: argument types. Optional.
+ If defined, code will be added to ensure that each argument matches it's type.
+ Known types are real, bool, string;
+ color, int, index, id can also be used, but are treated same as real.
+
rtype: returned type, if the function returns a specific one.
+ If set to bool, return-statement will be wrapped in lua_bool call.
+
If prefixed with :, function will be marked as "instance function" and will accept an instance ID as first argument, also allowing to call it as inst.func(...) if instance access scripts are set up.
+
+ Constants can be defined either as name# (uses the value of same-named constant/variable) or name = value (computes the given GML value at inclusion time).
+
+ The tool is included with the extension as ApolloGen.exe;
+
+ A web-based version is available below:
+
Whenever the contents of above field are changed, updated loader script will be output into the field below:
+
You can then save them into a .gml file and import it to your project.
+
+
+ If you have pre-existing GML code that you'd like to quickly port for use with Apollo, I have also developed an online GML->Lua compiler.
+
+ While automatic conversion won't make extensive use of Lua-specific language features, it produces functional code in vast majority of cases and the output is clean enough to tweak it manually if needed.
+
+ A coroutine, in short, is a function that can pause/resume execution at arbitrary points. These can be used for iterators, cutscenes (pausing/resuming allows to write timing in an intuitive way), tweening, AI, or anything else that benefits from maintaining the state across multi-call execution.
+
+ Creates a "thread" state for the given Lua state and returns it's ID.
+
+ Such "threads" share the global context (variables, functions, etc.) with their parent state, but have their own clal stack, meaning that they can do their own thing (namely, executing coroutines) while the parent state does something else.
+
+ Does not free resources of the parent state, only what was owned by the thread itself.
+ Is a convenience function and is interchangeable with lua_state_destroy.
+
+ Starts a coroutine call on the given sate, returns whether the operation succeeded.
+
+ Note that some functions will work oddly (or not work at all) on a state that is currently amidst the coroutine call, which is why you should generally create a thread for the coroutine call.
+
+ Executes the next iteration on the given state and returns whether the coroutine call is ongoing (as opposed to finishing or encountering a runtime error).
+
+ The general scheme of performing coroutine calls is thus as following:
+
+ In case you'd like a custom version (such as to use LuaJIT, or to use a Lua fork with
+ different syntax), C++ source code is included - it will work with any Lua build
+ down to 5.1.
+
+ The extension runs on Windows, Mac, and Linux - linked dynamically in all cases.
+
+ Apollo v2 beta currently only comes with a Windows (GMS1,GMS2) binary,
+ but you can compile it yourself (code is portable).
+
+ Mac may require additional tinkering (via install_name_tool - example), as library inclusion paths may vary depending on whether the game is running from IDE, whether YYC is enabled, and GMS version. If you are familiar with Mac extension development yourself, feel free to get in touch about better ways of handling this.
+
+ While these are roughly equivalent to GM's ds_maps, the two work very differently -
+ ds_maps are passed by-index and managed manually (ds_map_destroy),
+ Lua' tables are passed by-reference and managed by garbage collector.
+
+ While future iterations on GML should make it possible to automatically convert between tables and lightweight data structures, this would only allow to return a new table/structure rather than modifying an existing one.
+
+ The issue can be approached in several ways:
+
+
Expose ds_maps to Lua code and use them instead of tables for transfer.
+
Have a wrapper function on Lua side to expand the table into multiple values prior to calling the GML script and/or wrap multiple returned values from GML back into a table.
+
If you do not need to read data from the table (but store/retrieve it), you can convert it to index and back on Lua side via lookup tables (see below).
+
+ Lua supports several additional reference types (such as Lua function references),
+ but these cannot be safely sent to GML as pointers as they are garbage-collected,
+ and thus may get recycled while still referenced on the GML side of things
+ (resulting in hard crash when trying to use the passed back value).
+
+ A good way to deal with this is to make a pair of lookup tables - since Lua allows table indexes to be of any type, you can do something like the following:
+
ref ={
+ __r2i ={},
+ __i2r ={},
+ __next =0
+}
+function ref.toid(fn)
+ local id = ref.__r2i[fn]
+ if(id ==nil)then
+ id = ref.__next
+ ref.__next = id +1
+ ref.__r2i[fn]= id
+ ref.__i2r[id]= fn
+ end
+ return id
+end
+function ref.fromid(id)
+ return ref.__i2r[id]
+end
+function ref.free(fn)
+ local id
+ if(type(fn)=="number")then
+ id = fn
+ fn = ref.__i2r[id]
+ else
+ id = ref.__r2i[fn]
+ end
+ ref.__r2i[fn]=nil
+ ref.__i2r[id]=nil
+end
Which allow you to use ref.toid(some_reference) to return/create a numeric ID for a reference, ref.fromid(index) to convert one of those back to a reference, and ref.free(index_or_reference) to remove the lookup pairs (allowing Lua to safely recycle the reference when it is no longer used).
+
+
+
+
+
diff --git a/datafiles/LuaLicense.txt b/datafiles/LuaLicense.txt
new file mode 100644
index 000000000..8ed741f40
--- /dev/null
+++ b/datafiles/LuaLicense.txt
@@ -0,0 +1,6 @@
+Copyright 19942017 Lua.org, PUC-Rio.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/datafiles/data/themes/default.zip b/datafiles/data/themes/default.zip
index 5c21a26cf..50642872e 100644
Binary files a/datafiles/data/themes/default.zip and b/datafiles/data/themes/default.zip differ
diff --git a/datafiles/data/themes/default/graphics/graphics.json b/datafiles/data/themes/default/graphics/graphics.json
index 9b5390e49..a7df8c509 100644
--- a/datafiles/data/themes/default/graphics/graphics.json
+++ b/datafiles/data/themes/default/graphics/graphics.json
@@ -850,6 +850,20 @@
"yorigin": 24,
"slice": null
},
+ "node_create": {
+ "path": "./icon/s_node_create.png",
+ "subimages": 1,
+ "xorigin": 24,
+ "yorigin": 24,
+ "slice": null
+ },
+ "node_use_global": {
+ "path": "./icon/s_node_use_global.png",
+ "subimages": 3,
+ "xorigin": 16,
+ "yorigin": 16,
+ "slice": null
+ },
"inspector_area": {
"path": "./inspector/s_inspector_area_strip2.png",
"subimages": 2,
diff --git a/datafiles/data/themes/default/graphics/icon/graphics x2.ai b/datafiles/data/themes/default/graphics/icon/graphics x2.ai
index c376ee4de..6f5e3d134 100644
--- a/datafiles/data/themes/default/graphics/icon/graphics x2.ai
+++ b/datafiles/data/themes/default/graphics/icon/graphics x2.ai
@@ -1,5 +1,5 @@
%PDF-1.6
%
-1 0 obj
<>/OCGs[33 0 R]>>/Pages 3 0 R/Type/Catalog>>
endobj
2 0 obj
<>stream
+1 0 obj
<>/OCGs[33 0 R]>>/Pages 3 0 R/Type/Catalog>>
endobj
2 0 obj
<>stream
@@ -24,22 +24,22 @@
Adobe Illustrator 27.0 (Windows)2022-11-26T09:16:08+07:00
- 2023-03-06T08:33:03+07:00
- 2023-03-06T08:33:03+07:00
+ 2023-03-08T12:26:32+07:00
+ 2023-03-08T12:26:32+07:0025696JPEG
- /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAYAEAAwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FULfR3L8fS
HJaEMvLgQ37LV9slEhUTGHCKHNXAHIjoT3yKpPpdlqsmoSahqLGMiqQ2wIIC+JoWFPDx6nsBiYcc
zLin8nYajLiEBjx795/H4+9Ocy3XuxV2KuxV2KuxV2KuxV2KuxV2KoKKa4M6KWY1dxIhSgVRXieV
Pl3yZApVe7d0RCpKgsA7KvIgUPahyIV1o7vGS5LUYhWI4kjttQYlUv1mG9e4tzC6KpNFDVBD9a/a
Wu2R37wPg2Q4a3BPx/Ymy1AAJqabnphay7FXYq7FVk8Mc8LwyAmNxxYAlSQfdSDkZwEhR5FEhYor
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
2KuxV2KuxV2KuxVCU0v9JA8ov0jwoF5D1fT/ANWtafRlfhR4uKvUnwD9deVrpLCN76K85FXjUqVF
OLdgTWv2anp45GWEGYn1DWYDi4kTlzN55+YQ0X/EmmtKWGorbvQxV9YDmPqxhNDSQy8uPD4j7jA9
H2T435efDXDxdeXL1cXlw1d7PQvj4dudPorhecee/l4NFPmTUnhLnUTbpUy19YjmfrHrmgrJ6oXl
z+IfLA9H2sc35eHFXDxHly5enh/o8Pds9DwvOOxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2
KuxV2KuxV2KuxV2KuxV2KuxVBfoTSf0v+mfqsf6U9H6v9bp+89KvLjX54t/5rJ4XhcR8O7rpaNxa
HYqtaKJnV2RS6fZYgEivgcUiRApdihascaszqoDPTmwABNOlTikyJ2XYodirsVdirsVdirsVdirs
VdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsV
dirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVd
irsVdirsVdirsVdirsVdirsVdirsVdirsVdir//Z
+ /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAYAEAAwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
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
VdirsVf/2Q==defaultuuid:65E6390686CF11DBA6E2D887CEACB407xmp.did:7647d1b0-ea83-ca49-b85e-bbc9513ca4bb
- uuid:52d6d9c3-35ea-4f88-a0f9-c383fbea1736
+ uuid:27c4546d-c6e4-4143-8012-0400b218be1euuid:673f9e21-4d80-48ad-ba53-812ef9241a78xmp.did:efa7ff44-b17d-d449-8cbc-4cf525bcc8d1
@@ -71,8 +71,8 @@
TrueFalse
- 24.000000
- 24.000000
+ 48.000000
+ 16.000000Pixels
@@ -309,20 +309,20 @@
-endstream
endobj
3 0 obj
<>
endobj
35 0 obj
<>
endobj
37 0 obj
<>
endobj
5 0 obj
<>>>/Thumb 3169 0 R/TrimBox[0.0 0.0 24.0 24.0]/Type/Page/PieceInfo<>>>
endobj
3166 0 obj
<>stream
-H10ݧjqvR Ƃ*
N3~[t-Z ZYŁzloZSP7E6H(6^\SftHfsF33Ü Y
-endstream
endobj
3167 0 obj
<>
endobj
3169 0 obj
<>stream
-8;Xp,*=;cJ$ihU'#ES~>
-endstream
endobj
3170 0 obj
<>
endobj
3172 0 obj
<>
endobj
3173 0 obj
<>stream
+endstream
endobj
3 0 obj
<>
endobj
35 0 obj
<>
endobj
37 0 obj
<>
endobj
5 0 obj
<>>>/Thumb 3454 0 R/TrimBox[0.0 0.0 48.0 16.0]/Type/Page/PieceInfo<>>>
endobj
3451 0 obj
<>stream
+H10ݧjq@dBMXo:H9-Z ZYŁvmINEpL/.)rSl:g$9iF? 'Z
+endstream
endobj
3452 0 obj
<>
endobj
3454 0 obj
<>stream
+8;Xp,*-A$iiSR$5E~>
+endstream
endobj
3455 0 obj
<>
endobj
3457 0 obj
<>
endobj
3458 0 obj
<>stream
%!PS-Adobe-3.0
%%Creator: Adobe Illustrator(R) 24.0
%%AI8_CreatorVersion: 27.3.1
%%For: (Makham) ()
%%Title: (graphics x2.ai)
-%%CreationDate: 3/6/2023 8:33 AM
+%%CreationDate: 3/8/2023 12:26 PM
%%Canvassize: 16383
-%%BoundingBox: -48 -240 604 0
-%%HiResBoundingBox: -47.3922855564306 -240 603.17639088057 0
+%%BoundingBox: -48 -241 604 0
+%%HiResBoundingBox: -47.3922855564306 -241 603.17639088057 0
%%DocumentProcessColors: Cyan Magenta Yellow Black
%AI5_FileFormat 14.0
%AI12_BuildNumber: 629
@@ -348,9 +348,9 @@ endstream
endobj
3170 0 obj
<>stream
-%AI24_ZStandard_Data(/ X.+
djIKY}!͕h$:AfWI6N*GyуM#ygXwh<T2N%K* jkt/%"=gf4}dɽ120P**LThP1@Hx`
&,fQ#0;͏~f\k`p]4`X)鹧$[uRw71EYۘeXėБUϡ@\葷S-%>@1<'=k ᰱ=氕%t%18 8z9'o\RVX[b/ҩQSKOF#l܍ӧ.I(vEt,qݎ*hqakyP>HJiUFǬh,Y㮻3QVd^s׳d4پne;N