Pick instance by comparing instance variable with choose/random doesn't work?

  • Say there are two sprites, one with id=0, another with id=1

    If I want to pick a random sprite using condition "Sprite compare instance variable id=choose(0,1)" - it doesn't work as expected! Sometimes it picks one instance, sometimes two, sometimes none.

    Am I going crazy, or is there a reasonable explanation?

    I tested in both C2 and C3. Example capx:

    dropbox.com/s/z4zsaevq92byut3/PickWithChoose.capx

    .

    EDIT: Never mind, I think I know what's going on. This event loops through all instances, comparing each with choose() expression, each time calculating a different value for choose(). I wonder if this can be considered a bug...

  • Okay, instead, add a local variable to contain the random value. Do this before your pick, and compare using the variable. Right?

  • Yes, I know about workarounds.

    It just seemed like such an obvious and easy way to pick random instances, and turned out that it doesn't work correctly. I will have to check all my old projects to make sure I didn't use this method...

  • Yeah, thanks for pointing out that behavior.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • i don't know how you thinked that choose(0,1) would make sense to the construct system, but what happened on my end, after i tweaked it a bit, is Construct started opening multiple sessions of Construct lol... basically froze my cpu at 100% usage... which doesn't matter cause i could still use my pc, but ... that was a strange experience. and not sure how to replicate this issue i had in C2 so ... i can't submit a bug.

    however the choose(0,1) what it does in your example, is when the start of layout happens the system compares the id of the sprite right... and because u didn't specified which instance of the sprite to compare the value on the system picks both instances top and bottom (not specifying which of the two you want the system to pick in order to make the comparison of the id to choose(0,1), would make the system act as the sprite object being a 1 main global instance and giving it both the values to the sprite), and say "well the sprite object has id 0 and 1" and the system falls back to automatically picking in the same tick one of the two or even both .. therefore giving you a false positive interference causing it to glitch out. this isn't a bug... is just miss usage.

    edited: try resetting the opacity on start of layout, cause on my end that kinda fixes a bit the issue, and also, the text is confusing ... has the same problem... as the sprite pickings....

  • I don't think what you are saying is correct, or maybe I didn't quite understand your message.

    "Compare instance variable" event picks instances. If I use "Compare instance variable id=1", this will pick all instances with id=1.

    So naturally I assumed if I use choose(0,1) in this event, it will first choose a random number (0 or 1) and then pick instances with id equal to that number.

    But what happens is that this event actually checks each instance separately, and for each instance calculates a new random number and compares id with this number. So it can pick one instance (which seems correct), but it can also pick two instances or none.

    See this example:

    dropbox.com/s/tsje45mszx2vepp/PickWithChoose3.capx

    Also, resetting opacity on start of the layout doesn't fix the issue, because all objects are reset anyway when the layout is restarted.

  • So naturally I assumed if I use choose(0,1) in this event, it will first choose a random number (0 or 1) and then pick instances with id equal to that number.

    But what happens is that this event actually checks each instance separately, and for each instance calculates a new random number and compares id with this number. So it can pick one instance (which seems correct), but it can also pick two instances or none.

    Also, resetting opacity on start of the layout doesn't fix the issue, because all objects are reset anyway when the layout is restarted.

    i already seen the example i think if is the one saying

    i never seen the pick being used like that before, and for me doesn't make sense, as i know the Sprite object if you don't tell the system what instance should pick, it picks all of them and considers all the same object( you get what im saying? it can be confusing or i might be having a wrong idea of how the object instances work it's possible). that's what i seen so far since i installed Construct 5 years back, and that never was changed it was always like that, also i remember something about sprite.objects specifically or any object that is put initially on the screen, is that if u don't specify instance the system automatically picks the 1st put instance in screen and considers that instance like a "master instance" and if u add a 2nd instance and u don't specify it, it picks the "master instance" but takes in account the 2nd instance anyway.

    so you can have 5 sprites, but when you are saying

    system check if the sprite.id equals with this value that you pick random, the system picks all the data available and gets a true on everything he picks, suddenly sprite.id = to 1,2 and even 0 at the same time, creating the current glitch. and the display of the opacity, is just a lag feedback(because of wait 2 seconds then restart, which sometimes can persist even though you restart the layout.), and probably because of the overlap in computing. atleast that's what i was thinking at back then when i typed the message, it might not be the case, and they might work like you say though lol (im laughing at my own confusion here not at you, not trying to be rude :D) ... i never used the comparison like that.

    that's why i was saying the choose(0,1) above in my opinion is just miss usage.

    anyway did you had the same problem on a older C2/C3 version? like going back .10 .20 versions?

    btw did i told you? that when i runned your example in C2 my C2 started opening himself up like non-stop? :O lol that was the latest stable version ... insane XD i think that is a bug i wanna investigate now! (maybe it was because of the = choose() :O the plot twist would be amazing... anyway im derailing my ADD started kicking in... over-editing my post just now ... im curious if there is any other reason of the =choose() behaving that way than the reasons displayed so far.

  • You are right about the part where the system treats multiple instances as one object, and when you try to access some property it takes it from the first instance etc. But I'm sure you are aware that "Compare instance variable" is very often used to pick or "filter out" instances. If you have multiple instances, some with id=0 and some with id=1, you can use this event to pick only instances with the id=1 for example.

    It has the same effect as using System event "Pick by evaluate" or "Pick by comparison". And actually you can change my capx to use "System Pick by evaluate Sprite.id=choose(0,1)" and it will have the same problem. The engine will loop through each instance, each time comparing with a different result of choose() expression.

    This seems wrong to me, because it works differently in SQL for example. If you do "SELECT * FROM table WHERE code=int(rand()*2)", this will select records with only one value in code field, either with 0 or 1, not a mix of both.

  • You are right about the part where the system treats multiple instances as one object, and when you try to access some property it takes it from the first instance etc. But I'm sure you are aware that "Compare instance variable" is very often used to pick or "filter out" instances. If you have multiple instances, some with id=0 and some with id=1, you can use this event to pick only instances with the id=1 for example.

    It has the same effect as using System event "Pick by evaluate" or "Pick by comparison". And actually you can change my capx to use "System Pick by evaluate Sprite.id=choose(0,1)" and it will have the same problem. The engine will loop through each instance, each time comparing with a different result of choose() expression.

    This seems wrong to me, because it works differently in SQL for example. If you do "SELECT * FROM table WHERE code=int(rand()*2)", this will select records with only one value in code field, either with 0 or 1, not a mix of both.

    oh that i am aware of it, i always use the

    , i never used choose() in that sort of pick cause of the original issue with multiple instances...

    ah now i see why you are using it like that ...

  • dop2000

    I'm no senior but remember Ashely explaining picking at some post regarding loops, arrays, picking and tokenat. He said picking always act as a loop. Runtime checks condition for every instance to see if that instance meet the criteria. The issue here seems to be that the expression choose() is rrseted for every isntance checking. One would expect that at the beginning of the event, it chosed a number and compared that 'now-constant' number for every instance. But it chooses a new number for every instance, because it runs the entire condition from the start for each instance, not just from choose(). Which is kinda weird, given the expression box at a very primitive level is meant for fixed strings or numbers, so my logic also tells me it should treat the expression as a variable to call from at the beginning of the action-function.

    I am no programmer, but recalling his words about it, the whole picking system works like that at a core level, so it is not likely to change in a near future, as it would imply the same code rewriting many SDK folks have complained about C3 runtime.

    I think here the only way is the typical workaround of setting the VAR in advance, as you indeed had tought me in other posts in the past.

    BTW, a bit odd to see you around asking things, instead of solving them :p

    Have a nice year!

  • It's a "feature" with how choose() works. I mean not really a bug because you shouldn't use random on a condition. Sort of like saying every random(60) seconds.

    Also, it's not iterating through all the instances:

    dropbox.com/s/bnbxhwvk460grds/choosebugr265.capx

    It may be that choose() is iterating over possible values.

    Also also, I think the choose() value is regarded as a string by the system sometimes.

  • newt Well, of course it's not iterating like "For" loop, the actions in the event are not repeated Object.PickedCount times. But internally, when the engine determines which instances should be picked, it iterates through all instances and compares each with choose(0,1), in each iteration calculating a new result for choose(0,1). It would make more sense to calculate it only once before running this loop.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)