• 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!

SOLVED Using functions in switch statements?

Wonsubon

Member
Is it possible to use functions in a switch statement? I have an object that, when destroyed, will destroy another object with it, but there are multiple security camera objects and only one can exist at a time.

GML:
if(instance_exists(obj_camera01)) instance_destroy();
if(instance_exists(obj_camera02)) instance_destroy();
if(instance_exists(obj_camera03)) instance_destroy();
Etc
I want to make this code more efficient with a switch statement, however I can't seem to find a way to do it with what I've tried:

GML:
switch(instance_exists) {
    case obj_camera_01:
        instance_destroy(obj_camera_01);
        break;
}
and
GML:
switch(instance_exists()) {
    case obj_camera_01:
        instance_destroy(obj_camera_01);
        break;
}
Help and advice would be greatly appreciated.
 

Simon Gust

Member
You can't do that, not in this way.
But, since you've presumably named your cameras in sequence 01, 02, 03, 04 and so on, you can maybe use a loop and then construct the object names via text.
GML:
for (var n = 1; n <= AMOUNT_OF_CAMERA_OBJECTS; n++)
{
    var txt = "obj_camera_" + string(n);
    var cam_id = asset_get_index(txt);
    if (instance_exists(cam_id)) {
        instance_destroy(cam_id);
    }
}
Now, to make this as easy as possible, it's best to remove every unnecessary numbers in the camera names. like obj_camera_01 to obj_camera_1 and so on.
 

kburkhart84

Firehammer Games
That simply is not going to work. The contents of the switch statement have to be a constant.

That said, in this specific case, if obj_camera_01 is the object name(not a variable storing an instance id), then you can do just put the object name in a with statement and call instance_destroy(with empty arguments) inside that. If there are no instances of that object, the with will do nothing, and if there are, they will all destroy themselves.

With other functions, it depends on what you are doing. You may just have to have some if statements to handle it.
 

Neptune

Member
GML:
for (var n = obj_camera0; n <= object_camera13; n++)
{
    with(n) {instance_destroy();} //accepts object index or instance ID destroys instances if they exist
}
Better yet, parent the camera objects, and then:
GML:
with(obj_camera_parent) {instance_destroy();}
The 'with' clause will run its contents for each instance, if given an object index.
Or run its contents for a single instance, if given an instance ID.
 
Last edited:

Gamebot

Member
Are you planning on switching cameras or just destroying them all at once? If switching I would just have something like:

GML:
global.cam = 0;
Then in the whatever code triggers them ( keypress, collision, timer...) you can use @Neptune idea except destroy all EXCEPT that camera.

GML:
var i;

for ( i = 0; i < totalcameras ; i++) {
  if ( global.cam != i ) { 
  instance_destroy(); 
 }
}
Then again, I would probably have one object that I could loop through like this:

GML:
var i;

for ( i = 0; i < totalcameras ; i++) {
  if ( global.cam != i ) { 
  view_visible[i] = false; 
 }
else {view_visible[i] = true}
}
 

TheouAegis

Member
GML:
for (var n = obj_camera0; n <= object_camera13; n++)
{
    with(n) {instance_destroy();} //accepts object index or instance ID destroys instances if they exist
}
That doesn't work in the newest version anymore. As long as he's still using 1.4 or 2.2, that works fine. I told them in a feedback that their new resource handling sucks and needs more work, but they just shrugged it off.
 

kburkhart84

Firehammer Games
I'm guessing it is the loop that doesn't work, because it relies on AFAIK undocumented (although largely consistent) behavior.
Indeed...the loop was never consistent because it depending on the object names being in numbered order(all names resolve in integers). I'm guessing in 2.3, since you can move things around in the asset browser, the names are no longer consistently ordered(which was undocumented anyway).

However, with(object_index) should still work, and should still hit all the instances of that object as usual. If it doesn't, there is a bug I haven't ran into yet.
 

Neptune

Member
Ok I see, I wouldnt even do the 'for loop' portion of my example personally xD

I reeeally wish when you created an asset in the tree, it would be given an ID, regardless of how it is shuffled around... And maybe you could manually see & edit the ID I guess.
 
Last edited:

TheouAegis

Member
So here's the thing, and I'll even clarify what my qualms are with the redesign:

In gm8, resources were indexed by creation order alone. It didn't matter what name you gave them or where they were positioned and the resource tree. When you created a new resource, you knew immediately what its index was, because it was slapped onto the end of the resource name every time. If you wanted to actually organize your resources not just by name but by index as well, you just needed to rearrange the order of the resource tree, export the resource tree to a gmres file, create a new project, and then import that file into it.

In Studio 1.4 and 2.2, resource indexes were never assigned by the IDE, they were only assigned when the project was compiled. I mean, yes it did to an extent, since when you created a new resource it slapped a sequential index on to the end of the resource name, but the resource's actual index doesn't get assigned until the project is compiled. This means any changes you make to ordering in the resource tree will modify the indexes in the compiled project. If you put all the resources in order before you compile it, their indexes will be in that order. GMS1.4 indexed based on the gmx file, while GMS2.2 indexed based on the "views" subdirectory.

In 2.3 (as of 174), they decided to do a complete overhaul of the resource tree. The "Asset Browser" requires so much more effort to work with than the resource trees ever did (even GM8) and it makes hardly any sense. They actually had internal organization in every version up until now, then they just said "screw it" and chucked it all in the trash. I don't-- I just don't know. I tried to write up a breakdown of how resource indexing was handled in GMS2.3 and... I couldn't. It makes no sense whatsoever to me. Don't get me wrong, I know how to make
Code:
for(var i=object0; i<=object9; i++)
work in spite of GMS2.3's mess, but how it's even generating this mess is beyond me.

So in the asset browser, resources are organized alphabetically within each group. The ordering in the asset browser has absolutely nothing to do with indexing. Each object is assigned a hidden status flag "order", which is presumably the order in which they were created, but it does nothing and it's particular to 2.3 only. This also has absolutely nothing to do with indexing. You could create the same series of files over and over and get a different set of indexes each time. Just to give an example, I created three objects: Object1, Object2, Object3. The first time, they were indexed 0, 1, 2 (why the f*** they named them starting from 1 is beyond me). Then I deleted the files. I created them again. They got the exact same names, but this time they were indexed 1,2,0, meaning Object3 came before Object1. I then renamed Object1 to Zetaman. This doesn't change anything, as I said. I then created a new object by right-clicking on Zetaman and choosing Create Object. I immediately named this new object Pisspot. So my asset browser now showed Object2, Object3, Pisspot, Zetaman and they were now indexed 3,0,2,1. I deleted Pisspot and created it again. This second time around, the indexes were 3,1,0,2, meaning Pisspot now came before Object3. I repeated the experiment and Pisspot was back to being placed after Zetaman.

I had many hypotheses about how to manipulate the indexing. I considered which resource you right-clicked on would determine the index. I considered if using the generic Create> context menu affected indexes. I considered of course alphabetization. I considered whether or not you pressed enter after changing the name of a resource. I even went so far as to clear the asset cache, clear the temp forlder, and clear the IDE cache -- none of which seemed to have any effect (I'd clear all caches, create an object, delete it, clear all caches again, create an object, and the index would be different). I threw my hands up in the air, laughed, worried my cat, then gave up after trying to wrap my head around this for over an hour.

....
Then I realized the ordering is based on (or seemingly based on) the yyp file, which in and of itself makes no sense to me. Whatever order each type of resource is listed in the yyp file is the order in which their indexes will be assigned. My rant above actually applies to the yyp file. It makes no sense to me at all how it's written. Resources are written to the beginning of the file, but I don't know what determines the order in which they're written, so there's clearly some data structure somewhere dictating it.

So yes, you can still manually edit resource indexes in 2.3, but it's an even bigger pain in the butt than GM8 since you now have to completely go outside the IDE. And unless your naming conventions are super strict, you'll have no way of reminding yourself via the asset browser what order the resources are actually indexed because everything's alphabetized in the IDE. On top of all that, there's no guarantee the IDE won't just insert the next resource your create smack in the middle of your manually indexed resources, throwing the whole thing off yet again (I mean, creating resources outside of groups might prevent that from happening, but I didn't test it). For now, none of that matters since this is the beta, but they love just saying "it's undocumented" so they can pretend like it's not a glitch they need to fix, so I predict indexing will be gimped from here on out.

Additional "fun facts" about messing with objects in the YYP file
Deleting a resource's reference in the YYP will not affect the resource folder data -- not sure if this causes any bugs or garbage.
The "order" flag is so useless: Two objects can have the same value by default, since "order" appears to be based on which group the resource is created in. Creating an object outside the groups assigns it an "order" value relative to the number of groups (e.g., creating one outside the default groups assigns a value of 15). Moving a resource to another group doesn't change its "order" value unless you rename it after moving it (e.g., moving said 15 into a group keeps it 15 until naming it, then its "order" becomes however many resources are in that group).
 
Last edited:

Neptune

Member
Interesting. It doesn't make sense to me why you cannot drag asset tree elements around, rename, and create sub folders while ALSO having unchanging indexes...

For saving, the tree organization should have nothing to do with the indexes, otherwise you cannot even save something as simple as a sprite index. You have to create your own whole internal save-able resource pointer system.
 

kburkhart84

Firehammer Games
The thing is though...the object indices numbering has ALWAYS as far as I know been a thing that you were never supposed to use for anything in the first place. Any usage you got out of it in the past was always based on undefined behavior, so the fact that they change it now shouldn't have anybody upset because we were all told never to count on it in the first place.

Also, the asset browser is still much better now than before. You can choose the alphabetical order as an option, not a requirement(in other words you can literally order exactly how you want to). And now, I can put all things related to a certain thing in one place instead of having to look in folders all over the tree. I can put a single boss's graphics, sounds, objects, etc... all in a single folder, instead of being forced to have sprites in one place, sounds in another, objects in yet another... I can have a folder for generic enemies....and then another folder with level structure, which includes graphics specific to that level, enemies for that level(if they are unique), etc... Basically, I can organize however the hell I want to. And better yet, if I really liked the old way, I could do that too!
 

kburkhart84

Firehammer Games
Oh, so you CAN organize and have permanent asset IDs?? Well thats exactly what is needed :)
I don't know if the asset IDs will change... that is the reason why you use the object name in code to access them. Anything else you depend on is going to be based on undefined behavior and should not be trusted, and never should have been trusted.

The one thing you can use in some cases is changing the ID of the instances in the room creator(its part of the object dialog). But that's an instance ID, not an asset ID. That is of course defined behavior, documented, etc...
 

TheouAegis

Member
You can choose the alphabetical order as an option, not a requirement(in other words you can literally order exactly how you want to).
Where is the ordering option? In fact, where are any of the options for the asset browser? I can't even find the option to make it stop going to the default GM 2.2 browser.

Resource indexing was documented enough to be consistently functionally identical through two different iterations, and relatively consistent enough for up to 8 different iterations before that. Up until now, indexing actually had structure to it; now there is no structure, it's mostly randomness. If the tool has structures implemented that you can make use of, it's silly to not take advantage of them. I have no problem with being able to organize the resource tree however one wants, nor do I have issue with them changing indexing between versions. I have issue with how apparently sloppy the programming around that new functionality, as every version before now had clear, documentable behavior. It was undocumented in old versions, now it is documented in those versions thanks to me. In 2.3+, it's currently impossible for anyone outside YYC to document it.

Oh, so you CAN organize and have permanent asset IDs?? Well thats exactly what is needed
I never said names aren't permanent. What you name a resource is saved. I was talking about internal structuring.
 

kburkhart84

Firehammer Games
Where is the ordering option? In fact, where are any of the options for the asset browser? I can't even find the option to make it stop going to the default GM 2.2 browser.

Resource indexing was documented enough to be consistently functionally identical through two different iterations, and relatively consistent enough for up to 8 different iterations before that. Up until now, indexing actually had structure to it; now there is no structure, it's mostly randomness. If the tool has structures implemented that you can make use of, it's silly to not take advantage of them. I have no problem with being able to organize the resource tree however one wants, nor do I have issue with them changing indexing between versions. I have issue with how apparently sloppy the programming around that new functionality, as every version before now had clear, documentable behavior. It was undocumented in old versions, now it is documented in those versions thanks to me. In 2.3+, it's currently impossible for anyone outside YYC to document it.
The options are part of the preferences for default ordering of new asset browsers(you can show more than one). And the little filter icon next to the search bar does filtering and ordering as well, including custom order if you don't like the alphabetical ordering at all. I don't know if there is even an option to not create default folders, but you should only have to delete them once when you start a project.

About the documenting of object indices...maybe I'm missing something...but I've never noticed any formal documentation on that, maybe before version 7 there was some?! Also, you clearly see a difference between documenable and documented....so if you are depending on "documentable" behavior, that's your own fault. In my opinion, I could care less about the object indices. Anything I need to do with objects, I can simply access them by name. If I want to create a list of them, I can either play with strings and get asset IDs, or simply make an array of the names to move through in code. The names themselves are enough for all my needs, so I have no need to go through undocumented behavior for anything at all. So yeah, they may have a huge mess under the hood as far as the indices go...but they have never told us to directly use those values anyway...they were always "subject to change" even if they only did any actual change a few times, and even if only this last time it turned into a mess...but we were never meant to use those values anyway, so it doesn't matter. I get that you wanted to take advantage of the thing while it was there(it was silly not to as you say)...but you shouldn't expect it to always be the same since the devs didn't document it as stable. I don't judge you for using it as you could before(even though I never depend on undocumented behavior)...I'm judging you for complaining about them changing it, when it isn't their fault that you chose to use it incorrectly, just because it was working and was "silly" not to do so. I believe it is "silly" to ever depend on such behavior because you never know when they might decide to change something.
 

Neptune

Member
Maybe I'm using the wrong terminology.

I'm talking about the damn integer that gets assigned to each element in the tree xD
0, 1, 2, 3, 4, N for sprites
0, 1, 2, 3, 4, N for objects, sounds, etc

The reason you *could* (shouldnt) do for(i = sprite0, i < spriteN, i++) {}

IMO that number should not change based on where it is in the tree -- also not collapsing when an element is removed from the tree, and not incrementing additions to the tree.

Imagine you release a game, and in save data you have
GML:
last_room = room0;
And then you release an update with new rooms... Whoop, the saved value for room0 is now pointing to room3, and save data is corrupt.
I understand there are work-arounds, and it has always been intended to be a bad system, but it seems like such an easy fix...
 

kburkhart84

Firehammer Games
I'm talking about the damn integer that gets assigned to each element in the tree xD
0, 1, 2, 3, 4, N for sprites
0, 1, 2, 3, 4, N for objects, sounds, etc
But that's just it...those values are only meant for internal use....as far as OUR code is concerned we should only be using the names of the objects, and then getting the indices accordingly. Internally, they can do what they want. What if they start at 10,000 for some reason? What if they decided to make ALL assets part of the same list, sprites would be 0 - X, sounds X+1 to Y, and etc... maybe they find a way to get better performance that way or something strange. We have no idea...and until they suggest we use those indices directly, we really shouldn't be.

And then you release an update with new rooms... Whoop, room0 is now room1, and save data is corrupt.
I wouldn't ever put the room index into my save game...I would put the level ID based on my own system. That is part of the whole depending on undefined behavior that you would be doing and shouldn't be. There are even some documented behaviors that I feel itchy depending on and don't. An example is the room ordering in general.... the only room I count on ordering for is the first one. From there, you will NEVER see my code going to the "next" or "previous" room. I will always choose to go to a room by name only. Anything else just doesn't feel right to me, even though it IS documented and there are even functions for it. I feel like my code would know what rooms to go to. If I have an ordering for levels, I can just stick them in an array by name.
 

Neptune

Member
It doesnt matter what they do, start at -10000 and increment by 17.3 just dont change them please lol
We have this fantastic tree with numbered IDs and we cant even use it for saving... ??

I too have a work-around system, but that is not my point here. The point is it could be better, and I don't think "we cant trust yoyo to not randomly change all the tree numbers" is a justified answer.
 

kburkhart84

Firehammer Games
It doesnt matter what they do, start at -10000 and increment by 17.3 just dont change them please lol
We have this fantastic tree with numbered IDs and we cant even use it for saving... ??

I too have a work-around system, but that is not my point here. The point is it could be better, and I don't think "we cant trust yoyo to not randomly change all the tree numbers" is a justified answer.
Then what you should do is post a suggestion to the 2.3 beta forum. (It wasn't you)Complaining about undocumented behavior changing won't help. As far as it being a proper suggestion, I agree with that idea 100%.
 

kburkhart84

Firehammer Games
I have actually brought it up with them to some extent, and the answer was basically it's not a consideration.
I believe it. I understand them though...its something that is easily enough worked around, and like many things, even though optional, could confuse newer coders.
 
Top