Runaway loop error annoyance...

Discuss Artificial Intelligence and Bot programming.
Post Reply
blubswillrule
Posts: 68
Joined: Mon Oct 04, 2010 9:08 pm
Location: Lincoln, California

Runaway loop error annoyance...

Post by blubswillrule »

Hey guys, I've been' having this major problem with my ai for a mod of mine, and I cannot figure out what is wrong for the life of me!

The ai is basically following the AStar algorithm for pathfinding (in case anyone here knows about it)

The function looks for waypoint with a .link of "OPEN", and the lowest F value, and it looks at all the waypoints on the map.

Code: Select all

entity(entity treeb) find_open = 
{
	local entity way;
	local float fbest;
	local entity best;
	fbest = 10000;
	way = find(world,classname, "waypoint");
	self.loopcount = 0;
	while(way)
	{
                /////////////////////////////////
		if(self.loopcount > 300)
		{
			bprint("find_open-loopcount max! \n");
			self.loopcount = 0;
			return(world);
		}
			self.loopcount = self.loopcount + 1;
                /////////////////////////////////
		if(way.link == "OPEN")
		{
	        	if(way.F < fbest)
		        {	
		        	fbest = way.F;
		        	best = way;
		        }
		}
		way = find(way, classname, "waypoint");
	}
	
	return(best);
};
This code will spontaneously crash with a runaway loop error, even though I added something to counter that (limiting the loops to 300, when the quake limit is something like 10000 )

Could anybody please help?

Thanks.
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it :)
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Post by Spike »

that code is not an infinite loop.

check where its called from, you might find the parent function is the looper, or just really expensive.
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Post by frag.machine »

For a start, I suggest not using an entity field as break condition for your loop. Use a local var instead.

Also, in the case of path finding, may be a good idea to adapt the code to use findradius() instead.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
blubswillrule
Posts: 68
Joined: Mon Oct 04, 2010 9:08 pm
Location: Lincoln, California

Post by blubswillrule »

I tried using a local float, but it still gets the runaway loop error

What is realy interesting is how can it get a runaway loop error if it should only run 300 times then stop.
(it technically should only run like 60 times, that's the average amount of waypoints on a map)

Also, as for findradius...

this find_open function is for finding the path basically, so it won't exactly run from the ai's perspective...

unless you had some other form of using it in mind.
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it :)
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Post by frag.machine »

blubswillrule wrote:I tried using a local float, but it still gets the runaway loop error

What is realy interesting is how can it get a runaway loop error if it should only run 300 times then stop.
(it technically should only run like 60 times, that's the average amount of waypoints on a map)

Also, as for findradius...

this find_open function is for finding the path basically, so it won't exactly run from the ai's perspective...

unless you had some other form of using it in mind.
Its not like using find() wouldn't work, absolutely. It's just that if you're creating a function that does something like "here, take this waypoint entity and find the nearest similar one" a findradius() would chop off all too far entities, engine-side. Besides, findradius() isn't restricted to AI aspects (although finding a waypoint may be considered part of AI).

To ensure your code is actually being interrupted below 300 interactions, you may want to use this instead:

Code: Select all

(...)
loopcount = 0;
way = find(world, classname, "waypoint");
while((way) && (loopcount < 300))
{
    (...)
    loopcount = loopcount + 1;
    way = find(way, classname, "waypoint");
}
(...)
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
andrewj
Posts: 133
Joined: Mon Aug 30, 2010 3:29 pm
Location: Australia

Post by andrewj »

blubswillrule wrote:What is realy interesting is how can it get a runaway loop error if it should only run 300 times then stop.
You misunderstand the runaway error. It is a limit on instructions and applies to all the code that gets executed once the engine starts running some QuakeC code -- not just the code in a single function.

As Spike said, it's not the find_open() code which is the problem (or main problem) but the parent function which calls it. The combination of them both will be causing the limit to be hit.
blubswillrule
Posts: 68
Joined: Mon Oct 04, 2010 9:08 pm
Location: Lincoln, California

Post by blubswillrule »

Well guys, I've hit a brick wall with this... yet again, I now understand that I get this because of everything going on at once, and heres the details...

average number of waypoints in a map ~ 60

find_open is in another while statement.
(this while statement varies on how much it runs, the ideal testing condition would be it running once per waypoint on a map (it won't always use every waypoint)

so, theoretically, within a single frame, the while statement in find_open is being ran 3600 times, (not sure if it's enough to cause a runaway loop error on a psp)


Also, I ONLY EVER get a runaway loop error on psp, NEVER on pc (obviously due to different runaway loop # limits (darkplaces's is 10,000,000?))

Frankly, this bug is extremely annoying.

I was looking through the frikbot source, and they had an interesting comment there. (something along the lines of) "use thinks to avoid triggering the runaway loop counter"

I have tried to make my pathfinding use thinks, but have failed miserably, could anyone lend a hand please?
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it :)
Arkage
Posts: 66
Joined: Thu Nov 19, 2009 4:17 pm

Post by Arkage »

The limits a 100000 on the psp.
If you want to bump it up its line 372 ish in pr_exec.c.
blubswillrule
Posts: 68
Joined: Mon Oct 04, 2010 9:08 pm
Location: Lincoln, California

Post by blubswillrule »

would bumping it up cause any undesired results?

Since nothing else causes a runaway loop error, they'll stop way before going too high up the count... so the only function to go up that high would be these.
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it :)
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Post by Spike »

increasing the limit is fairly safe

removing it entirely won't break anything either, except that if a mod does go wrong the user will need to end-task, which shouldn't happen anyway. same problem as an unreasonably high limit.

the limit is already fatal, the map will be killed.

really the value should be in seconds-on-the-lowest-reasonably-specced-computer, which means the ideal limit changes over time. bumping the limit is consistant with that. even if the limit is fairly generous, its not too bad.
necros
Posts: 77
Joined: Thu Dec 16, 2004 10:32 pm

Post by necros »

i haven't seen the frikbot code, but probably what he meant by 'use thinks' is he is deferring some of the while loop to another frame.

for example, if you use find(), you can tell it to loop only 10 times then at the end of the loop, store the last entity in a field until next frame, then, next frame, instead of starting your find() at world (the start of the list), feed in that stored entity field, and you'll basically pick up where you left off.

spreading out large loops in thinks can speed things up too, because if you have multiple loops going on that are extensive, they may not trip the runaway loop error (because they are spread out in multiple loops) but you'll be able to see a visible slow down as the engine is looping through all those instructions.
blubswillrule
Posts: 68
Joined: Mon Oct 04, 2010 9:08 pm
Location: Lincoln, California

Post by blubswillrule »

yeah, I couldn't get thinks to work for the life of me, haha, the hardest part was getting the ai to recognize where it left off...

but anyways, raising the runaway loop counter to 1,000,000 worked :D

thanks guys!
A truly rewarding experience for an AI coder: watching your ai navigate the map... makes all the time invested in the code worth it :)
Jukki
Posts: 214
Joined: Wed Apr 07, 2010 4:59 am

Post by Jukki »

YEah. while making it so that there is a lagspike where used to be crash
Post Reply