What counts as a "Iteration" and how can I parse giant loops into smaller chunks?

Edit: My code iterates millions of times on purpose.

I guess I only have 2 simple questions:

  1. What counts as an “Iteration”?
  2. Has anyone found a workaround blueprint method for parsing these giant loops into smaller chunks?

I am procedurally generating a hex map. With 800 hexes, and ~270 loops per hex, I am hitting the 1,000,000 loop limit.

200x135 = 27,000 Executions(No problem)

800x270 = 216,000 Executions(Hits Limit)

I have 270 items spread throughout 6 arrays which are being run by a ForEachLoop on the 800 tiles in the map.

The only thing I can see bringing me up to the 1million mark is perhaps math and boolean nodes leading into the executions?

Each math operation counts towards the limit? I am easily doing a million math operations on the side for my 216K executions.

(quick math tells me I will be hitting 1-10 billion iterations by the time I am done with the generator and generating maps with 10-20K tiles… :stuck_out_tongue: )

Im not entirely sure on the answer but I have had this explained to me for unreal script, and I think it works out that for loops use less iterations than foreach and do/until use the least. That said Id recommend trying to use Do N nodes where possible and see if that helps. You can also offset doing more operations inside loops by saving multiple arrays of data so you are only iterating the relevant set instead of every single item each time. I’d really need to see how the looping is working to offer better suggestions for optimization.

Arbitrarily limiting the loops isn’t going to help.

I have one trick I could use to cut down iterations by a factor of 10-20. I can do lat/long range checks to ensure that the loop isn’t calculating vectors that are too far from the target area. It will take more than a hundred branches to narrow it down. It won’t be pretty, but it I was going to have to do it anyway.

Problem remains however. I am hitting the limit on a map with 800 tiles, and I have only implemented one third of the tile types, no resources, no rivers, no tile volumes, and max map size will be somewhere around 20-40,000 tiles.

I am estimating a billion iterations on the largest map generation even after sectioning the loop zones.

You could use the EventTick with a gate or a branch and a boolean variable to stop the “ticks” from activating your code indefinitely.

4583-bp.png

My code doesn’t activate indefinitely, it activates a set number of times that happens to be in the millions of iterations by design.

I did try using a gate just to see if opening and closing it would count as separate loops, but no luck… :stuck_out_tongue:

You could do parts of the logic in c++ that would avoid the hassles, honestly its probably better for you if you have a complex tile system. There is TMap and TMultimap that might be better for these purposes.

I think you are iterating some portions you dont need to though if you only need 800 tiles, Ive done a 30x30 grid of meshes and I had no issues.

I try to clarify things a bit

You can easily spawn 1 Million Actors with this “Loop”. Instead of Spawning Actors, you could do some calculations where the “SpawnActor”-Function is right now.
The Problem could be that EventTick is framerate dependent, so more FPS equals faster execution times :frowning:

I am sorry but I don’t want to stop my map generator from iterating past a million.

I want to remove the limit.

Given the complexity of the generator, I will definitely move it to C++ at some point just for performance reasons.

However, I am not a programmer and I would like to get it fully working in BP before moving it. I may either learn how to do that myself, or find someone who can help but it will be done eventually.

The huge amount of iterations comes from the generation itself. For every tile generated, I am doing at least 10 math operations 100-200 times.

There are efficiencies to be had with the number of iterations, but that will be offset by adding more tile types. Additionally, the math operations will only rise as I make the generator more complex.

If I want to continue to rapidly prototype in BP, I need to have the limit removed.

I mean no offense but it sounds like you are doing something wrong or making something needlessly complex. If you are having to perform so many operations on tiles how come you dont do that logic in the tiles themselves?

Ive looked over your thread and I have no idea why you needed all those booleans, Id really like to help you optimize your thinking and your maths for that matter but its hard when I only see a small part of the picture.

The limit is there for other reasons not just to annoy you, it might be an annoyance but I honestly think there are ways you could optimize what you are doing and you should ultimately save yourself alot of trouble sooner and talk to a programmer asap.

The logic is to determine where the tiles get placed in the first place. I am checking for many conditions to find out whether a tile should go in a specific location or not.

Besides cutting off my map generation before it is finished, what exactly is Do N going to do for me?

When I get back in a few hours I will try and lay out how my operation is run so you can get an idea of what is going on. Probably do it in a forum post and link here.

Look I’ll just save you the hassle and link you want you want, I really hope your maths is top notch.

https://github.com/AndrewScheidecker/BrickGame/tree/master/Plugins/SuperLoopLibrary

Thank you for the link!

Here is the forum post: Map Generator- Please Critique! - Blueprint - Unreal Engine Forums

Rereading this thread I think now I have a better idea of what Yibby was trying to tell me.

The iteration limit was increased to ~2 billion which is currently high enough for my needs right now. It takes roughly 3.5 minutes for a map with 20,000 tiles to generate which includes things like plate tectonics, weather, river generation, etc, etc.

Would doing this on a Tick be faster than using ForEachLoops?

How do I ensure this whole process occurs on a separate thread in blueprint?

How would you suggest splitting up the work?

there is a limit to forEachLoop because it pauses execution until the loop is complete. instead you need to find a way to split up the work into manageable chunks that you process separately. i can’t tell you how to do this because its completely dependent on how your function works, but adding a delay into some of your loops might help you avoid doing it all at once:

It is mostly ok for things to stop while the map generator does it’s business. In most games of this type, the player starts the game, and waits up to a few minutes for the map to generate.

What I need to happen during this time is perhaps a loading bar to fill up showing generator progress, and maybe some additional text to keep the player occupied while everything is loading.

That seems pretty straightforward since I can call these actions between sections of my generator pretty easily.

Getting it to run on another thread interests me more though, because then I could have more involved things going on while the map loads such as animations, movies, or potentially other interactive bits. I am not sure I want to fill my loops full of delays because that would increase generation time without really giving me much benefit.

My original problem involved getting around the editor loop limit, and I don’t want to code everything just to get around some arbitrary editor limitation, but that is mostly moot now anyway.

So I don’t think I need to split things up for the sake of splitting them up, but I do want to interject at a few points in the generation, and obviously make the whole process a fast as possible.