Gamemaker crashes without error message in a recursion script

Hi everyone
I usually try to figure things out on my own and with the help of already posted questions, but with this one I don't even know what to search for.

I am building a level editor for my game. The level consists of nodes that are either on or of, stored in a 2d array.
I wrote a recursive script to fill areas of the array kind of like the paint bucket tool in paint. The script checks for one node if it is on and if it isn't (and therefor is inside the barriers) it turns on and then executes the script for the four neigbouring nodes.
here is the script:

GML:
///fill(x, y, mode)

var fill_x = argument0
var fill_y = argument1
var mode = argument2

if(lvl_map[fill_x, fill_y] = mode)
{
    if(mode = 0)lvl_map[fill_x, fill_y] = 1;
    if(mode = 1)lvl_map[fill_x, fill_y] = 0;
    
    if(fill_x>1)
    {
        fill(fill_x-1, fill_y, mode)
    }
    if(fill_x<(room_width/block_size)-1)
    {
        fill(fill_x+1, fill_y, mode)
    }
    if(fill_y>1)
    {
        fill(fill_x, fill_y-1, mode)
    }
    if(fill_y<(room_height/block_size)-1)
    {
        fill(fill_x, fill_y+1, mode)
    }
}
It seems to work fine with small areas, but when I make bigger areas it just crashes without an error message, just returns to the editor
I can't find a clear rule for when it crashes and when it doesn't

Any help in figuring out the problem is greatly appreciated
 

Attachments

curato

Member
Try opening up task manager and keep track of available memory. recursion is nice but each step in requires resources. you may just be maxing the system out.
 

Nidoking

Member
I don't see any end to the recursion. What's supposed to prevent it from looping back and forth between the same two tiles forever?

Oh, wait. There is an if. But you'd be better off putting these in a list and doing the job by iterating over the list instead of calling a recursive function.
 
I don't see any end to the recursion. What's supposed to prevent it from looping back and forth between the same two tiles forever?

Oh, wait. There is an if. But you'd be better off putting these in a list and doing the job by iterating over the list instead of calling a recursive function.
I want to only fill the nodes that are inside the boundrys, like in the screenshot
how would I check whether it is inside without a recursion?
 

Roldy

Member
As others have said, re-write this to have a clear and guaranteed exit point. Or better unwind it and don't do recursion.

I would think you would run out of stack. Out of curiosity I did a quick test:

GML:
function foo(a) {
    show_debug_message(a);
    a++;
    foo(a);

}

foo(0);
At recursion depth 1,000,000 there is a significant slow down in FPS and memory usage increases by about 30%. I assume from growing the stack. So possibly the stack grows and you can't overflow it?

What is interesting is if I pass more variables to the function (pushing more onto the stack) it doesn't change the behavior. The slow down and memory growth still occurs at recursion 1,000,000.

I ran this up to about 1.6 million recursion and it never crashed. But it was going so slow I got bored and didn't wait to see it grow further.
 
Last edited:

Nidoking

Member
Set value of first cell.
Put cell in list.
Check surrounding cells - if they need to be set, set them and put them in the list. DO NOT RECURSE. DO NOT RECURSE. DO NOT RECURSE.
Remove the first cell in the list.
Repeat with the first cell in the list until there are no more cells in the list.
DO NOT RECURSE.
 
okay that sounds like a great idea
sorry for draining out your patience

btw it crashes at a recursion depth of arround 100 so there still is a problem I don't understand
but whatever since i DO NOT RECURSE it's fine

thanks y'all
 
Top