GameMaker: Passing variables into Create event

Time to time I see questions being asked about whether it's possible to set variables prior to instance' Create event being executed or otherwise passing values into the freshly created instance.

Most often, people will say that, no, you can't do that, but here's a bunch of strange workarounds instead (executing in alarm event \ moving all Create code into a user event).

Now, as you might be suspecting by the title of the post, that is not quite correct - there's a bunch of substantially more valid methods of approaching the problem. This post covers them.

A straightforward method

The simplest approach to having some variables accessible in an instance' Create event is to store them somewhere where you can easily find them - in global variables, for example:

global.player_index = 1;
instance_create(x, y, obj_player);

And in the Create event you would have:

index = global.player_index;

Now, this requires you to not forget about setting variables prior to creating instances (at best you could assign undefined into the variable once done), but otherwise it's a perfectly good solution.

An organized method

What many people seem to want is passing arguments into a Create event.

And it would seem like you can't do that... or can you? Well, perhaps not the actual argument array, but there is nothing that stops you from making your own.

So you would make a macro with name like ct_argument and value being global.g_ct_argument, making it a "shortcut" to a global variable. And perhaps a ct_count with value being global.g_ct_count for convenience.

Then, you would make a variable-argument-count variant of instance_create script that would store the "excess" arguments in that global variable (and their quantity in other global variable):

/// instance_create_v(x, y, object, ...args)
var n = argument_count - 3;
ct_argument = undefined;
ct_count = n;
for (var i = 0; i < n; i++) ct_argument[i] = argument[3 + i];
var r = instance_create(argument[0], argument[1], argument[2]);
ct_argument = undefined;
ct_count = undefined;
return r;

In Create event, you would read the now-assigned variable,

index = ct_argument[0];

Permitting you to do

instance_create_v(x, y, obj_player, 1);

Which, I believe, is the best approach - you get timely error messages about forgotten arguments, you can have optional arguments, and you can even make some "wrapper" scripts for having argument name tooltips for cases that need it.

A delightful hack

And, let me close this post with something that you probably never considered for the mere fact of it looking like something you are not supposed to be doing.

Little known fact, but the way GameMaker stores object' instances in memory isn't like things usually work in stronger-typed programming languages - while it would appear like it has conventional inheritance system and instances belong to their corresponding object, internally a reference to the object' "type" is stored in an instance (and used in event lookups), meaning that no instance is actually "hard-linked" to an object type, and allowing a little function called instance_change to exist.

instance_change changes the executing instance' object on fly, at exact moment of execution. Any existing instance' variables are (conveniently) preserved, and you are also (again, conveniently) offered an option to execute the old object type's Destroy event and new object type's Create event during the change.

So the trick is simple enough - first, you add a special empty object, such as obj_blank. This object wouldn't have a parent, sprite, events, or anything else to it.

Then, you would structure your calls as following:

with (instance_create(x, y, obj_blank)) {
    index = 1;
    instance_change(obj_player, true);
}

Creating a blank instance, assigning variables to it, and only then changing it to the actual object, executing it's Create event.

And then you could do

show_debug_message(index);

in obj_player' Create event, and that would actually work.

One particular disadvantage of such approach would be that you would have to re-assign sprite_index/mask_index/physics properties explicitly, though that can be automated with a script.

In conclusion

Overall, while a purpose-specific thing, there are a plenty of valid ways to solve the problem.

Have fun!

Related posts:

3 thoughts on “GameMaker: Passing variables into Create event

  1. I do the Organized Method. And with GM2 you can now add helper comments at the top so that when you call it you can see what arguments to pass in.

  2. I’ve done it with instance_copy() and then instance_change()
    So you can clone yourself with all your variables, and then change it to whatever you need.
    Usually, I just save the created objects id and then use with () to pass down whatever variables I need.

  3. I use a script function and pass the variables into that…

    CreateHero(100, 200, 300);

    var ins = instance_create(argument0, argument1, hero_obj);
    ins.hp = argument2;

Leave a Reply

Your email address will not be published. Required fields are marked *