• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Destroyed & recreated object not operated on properly when passed into function

Masstertron

Member
Hi folks!

I've come across a peculiar problem that I've been able to replicate in a simple test project, and I'm posting about it here to see if anyone else has had the issue, and discuss if it's a more serious issue I should post a bug report about.
Or maybe I'm a bone head and it's somehow expected behaviour!

When destroying, recreating, then passing an object index into a function, my operations on the object are not performed.
Here is the code I have where a white triangle is created when the room opens, and it turns red when you press spacebar.

In example 1, the triangle does not turn red, but in example 2 it does because I use instance_find() instead of trying to call the object index itself.
However, example 3 DOES work when I use the same technique as example 1, but I avoid the use of functions.

It's important to note that this issue only happens when there is no time in between the destruction and recreation of the object.
Also important to note is that I'm only ever expecting there to be one instance of Object2, so using the object index to perform changes on the instance is safe.

Not sure if I'm going crazy and I've done something silly.

Windows 10
IDE 2.3.3.574
Runtime 2.3.3.437
 

Attachments

Last edited:

Nidoking

Member
Keep in mind the lessons you should have learned about the difference between objects and instances. That is object dot variable syntax. You are creating and destroying instances of that object, so it's clearly not a singleton. Do not use object dot variable syntax with non-singleton objects. Just don't. instance_find gets you an instance ID, so it's safe to use. Otherwise, use a with.

Also important to note is that I'm only ever expecting there to be one instance of Object2, so using the object index to perform changes on the instance is safe.
This is a false statement. You are destroying the instance, resulting in zero instances of the object. Whether that's true at the time you try to reference it or not is irrelevant. There is a time when there is not exactly one instance of the object. It is unsafe.
 

Masstertron

Member
Thank you for the heads up, but I do already understand that. To quote the post you linked, " NEVER access a single instance by object ID if multiple instances of the object exist. " I've addressed that.

instance_number(Object2) returned 1, so that's not the issue.
 

Posh Indie

That Guy
Thank you for the heads up, but I do already understand that. To quote the post you linked, " NEVER access a single instance by object ID if multiple instances of the object exist. " I've addressed that.

instance_number(Object2) returned 1, so that's not the issue.
I think what @Nidoking is getting at is that you are calling instance_destroy() on an object (Which would be the Object ID). You want the Instance ID in this case, because the Instance ID is very... VERY... likely not the same as the Object ID (And if it was you would have bigger problems down the line because you would not know about the issue until it was too late).

For added clarity, instance_number() returns the number of instances of an object. The parameter in this case is correctly an object, so that does not prove anything about the issue at hand.
 

Nidoking

Member
To quote the post you linked, " NEVER access a single instance by object ID if multiple instances of the object exist. " I've addressed that.
To quote the post I made:

This is a false statement. You are destroying the instance, resulting in zero instances of the object. Whether that's true at the time you try to reference it or not is irrelevant. There is a time when there is not exactly one instance of the object. It is unsafe.
You have failed to address this. Specifically and explicitly. Your instances are not singletons because you create and destroy them. There is a time, between the destroy and the create, when there is not exactly one instance of that object, because there are zero instances of the object. Therefore, it is not the case that there is always, at all times during your game, exactly one instance of the object. Since that is not true, it is never safe to treat the object ID like an instance ID. Now, I obviously don't know exactly what goes on under the hood of the runner when it uses an object ID to look up instances, and if I did, I'm sure I wouldn't be allowed to tell you. But it's pretty well known that it isn't instantly responsive, and it's explicitly stated in the Manual that the results will depend between platforms, and probably on other undisclosed factors too. You're doing something you're not supposed to do and complaining when it doesn't work the way you want it to. You opened your thread with an advisory that you might be a bone head. I didn't want to have to agree with you on that point, but here we are.
 

Masstertron

Member
I never complained, I'm simply discussing.
The engine documentation states using object.variable = 1234 has unique behaviour on HTML. Is there further documentation on this that I've missed? I've tried to find more info but fell short. Thanks :)
 
There is a lot of information out there about the differences between instances and objects, as it is probably the thing that people new to GMS screw up the most often. An object is a blueprint that never exists in-game. An instance is a thing created from that object blueprint, which is the only thing that will ever exist in-game. Using an object index is generally a sure-fire way to wreck things unless you have a good understanding of what the difference is. Until you do, always use instance ID's (which can be found through a variety of ways).
 

Masstertron

Member
In the documentation:

----------
obj_ball.speed = 0;

With the above code you are setting the speed of an instance of "obj_ball". However if you have more than one instance of the given object in the room, then it will apply to ALL of them equally - unless you are using HTML5, in which case it will affect only one, but you have no way of knowing which one it will affect - so if you need to access all instances of an object, you should be using with(), as that is 100% cross platform compatible. In general, this format should only be used when you have a single instance of the object in the room, or (as you will see in the next part) when you have a specific instance ID.

You can also access a single instance of an object when there are multiple instances within the room using the unique instance name to tell GameMaker Studio 2 exactly which instance we wish to address. The instance name constant is the unique identifying constant that is given to each and every instance added to a room in your game. You can find this constant by double clicking on an instance in the room editor:
----------
 
Last edited:

chamaeleon

Member
After painstakingly writing the code from your screenshot (why do people find it easier to use screenshots instead of copy-paste text?) I can report I don't see any difference in behavior between the three cases using GMS IDE 2.3.4.580, Runtime 2.3.4.442, with Windows VM+YYC and HTML5 targets.
 

Nidoking

Member
In general, this format should only be used when you have a single instance of the object in the room
You don't have a single instance of the object in the room. You had one, then you destroyed it and made a new one. The new one is not identically the same instance as the old one. It is a new instance. It is a different instance. You have not moved to a new room. You are creating the second instance in the same room where the first instance was. There have been at least two instances of that object in the room. I don't understand how this can be any clearer. You are insisting on doing something that should not be done, and you have two other, correct ways to do exactly the same thing, and that doesn't include with (which the Manual page you quoted also tells you you should do), so I can't understand why that isn't enough for you. When the doctor says you should stop hitting your foot with that hammer, the correct course of action is not to contact the hammer manufacturer and insist that they make a hammer that does all the same things but doesn't hurt your foot when you hit your foot with it. You stop hitting your dang foot and go find some friends to sign your cast.
 

chmod777

Member
I think this is the same issue as in the following thread: https://forum.yoyogames.com/index.php?threads/not-sure-what-is-going-on.88345/
It shows that it's still possible to access a recently destroyed instance when using the dot notation with an object name on HTML5.


Code:
a = instance_create_depth(10, 10, 0, Object2);
instance_destroy(a);
show_message(Object2.x);
=> Shows "10" on HTML5, crashes on Windows ("Unable to find any instance for object index '0' name 'Object2'")

Code:
a = instance_create_depth(10, 10, 0, Object2);
b = instance_create_depth(20, 20, 0, Object2);
instance_destroy(a);
show_message(Object2.x);
=> Shows "10" on HTML5, "20" on Windows.

I've already reported the issue but it's not addressed yet. According to Roldy in the thread I mentioned, instance_find can be used as a workaround.
 

Masstertron

Member
Yeah instance_find is definitely the go to for now :) Interesting!
It's a super tricky little bug but no biggie.

I reported it to YYG and they confirmed the issue, and have logged it internally.
 
Top