Compare values for separate Instances?

Welcome to our brand new Clickteam Community Hub! We hope you will enjoy using the new features, which we will be further expanding in the coming months.

A few features including Passport are unavailable initially whilst we monitor stability of the new platform, we hope to bring these online very soon. Small issues will crop up following the import from our old system, including some message formatting, translation accuracy and other things.

Thank you for your patience whilst we've worked on this and we look forward to more exciting community developments soon!

Clickteam.
  • I hope I can explain this question correctly.

    I have a shop area in my game that when the player enters, it'll drop down three random things the player can buy. It creates the same objects three separate times. I assume it automatically gives each one an instance? Say I have 15 random items for it to choose from. As of right now, two (or all three) might have the same item. Is it possible to compare the value of one of these instances to another instance? If Instance 1 has the same random item as Instance 2, I'd like Instance 2 to 're-roll' it's random item so it's different. I know I can probably get this working right if they were completely different objects.

    Basically, I'm trying to do something like this -
    If Instance 2 (ShopItem) Alterable Value A = Instance 1 (ShopItem) Alterable Value A
    Set Instance 2 (ShopItem) Alterable Value A to RRandom (1,15)

    Is something like this even possible? I can't seem to figure out how to do it if it is. It’s also possible I’m completely misunderstanding Instance Values too.

    Here's a video of what the shop looks like if it helps explain what I'm trying to do.
    Please login to see this link.

    Thanks!

    Please login to see this link.

    Edited 3 times, last by xhedgehogx (July 16, 2023 at 5:32 AM).

  • I know that any time I've tried to do this sort of thing it's proved to be quite tricky. Singling out just one instance is trivial, but comparing it against another instance of the same object - without Fusion losing track of which instance you're talking about at any given time - is trickier. There are no doubt ways to do it, but probably with slightly convoluted methods where you record the details of each object one by one, then compare each object one by one to the details you previously recorded.

    You might want to consider going about this a different way, and going to the source of the problem: the random number generator. If your game is for Windows, the easiest way is probably to use the Random Multipool Object (Windows only). This extension allows you to generate random numbers with guaranteed unique results (no repetitions). If you can't use the extension, you could make it work yourself easily enough. I've seen people submit examples of how to do this sort of thing, so have a search.

    Off the top of my head, I can think of 2 ways to do it. One would involve fastloops:


    The second method would be to fill a List object (or Internal List object) with all possible results. For example, 15 items:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    Next, choose a random number and record it into an AltVal. This won't be your actual number, but will be a random spot on your list:

    Code
    set [I]chosenLineNumber[/I] to random(List Nb Lines( "List" ))

    Because there are 15 items on the list, the above expression would essentially be the same as doing Random(15). It will choose a random number between 0 and 14. Use this number to assign your first random number from whatever appears on that line of the list (remember that the list is text, so use Val to convert it from a string to a value - eg. to turn "7" to 7):

    Code
    set [I]firstNumber[/I] to Val(List Line Text$( "List",  [I]chosenLineNumber[/I]  ))

    So if your chosenLineNumber was 6, it will set your random number to whatever is on Line 6 in the list (which, because the list is 0-based, will be the number 7). Next, delete that line:

    Code
    List : Delete line [I]chosenLineNumber[/I]

    Now you will have a list that contains 14 items:

    1
    2
    3
    4
    5
    6
    8 <-- 7 is now missing
    9
    10
    11
    12
    13
    14
    15

    Then you can continue choosing (and deleting) more numbers from the list, safe in the knowledge that you'll be guaranteed unique numbers each time. The whole thing would look like this:

    Please login to see this link.
    My Fusion Tools: Please login to see this link. | Please login to see this link. | Please login to see this link.

    Edited 5 times, last by Volnaiskra (July 16, 2023 at 5:07 AM).

  • Hi there Hedgehog,

    What you want to do is very much possible, and indeed it's possible in a myriad of different ways and techniques.

    The simplest (for me) would be to use a List object.

    1) Place the List object outside your frame, then set it up with no scroll bar and with the "Hide on start" property switched on, so it doesn't take up your resources and doesn't show up on the screen. Note that you can decide whether the List should be 0-based (start with 0) or 1-based (start with 1) in the properties.

    2) Populate the List with 15 lines, each containing the ID number of one of your items (I'm assuming 1, 2, 3 etc. all up to 15). Best way to do that would be to use a fast loop: run a fast loop (Action: Special conditions > Fast loops > Start loop) 15 times at the start of your frame and add a new line to the List on each loop (Condition: Special conditions > On loop, then Action: List > Add a line): set it up so that the new line added contains your fast loop's index (Expression: Special conditions > Fast loops > Get loop index), with 1 added to it (we add +1 due to fast loops being 0-based -- and we want our first line to be "1").

    3) Once you have 15 lines in your List, you can use it as a number pool for your items: when you create one of those three items, assign it a number from the List (choose a line at random - Expression: List > Get Line), then remove that line from the List. Once assigned, the chosen number is removed from the pool, making sure you won't draw it again during this store visit.

    Also, remember that when you're choosing the next number (after you already assigned one or two), you should do so with a smaller random pool (as there will now be 14 or 13 numbers in the List) - simply subtract the number of items already assigned from your random pool, storing said number in some value, perhaps the alterable of the List or another object.

    When using a list you'll always have a way to make sure all your items are unique - and you can even store this List to make sure same items don't pop up two times in a row, during two separate store visits (in that case you would simply clear the list and repopulate it on the 2nd or 3rd time that the player enters the store, instead of doing it on every visit).

    Now, as I mentioned, this would be my prefered method, but it's far from the only one. If you'd like to compare the ID numbers between your objects, you can "brute force it" (reroll numbers until they're unique) by scoping your objects with ForEach loops and comparing the alterable value containing your randomized item ID. You can take the basic "number pool" idea and pair it with an Array, if you'd like, or reverse it and use an Array to store the numbers you've already drawn, which would be compared with loops and assigned to the objects once the comparisons and redraws are complete.

    Finally, a quirky, silly little solution if you're adamant you don't want to use a random pool: the bamboozle. You can divide your 15 item IDs into three little piles of 5, assign each pile to one object (so, one can only draw from 1-5, the other from 5-10, the third from 10-15) and then, after they've drawn their numbers... switch them around at random, instantly swapping their positions between them. Players will never know. I won't tell either.

    One more thing: performance considerations. The List object is "heavier" than most data storage options, but I'm sure that unless you're squeezing out everything from your engine and fighting for scraps of performance by juggling groups activations to lock down each and every fastloop... you won't even notice. If your application is Windows-only, you might want to consider the Internal List object, which is faster, but Windows-exclusive (while the standard List can be used across multiple platforms).

    Edit: Volnaiskra explained the pool idea above while I was still typing this out :)

    :D My game project: Please login to see this link. :D

    Edited 4 times, last by koobare (July 16, 2023 at 5:25 AM).

  • Thanks for the responses!

    I ended up playing around with it a little more after posting my original question. Eventually gave each instance of my shop item its own value in a separate object. (Ex. ShopItem1 is the ShopCharacter’s AltVal X, ShopItem2 is ShopCharacter’s AltVal Y, etc). And was able to compare there. I have things a little bit more complicated that the shop also won’t show items that the player already has. I made it so when the shop is ‘open,’ it’ll choose the shop’s items in the background now, instead of as the player is entering the room. So if ShopCharacter’s AltValX = AltVal Y, then AltVal Y will use the built in random number generator to keep cycling through until it has a value that isn’t being used by another shop item, and isn’t in the player’s possession.

    Unfortunately, this added about 50 more events, but it’s working how I want it. I’m sure there’s a way I can optimize what I did, but I’m open to try the suggestions posted here. As of right now, I’m building it for Windows only, but trying to keep as many extensions and objects as universal as possible. I’ll probably see what I can do with koobare‘s idea first.

    Please login to see this link.

  • If you're building for Windows only, then I think you're probably adding unnecessary difficulty to your life by shying away from extensions. In my experience, you end up finding a good few extensions that you can't really live without anyway. Then there are those like Random Multipool that you could live without, but just make things that much more convenient. You could do much of what you've described in a single event. The following code would create 3 non-duplicate random numbers that were not items the player already owned (which the example assumes are items #4 and #8).

    Please login to see this picture.


    The list method that koobare and I described basically just replicates the above functionality, only in a more convoluted, clunky and less performant way. If you absolutely positively can't use extensions, then it's a perfectly acceptable method. But I wouldn't make it my first choice.

    Please login to see this link.
    My Fusion Tools: Please login to see this link. | Please login to see this link. | Please login to see this link.

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!