Frikbot Item desirability

Discuss Artificial Intelligence and Bot programming.
Post Reply
Lightning Hunter
Posts: 169
Joined: Wed Nov 28, 2007 6:15 am

Frikbot Item desirability

Post by Lightning Hunter »

Hey FrikaC, long time no chat. I got the urge to do some more waypoints recently (I know, shocking eh?). I was waypointing today, and decided to investigate something that baffled me for a long time. I always wondered why on certain maps, the Frikbots completely ignored some armor pickups. They seem to choose their "favorite" armors to grab, which sometimes doesn't make sense. For example, they will sometimes choose blue or yellow armor over a red armor, and leave other armors untouched, even if they run right by them. This made me wonder what exactly made them do this, so I tried modifying a .ent file of a level that had this issue. As it happens, the bots will go for armor that appears last in the .ent. I'm not completely certain how this works still, but I think the bots will only grab the last 3 armors on the list, and ignore the rest. So if a large map has more than 3 armor pickups, the bots will only go for the last 3 in the .ent. There might be more to the equation of what makes them choose certain armor pickups, but this is what my current conclusion is.

Is there any way to fix this? I can modify the code myself if you tell me what to do. I'm thinking about releasing an improved version of the Frikbots with version3 of my waypoint pack. I already PM'ed Supa and asked for coding help. If anyone can help me improve the Frikbots, I will include the improvements in the next release. I think it's time some of these issues were fixed, to put Frikbots at the very top.
FrikaC
Site Admin
Posts: 1026
Joined: Fri Oct 08, 2004 11:19 pm

Re: Frikbot Item desirability

Post by FrikaC »

That doesn't sound right. FrikBot finds items by searching using a findradius call, it then iterates through the list created by findradius and ranks every item (priority_for_thing in bot_ai.qc). Red armor is given a priority of 65 if the bot has less than 200 armor, all other armors are given 25 if the bot has less than 100. 25 is as low as the super shotgun, 65 is just slightly above the rocket launcher (60). Possibly what you're seeing is the paths for some of the armors are inordinately long and as a result, FrikBot ranks them much lower than any thing else, thus they never try to get them. The priority values decay by how far away they are, so a long path will decay the 65 down quite rapidly.
Lightning Hunter
Posts: 169
Joined: Wed Nov 28, 2007 6:15 am

Re: Frikbot Item desirability

Post by Lightning Hunter »

FrikaC wrote:That doesn't sound right. FrikBot finds items by searching using a findradius call, it then iterates through the list created by findradius and ranks every item (priority_for_thing in bot_ai.qc). Red armor is given a priority of 65 if the bot has less than 200 armor, all other armors are given 25 if the bot has less than 100. 25 is as low as the super shotgun, 65 is just slightly above the rocket launcher (60). Possibly what you're seeing is the paths for some of the armors are inordinately long and as a result, FrikBot ranks them much lower than any thing else, thus they never try to get them. The priority values decay by how far away they are, so a long path will decay the 65 down quite rapidly.
I think what you are saying only seems to apply when there are 3 armors on the map. In one map I just waypointed, the bots would go for a Blue Armor that was out of the way, yet walk right by a yellow armor and red armor without collecting it. When I moved the Red Armor down to the end of the ENT, the bots suddenly went for it all the time and ignored the Blue Armor. I tested it quite a lot, too. They never went for the RA once until I moved it down the ENT. I think maybe there is a limit on how many Armor pickups are calculated (possibly defined elsewhere in the Quake engine). This is not the only thing influenced by the ENT. I also found that bots will choose buttons based on their location in the ENT. For example, if a door is opened by two buttons, the bot will choose the button that appears last in the ENT.
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Frikbot Item desirability

Post by frag.machine »

Just a wild guess, but since the problem appears to be related to the entity spawning sequence (spawns later, more chance to be noted by FB) maybe the problem can be related to the findradius() builtin behavior not being consistent across different implementations ? Have you tried to test the mod with different engines (say, DP, fitzquake, FTE, etc) to check if there are changes in results ?
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Lightning Hunter
Posts: 169
Joined: Wed Nov 28, 2007 6:15 am

Re: Frikbot Item desirability

Post by Lightning Hunter »

Ok, well I just now tested FitzQuake, Darkplaces, WinQuake, and Qrack. My initial results above were with Qrack, which is my engine of choice.

I've been testing using the map AC2.bsp. This map has 2 yellow armors, two red, and one green. Darkplaces does appear to have less influence from the ENT than Qrack, so I believe Frag Machine is correct. In Qrack, the bots would always obtain the Armor at the bottom of the ENT, and ignore the Armor at the top. In Darkplaces, they go for the Red Armor the most (regardless of their position in the ENT), and ignore the lesser Armor pickups. Is this something that can be fixed with the Frikbots, or does each engine individually need to be fixed?
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Frikbot Item desirability

Post by frag.machine »

I am afraid you will need a fix to the engine. Good news is, findradius is a relatively simple function, so I reckon comparing Qrack's implementation with Fitzquake's (for example) should be easy.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
r00k
Posts: 1111
Joined: Sat Nov 13, 2004 10:39 pm

Re: Frikbot Item desirability

Post by r00k »

Code: Select all

/*
=================
PF_findradius

Returns a chain of entities that have origins within a spherical area

findradius (origin, radius)
=================
*/
void PF_findradius (void)
{
	edict_t *ent, *chain;
	float radius;
	float radius2;
	float *org;
	float eorg[3];
	int i;

	chain = (edict_t *)sv.edicts;

	org = G_VECTOR(OFS_PARM0);
	radius = G_FLOAT(OFS_PARM1);
	radius2 = radius * radius;

	ent = NEXT_EDICT(sv.edicts);
	for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
	{
		//pr_xfunction->builtinsprofile++;
		if (ent->free)
			continue;
		if (ent->v.solid == SOLID_NOT)
			continue;

		// LordHavoc: compare against bounding box rather than center,
		// and use DotProduct instead of Length, major speedup
		eorg[0] = (org[0] - ent->v.origin[0]) - bound(ent->v.mins[0], (org[0] - ent->v.origin[0]), ent->v.maxs[0]);
		eorg[1] = (org[1] - ent->v.origin[1]) - bound(ent->v.mins[1], (org[1] - ent->v.origin[1]), ent->v.maxs[1]);
		eorg[2] = (org[2] - ent->v.origin[2]) - bound(ent->v.mins[2], (org[2] - ent->v.origin[2]), ent->v.maxs[2]);

		if (DotProduct(eorg, eorg) > radius2)
			continue;

		ent->v.chain = EDICT_TO_PROG(chain);
		chain = ent;
	}

	RETURN_EDICT(chain);
}
been so long dont really remember when i changed this...
Lightning Hunter
Posts: 169
Joined: Wed Nov 28, 2007 6:15 am

Re: Frikbot Item desirability

Post by Lightning Hunter »

Fancy seeing you here, R00k. :D

It would be great to see this fixed in a new build of Qrack. I've noticed this issue for a long time when I tested the Frikbots, but never even considered it might be Qrack. :P
Lightning Hunter
Posts: 169
Joined: Wed Nov 28, 2007 6:15 am

Re: Frikbot Item desirability

Post by Lightning Hunter »

I've been messing with the Frikbot item priority lately, but had a few questions (I'm pretty much a noob coder). I successfully got the bots to collect armor the way they should - meaning they ignore blue armor if they have anything less than 100, ignore yellow armor with less than 150, and mostly go for Red armor. However, I was also wanting to add some randomness to the pickup priority, so I tried something like this with the code:

Code: Select all

				else if (thing.classname == "item_armor1" && self.armorvalue <= 99)
					thisp = 40*(random()) + 55;
				else if (thing.classname == "item_armor2" && self.armorvalue <= 149)
					thisp = 50*(random()) + 60;
				else if (thing.classname == "item_armorInv" && self.armorvalue <= 200)
					thisp = 60*(random()) + 65;
In theory, shouldn't this code make the default priority of the green armor 40, with a random chance that it will be 55? Or do I have it figured all wrong? I'm still trying to figure out if this code does anything at all. I saw similar code as this for the Quad Damage, and attempted to copy it for the Armor pickups, but am unsure exactly how it works.

I was hoping to perhaps add some randomness to some of the weapons as well, if I can get this working right (I'm starting with the armor).
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

Re: Frikbot Item desirability

Post by gnounc »

I dont know what the code that reads your priority value looks like, so I dont know what range its expecting, but the answer to your question is no.

random() produces a number between 0 and 1. So a random number between 0 and 1 might be say... 0.3.
0.3*40 would be 12, add the 55 and you've got 67 as your final priority value.

The priority will be a number between 0*40 + 55 and 1*40 + 55
55 - 95

So look at whatever is reading your priority value, and see what kind of a range it expects.
If you want exactly 55 to happen a certain percentage of the time, decide on the percentage, here we'll say 33%,
and do:

Code: Select all

r = random();
if(r <= 0.33)
{
    thisp = 55;
};
which works because 33% of the numbers between 0 and 1 are less than 0.33.

I hope that helps.
Lightning Hunter
Posts: 169
Joined: Wed Nov 28, 2007 6:15 am

Re: Frikbot Item desirability

Post by Lightning Hunter »

gnounc wrote:I dont know what the code that reads your priority value looks like, so I dont know what range its expecting, but the answer to your question is no.

random() produces a number between 0 and 1. So a random number between 0 and 1 might be say... 0.3.
0.3*40 would be 12, add the 55 and you've got 67 as your final priority value.

The priority will be a number between 0*40 + 55 and 1*40 + 55
55 - 95

So look at whatever is reading your priority value, and see what kind of a range it expects.
If you want exactly 55 to happen a certain percentage of the time, decide on the percentage, here we'll say 33%,
and do:

Code: Select all

r = random();
if(r <= 0.33)
{
    thisp = 55;
};
which works because 33% of the numbers between 0 and 1 are less than 0.33.

I hope that helps.
That helps a lot! Thanks. The only other question I have is if these random numbers are only calculated once at the start of each map, or if they are calculated each time the item is spawned. If it isn't the latter, then it's useless (The randomness should change during the match, so the bots occasionally choose the rocket launcher over the Red Armor for example, but not all the time).
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Frikbot Item desirability

Post by frag.machine »

I suspect (cannot check the frikbot code right now to confirm) the snippet you posted is executed periodically by every bot (it seems to be part of the target seek/evaluation code). At least it wouldn't make a lot of sense to be executed only once.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

Re: Frikbot Item desirability

Post by gnounc »

ack, thats a good point.
If that check is run during an ai routine, and random is being called inside it, its going to lead to weird behavior where
a bot will be headed to an item because it has a higher thisp than another item, and then may suddenly turn around,
and then turn around again confused because of a fluctating thisp.

The thisp values should be static for the lifetime of the item in question, so it shouldnt be in an evaluation routine, it should be in a spawn routine.

You'll want to find the items spawn function in items.qc and create a new field called thisp.
and before its spawned call random(), and set that to the new field.

then you'll need to change any code in frikbot that finds objects and checks thisp, and make it check that particular
items self.thisp field. That may sound complicated to you but its uber easy, maybe head to the irc channels for some help.
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Frikbot Item desirability

Post by frag.machine »

Well, as the G-Man would say, prepare for unforeseen consequences when messing with bot brains.

With the fragbot (which borrows a lot of the concepts from the Frikbot, mostly the "stack of interesting target") I stumbled on this same problem of bots becoming indecise about what they wanted to do but for different reasons ("ohh look, a shiny red armor! Oh wait, there's a rocket launcher just over there, oh never mind, now the armor is closer, oh noes, now the rocket launcher is closer...").

I had to add a "interest time" to the equation, so if I am heading for the shiny red armor, I won't bother looking for something else until I reach it or at least for N seconds, where N was estimated based on distance mostly. If the item wasn't reached until the end of the interest time, it was removed from the stack and the second more relevant target took its place. Of course, things were a bit more complex than that, but in general that's the idea.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Lightning Hunter
Posts: 169
Joined: Wed Nov 28, 2007 6:15 am

Re: Frikbot Item desirability

Post by Lightning Hunter »

I've been observing the bots for a while now with the random "thisp" code added, and have found that it might only be calculated once at the start of a map. I noticed that bots pick their favorite items at the start, and consistently go for them the entire match. Each time I start the map over, they pick different favorite items (based on the random factor). I also know that once Frikbots decide they want a certain item, they continue trying to get the item even if it has been picked up by someone else. They then proceed to stand on the spot where the item used to be for a few seconds, then start heading toward a different item (this is a minor nitpick of mine with the Frikbots).

Not sure if anyone knows how to fix these issues.
Post Reply