GameMaker: getting the arguments-array

This is a small post on how to conveniently and optimally pack an arbitrary number of incoming script arguments into an array.

Background

GameMaker allows variable argument count through the built-in arguments array. However, it's not exactly an array - you cannot use any array functions on it, and you cannot get a reference to it either - not too unlike JavaScript's arguments, really.

So you usually end up making a real array and copying the contents to it if you need to:

var args = array_create(argument_count);
for (var i = 0; i < argument_count; i++) args[i] = argument[i];

And that's a bit of an overhead for something that you might need often.

Obviously, we can do better.

The code

GameMaker has C-style macros. That is, the macro's contents will be inserted at place of it's use during parsing, meaning that you can do all sorts of wacky stuff with them. However, for some reason, GML macros very specifically are not allowed to access argument[] array, so we'll have to get a bit creative:

#macro argument_array __argument_array
#macro argument_index __argument_index
#macro argument_make_array var __argument_array = array_create(argument_count); for (var __argument_index = 0; __argument_index < argument_count; __argument_index++) __argument_array[__argument_index]

(in GMS1 you'd add each of these using the macro editor instead)

and then you could use it like

/// scr_test(...values)
argument_make_array = argument[argument_index];
show_debug_message(argument_array); // {{1,2,3}} if doing scr_test(1,2,3)

As this probably made absolutely no sense, let's break this down a bit:

The first two macros set up alias for future local variables so that we get auto-completion for them and so that GM code editor doesn't highlight them as instance variables for fact of being unaware of macro expansion.

Then, the slightly longer macro combines declaration of these variables with a loop to fill out the array, stopping just before we'd assign a value to the next array item:

// <macro starts>
var __argument_array = array_create(argument_count);
for (var __argument_index = 0; __argument_index < argument_count; __argument_index++)
    __argument_array[__argument_index]
    // <macro ends>
    = argument[__argument_index];
show_debug_message(__argument_array);

Thus, this way we produce a direct equivalent of the best-case code, except pretty much all of it is contained within a macro.

And, since this results in conventional macroname = value, the code editor will not be confused about unusual syntax.

That's about it, really. Have fun!

Related posts:

5 thoughts on “GameMaker: getting the arguments-array

  1. The pain that afflicted me for a long time was relieved at once. Thank you so much for your generosity to share your knowledge.

  2. Awesome stuff a bit annoying that the macros have the limitations with the argument keyword, but it’s definitely a lot better than the overhead mentioned in your article.

    • The end result is exactly the same – I meant in the sense of having to type that out / copy from somewhere / paste from snippets (if you use those)

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.