The difference between instance ids and indexes

Indexes
Whenever you add a new resource (sprites, sounds, fonts, objects, etc) into your game, the resource is given a new value associated with it called an index. These index values start from 0 for each particular resource and increase by 1 subsequently. (And note if you delete a resource a newly created one is not given the first available index value but instead the index just keeps increasing.) Whenever you give a resource a name, GameMaker automatically creates a variable with the same name and assigns it a value corresponding to the resource index. So when you use something like:

instance_create(x, y, obj_player1);

obj_player1 is actually just a variable equal to the corresponding object index value. For example if obj_player1 is the first object you have created (thus giving it an index of 0) what GameMaker will actually be reading is just:

instance_create(x, y, 0);

It is a common misconception that you can create an object using a string like so:

instance_create(x, y, "obj_player1");

This however can not be done because GameMaker creates the object from an index number not a string! Quite commonly you may actually wish do create objects from a string though (like when wanting to create objects such as obj_player+i, where i is the number of the player you wish to create), however to do this you should instead do something like set up an array. For example:

player[1] = obj_player1; player[2] = obj_player2; player[3] = obj_player3; ..etc

Then to create the objects you can use:

instance_create(x, y, player[i]);

I will also note the variable object_index which can be called, this gets the index value corresponding to the object it is called within .The function is different, this gets the name of the object as a string, as said previously this cannot be used to create an object it's just be used for something like drawing the name of an object.

If you wish to be able to call any object from it's name there are ways of doing so by mapping the objects to there names (note ds_maps require the Standard version of GameMaker). For example:

objs_map = ds_map_create; ds_map_add(objs_map, "obj_player1", obj_player1); ds_map_add(objs_map, "obj_player2", obj_player2); ds_map_add(objs_map, "obj_player3", obj_player3); ds_map_add(objs_map, "obj_enemy1", obj_enemy1); ..etc

Once you have set up this ds_map you can call upon an object index using. For example if you want to create obj_player2 from the string "obj_player2" so can use:

var obj; obj = ds_map_find_value(obj_maps, "obj_player2"); if (object_exists(obj)) { instance_create(x, y, obj); }

Instances
Unlike indexes, instances apply only to objects not to any other resources. From the manual: "An object describes a certain entity, e.g. a monster. There can be multiple instances of this object in the game. When we talk about an instance we mean one particular instance of the object. When we talk about an object we mean all the instances of this object."

This means that in rooms only instances are actually used, never objects. You can think of objects more like a template, you add events and actions to them, then when you create from an object (either in game or by adding one in a room) GameMaker creates an instance based on that object template. Once the instance is created though it will behave completely separately to all other instances of the same object created. Obviously though instances of the same object will naturally behave similar since they will be given the same events and actions from the object template.

Now although all instances behave separately you can still refer all instances of an object, by calling the object index. For example in a with statement by using:

with (obj_monster) {  x = 10; }

GameMaker loops through upon every instance of obj_monster and applies the action to all of then. So using this code will set x equal to 10 for every individual instance of obj_monster. Another example is in collisions where if you use the object index it will check for collisions with every instance of the object. But, as said instances all actually behave separately so you can also call upon them all separately. This is where ids come in.

Id's
Whenever you create an instance of an object it is given a unique id number, this number starts 100001 and works exactly the same as resource indexes do, increasing every time an instance is added to a room or created in the game (and again id's do not fill in gaps when an instance is deleted). You can see the particular id of an object added in a room by hovering the mouse over it (it will say at the bottom-right of the window), so if this id shows 100001 for example you can then control the instance by using:

with (100001) {  x = 10; }

This will set x = 10 only for that particular instance and the rest of the instances in the game will not be affected. Code like this though is uncommon to use, more often that not you want to be applying code to created instances rather than instances that start in the room. To do this you need to know that when you use the function returns the id value of the instance it just created, so if you store this id you will be able to control the created instance individually. For example:

obj = instance_create(x, y, obj_enemy);

The instance_create function will return the id of the enemy it creates, this id value will then be assigned to the variable obj. So now you can control this instance by calling upon the variable obj. For example:

obj = instance_create(x, y, obj_enemy); obj.x = 10;

This will create an instance of obj_enemy and then set this instance's x value to 10. This technique can be highly useful for controlling your game, by instantly calling upon a created instance like in the example above it is effectively the same as using the creation event of the object. A common use of this is when creating bullets, for example you could use this code:

var bullet; bullet = instance_create(x, y, obj_bullet); bullet.direction = direction;

This will then set the direction of the created bullet instance to the same direction as the instance (like a player or enemy) shooting it, straight after it is created.

I will also mention at this point the instance creation code. This can be found by holding down ctrl and right clicking on an instance in a room then clicking on the bottom option. If you put any code in here it is like the creation code just for that particular instance. Using the instance creation code has it's disadvantages though; it is rather fiddly, not flexible, you can easily forget about code you put there and when posting an example most people don't think to look there for code also error messages do not display properly for the code used.

If you need to define the creation event of an instance put into a room, another way is to create the instances from a controller object instead of placing them in a room. By doing this you can then take advantage of having the instance id returned by the instance_create function. The downside of doing this perhaps though is that it can make level design more difficult to manage.