#Maze not random, and my blueprint logic isn't working somehow

1 messages ยท Page 1 of 1 (latest)

naive tiger
#

Update:
Ive had a lot of help, and im happy with where i am so far.
https://cdn.discordapp.com/attachments/1272092288620822548/1274108434811453470/2024-08-16_13-50-42.mp4?ex=66c10d72&is=66bfbbf2&hm=00a43e9f65fbe07c2078aa9ac018d1100056e0c6e8bcf2e111c48a7871282517&

An overview of the project:

My cell generator actor spawns a grid of cells, with each cell dynamically placed based on where the cell generator is, and where the cell before it was placed. It stores a reference to each cell inside its cell array.
Then, for each cell in that array, it calls on the cell's find adjacent method, that finds and stores each cell next to it as variables and in an array. Now, each cell knows where its neighbors are on its 4 sides.
Each cell has a Visited? boolean variable. Each cell will check if their adjacent cells have been visited, and if they havent that cell will be added to another array of cells to visit.
The cell generator has another method to find the starting cell, and the ending cell. These 2 cell's should be chosen from the list at random, and if the cell has 4 adjacents we know it is in the center of the maze and is not a valid start or end, and it will do it again until it finds a valid cell.
From the starting cell, my break walls method in the cell blueprint should choose a random cell in it's to visit list of cells that has not been visited, break the wall between the 2 cells, and then call the same method on the chosen cell, and remove it from the to visit array. It also sets the current cells Visited? bool to True. In this way, every cell will be visited, and at least one wall will be broken in a randomized manner.
I also want this method to be delayed, and happen in realtime.

rapid oyster
#

So, I'm not going to watch the entire video, but a few points:

For procedural generation like this, we would usually do the actual generation purely in data and then translate that data to objects in a scene.

Using overlaps to get neighbours is overkill. If you have all the cells in an ordered array, you can get neighbours and see if a cell is on an edge using very simple math.

If the delay you want is purely visual, it's probably better to do the logic offline (as in, not real time) and then animate it after by storing the move order in the cell data

#

I would personally do the grid by having an array representing a grid of a struct containing the data needed.

naive tiger
#

im pretty new to UE, so im not actually sure how to use structs.

i have tried to do the animation after the calculation. i have a separate function that updates the walls. each cell has 4 wall booleans like HasLeftWall, and i did the wall breaking first which flips those, and then just updated all the cells to reflect the changes made to those booleans. when a wall is false, it just hides the wall and turns off its collision.
Im not sure how i would store the path that the breaker function takes.

I was doing overlaps because i was too lazy for math! my original plan was actually to do a nested array, to make a matrix. however i quickly learned that im not able to do that in UE. i considered using maps, but i read a bit about them and they seem different from the mapping objects i know from python, so i discarded that idea until i learn more about them.
However, my overlap tech does work. each cell accurately knows all their adjacent cells. I just don't understand why my logic for finding the start and end is not working. it makes no sense to me.
if there is an efficiency reason to not check for overlaps then ill change it, but i want to figure out why it doesnt work how it is currently.

rapid oyster
#

You can always use a 1D array to represent a grid (and I would always choose it over nested arrays).

Array size equals gridWidth ร— gridHeight

To get index from grid cell (x, y) you do:
y ร— gridWidth + x

Inversely, to get grid cell from index you do:
x = index % width
y = index / width

naive tiger
#

I'm not sure I understand. I'll do some googling though.
I assume 1d array is like what I have already
I'm also not sure how to access an actor based on its position, and I don't think I can access an object from an array by it's index in the array. Pretty sure I tried something like that before.

What I did not try was doing a name concatenation of the actors class name with whatever number I extrapolates from the math onto the end of it. I'm pretty sure I can do something like that and pull an object from an array using a specific name.

naive tiger
#

i did a quick mock up, and your math is correct

#

in this mockup example i used a list of lists so i can print it out nicely.

naive tiger
#

oh im so dumb

#

oh my

#

its glorious

naive tiger
#

@rapid oyster
while i havent implemented your math idea yet, i did take a fresh look at my project and i got some things working, but some other things are broken. im getting a weird infinite loop

rapid oyster
#

First of:
I appreciate that it may be easier for you to record a video on it, but it does make it really hard to review the code. Screenshots would be preferable

Not having reviewed it closely, my guess is the infinite loop is a result of your wall breaking getting stuck in a repeated pattern or something similar. But again, without a closer look it's hard to tell

naive tiger
#

my bad. ill take some screenshots

#

mm its quite difficult when the code is spread out. all the text becomes really blurry if i zoom out too much

#

wall breaker between cells does nothing besides flipping booleans. idk why it would be a problem

#

i could probably make this a sequence or something and make the code a lot more compact instead of a branch tree

rapid oyster
#

But it is recursive. If an infinite loop is detected, it means your recursive function is unable to find the exit condition

naive tiger
#

right, but what makes my maze different from having 10x10 cells to having 20x20?
each cell is only checking a maximum of 4 adjacent cells

#

the exit condition is running out of array items to loop over

#

i dont see where it can get stuck

rapid oyster
#

So usually it happening at a higher size is an indication that it's an edge case. A higher size means more opportunities for it to happen.

But as an excersize, try graphing out on a piece of paper, or in some other drawing medium, what actually happens in this recursion.

I'll look more at it to see if I can find the issue

naive tiger
#

alright thanks dude. ill go eat lunch and think about it as well

#

The real question is why wall breaker between cells is on the call stack. All it does is take one cell and another cell and flip bools.

#

I don't see how that can be part of the infinite loop occuring

#

I think I had a similar thing happen before, and I also couldn't figure it out then. I just redid all my code and got the broken code i had earlier

naive tiger
#

i tried adding a manual break just in case one of the loops was going too far. didnt work

#

there cant be more than 4 array items anyway though

naive tiger
#

im doing debug sessions, but its rly hard to know what im looking for. everything is working as intended for the most part. i havent yet found a problem

#

well damn. i was clicking through the breakpoints and my debugging session crashed from the loop. its impossible for me to know when it will happen, and there are so many cells to click through and i dont know what im looking for

#

It encounters the infinite loop at random times during the debugging and I'm not able to catch the reason

naive tiger
#

i have gone through and checked every cell before the recursion comes into play. they all have exactly as many items in their adjacent cells as they should. 2 for the corners, 3 for the sides, and 4 for everything else.
i checked a few random ones, and they match up on adjacent cells in their list, and the specific reference they have depending on which side the other cell is on.
i see no indication of where a problem can happen

rapid oyster
#

bp.ScriptRecurseLimit

#

set that to a higher number than the default 120

naive tiger
#

!! it has a limit??
where can i find that

rapid oyster
#

in the console

naive tiger
#

o

rapid oyster
naive tiger
#

! you made the maze i spent a week on in an hour.

#

youre so good

#

so i type:
bp.ScriptRecurseLimit 800
into the console?

#

or some other number

#

IT WORKS

#

FUCK ME WHY IS THERE A LIMIT

rapid oyster
#

You'll never go above width * height

#

well, the reason is because recursion is the devil

naive tiger
#

dude thank you so much for finding that for me

rapid oyster
#

sorry for not thinking of it sooner

naive tiger
#

no problem. stewing is good for the soul

#

is there a similar thing stopping my delay from working?

#

i dont know what else might be in the console

rapid oyster
#

Yeah, the lesson here is to read the output log

#

hmm not sure

#

how is your delay implemented?

naive tiger
#

im pretty sure i read it. i dont understand some of the things it says tho

#

basically just stick this delay into the loop

#

see, my cell gets visited

#

but it never updates

#

the delay just breaks it

#

is there a way to set the recursion limit within the event graph?

#

oh

rapid oyster
#

ye

#

for the delay part, I'd add a variable per cell that would be the "age" of that cell. start cell is age 0, the first cell it enters gets 1, the first cell that one enters gets 2 etc etc

#

Then use some time logic to animate that

#

I definitely wouldn't time gate the generation logic

naive tiger
#

how do i animate it without doing actual changes. im not that far into my learning of UE maybe

#

ok so now it should always be a proper recursion length

#

well i can do this part at least

#

oh wait thats not correct

#

there we go

#

so i know that moving actors have an animation graph, but i dont see something like that for my cell actors. they are made of static mesh walls

naive tiger
# rapid oyster Then use some time logic to animate that

you know what, im really happy with what ive accomplished so far, and im VERY thankful for you taking the time to help me out.
i have to get back to learning C++ though, and ill work on this maze more in the future when im more knowledgeable about unreal.

rapid oyster
#

You're doing good!

naive tiger
#

thanks bro. i should take the time to look through console commands too. seems important

tired fiber
# naive tiger the delay just breaks it

i see this has been solved but for future ref if u double click loop on the for each node u can duplicate the macro and add a delay somewhere in there and add duration as an input. i'll add a screenshot when im home but it's helped me avoid the dreaded infinite loop and helps w performance!

naive tiger
#

like so?

#

this doesnt seem to do anything unfortunately.

naive tiger
#

everything still happens at once

tired fiber
#

aw man i totally forgot after getting home my bad but you'll want to place the delay node here

#

bottom right of the image

#

trust it works wonders

tired fiber
# naive tiger

but yeah u were on the right track w the input just off placement

#

took a lot of experimenting but so worth it

#

u can use the same technique with any of the for loop nodes btw

#

oof i just realized the image isnt that clear what with the straight node lines but the delay goes into the branch node near the center of the screenshot

naive tiger
whole geyser
# tired fiber

out of curiosity, what version of UE are you using?

in UE5.3.2, it won't let me add a Delay node to my Macro Library ๐Ÿ˜ฆ

#

(wait nvm i just realised it's a local macro, and that did let me add a delay ๐Ÿ™‚ )

#

wish it let me add to a library though

tired fiber
tired fiber
tired fiber
rapid oyster
#

I just want to add:

I offhandedly said recursion is the devil, but I do want to stress the point that 90% of the time, you really want to use an iterative approach rather than recursion.

Recursion is generally a bad idea, which is why it has a cap here.

Making this iteratively instead of recursively isn't that complicated. Virtually the same logic, but instead of jumping in to branching recursive functions, you'd use something more akin to a pathfinding algorithm (like A*), keeping track of open and closed positions with lists

naive tiger
#

i can try that. i come from just learning python, and the algorithms i learned there have a lot of recursion, its just code and line efficient. im no guru, but i know lists take memory space, and recursion takes processing power, so its a tradeoff.

naive tiger
#

I'm gonna read this

rapid oyster
#

Recursion is as, if not more, memory intensive. Performance wise it's not much of a difference.

I won't go into detail, but it's got to do with generating stack frames for each function call

In this specific case, it's actually not that big of a difference, but in many cases the difference can be massive

Like using recursion to calculate a large fibonacci number will explode in memory cost (which also costs performance), while doing it iteratively keeps that cost constant. This is a more extreme example though

The main draw of recursion is that it's often just more "elegant" and can be done with fewer lines of code, but it's rarely the better choice.

Again, it's not that important in this case, so you don't have to waste much time on it.

naive tiger
#

Imma waste all the time on it!!!!

naive tiger
#

Right now I have it on begin play event, when the game has already loaded. I'm not sure how to do it before that

#

I could pre-load the game from my main menu screen maybe

#

Before switching levels, but after I've hit play

rapid oyster
#

No I meant to generate the path to be taken in one single instant sweep, and then animate the visual aspect of it over time.

#

Not to pregenarate the maze

naive tiger
#

Ah ok. So yeah that's what I'm doing now

rapid oyster
#

Well in that case, great!

naive tiger
#

The other thing with iteration is that id have to do it from the generator class. Then my cells would be left with nothing to do, and they would be sad

#

its more than just 4 walls and a floor. it has a rectangle light that represents it's soul

naive tiger
# naive tiger https://professor-l.github.io/mazes/

well this was rly cool to read. i still like the backtracking algorithm the most (the one im using), because it looks clean and fun. even tho some of the other algorithms may be more technically maze-like, they also have so many 1 block dead ends and short branches that make them really unappealing

#

i think wilsons algorithm has cool results, but its probably the most inefficient thing ive ever seen

#

its been going for 5 minutes, not past the first step

rapid oyster
#

You can make the exact same logic as your current but iterative, no problem

#

I do like the approach, it is very simple and effective

#

My one issue with it is that it doesn't guarantee the ending point is the end of a path

#

Though that can also be a bonus, making it harder to backtrack

naive tiger
#

yeah currently i just choose a random cell as the end, but i might take a different approach when i have everything working the way i want it to.

#

i started trying to implement the iterative version, but im having trouble understanding blueprint array methods.
how do i pop an item?
i can get an item with the get node, but it only returns a copy, and i cant find a reference get.

#

i googled it, and i see that other people have the option for reference get, but its not showing up for me

#

what the shit

#

i can find it by turning off context sensitive, but it automatically changes it into a copy

#

this program tries to kick my shin at every turn

naive tiger
#

its hard to make things readable when you zoom out, i hope this is fine tho.
my logic here should work right? i think its the proper method, but im getting that None error.

#

i did like an hour of research trying to figure out how to change the font or sharpness settings, or really anything, on the blueprint editor. the text is so bad in this program and i cant believe theres no way to change it natively

naive tiger
#

so i needed to cast it

#

hmm. idk whats going on

#

very weird

tired fiber
#

not sure if this'll fix the issue or if ur even doing this but afaik ur not supposed to change the order (remove/add) of an array inside a for each node that takes that same array as an input. again not sure if ur doing that but if you are, try first duplicating the array you want to reorder and use that as the input to the macro, while using the "real" array inside the loop.

#

someone more knowledgeable please feel free to correct me if im wrong though

rapid oyster
#

I'm a bit busy, so I'll get back to you @naive tiger

naive tiger
naive tiger
#

although it does seem less chaotic than before

#

so i think it did fix one of the problems

#

i guess i had multiple

#

some cells arent clearing their arrays

naive tiger
#

oh my god. apparently every time i use this random thing it chooses a new one. i thought i was choosing one item, and then i could use that item for different things.

#

it works....

naive tiger
#

finally. this took me way longer than it should have

naive tiger
#

@rapid oyster @tired fiber
once again, thanks for all the help with this. still some things to work on, but im satisfied with what i have right now. i have to move on with my learning journey.

rapid oyster
rapid oyster
naive tiger
#

thats very true. thanks for the encouragement!