The annoying picking problem (Ashley please clarify it ty)

0 favourites
From the Asset Store
For problem solving, puzzles, bubbles, platforms and other adventures.
  • Think most people that have used C2 for a while have experienced this problem, when working with newly created objects. I search the manual and tutorials for something about doing this was not reliable, but I couldn't find it. But please correct me if im wrong, but as far as I remember from others posts, its due to these objects not actually being available or created until next tick, which is how C2 handles this at the very core and therefore cant be easily changed. And therefore this make picking/working with newly created objects unreliable. And the most common way to solve it I believe is to add a wait with 0 or very low wait time.

    However since I ran into this problem with my game, as I create an object, which will again spawn another object that are connected to this, which again will connect to another object. And depending on some of the variable of these later created objects, the first object will have different settings. And it works in some cases, meaning that if I do it through a key like "D" it works. However if I do the exact same thing from a function it doesn't work.

    So I made a small pointless program to show the problem.

    What it does is spawn 3 objects (Clients) of different color, and each have a there color stored in a "color" variable as well. Then it also spawns another object (Master) with the same variable. It will then choose a random client object and copy its color to the masters variable.

    I have made it so one uses functions and the other doesn't and also uses a "wait", which will make it work. However if you remove the wait it doesn't work either.

    So my question is, as I really don't like the idea of having to slow down my game on purpose due to this, and because it doesn't solve my problem anyway when using functions.

    How do you do this probably and can you do it without using a wait, really hope you can clarify this for me Ashley or someone else with a capx. As its probably the number one thing that annoys me?

    (Check the "color" variable in the debugger for the master object, after clicking one of the buttons.)

  • I feel your pain trying to keep things straight when calling multiple functions against a newly created object. However, you're actually running into a different issue here. Check this out in the manual: https://www.scirra.com/manual/142/families

    [quote:15e3ztoi]Picking families in events

    Families pick instances in the event sheet independently of the object types in the family. For example, consider Family1 consisting of SpriteA and SpriteB. Conditions for Family1 will never affect which SpriteA and SpriteB instances are picked. It will only affect which instances are affected when running an action for Family1. Likewise, conditions picking SpriteA and SpriteB instances will never affect which instances are picked in Family1. In other words, in the event sheet families are treated like an entirely separate object type, which just happens to have instances from other object types.

    So, for example, in your Button2 On clicked event, you're creating child objects and then trying to pick randomly against the Family. The Family is a different object, and can't see the child objects until you hit a top level event. If you were to instead create a new Family1 object instead of the red/green/blue objects, it then works (however that's not an ideal solution either because when you create a new Family object, it randomly picks a child object to create). Also, you don't need the Wait in this case.

    As far as the function calls (Button1), you're running into three issues . The first is the same as the issue above, where you're creating red/green/blue objects, but then trying to pick a Family object in the "Choose random color" function. The second issue is that you're assigning Master's color to the return value of the current function, not the one you're calling.

    When trying to assign something to the return value of a function, use this:

    Set Color to Function.Call("Choose random color")[/code:15e3ztoi]
    
    But there's one more thing, and this is the thing you're talking about in your post, is that the object isn't ready for picking unless you specify UID (like you do in the first two function calls).  So, to put all three things together and get the desired outcome,
    
    1) Create a Family object in the "Set color" function
    2) use [code:15e3ztoi]Set Color to Function.Call("Choose random color",Family1.UID)[/code:15e3ztoi]
    3) Delete the "Pick a random Family1 instance" condition and replace it with Family1 > Pick instance with UID Function.Param(0).
    
    I realize this doesn't completely get you where you want to be because you might not want to create random objects, but hopefully it clears up what's going on with picking
  • i see its already been handled i had this solution..

    https://dl.dropboxusercontent.com/u/61666915/pickingproblem_test.capx

    but i agree that its really a pain this issue, especially if you don't know of this, and how to work around it,

    having the javascript console open can really help,, it showed an error on the color function

    + with the browser plugin, you can quickly log returnvalue

    ps: i think the only problem was the "pick random family instance"

  • You probably won't like my suggestion any better than the others, but this has been debated many times before, and I doubt things will change. You just need to structure your code to create at a top level event and pick after, at the same level.

    (Only addressed 'Start function' button).

  • [quote:ogi13g4n]So, for example, in your Button2 On clicked event, you're creating child objects and then trying to pick randomly against the Family. The Family is a different object, and can't see the child objects until you hit a top level event. If you were to instead create a new Family1 object instead of the red/green/blue objects, it then works (however that's not an ideal solution either because when you create a new Family object, it randomly picks a child object to create). Also, you don't need the Wait in this case.

    Yeah that's pretty huge problem, agree. Because well first of all spawning family objects are rarely very useful if you need to be precise

    However in my game these objects are not part of families, but it still occurs however I can fix it by using a wait and make the call from a keystroke but not if I make the call from a function. I simply made the example using a family to make it faster to make. But ill try to make a more precise copy.

    [quote:ogi13g4n]The second issue is that you're assigning Master's color to the return value of the current function, not the one you're calling.

    There are nothing wrong with the way I use the return value, both ways work. If you make a new return in "Choose random color"

    Set return value to "Hello"[/code:ogi13g4n]
    And remove the pick random Family1, it have no problem setting the value of the master using this return value. 
    
    [quote:ogi13g4n]I realize this doesn't completely get you where you want to be because you might not want to create random objects, but hopefully it clears up what's going on with picking 
    
    Yeah that will get me absolutely no where as these things shouldn't be random, but also as I mentioned they are not part of families, so in this case its not even possible 
    
    EDIT: In regards to them not being families, it might be because its all in functions and therefore it never hits top level. Just a thought.
  • i see its already been handled i had this solution..

    https://dl.dropboxusercontent.com/u/61666915/pickingproblem_test.capx

    but i agree that its really a pain this issue, especially if you don't know of this, and how to work around it,

    having the javascript console open can really help,, it showed an error on the color function

    + with the browser plugin, you can quickly log returnvalue

    ps: i think the only problem was the "pick random family instance"

    The way you have done it in "Set color" when you pass UIDs is also how I do It in my game.

  • You probably won't like my suggestion any better than the others, but this has been debated many times before, and I doubt things will change. You just need to structure your code to create at a top level event and pick after, at the same level.

    (Only addressed 'Start function' button).

    Im not really expecting it to change, just to know if it was possible some how However your suggestion is probably what ill end up doing, just redesigning it, and link them together in another way.

  • [quote:c3z6vqno]There are nothing wrong with the way I use the return value, both ways work. If you make a new return in "Choose random color"

    Set return value to "Hello"[/code:c3z6vqno]
    And remove the pick random Family1, it have no problem setting the value of the master using this return value. 
    
    
    I apologize, you're right about this.  I just tested it out and learned something new
  • [quote:3sr8tqpi]I apologize, you're right about this. I just tested it out and learned something new

    Me to had actually forgotten all about top levels

    [quote:3sr8tqpi]EDIT: In regards to them not being families, it might be because its all in functions and therefore it never hits top level. Just a thought.

    However do you know if this is the case, because that might explain it I think?

  • [quote:3kpsfvku]EDIT: In regards to them not being families, it might be because its all in functions and therefore it never hits top level. Just a thought.

    However do you know if this is the case, because that might explain it I think?

    That's the conclusion I came to when I was trying to do something similar in my last project. It was a very text-heavy educational game, and I wanted to streamline the sprite font creation process, but once I got past the first function call I lost the newly created spritefont and had to go with a more primitive brute force approach . If I were to go back and try again perhaps I'll see that I was just doing something else wrong, but I was at it for quite some time trying to get it working without adding Wait 0s everywhere!

  • Just hoped that I had missed something, and it was because you just have to "do this and this" kind of thing But guess ill just restructure how I do it.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Think I might have found a solution to do it without using waits. However it does requires an extra check every tick. But if it works I think its worth it

    The Idea is to use an object handler, that can handle all newly created objects.

    You can make it with a list or array whatever you prefer. However you still need to organize the way you create objects according to the normal rules.

    In my case it uses a list, the idea is that these objects that rely on other objects that might not be created yet during the cycle, are added to this list. And then you apply whatever extensions to them that you want. And its actually quite simple to make.

    In my game the handler looks like this:

    Which in this case is the Quest_master_object that give me the problem. As its the one that rely on a Quest_step, which is a sub quest that are part of the master quest. To this Quest_step there is a dungeon attached. Which again is used to generate a random Quest description.

    To use the object handler all you have to do, is tell it what action you want it to do, in form of a Boolean, and then add the UID to the list. And then hook it up to a function, or whatever you prefer.

    And you can just add as many conditions and objects to the object handler as needed. I think the benefit comes when you have to do something several times during one tick. For instant in my case I actually have to repeat it 5 times, but having to wait each time is first of all not something I like, but also seems to create problems, as sometimes the descriptions got mixed, some steps weren't made etc.

    Anyway haven't tested it fully, but the initial tests seems to work very well, and now at least this problem is solved

  • Nice work. Looks pretty slick.

    I was reading up on the thread that explains why picking works this way now, and I'm actually confused.

    https://www.scirra.com/forum/viewtopic.php?t=73647&start=0

    In the thread, it is explained that the object doesn't exist to same-level events until the next top level event. Then how come pick by UID works on our tests?

  • [quote:28c7c1a7]Nice work. Looks pretty slick.

    I was reading up on the thread that explains why picking works this way now, and I'm actually confused.

    In the thread, it is explained that the object doesn't exist to same-level events until the next top level event. Then how come pick by UID works on our tests?

    Agree that it gets confusing, because its logic that you have created the object, so surely it must be there, but it actually ain't as explained by Ashley in that post.

    A solution also from that post is:

    [quote:28c7c1a7]The workaround is to try to do everything in the same event - nest the other events beneath the creating event if possible, so everything is moved up in to the green area.

    Which are the reason that you can create an object and right afterwards set its variables.

    Create object

    Set Object name = "Whatever"

    That also means that you can pick UID of the object if its in a sub level of the create function.

    But if you do it like this:

    level 1: Create object

    --------------Do something

    Level 1: Pick Object with UID of the newly created object shouldn't work.

    You have to reach a top level. (Now this post is from version r102, so its pretty old, but don't think a lot if any have changed.)

    However the common way of dealing with this problem as you most likely know is to throw in a Wait of 0, 0.1 or 0.01 or whatever as it will then go through to the next tick and force it to reach a top level or what to say and then it works. Im not really sure how solid this actually is, it seems to work well with simple stuff, but if it gets a bit complex it seems to not really work well.

    For instant if you have an event:

    Repeat 10 times

    ------- Call function("Spawn enemy")

    Function Spawn enemy

    Create enemy()

    Call function ("initialize enemy")

    Function Initialize enemy

    Call function ("Create enemy weapon")

    Function Create enemy weapon

    Create Enemy_weapon

    Then suddenly things starts to go wrong as I see it.

    Because now there are actually two objects that doesn't exist yet, The Enemy and the Weapon that you want it to use. So if you throw in a Wait different places to solve it, It might work. However at the very start we are actually repeating this 10 times, to create 10 enemies which will then create 10 different weapons, so suddenly you might have 20 objects that actually doesn't exist, and then it seems to go wrong. Whether that's completely true im not 100% sure about, but it seems that a function doesn't count as a top level, which I find to be logic if its the case, but I haven't seen anything saying that it ain't which is why im not certain.

    As I mentioned in my last post, I had to repeat it 5 times, but I did something similar with 50 objects using a wait, and it looked like it was working fine, however as I went through the objects in the debugger I could see that suddenly some of the objects would have "NaN" in some of the variables. Which didn't make sense as 95-98% of them had no problems and all different possibilities for this variable was used, but for some reason some of them just failed, and my guess it that since I repeated it several times, it might have screwed up with the wait somehow. So the only thing I did, was to move the function call to the Object handler, didn't change any code and none of them had any problems after that, same goes for several other mistakes that was happening. So I moved those as well and now all of them gets initialized correctly, without having to use wait, which I think in itself is a huge benefit.

  • Just to add that the "pick by uid" condition is the exception to the rule about picking since r127.

    https://www.scirra.com/construct2/releases/r127

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