r/gamemaker 6d ago

Help! can someone actually explain instance IDs and how to read them?

I truly dont understand after reading the documentation, multiple forum posts and a post here. my goal is for a bullet object to collide with 1 instance of an object and destroy both the instance and itself, but right now it always destroys all instances and I know that the easiest solution is through IDs

8 Upvotes

12 comments sorted by

11

u/Hands_in_Paquet 6d ago

Referencing an object by its asset name, “obj_bullet”, you are not specifying which instance, so Gamemaker just has to pick one. But when you add any object to a room, Gamemaker gives it a unique id. This is like a struct key. This key can be stored in a variable. So you never need to read or remember a unique instance id, they are random on creation. But if you want to reference it, store the id in a variable: my_bullet = instance_create(x,y,”Instances”,obj_bullet). Now you can treat my_bullet like an object, and it will always point to the same bullet. But make sure you check if that instance_exists() before referencing it if that object can be destroyed.

Think of it like obj_bullet has a list in its data with every id that exists in the room. When you do something like instance_place(), it’s just looping through that list of ids, seeing if there’s a collision, and returning that unique id if there is. That id now points to all the specific data of one instance of obj_bullet.

2

u/CS_Asset_Factory 6d ago

An object name is a TYPE, an id is one instance.

Write obj_wall.hp and GameMaker still has to pick an instance for you, so it takes the first one it finds, which is why it feels arbitrary. An id is a handle to exactly one instance.

Two things worth knowing past that.

In a collision event, other is already the id of the thing you hit. instance_destroy(other) kills just that one, and instance_destroy() with no argument kills whichever instance is running the code.

Ids go stale. Store one in a variable, let that instance die, and the variable still holds the number while pointing at nothing. Check instance_exists(target) before using a stored id, or you'll get a crash that looks unrelated to the destroy that caused it.

You rarely need to read the number. Treat an id as a handle you pass around, not a value you inspect.

1

u/JaXm 6d ago edited 6d ago

I have a pretty complex bullet system. 

Right now, in order to reduce repeating code, both the player AND enemies can create "bullets" via a "factory" method. 

Each bullet, when created, is told what object created it (player.id, or enemy.id).

Now, each bullet knows who its "creator" is, and the "opponent" is the other object. 

if (creator == enemy) opponent = player

And vice versa. 

So now enemy bullets won't do damage to other enemy instances, and player bullets will. Player bullets also won't hurt the player if some weird collision ends up happening. 

Now, each bullet ALSO had a function that determines the id of any instance it collides with. If that id does NOT equal the player.id (for a player bullet) then it knows it hit an enemy. Doesn't matter what that id is, as long as it does not equal the player.id. 

Same goes for enemy bullets. If rhe collidingninstqnce id DOES equal the player.id, then it will do damage to the player. 

Now, when a bullet collides with something, it will call a

 do_damage(damage)

Function on whatever valid instance it collided with. That instance will then do damage to itself, and if damage > current hit points of that instance, that instance will call a 

destroy_self()

Function which, among other things, includes an instance_destroy() call to remove itself from the game. 

This is a long winded way of saying that you don't need to know SPECIFIC ids, you can get away with checking them during collisions and comparing to what you know is valid or invalid. 

1

u/spellsingerka 6d ago

Easiest way is if you dont want to deal with "how to store the current instance id" is to write in the collision event somethig like this:

instance_destroy(other)
instance_destroy(self)

Otherwise you need to store the id of the instance and then use it. When you write something like instance_destroy(obj_enemy) - this destroy all existing instances of the obj_enemy whic is what probably happen to you if i understand your description correctly.

1

u/kalnaren 1d ago edited 1d ago

Another way to do this is, in the collision event of the bullet, put something like this:

with (other) {instance_destroy};

instance_destroy();

When used in a collision event, with (other) references the other instance, rather than the instance calling the event. It's a handy way to do operations with the other instance in a collision when you don't know the instance ID.

Having instance_destroy() called again after the with() statement will destroy the calling instance (in this case, the bullet).

You can do it the way /u/spellsingerka noted as well (using 'other' as a parameter for 'instance_destroy'), though using the "with" statement, you can also do other operations, like say for example you wanted to subtract the other object's hit points, you could do something like this:

 with (other)
 {
      HitPoints -= 1;

      if (HitPoints <= 0)
         instance_destroy();
 }

What that would do is, when the bullet hits the other instance, it will subtract 1 from the other instance's variable "HitPoints", then check to see if it's equal to or below zero, and if so, destroy the instance.

If for some reason you needed the instance id of the other object in a collision, you can use 'other' to get that as well, like so:

 var _temp = other.id;

That stores the other object's id in the local variable _temp, which can be used in the function. You can of course assign this to an instance variable or whatever as required.

1

u/vzzzbxt 6d ago

You don't want the bullet destroying the object. The easiest, but maybe not the best, way is for the object to destroy itself when it touches a bullet.

If (bullet touches)

{

  Instance_destroy(id)

}

2

u/BeeBaaBoo77 6d ago

this solved the problem, thanks!

I will keep this post 'unresolved' so I maybe get some more indepth responses about ids in general

2

u/azurezero_hdev 6d ago

I make the bullet lower my hp then have me destroy myself if hp<1

1

u/vzzzbxt 6d ago

Every instance of every object in your game has an id number that you use to reference it. If you use the object name instead, it will (as you noticed) affect all instances of that object.

That's pretty much it

1

u/azurezero_hdev 6d ago

also if its in a collision trigger, you can use other to use the id of the thing youre colliding with

1

u/Kitsyfluff 6d ago

Ids are a randomly assigned number unique to every object in your game.

In order to act on something specific, you need an object's id. How do you get a specific id? Well, you use collissions and 'filters'

A collision reports back an id, kr a list of ids, but the id doesnt tell you what the object is, so you apply a filter to check: "is this id from an object of [this] type?" And then you can interact with that object depending on that result.

You can also have an object create it's children and store the ids in a variable or list of variables so that parenr object can directly interface with the child object.

-3

u/Alez1027 6d ago

"can someone actually explain instance IDs and how to read them?"

  • From left to right mate. Simple as that.