GameMaker: Finding resources by name

Once in a while you might want to get a resource index out of it's string name, like so:

instance_create(x, y, 'obj_item' + string(irandom_range(1, 3)));

But, resource indexes aren't strings, so that wouldn't work.

You could add indexes into an array, or have a little switch-statement, but take a bit to set up.

So let's see what else you can do about this,

GameMaker ≤ 8.1

In old versions of GameMaker many would find it tempting to straight up use execute_string:

execute_string('instance_create(x, y, obj_item' + string(irandom_range(1, 3)) + ');');
// [PLEASE DON'T]

However, this was pretty slow, as your game has to re-compile that expression every time it's ran.

A better way is to build a ds_map. So, on game start you would do, for instance,

var i, n, m;
n = object_add(); // now holds max object index
object_delete(n);
m = ds_map_create();
for (i = 0; i < n; i += 1) {
    if (object_exists(i)) ds_map_add(m, object_get_name(i), i);
}
global.object_map = m;

and then have a script called object_find, which would do

/// object_find(name)
if (ds_map_exists(global.object_map, argument0)) {
    return ds_map_find_value(global.object_map, argument0);
} else return -1;

and then you could use it like so:

instance_create(x, y, object_find('obj_item' + string(irandom_range(1, 3))));

you can also download the example with a bunch of these pre-made:

Download GMK

GameMaker ≥ Studio

GameMaker: Studio introduced a function called asset_get_index which does exactly this thing,

instance_create(x, y, asset_get_index('obj_item' + string(irandom_range(1, 3))));

If you want to do this kind of thing a lot, you can still build a ds_map, but this is done slightly differently as now there are no longer functions for dynamically creating some of the resource types, and also resource indexes are warranted to not have "holes" in them,

var m = ds_map_create();
for (var i = 0; object_exists(i); i += 1) {
    m[?object_get_name(i)] = i;
}
global.object_map = m;

and have your object_find be like so:

/// object_find(name)
var q = global.object_map[?argument0];
if (q == undefined) return -1; else return q;

Related posts:

2 thoughts on “GameMaker: Finding resources by name

  1. I agree, I’ve used ds_map for this as well as referencing objects via name, etc.

    The yoyo wiki actually has some useful example on ds_map(s) if I remember correctly.

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.