Question about Loops and Nested Loops

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.
  • Hello! I am still learning a lot and I'm new to posting (I hope this is the correct spot), but I've come across a problem with my code that I can't seem to solve. Here a detailed description of the situation (MAIN ISSUE listed lower):

    I start by spreading IDs through tiles in the map and then assigning a random value to "distance"

    Always spread 0 in ID of "sensor" object.

    I then have a main loop that will cycle through all tiles in the map. When ID = loopindex, it will create 4 "sensors" N S E W of the tile. Next, I run the first nested loop. This loop runs # of "sensors" times. When ID of sensor = loopindex( nested1 ) and sensor is overlapping a tile, take the "distance" value and store it in the sensor.

    Once the loopindex ( nested1 ) = number of sensors, I start a loop "findhighest" # of sensors times. The next bit of code determines which of the four sensors has the lowest stored value (that they got from the tile they are on top of) and erases the others. Once the loopindex ( findhighest ) is equal to the number of sensors, I run 1 loop ( setdirection ). On loop, if ID (tile) = counter-stored loopindex( main loop ) , set direction to look at the one remaining "sensor" and then delete it.


    MAIN ISSUE:

    I told Fusion to run the main loop 1 time (to set up a controlled environment). The code as is causes the desired results. Once I up the main loop (called VECTOR) repetitions to anything higher than one, it skips to the very last tile and then completes the nested loops. If anyone is brave enough, I've attached the project file. I did my best to organize it for easy reading.

    Thanks ahead of time to anyone who can help me out!

  • That's a complex piece of code if you've just started using Fusion (welcome!)
    cool!

    If I got it correctly, I think it can be vastly simplified:

    Please login to see this attachment.

    though if you have specific questions on nested loops,
    foreach loops, or other mechanics, let us know :)

    a selection of my Fusion examples can be found Please login to see this link.

  • Thanks for the fast reply and edit! I am actually not new to Fusion 2.5 as I've been around since MMF2. This is my first time coming to the forums because I've gotten WAY over my head. Essentially this program is supposed to cause each node to point to the one around it with the lowest distance value, like it does in your edit. This is part of the program I'm working on for a goal-based vector "pathfinding" algorithm.

    I have a few more questions.


    The loop will sometimes cause certain tiles to not have a direction (ie pointing to a node). I'll try to work with it but if you have a quick fix off the top of your head I'd love to hear it.

    Previously I used 4 "scanners" but your change only uses 1 and is placed on the tile rather than all around it. Why is that and how does that work so much better?

    This code is "part 2" of the algorithm. "Part 1" scans outward like A* but from the goal, writing increasing distance values as it progresses. Right now, it works but takes about 2-3 seconds to fully scan the frame. I need it to all happen before it draws the frame. In the end, both Part 1 and Part 2 will be stacked so after the distance values are set, it adjusts the vectors (each part can happen on different frames if the strain is too much). If you're willing to take a look, let me know and I'll upload that as well.

    Thanks again! I'm really interested in game design and right now I'm testing different concepts to hopefully use later.

  • Quote

    The loop will sometimes cause certain tiles to not have a direction (ie pointing to a node). I'll try to work with it but if you have a quick fix off the top of your head I'd love to hear it.

    You mean in the latest example above?
    I think the only tile not having a "correct" direction should be the "target" itself, because it would point to itself
    but on the other hand - which would be the correct direction to point for this tile?
    You could make an animation with "no direction", like a single center dot without line
    (if this can be of any use for your application of course X))


    Quote

    Previously I used 4 "scanners" but your change only uses 1 and is placed on the tile rather than all around it. Why is that and how does that work so much better?

    The example doesn't use scanners at all, since you were already storing the "distance" value in tiles,
    I've simply cycled through all tiles (with the foreach loop), finding the one with lower distance value,
    and then placing the green tile as a "target" on top of that (this object could be avoided entirely)

    ...though, reading your latest post, I'm not sure the example does what you were aiming to do XD
    as I'm not sure I understood what you are willing to do:

    Quote

    this program is supposed to cause each node to point to the one around it with the lowest distance value

    you mean that each "node" (grey tile) should look to the one around it with lowest value in the whole neighborhood (same "cluster" of 100 tiles)
    or only among the 8 adjacent ones.. which the example doesn't do and I think you probably need if you're making a pathfinding algorithm!

    Btw, if you are interested in Pathfinding and willing to look at other "precooked" solutions,
    there's the Pathfinding extension, and a number of Fusion-made implementations (including Please login to see this link. >:) which is cross-platform) you could look into.

    Otherwise, I could modify the example above to do so, without detectors (assuming you'll work with a strict "grid")
    but the better (fastest) way to do this is probably using an array

    a selection of my Fusion examples can be found Please login to see this link.

  • Hey I'm interested in your pathfinding algorithm that you're working on. A couple years ago I created an A* pathfinding algorithm by scratch and it was pretty fun. This is the first time I'm looking into goal-based vector pathfinding. I know Schrodinger also made his own custom pathfinding algorithm as well in Fusion. I haven't looked at the file yet since I'm at work now, maybe I'll take a look at it later.

    Instead of creating four actives in the cardinal directions when testing for the distance, why not just use one detector and position in four times around the node you're checking using another nested loop. Or better yet, record your distance values in an array that's linked to the grid on your level then just compare the data values from the array using offset X and Y array cells? Just food for thought. When I created my system I used a list to record each node and each line had a bunch of data separated by commas. I used string delimiters to parse the data.

    Another pathfinding example that was pretty good was Sketchy's example from the Daily Click. You can check that one out here: Please login to see this link.

    I'm sure other people on this forum can tell me how to improve and optimize my system, but it was definitely fun figuring it out!

    I made a video showcasing it if you wanna check it out.

    Please login to see this media element.

    Custom A* Pathfinding in MMF2: Please login to see this link.
    Random Tile World Generation: Please login to see this link.

  • Sorry if I'm not 100% clear. This algorithm I'm making is still new to me and my approach is probably not the most efficient. Here is exactly what is going on in the bigger picture (entire algorithm):


    - Starting from the tile that is the goal, distance values are set based on the main loop index. For example, the starting tile (which is the goal) would be ZERO. Each loop the program adds any unchecked tiles in each cardinal direction (4 directions total for this algorithm's purposes) and then sets their distance value.

    NOTE: I would use 8 directions but I don't want my units to clip over obstacles. If there is a way to get around this I am all ears and willing to learn.

    - Once all the tiles have been checked and updated, the second phase begins. Here, every tile checks its neighbors (the 4 around it) and then finds the one with the LOWEST distance value. Then the tile doing the "looking" stores another value which will "point" to that LOWEST distance value tile.


    Essentially, the program updates the distances and the vectors based on the goal, and then the units "seeking" follow the direction (vector) of the tile they are on top of. This really isn't a true pathfinding algorithm, but accomplishes the same goals. The reason I chose this method instead of true A* is that this will allow for potentially 100s of units to seek the goal at a much faster computation speed than finding paths for each unit using traditional A*.

    Here is a video example of what I'm talking about and trying to replicate in Fusion 2.5. I don't plan on using any code to make the units spread out based on density like his does, though I might consider something like it in the future.

    Please login to see this media element.

  • Does that mean you have to loop through every possible tile in your game to update its distance value relative to the goal? Sounds intensive and it would take awhile to check all of them, maybe a few seconds at most even with the nested loops. I guess it also depends on how big the area is and how big your tiles will be. Maybe you can restrict the search area to lower the requirement, as long as you know it doesn't hinder the search process. As long as I'm not misunderstanding the video.

    Custom A* Pathfinding in MMF2: Please login to see this link.
    Random Tile World Generation: Please login to see this link.

  • I have an example somewhat working right now that is a 640x480 screen with 20x20 tiles that runs the first half of the algorithm. Considering it is a very rough and non-optimized program, it isn't lightning fast but is still considerably speedy. I'll link that file here if you want to see that.

    I've done a lot of reading and I know that in larger maps, you should divide the map into smaller "sections" containing a certain number of tiles. Using that, you only update the values in the section the player is in every frame and only update the other sections to "pathfind" from that section to the next nearest section once if the player is not in those areas.

    So right now I'm just working on a relatively small map. Later I'll work to scale it up.

    I'll post the example. I didn't add in any notations for this one, but using "0" "1" and "2" will cycle through the different view styles so you can see the "scan", the "distance values" and invisible.

  • Interesting video, the effect looks very cool also,
    though - off top of my head, so I may be more easily mistaken XD -
    it doesn't seem to be very different from non-vector-field pathfinding?

    The first step is what most pathfinding algorithms actually do (calculating the distance -steps- of each cell from the "target" position)
    the second step is avoided (drawing the vector field)
    but once you have step one, it would be highly unefficient (as Sumo says) calculating vector directions to each adjacent cell
    and generally unuseful, as you can simply calculate those vectors for the single objects lying in the field whenever you need to poll those
    (like, obejct at cell 33,12 wants to move, and so polls for vectors around cell 33,12, reading grid values got on step 1)

    can't see how drawing all the vector field can grant better performances :o
    unless you use a very large number of objects going pathfind and constantly moving (swarms or particles, like in the video)
    then doing the math on the grid *could* maybe be more efficient than picking single objects of the swarm
    (always speaking of Fusion --- in other languages probably not?)
    and probably in all languages, when the swarm is larger than the number of cells in the grid XD


    EDIT
    had the audio turned off on first seconds of the video - ok, so it is what the guy says, it is useful for a very large number of objects.
    However, if this is your goal, with similar figures, I'm sorry this may be not possible to do with Fusion,
    you'll very likely have problems when in the order of few hundreds of objects
    don't know if these figures can suit your needs?

    Quote

    you should divide the map into smaller "sections" containing a certain number of tiles

    this would surely help, for the vector field, but handling a very big number of objects will be a problem nonetheless :(

    a selection of my Fusion examples can be found Please login to see this link.

    Edited once, last by schrodinger (October 6, 2016 at 8:46 PM).

  • The drawing of the vector field (displaying an animation frame) would simply be for development and seeing it work.

    I was originally thinking to calculate and then store the vector value based on the surrounding tiles so that instead of calculating for each unit on the tile, they would just reference the single value and set their direction to that. My game in mind was a zombie-style top-down shooter where the player runs around trying to stay alive, so the sheer number of zombies (as the difficulty progresses) would probably require computing once per tile rather than once per unit on a tile.

    I'm no programming expert. If I chose to calculate based on neighbor tiles, how would I do that as efficiently as possible? I'm working on trying to use an array but it isn't quite working properly yet.

  • I will NOT need that many units. My ideal game is a zombie shooter and there won't be more than 250 zombies probably depending on how Fusion reacts to that. I think I got the vector value updating to work, so I'll now work on optimizing the distance-step part and likely come back with questions on that.

  • Sorry, I said "drawing" but I meant "calculating", that would be anyway a performance hit.

    The array is likely your best bet,
    sorry for the question: do you plan to allow multiplayer on this game?

    If not, you can avoid recalculating the first step for each zombie, making for just one pathfinding call (reading all cells from target position) for all the zombies whenever their target is the same
    (but that could also be done with multiple players by calculating N different path maps for N different players)
    this is something some pathfinding engines do to lower calculations (my widget does it i.e.)
    so calculating 100 paths to a single target counts much less than calculating 100 paths to 100 different targets

    Another idea, when you have a grid of distances (step 1)
    you can simply do something like this (assuming the grid is stored in array where Z=2 is the dimension for the vector field):

    for each zombie
    value at (zombieXY/gridsize - Z=1) > 0 (the vector is calculated)
    >>> zombie looks at vector direction

    for each zombie
    value at (zombieXY/gridsize - Z=1) = 0 (the vector is NOT calculated)
    >>> start loop "calculate vector field" (for this cell)
    >>> zombie looks at vector direction

    so following zombies will inherit the calculated vector
    but you wouldn't calculate unnecessary cells
    (hardly your zombies will cover the whole play area?)


    You can also see this awesome example by SolarB, that I think implements a similar solution to increase performances with swarms:
    Please login to see this link.

    Having a "sheer number" of objects isn't generally possible in Fusion without hitting some performance walls
    it's likely you'll end up with some headaches with this ..
    but will surely be an interesting challenge :)


    EDIT
    wrote this after seeing you need 250 units - then I think you can have that!
    More so I think calculating the whole vector field would be less efficient than choosing one of the options above
    let us know what you end up doing and how performance goes, your project looks interesting! ;D

    a selection of my Fusion examples can be found Please login to see this link.

Participate now!

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