Automatic code execution upon starting the game(see topic please as it isn't just using create or roomstart code)

kburkhart84

Firehammer Games
I wasn't sure of the best way to name this topic, so if you have an idea, I can change it(I think I can anyway).

In older versions before studio, you could have these things called extensions. They allowed you to actually run code just by having the extension in your project. In one case I was using that feature to automatically initialize a system and control objects for it instead of the user having to call a function to do that. Now, I don't know of any way to do that since GMS1/2. So anytime I have something like that, I'm forcing you to call an initialize function, which then creates the needed instances, etc... Of course you can put that function call in some controller object, etc... and it isn't that hard...but I liked it when you did not actually have to do that.

Is there anything that compares to that now? If not, by chance, since with 2.3 scripts are basically going to be code that runs right away, would that allow for something like creating an instance automatically instead of having to actually add a function call? Is there something that I'm simply missing that would make my dream possible? I'm basically wanting to have an instance of my controller object be created upon starting the game simply because the package is in the resource tree(which is how it was with the old style extensions).
 

kburkhart84

Firehammer Games
The gml_pragma wouldn't help for what I'm looking for because it actually happens before a room exists and so you can't use it to create an instance like I was wanting.

I DO see the extension Init Function which seems to be basically the same as the old style extensions....but what about if my system is all using code resources in the scripts folders instead of in an old style extension?
 

Homunculus

Member
You can create the extension in the resource tree, add a single init gml script, and include the extension in your asset package along with your other assets. When importing, simply including this extension resource as part of the imported assets, should call your init script at game start. No idea about the exact order of execution though, I suppose it's before any of the instance events.
 

kburkhart84

Firehammer Games
You can create the extension in the resource tree, add a single init gml script, and include the extension in your asset package along with your other assets. When importing, simply including this extension resource as part of the imported assets, should call your init script at game start. No idea about the exact order of execution though, I suppose it's before any of the instance events.
This is true, but feels like a hacky workaround. I feel like I'm better off just having the user call the script wherever they feel like it.

I DID ping Nocturne in the 2.3 beta announcement with this question because with the new GML have function declarations work like global ran code, I'm wondering if it couldn't also create an object instance in the first ran room.
 

Homunculus

Member
This is true, but feels like a hacky workaround. I feel like I'm better off just having the user call the script wherever they feel like it.

I DID ping Nocturne in the 2.3 beta announcement with this question because with the new GML have function declarations work like global ran code, I'm wondering if it couldn't also create an object instance in the first ran room.
My guess is that the stuff outside of function declarations will be the same as gml_pragma, but you never know... Other than the above, I don't know any other way to execute some code that is guaranteed to run before anything in the first game room. My policy is to let the user call the init script manually as well, after all, you should have an init routine for this kind of stuff right? :rolleyes:
 

Alice

Toolmaker of Bucuresti
Forum Staff
Moderator
Since there's all that buzz about GM:S 2.3, how about using the new syntax like this?
(NOTE: I have yet to actually try out if it works like this)

Code:
global.init_callbacks= ds_list_create();

function onRoomInit(callback) {
    ds_list_add(global.init_callbacks, callback);
}
Then elsewhere:
Code:
onRoomInit(function () {
    instance_create_depth(0, 0, 0, some_object);
    // do other initialization stuff
});
And then have a ctrl_Init object with this in Game Start:
Code:
for (var i = 0; i < ds_list_size(global.init_callbacks); i++) {
    script_execute(global.init_callbacks[| i]);
}
ds_list_destroy(global.init_callbacks);
It still requires the user to put ctrl_Init in the first room manually, but at least it's a single object, and the rest is handled automatically. If you had multiple extensions and included the onRoomInit and ctrl_Init definitions in each extension, then all the user would need to do is to place a single object to initialize all your extensions?

Or maybe even add a rm_Init resource which basically calls the logic I presented for ctrl_Init and then goes to the next room? Then, as long as user doesn't push rm_Init from the first position, it should work from the get-go... 🤔
 

Homunculus

Member
@Alice (see? i can get it right!) are we really allowed to pass anonymous functions lime that as arguments in 2.3?
The problem with the above though is that even the game start event is called after the create event of the other instances, which probably is part of the problem kburkhart is trying to address.
 

kburkhart84

Firehammer Games
My guess is that the stuff outside of function declarations will be the same as gml_pragma, but you never know... Other than the above, I don't know any other way to execute some code that is guaranteed to run before anything in the first game room. My policy is to let the user call the init script manually as well, after all, you should have an init routine for this kind of stuff right? :rolleyes:
LOL, of course I have an init routine in place for these things. The idea was just that for some things, the init is always the same and doesn't need any user defined parameters. My input system for example has to have parameters that define the input scheme for the game so it makes sense to let them do the initialization. But for my Easing system, though there is some initialization I'm doing, it isnt' something the user would make changes to and therefore could be something that is done without them doing it themselves.

Since there's all that buzz about GM:S 2.3, how about using the new syntax like this?
(NOTE: I have yet to actually try out if it works like this)

Code:
global.init_callbacks= ds_list_create();

function onRoomInit(callback) {
    ds_list_add(global.init_callbacks, callback);
}
Then elsewhere:
Code:
onRoomInit(function () {
    instance_create_depth(0, 0, 0, some_object);
    // do other initialization stuff
});
And then have a ctrl_Init object with this in Game Start:
Code:
for (var i = 0; i < ds_list_size(global.init_callbacks); i++) {
    script_execute(global.init_callbacks[| i]);
}
ds_list_destroy(global.init_callbacks);
It still requires the user to put ctrl_Init in the first room manually, but at least it's a single object, and the rest is handled automatically. If you had multiple extensions and included the onRoomInit and ctrl_Init definitions in each extension, then all the user would need to do is to place a single object to initialize all your extensions?

Or maybe even add a rm_Init resource which basically calls the logic I presented for ctrl_Init and then goes to the next room? Then, as long as user doesn't push rm_Init from the first position, it should work from the get-go... 🤔
The thing is that the users still have to either put an object themselves. I'm better off just letting them call an initialization function and then having that create the objects I need. They can then put that function call along with other ones they may have on some control object they likely have, in some intro room they likely already have. I was just trying to save a step like I did in the past when assets were generally passed around as extensions.

That said...if the extension system is really going to stay around, even with this new gml stuff, then I could just have a mini-gml script/function that calls my init in an extension. But I thought that they were soon deprecating it in favor of simply letting you include all the resource types in the asset packages. The extensions were good but you couldn't include things like objects. I remember I even used the old run-time compiler thing to make my objects themselves get created through code like you used to be able to do just to get around not being able to include them in extensions.

@Alice (see? i can get it right!) are we really allowed to pass anonymous functions lime that as arguments in 2.3?
The problem with the above though is that even the game start event is called after the create event of the other instances, which probably is part of the problem kburkhart is trying to address.
Yes, you will be able to pass functions around in variables just like you already can right now(see script_execute() for the usage of that). What I'm trying to get around is simply having the user of my assets have to call initialization functions or manually place objects in rooms. I'd like it to somehow happen automatically just by having my stuff in the resources in the first place. The only way it seems I will be able to do that is by having that extension in place that does it like your first suggestion(which is how I did it in previous versions too).
 

Homunculus

Member
You can definitely pass SOME functions around (definitely those with a global scope), but what about passing an anonymous function as an argument like that? Not sure... scoping of functions and variables in 2.3 is already causing me an headache, and it’s not even out yet...
 

kburkhart84

Firehammer Games
You can definitely pass SOME functions around (definitely those with a global scope), but what about passing an anonymous function as an argument like that? Not sure... scoping of functions and variables in 2.3 is already causing me an headache, and it’s not even out yet...
I'm not sure what the anonymous part is in this example. The init function would be passed into the global onRoomInit(callback) function. This function isn't being called right there where it is declared, rather later on . Since the system won't let you create instances in that global code(confirmed by Nocturne in the announcement topic), I'm wondering if it would indeed allow you to create global variables and data structures like that.
 

Homunculus

Member
I mean this part (sorry I know this isn’t strictly relatd to your question):

GML:
onRoomInit(function () { [...] });
 

kburkhart84

Firehammer Games
Gotcha...the reason that would theoretically work is similar to how you can do with(instance_create()){//do stuff} in that the value returned by instance create isn't stored in a variable, rather directly passed into the with construct. The function creation part there would be the same way. That whole function declaration in the new GML actually returns a variable which can be used to call the function, just that in this case that variable is being directly passed to the function onRoomInit() as an argument instead of being stored. In fact, there is a thing in the update description blog that says you could declare a function using
Code:
myFunctionVariable = function(){};
instead of
Code:
function myFunctionVariable(){};
 

Homunculus

Member
That’s true, but at the same time there’s also a parte in the Q&A that states that the last line of this script for example will NOT work.

GML:
// In a script
function foo() {
  return x;
}
// In obj_a's Create event
goo = foo;
// In obj_b
bar = obj_a.goo();
Let’s not extend this OT though, we’ll probably have our answers soon enough.
 

kburkhart84

Firehammer Games
One thing now....since we can put resources into whatever folders we want with version 2.3, I'm thinking it may not be that much of a deal to just have an extension that does this for me. I'm also considering using gml files or maybe an included file(if they are easy to modify externally) to support configurations, etc... for my input system instead of having to copy/paste strings into code.

So if I add an extension, it can be simply one more asset in the system's folder, instead of adding more branches to the tree of the resource folder like it was before.
 

kburkhart84

Firehammer Games
New info, new post instead of editting.

I found out that the init function of extensions is ALSO ran at the same time with global script execution, and therefore you cannot create an instance there either. This is something that changed, likely when GMS1 came out, as I know it used to be able to add instances.

That said, someone(Devon Mullane) in the beta forum mentioned a workaround that I'm surprised I didn't think of myself. In some script, I can put a call to the room_instance_add() function. This will add an object to the first room of the game. It wont' be on a layer or anything like that, but I could add code to the create event if I cared about anything like that. And if the user changes the room order later, this trick is proof against that. It won't protect if the user does something like destroying all instances or deactivating them...but its on them if they destroy everything...and I already have a function that makes it easy to re-activate the system's objects if the user wants to do de-activation on everything without worrying about the system's objects.
 
Top