Improvements to SemperFi-js AI

For AI and campaign script related discussions and questions
Post Reply
User avatar
Berserk Cyborg
Code contributor
Code contributor
Posts: 938
Joined: 26 Sep 2016, 19:56

Improvements to SemperFi-js AI

Post by Berserk Cyborg »

I looked at the SemperFi-js AI code and it looked a bit... unfinished. So I went and fixed it up and made it a lot more maintainable. Added stuff like hover map support and anti-air defense building. It never built rearming pads for VTOL units, so I added that as well.

I still need to see how the original Semper-FI AI works and add anything missing from it and do more tests and bug fixes. Right now it might trigger a fatal lockup that I can not always reproduce (really just slows down warzone a bit and then crashes hard). Have not found the cause of that yet. Fixed it.
semperfi.wz
Git branch here.

Edit: Try preventing it from taking control of trucks that it does not own.
Last edited by Berserk Cyborg on 20 May 2017, 23:23, edited 3 times in total.
Per
Warzone 2100 Team Member
Warzone 2100 Team Member
Posts: 3780
Joined: 03 Aug 2006, 19:39

Re: Improvements to SemperFi-js AI

Post by Per »

Looks really good!

One annoying little bug I found: Whenever the AI ally steals an oil derrick from right under my nose (which every AI does), it orders my trucks to build defenses for it. An ally should never order my droids around...
User avatar
Berserk Cyborg
Code contributor
Code contributor
Posts: 938
Joined: 26 Sep 2016, 19:56

Re: Improvements to SemperFi-js AI

Post by Berserk Cyborg »

Per wrote:... it orders my trucks to build defenses for it. An ally should never order my droids around...
Sounds like a legit tactic to conserve its own power. In all seriousness, does the new version I uploaded stop that?
Per
Warzone 2100 Team Member
Warzone 2100 Team Member
Posts: 3780
Joined: 03 Aug 2006, 19:39

Re: Improvements to SemperFi-js AI

Post by Per »

Seems fixed now.

On a side note, I wonder if there is anything we can do to make the AI stop "stealing" "my" oil derricks... It is a bit annoying when you play with an AI buddy. (No idea if playing with an AI ally is something someone else does, or if it just me, though.)
User avatar
Berg
Regular
Regular
Posts: 2204
Joined: 02 Sep 2007, 23:25
Location: Australia

Re: Improvements to SemperFi-js AI

Post by Berg »

The "Stealing of oil" by the AI is one of the magor reasons I dont use Ai's in team play.
User avatar
Berserk Cyborg
Code contributor
Code contributor
Posts: 938
Joined: 26 Sep 2016, 19:56

Re: Improvements to SemperFi-js AI

Post by Berserk Cyborg »

The author of this AI does that. Basically the AI checks if the distance between the startPosition of an ally and an oil is less than some value and it will not take that oil if it within a certain distance of their base.
MIH-XTC
Trained
Trained
Posts: 368
Joined: 31 Jan 2014, 07:06

Re: Improvements to SemperFi-js AI

Post by MIH-XTC »

Per wrote:Seems fixed now.

On a side note, I wonder if there is anything we can do to make the AI stop "stealing" "my" oil derricks... It is a bit annoying when you play with an AI buddy. (No idea if playing with an AI ally is something someone else does, or if it just me, though.)
On game init I loop through all players to find the closest ally and closest enemy x,y coordinates by searching for their HQ or first constructor droid they have if they don't have a HQ.

Code: Select all


function int nearestAlly()
{
		local		int			_ally,_closestAlly,_newDist,_bestDist,_closestAllyX,_closestAllyY,_numUnits;
		local		bool		_haveTruck;
		_bestDist = 99999;
		_closestAlly = -1;
		_ally = 0;
		_numUnits = 0;
		while(_ally < 10)
		{
			if(allianceExistsBetween(me, _ally) and me != _ally)
			{
				
				initEnumStruct(FALSE,playerHQ,_ally,_ally);					
				structure= enumStruct();
				while(structure != NULLOBJECT)
				{
					_newDist = distBetweenTwoPoints(baseX, baseY, structure.x, structure.y);
	
					if (_newDist < _bestDist)	
					{
						_bestDist = _newDist;
						_closestAlly = structure.player;
						_closestAllyX = structure.x;
						_closestAllyY = structure.y;
					}
					structure= enumStruct();
				}
				
				if(getStructure(playerHQ, _ally) == NULLOBJECT)
				{	
					_haveTruck = FALSE;
					InitEnumDroids(_ally,_ally);
					droid = EnumDroid();
					while (droid != NULLOBJECT and _haveTruck == FALSE)
					{
						if(droid.droidType == DROID_CONSTRUCT or droid.droidType == DROID_CYBORG_CONSTRUCT) // check to see if any of our allies don't have a truck
						{
							_haveTruck = TRUE;
							_newDist = distBetweenTwoPoints(baseX, baseY, droid.x, droid.y);
							
							if (_newDist < _bestDist)	
							{
								_bestDist = _newDist;
								_closestAlly = droid.player;
								_closestAllyX = droid.x;
								_closestAllyY = droid.y;
							}
						}
						_numUnits++;
						droid = EnumDroid();
					}
				}

				
				closestAllyDist = _bestDist;
				closestAllyHQx = _closestAllyX;
				closestAllyHQy = _closestAllyY;
				numAllyUnits = _numUnits;
			}
			_ally++;
		}
		
	return _closestAlly;
}

Then if gameTime < 6000 (first 10 minutes of game) I check if the distance between the oil resource is closer to the closest ally or closer to me. If closer to the closest ally then don't build it.

I backed it out because it caused problems when trying to compete for legit resources out on the map and never revisited it. It would probably be better to just keep track of all ally x,y base coordinates and just check if the oil resource is within say ~10 tiles of their base like Berserk said above.
Per
Warzone 2100 Team Member
Warzone 2100 Team Member
Posts: 3780
Joined: 03 Aug 2006, 19:39

Re: Improvements to SemperFi-js AI

Post by Per »

I'm not sure if that is going to produce the best results. Often the derricks that my ally AI steals from me are far from my base. I just killed all enemies around the oil well, and it is burning. By the time I revisit the area, my ally has sent a truck and built that derrick. The derricks closest to my base I usually get to first anyway, although I can see that it would be frustrating for players that are slower to lose even those.

Perhaps a combination of proximity check of distance to ally's base, and a proximity check of allied forces around the oil well, would work.
User avatar
NoQ
Special
Special
Posts: 6226
Joined: 24 Dec 2009, 11:35
Location: /var/zone

Re: Improvements to SemperFi-js AI

Post by NoQ »

A couple of ideas.

(1) I still believe that AI stealing oils is a non-issue. It's better to let the AI mine the oil and compensate it via asking for gifts of energy through chat commands if you still want this energy for yourself. You're a team, your resources are shared, and it's better to let the AI mine than to not mine at all.

(2) If we still want to avoid AI taking "your" derricks, the AI could ping you with a beacon and a chat message "hey, this oil is yours, please don't forget to take it, or i'm going to take it away from you in 30 seconds".
User avatar
Berserk Cyborg
Code contributor
Code contributor
Posts: 938
Joined: 26 Sep 2016, 19:56

Re: Improvements to SemperFi-js AI

Post by Berserk Cyborg »

Pushed some updates for SemperFi-js. Fixes a few minor things and added electronic defense building (random chance) and allow Dragon body units to use an EMP-cannon on occasion.

Is it possible to make the mini AI (source side) more aggressive with destroying nearby features near its base? I have seen that the numerous trees in maps like Melting can stall an AI's building process.
Per
Warzone 2100 Team Member
Warzone 2100 Team Member
Posts: 3780
Joined: 03 Aug 2006, 19:39

Re: Improvements to SemperFi-js AI

Post by Per »

Berserk Cyborg wrote:Is it possible to make the mini AI (source side) more aggressive with destroying nearby features near its base? I have seen that the numerous trees in maps like Melting can stall an AI's building process.
That's not hard to do, I'm just worried that it will make the AI waste a lot of precious time in the early game destroying features when it should be putting pressure on the enemy. I think if such problematic features exist, then it is a map problem, not an AI problem.
User avatar
Berserk Cyborg
Code contributor
Code contributor
Posts: 938
Joined: 26 Sep 2016, 19:56

Re: Improvements to SemperFi-js AI

Post by Berserk Cyborg »

Been slowly working on a few improvements. Still, very basic but effective. Has an oil and base builder group and now does a more desirable battle tactic (oil->factories->constructors). Thing I still have yet to figure out is how to prevent multiple constructors from going after the same oil.

I also included a cheap knock off of Nexus called "Nexus JS". Essentially a SemperFi-JS personality, but with a preference for cannons/gauss/lasers and cyborgs. One time I had these two fight in a FFA skirmish in the Melting map and later saw these two were the last ones alive and then proceeded to have a stalemate. It lasted for a simulated 4.5 hours before I quit the match (to date I have only ever seen a stalemate four times with completely different AI).
semperfi.wz
nexus.wz
User avatar
NoQ
Special
Special
Posts: 6226
Joined: 24 Dec 2009, 11:35
Location: /var/zone

Re: Improvements to SemperFi-js AI

Post by NoQ »

Berserk Cyborg wrote:Thing I still have yet to figure out is how to prevent multiple constructors from going after the same oil.
In NullBot3 i throttle the "take this particular oil" function. Simplified code from there:

Code: Select all

var throttleTimes = {};

// Universal utility function that returns true if event described in "notes"
// has already occured in the last "interval" seconds.
// I'm using this function all over the place
// to avoid calling the same stuff too often.
function throttled(interval, notes)
{
	if (!defined(throttleTimes[notes]))
	{
		throttleTimes[notes] = gameTime;
		return false;
	}
	if (gameTime - throttleTimes[notes] < interval)
	{
		return true;
	}
	throttleTimes[notes] = gameTime;
	return false;
}

function captureOil(oil)
{
	// "oil.y * mapWidth + oil.x" is a number that uniquely (but not very verbosely)
	// describes the "let's capture the oil at these coordinates" event.
	if (throttled(90000, oil.y * mapWidth + oil.x))
	{
		return;
	}
	// Proceed with ordering a single truck to build the derrick.
}
While the approach with the map is quite trivial and seems performant, it might still be valid to ask for an API function, eg. hasBlueprint(oil, player) or maybe even enumBlueprints(label|area|whatever, player).
Post Reply