Fengist's Forum Posts

  • So I have this function that calls a bunch of other functions. I wanted to add a progress bar so that after each of the inner functions are run, it would show the progress. However, I'm discovering (I think) that while a function is being run, the layout isn't being updated. Once I click the button to start, the progress bar doesn't move until the main function completes.

    Is there anyway to refresh the layout so that this progress bar shows movement?

    * On function 'Startup'
    -> Functions: Call BuildArrayRandom
    -> ProgressBar: Set progress to ProgressBar.Progress+1
    -> Functions: Call AverageTheArray
    -> ProgressBar: Set progress to ProgressBar.Progress+1
    -> System: Set ArrayTotal to round((ArrayTotal÷ArrayCount))×MapFilter
    -> Functions: Call SetTerrainIslandorWater
    -> ProgressBar: Set progress to ProgressBar.Progress+1
    -> System: Set ArrayCount to 0
    -> Functions: Call EliminateOrphans
    -> ProgressBar: Set progress to ProgressBar.Progress+1
    -> Functions: Call FillInPonds
    -> ProgressBar: Set progress to ProgressBar.Progress+1
    -> Functions: Call FixConnectors
    -> ProgressBar: Set progress to ProgressBar.Progress+1
    -> Functions: Call PlaceBeaches
    -> ProgressBar: Set progress to ProgressBar.Progress+1
    -> Functions: Call CopyToTilemap
    -> ProgressBar: Set progress to ProgressBar.Progress+1
    
  • Ah yeah that algorithm, I've actually looked at that in the past. I did a fair bit of reading on procedural terrain generation at one point and that was recommended for smoothing out caves.

    http://www.roguebasin.com/index.php?title=Cellular_Automata_Method_for_Generating_Random_Cave-Like_Levels

    You, sir, must be a mind reader. I'll study these links further today. Thanks for pointing them out!

  • Your project looks very exciting.. must be fun programming it! Would love to see it in action :)

    As soon as I get something solid, I'll update this post to a working example.

    Just wondering if the loops are causing any delay? or they're instantaneous?

    So far, it's not too horrible. A second or two. But, I'm far from being done. Nepeo pretty much figured out what I'm doing. I'm using a technique similar to what he linked to:

    roguebasin.com/index.php

    So far, these are the steps I'm taking but, I need at least one more routine and your Quadtree may just fit the bill. I'll study that today.

    * On function 'Startup'
    -> Functions: Call BuildArrayRandom
    -> Functions: Call AverageTheArray
    -> System: Set ArrayTotal to round((ArrayTotal÷ArrayCount))×MapFilter
    -> Functions: Call SetTerrainIslandorWater
    -> System: Set ArrayCount to 0
    -> Functions: Call FillInPonds
    -> Functions: Call EliminateOrphans
    -> Functions: Call PlaceBeaches
    -> Functions: Call CopyToTilemap
    

    First, it builds an array of random numbers.

    Then, it iterates through the array, looking at each cell. It looks at the 8 surrounding cells and replaces the one it's looking at with an average of the other 8.

    The ArrayTotal is the average of all cells in the entire array. By adding the MapFilter (say 0.9 to 1.1) I can easily generate more or less land mass.

    Then, it loops again through the array. If the cell is above that ArrayTotal average, it sets it to the value for the land tile, otherwise, it sets the value to the WaterTile.

    Next, it attempts to look at water tiles that have a lot of land around them and fills them with land tiles.

    The EliminateOrphans is the smoothing I posted above.

    And this next part I'm still working on. It loops again through the array, looks at surrounding tiles and attempts to create a beaches on the island borders from one of 12 possible tiles (N,S,E,W outside curved tiles NW,NE,SW,SE and inside curved tiles NW,NE,SW,SE).

    Finally, it copies the array over to the tilemap and shows it.

    But if your algorithm if fast enough, then you don't need anything else.

    So far, it's pretty quick. That may change as there are still trees, bushes, etc to place. I'm liberally stealing the idea from a game jam project and his would take a full minute or two to generate a map. I'm hoping to be a lot faster than that.

    This is a 200x200 array which it does in about 5 seconds.

    And to show how the map filter works, the above example was at 1.075. The one below was created just by changing that filter to 0.95.

  • No, that is not odd, that is the whole point of the image point.. :)

    LOL, yea, it is. It's what some of us would call an anchor point. Should you decide to like rotate the sprite, it'll rotate around that image point. It tells Construct where to place the actual sprite image in relation to the x,y location you choose.

    When you originally placed that sprite you looked at where you wanted the image. The actual location was down and right. When you moved the image point on the sprite, the x,y on the layout didn't change but the location of the graphic in relation to that x,y did.

  • Is that the image point that somehow got drug all the way down there? Edit your sprite, select edit image points on the left and click in the center and see if that doesn't fix it.

  • Would be interested to see the same project with the new beta Fengist

    New r161 version uploaded. Link in the OP for comparison.

  • Which means, let's say in the 500th recursion, if all the found = false, it won't repeat anymore.

    While a good idea, in my case, a recursion would likely cause an even bigger delay in completion. Each cycle through the loop I'm looking at an element in the array. I'm then looking at the 9 elements surrounding it (x-1, y-1 to x+1, y+1) and basing changes off the results of that. Changing the element the loop is looking at could affect the element prior to it but I wouldn't know that until I ran through the loop again. (I'm playing with procedurally generating island terrain using an array as the template for the tileset.)

    And as an update, the While worked great, just like a good ole' Pascal repeat until. Here's the resulting code. It's purpose is to 'smooth' out the terrain generation. The OrphanCheck is the conditional to stop the while and the -1 in the array indicates it's a water tile. ArrayOffset is a 'border' around the islands that's guaranteed to be water.

    * On function 'EliminateOrphans'
    ----+ System: While
    -----> System: Set OrphanCheck to False
    --------+ System: For "IslandColumns" from ArrayOffset-1 to ArrayWidth-ArrayOffset
    ------------+ System: For "IslandRows" from ArrayOffset-1 to ArrayHeight-ArrayOffset
    ----------------+ System: Array.At(LoopIndex("IslandColumns"),LoopIndex("IslandRows")) ≠ -1
    -----------------> Array: Set ThisX to LoopIndex("IslandColumns")
    -----------------> Array: Set ThisY to LoopIndex("IslandRows")
    -----------------> Array: Set ArrayAve to 0
    -----------------> Functions: Call OrphanCount
    --------------------+ System: Array.ArrayAve ≤ 4
    ---------------------> Array: Set value at (LoopIndex("IslandColumns"), LoopIndex("IslandRows")) to -1
    ---------------------> System: Set OrphanCheck to True
    ---------------------> System: Add 1 to ArrayCount
    --------+ System: [X] Is OrphanCheck
    ---------> System: Stop loop
    
    * On function 'OrphanCount'
    ----+ System: For "IslandXCheck" from Array.ThisX-1 to Array.ThisX+1
    --------+ System: For "IslandYCheck" from Array.ThisY-1 to Array.ThisY+1
    ------------+ Array: Value at (LoopIndex("IslandXCheck"), LoopIndex("IslandYCheck")) ≠ -1
    -------------> Array: Add 1 to ArrayAve
    
    
    

    And to show what I'm doing and why I needed this, here's what the 'island' terrain looks like without running this loop.

    And after running the while loop

    Basically, it's purpose was doing some 'cellular automata' to check and see if a land tile had at least 3 neighboring tiles that were terrain and if not, set it back to a water tile (-1)

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Chrome:

    Click the 3 dots top right.

    Look for Zoom, click the +

  • AFAIK there's no way to determine if an app crashed or the user simply closed it normally, ended the task or exited normally. And, the console log doesn't keep a history that I know of, it's created as the app is running.

    If I really wanted to track down a specific cause I'd have a 'hidden' debug mode which sets a boolean to true if the user selects it and stores that as a local variable.

    I'd use the Browser plugin to write various events in my app to the log (if debug is true) to keep track of what the app is doing. I'd use the JS code above to try to constantly capture that log and store it locally as well. The next time the app is run, I'd check to see if the debug is true and if so, either send that entire log off to a server somewhere or have a 'developer' layout where you can pull that previous run log up and examine it.

    Using that basic method, you could at least determine where the app crashed and possibly the cause.

    You could test your app on your phone in developer mode as that post suggests but more than likely, if your app runs fine in preview without errors, any errors generated on your phone are likely going to be a result of that platform's hardware/drivers/etc and not bad code.

    Again, all of these ideas are just theories, nothing I've actually done or tested.

  • ( had to outdo your pascal after all ;) ).

    I love you guys, I really do.

  • In most other languages there are things called exceptions that can be checked for.

    en.wikipedia.org/wiki/Exception_handling

    In some languages, exceptions can be checked for globally so that if the program crashes anywhere, it breaks out of what it's doing and the programmer can decide how to handle the crash, like a bug report. In JS there is the try/catch which can be used on blocks of code to find when things go wrong.

    In Construct there appears to be nothing like this. In most languages

    4÷0

    would cause an exception. In construct, it let's it fly and gives the results as Infinity. This tells me that Construct is likely set up to at least avert crashes caused by the programmers bad code.

    So, as far as I know, there's no way to have your actual app check itself for errors or crashes and report those crashes back to you. My method of debugging is to run in Chrome and hit the F12 to bring up the developer console. I keep watch on it to see if any serious errors are occurring. If my app runs on my hardware, it's able to do everything I want it to do and I see no errors, then I've done all I can.

    As Ashley pointed out, there are so many different hardware and software configurations out there that it's impossible to test for all of them.

    About the closest thing I've found that can help you track down errors is this:

    stackoverflow.com/questions/19846078/how-to-read-from-chromes-console-in-javascript

    I haven't tried this, but supposedly this JS will capture the console log (in Chrome, I don't know about other browsers). You could likely adapt this to store the log locally and send that log back to a web server somewhere where you could review it. Determining whether the app crashed or not is another ball of wax you'd have to solve. Another thing that could give you some insight is the PlatformInfo plugin. The information it provides is pretty limited but you could also have that sent back to a server to at least know what OS the user is running.

  • Let me demonstrate how old school I am. The pseudo code in my op... it's Pascal

    tutorialspoint.com/pascal/pascal_repeat_until_loop.htm

    And yea, the Do While seems to be Java's equivalent.

    The While loop in Pascal seems pretty close to what you described in Rust. In Pascal, the moment the condition becomes true the loop breaks, and I didn't consider that it would work any differently in Construct.

    In my case, I needed to run through an array of 20,000 elements and check for a number of true conditions and make changes which could affect cells already examined in the loop, making them true. I needed to keep checking the array until all conditions were false.

    I don't need them often either which is why I haven't encountered this in Construct before, but when I do need one, there's just no good substitute.

    Thanks guys, I have been educated.

  • Well be damned.

    In every other language the While requires a condition.

    While found=false do begin
     do stuff
    end while
    

    In that case, even a single found=true breaks the while loop.

    Apparently Construct doesn't even require a condition for the while. Never needed one before so that was a bit unexpected.

    Thanks.

  • lol, yea, crashed the editor to the point that I got an Aww Snap trying that stunt. Lost about 4 hours of work.

  • Does the stop loop action work?

    I imagine it would but, both For and Repeat in Construct force you to enter a number of times it should be repeated. Seems like bad coding to add in a for loop to run a million times just to make sure you get the job done when a repeat until a boolean condition exists would work.

    While is totally unsuitable, at least in my coding experience, because the instant 'Found' becomes true, it breaks the loop.

    But yea, thanks for the idea. I guess a million for loop is on the way.