GML What solutions do you have to sort instance creation order (initialize vars in create) for instances placed in room editor? - 6 solutions so far :)

MartinK12

Member
I know how creation/execution order works in GMS, at least I think so ;)
I’m looking for how to create my own solutions to sorting - the problem is with creation code of instances placed in the room and dependent on each other variables - for example obj_tree need to setup in its create event its color bases on obj_wall below him but in room editor first we place obj_tree, then obj_wall so obj_tree variables are setup before obj_wall variables.
I don't have problems with sorting instanced I created through code during gameplay but those that I need to place in room editor - just requires more testing ;) Also I'm looking for the optimal solution - performance and to work with.

SOLUTION 1 - DEFAULT GMS - instance variables are initialized in the order based on instance creation order list
pros: this is easy for very small projects
cons: manual labor moving instances on this list up and down so it's worst solution ever ;)

SOLUTION 2 - STEP EVENT - put variables dependent on other objects variables to step event and place all instances on specific layers so obj_wall instances with their variables are always initialized first (have higher depth layer, ie. 100) and obj_tree instances with their variables after that (have lower depth layer, ie -100).
pros: it's working like a charm ;)
cons: code runs once but if check still take unnecessary processing power every step for possible several hundreds instances, but it’s easiest and best one I got so far.
Example code:
GML:
//code in obj_tree - create:
set_variables = true;

//example code in obj_tree step event:
if (set_variables) {
    set_variables = false; //so every other game frame this is false but still takes processing power

    wall_below_us = instance_place(x, y+1, obj_wall);
    if (wall_below_us) {
        my_color = wall_below_us.my_color;
    } else {
        my_color = c_white; //default color
    }
}
SOLUTION 3 - COLLISION CHECK WORKS - I'm surprise that this solution works but looks like when game starts all instances are already placed in room so we can check all their ids through collisions with each other in create event?! But their variables are not initialized yet! So we ignore their variables and in create event we can check for instances id and we can set our variables based on instance id and object_index.
pros: this code runs only once in create event
cons: uses strings to compare, suitable only for some situations (we must know all variable values that object can have), also I’m surprise that it works, will it always work?
Example code:
GML:
//example code in obj_tree - create:
wall_below_us = instance_place(x, y + 1, obj_wall);
if (wall_bellow_us) {
    obj_name = object_get_name(wall_below_us.object_index);
 
    if (obj_name = “obj_grass”) {
        my_color = c_green; //just switch for all possible object names
    } else {
        my_color = c_white; //default color
    }
}
What do you think about above solutions, do you see any possible bugs with them, can you explain why solution 3 works, and what other solutions are there for initializing variables in create event that depend on other objects variables?
Thank You :)
 
Last edited:

vdweller

Member
Instead of putting the if check in every o ject step eventin Solution 2 have a controller object run it its own step event only once, with only one if check (negligible) for all involved objects.
 
Another solution instead of the step event is to set an alarm to 1 and read the variables that need to be read in the alarm event instead of the create event. This gives every instance a frame to create their variables before those variables start getting read.
 
H

Homunculus

Guest
I generally use alarm events like RefresherTowel suggested, or use other events when applicable like room start, which happens after the create event.
It really depends on the specific project, sometimes you can even get away with a controller object iterating over the instances and running an initialization routine, splitting the init into two:

1. Setup basic independent data in create
2. Run all other checks and assignments from a controller by executing a user event for all affected instances.
 
Last edited by a moderator:

samspade

Member
Depending upon what you're doing you can use the room start event. All instances run all their create code (object variables, create event, and creation code) before any instance runs the room start event.

See: https://docs2.yoyogames.com/source/_build/2_interface/1_editors/events/index.html

Note that even though the manual says Object Variables / Instance Variables are initialised prior to create events, this appears to be true after some testing only at the instance level (in other words it seems that an instance runs its creation code in the order of object variable, create event, creation code) as I had a project where the create event relied on object variables in another object and the game would crash depending on create order.
 

kburkhart84

Firehammer Games
The alarm solution is not a bad way to handle it.

I should also mention, to make code easier to read if you were doing step 2, instead of putting all the step event in the if statement....
Code:
if(variables_set)
{
//all the code
}
You can do the following instead.
Code:
if(!variables_set)
    exit;
//all the code
This trick doesn't save you the if statement(like the alarm method does)...but both for solution 2 and for other similar situations, this can make your code easier to understand, using the "early out" exit statement. I use it for functions as well, if I have code that should stop the rest of the function from even running, I just return right then, instead of putting everything in the if statement brackets. It feels neater to me that way too.
 
Last edited:
H

Homunculus

Guest
@kburkhart84 I guess you mean exit; and not break;, but I agree, it's definitely more readable like this, I tend to use it as well when it makes sense.
 
S

Sybok

Guest
If I’m understanding the question correctly (which I’m not sure if I am admittedly), I’d create the instances manually in an objects create event.

This is actually what I do in practice with all of my projects anyway. It sometimes becomes a spaghetti nightmare doing it in the room editor. At least in code, I know exactly where I stand.
 
Top