Jump to content

Improving the AI


Recommended Posts

  • 9 months later...
2 hours ago, andy5995 said:

I found it's easier to make a harder civ than a harder AI (see attached). Here, Kush is very hard AI (T1) versus 3 very hard AIs (T2).

 

I gave the Kush an upgrade they can research at game start. It multiplies a lot of things by 3x and affects most units.

screenshot0001.png

screenshot0002.png

This is an amazing idea, we can make an op Civ with all units' health multiplied by 2 and cost decreased slightly.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

6 hours ago, Sevda said:

This is an amazing idea, we can make an op Civ with all units' health multiplied by 2 and cost decreased slightly.

@SevdaThank you for your interest! I'm glad you like the idea so far. I created a separate thread for this mod at

I probably won't change the cost. I'd like to reduce the amount of files to make long-term maintenance easier.

Link to comment
Share on other sites

  • 9 months later...

The AI, PetraBot, certainly can be improved. It often uses bad strategies and is weak; I consistently beat 7 AIs all teamed up against me. So I am trying to improve the AI behaviour by tweaking its code and I would appreciate any inputs / suggestions.

Firstly, I will identify a list of imperfections with the current AI:

  1. Suicidal early attacks - sends some units to attack you but then suicide all of them at your civic centre. It doesn't know how to retreat. The long march also delays their development by a huge amount. 
  2. Wasting resources on non-essential buildings and techs: Greek theatres, towers, wonders (even though it's far from reaching the limit population and needs to spend resources elsewhere)
  3. Wasting time on capturing / damaging non-essential buildings, especially suicidal attempts at fully garrisoned fortresses. 
  4. Poorly optimised army: too many siege units, too many mercenary units but not enough real fighting force. 
  5. Does not interact with the player - they don't seem to care about what you are up to; they just attack walls and towers as they wish. 
  6. Unwise expansions - too many civic centres placed at poorly chosen areas when they really need to defend their main base. 
  7. Suicidal support units: they send women and traders into battle or under enemy towers
  8. Not playing: when checking the replays, I often see the AIs doing absolutely nothing for some time. 

 

If you spot any additional flaws, you are more than welcome to append to the list. 

  • Like 3
Link to comment
Share on other sites

I've made attempts to solve some of these issues. I first made changes to config.js at 0ad/binaries/data/mods/public/simulation/ai/petra/config.js

this.Military = {
		"towerLapseTime": 9000,	// Time to wait between building 2 towers
		"fortressLapseTime": 5000,	// Time to wait between building 2 fortresses
		"popForBarracks1": 40,
		"popForBarracks2": 95,
		"popForForge": 120,
		"numSentryTowers": 1
	};

	this.DamageTypeImportance = {
		"Hack": 0.075,
		"Pierce": 0.095,
		"Crush": 0.010,
		"Fire": 0.015
	};

	this.Economy = {
		"popPhase2": 150,	// How many units we want before aging to phase2.
		"workPhase3": 200,	// How many workers we want before aging to phase3.
		"workPhase4": 250,	// How many workers we want before aging to phase4 or higher.
		"popForDock": 30,
		"targetNumWorkers": 40,	// dummy, will be changed later
		"targetNumTraders": 0,	// Target number of traders
		"targetNumFishers": 0,	// Target number of fishers per sea
		"supportRatio": 0.35,	// fraction of support workers among the workforce
		"provisionFields": 2
	};

	// Note: attack settings are set directly in attack_plan.js
	// defense
	this.Defense =
	{
		"defenseRatio": { "ally": 1.4, "neutral": 1.8, "own": 2 },	// ratio of defenders/attackers.
		"armyCompactSize": 5000,	// squared. Half-diameter of an army.
		"armyBreakawaySize": 1000,	// squared.
		"armyMergeSize": 2000	// squared.
	};

 

	this.priorities =
	{
		"villager": 800,      // should be slightly lower than the citizen soldier one to not get all the food
		"citizenSoldier": 800,
		"trader": 1,
		"healer": 1,
		"ships": 1,
		"house": 550,
		"dropsites": 500,
		"field": 450,
		"dock": 1,
		"corral": 1,
		"economicBuilding": 90,
		"militaryBuilding": 200,
		"defenseBuilding": 1,
		"civilCentre": 1,
		"majorTech": 500,
		"minorTech": 50,
		"wonder": 1,
		"emergency": 1000    // used only in emergency situations, should be the highest one
	};

 

This part seems to determine its difficulty; the multipliers give the AI a bonus gathering rate and train time reduction. So I changed the easiest mode to the same as the hardest Petra AI, then the harder modes to more insane values. 

PETRA.Config.prototype.Cheat = function(gameState)
{
	// Sandbox, Very Easy, Easy, Medium, Hard, Very Hard
	// rate apply on resource stockpiling as gathering and trading
	// time apply on building, upgrading, packing, training and technologies
	const rate = [ 1.00, 1.3, 1.5, 1.7, 2, 5 ];
	const time = [ 1.00, 0.7, 0.5, 0.3, 0.2, 0.1 ];
	const AIDiff = Math.min(this.difficulty, rate.length - 1);
	SimEngine.QueryInterface(Sim.SYSTEM_ENTITY, Sim.IID_ModifiersManager).AddModifiers("AI Bonus", {
		"ResourceGatherer/BaseSpeed": [{ "affects": ["Unit", "Structure"], "multiply": rate[AIDiff] }],
		"Trader/GainMultiplier": [{ "affects": ["Unit", "Structure"], "multiply": rate[AIDiff] }],
		"Cost/BuildTime": [{ "affects": ["Unit", "Structure"], "multiply": time[AIDiff] }],
	}, gameState.playerData.entity);
};

At the new "Very Hard" level, this improved AI can beat 7 regular Petra AIs like I do! It still makes the same mistakes but the shear cheating bonus makes it dominate all. 

  • Like 1
Link to comment
Share on other sites

Now I change the attack strategies. For full scale attacks, I increased the minimum number of units participating so that its attacks would be more fruitful. For small early raids, I inhibited the use of infantry and limited it to only "fast-moving" (aka cavalry) class so that it can reach the enemy quickly without delaying the build-up at home. 

	if (type === PETRA.AttackPlan.TYPE_RUSH)
	{
		priority = 700;
		this.unitStat.Infantry = { "priority": 0.1, "minSize": 0, "targetSize": 1, "batchSize": 1, "classes": ["Infantry"],
			"interests": [["strength", 1], ["costsResource", 0.5, "stone"], ["costsResource", 0.6, "metal"]] };
		this.unitStat.FastMoving = { "priority": 1, "minSize": 10, "targetSize": 11, "batchSize": 1, "classes": ["FastMoving+CitizenSoldier"],
			"interests": [["strength", 1]] };
		if (data && data.targetSize)
			this.unitStat.Infantry.targetSize = data.targetSize;
		this.neededShips = 1;
	}
	else if (type === PETRA.AttackPlan.TYPE_RAID)
	{
		priority = 10;
		this.unitStat.FastMoving = { "priority": 1, "minSize": 3, "targetSize": 4, "batchSize": 2, "classes": ["FastMoving+CitizenSoldier"],
			"interests": [ ["strength", 1] ] };
		this.neededShips = 1;
	}
	else if (type === PETRA.AttackPlan.TYPE_HUGE_ATTACK)
	{
		priority = 900;
		// basically we want a mix of citizen soldiers so our barracks have a purpose, and champion units.
		this.unitStat.RangedInfantry = { "priority": 0.7, "minSize": 50, "targetSize": 80, "batchSize": 5, "classes": ["Infantry+Ranged+CitizenSoldier"],
			"interests": [["strength", 3]] };
		this.unitStat.MeleeInfantry = { "priority": 0.7, "minSize": 50, "targetSize": 70, "batchSize": 5, "classes": ["Infantry+Melee+CitizenSoldier"],
			"interests": [["strength", 3]] };
		this.unitStat.ChampRangedInfantry = { "priority": 1, "minSize": 0, "targetSize": 18, "batchSize": 3, "classes": ["Infantry+Ranged+Champion"],
			"interests": [["strength", 3]] };
		this.unitStat.ChampMeleeInfantry = { "priority": 1, "minSize": 0, "targetSize": 18, "batchSize": 3, "classes": ["Infantry+Melee+Champion"],
			"interests": [["strength", 3]] };
		this.unitStat.RangedFastMoving = { "priority": 0.7, "minSize": 1, "targetSize": 20, "batchSize": 4, "classes": ["FastMoving+Ranged+CitizenSoldier"],
			"interests": [["strength", 2]] };
		this.unitStat.MeleeFastMoving = { "priority": 0.7, "minSize": 1, "targetSize": 20, "batchSize": 4, "classes": ["FastMoving+Melee+CitizenSoldier"],
			"interests": [["strength", 2]] };
		this.unitStat.ChampRangedFastMoving = { "priority": 1, "minSize": 0, "targetSize": 15, "batchSize": 3, "classes": ["FastMoving+Ranged+Champion"],
			"interests": [["strength", 3]] };
		this.unitStat.ChampMeleeFastMoving = { "priority": 1, "minSize": 0, "targetSize": 15, "batchSize": 3, "classes": ["FastMoving+Melee+Champion"],
			"interests": [["strength", 2]] };
		this.unitStat.Hero = { "priority": 1, "minSize": 0, "targetSize": 0, "batchSize": 1, "classes": ["Hero"],
			"interests": [["strength", 2]] };
		this.neededShips = 1;
	}
	else
	{
		priority = 700;
		this.unitStat.RangedInfantry = { "priority": 1, "minSize": 50, "targetSize": 90, "batchSize": 3, "classes": ["Infantry+Ranged"],
			"interests": [["canGather", 1], ["strength", 1.6], ["costsResource", 0.3, "stone"], ["costsResource", 0.3, "metal"]] };
		this.unitStat.MeleeInfantry = { "priority": 1, "minSize": 40, "targetSize": 50, "batchSize": 3, "classes": ["Infantry+Melee"],
			"interests": [["canGather", 1], ["strength", 1.6], ["costsResource", 0.3, "stone"], ["costsResource", 0.3, "metal"]] };
		this.unitStat.FastMoving = { "priority": 1, "minSize": 0, "targetSize": 30, "batchSize": 2, "classes": ["FastMoving+CitizenSoldier"],
			"interests": [["strength", 1]] };
		this.neededShips = 1;
	}

The trick was increasing the minimum number of each unit type to ensure a large army. 

  • Like 1
Link to comment
Share on other sites

12 minutes ago, NitroVicky said:

If you spot any additional flaws, you are more than welcome to append to the list. 

9. Inefficient resource gathering

Just yesterday I saw some women gather stone real far out; no storehouse close, stating minerals hardly touched and not utilized.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

11. in maps with long and complex unpassable obstacles, the AI starts acting weirdly, only considering euclidean distance for espansions and attacks.

45 minutes ago, hyperion said:

10. Gathering resources under enemy tower.

I think this is the kind of things you may want the easy AI to do anyway. if it acts dumb it makes you feel smarter.

2 hours ago, NitroVicky said:

The AI, PetraBot, certainly can be improved. It often uses bad strategies and is weak; I consistently beat 7 AIs all teamed up against me. So I am trying to improve the AI behaviour by tweaking its code and I would appreciate any inputs / suggestions.

Firstly, I will identify a list of imperfections with the current AI:

  1. Suicidal early attacks - sends some units to attack you but then suicide all of them at your civic centre. It doesn't know how to retreat. The long march also delays their development by a huge amount. 
  2. Wasting resources on non-essential buildings and techs: Greek theatres, towers, wonders (even though it's far from reaching the limit population and needs to spend resources elsewhere)
  3. Wasting time on capturing / damaging non-essential buildings, especially suicidal attempts at fully garrisoned fortresses. 
  4. Poorly optimised army: too many siege units, too many mercenary units but not enough real fighting force. 
  5. Does not interact with the player - they don't seem to care about what you are up to; they just attack walls and towers as they wish. 
  6. Unwise expansions - too many civic centres placed at poorly chosen areas when they really need to defend their main base. 
  7. Suicidal support units: they send women and traders into battle or under enemy towers
  8. Not playing: when checking the replays, I often see the AIs doing absolutely nothing for some time. 

 

If you spot any additional flaws, you are more than welcome to append to the list. 

there have been some work on better AI in the past, which was never merged into the main game, @Yekaterina knows more. Catilina was pretty good I remember.

Edited by alre
  • Like 1
Link to comment
Share on other sites

I've made the first version of an improved AI - ElytraBot. You can install it as a mod using this Pyromod file. It is a separate bot from Petra so now you can make 2 different AIs fight against each other!

elytrabot.pyromod

 

Features:

  • Adds 4 "extreme" difficulties on top of "Very Hard" for both AIs, each featuring more bonus in gathering rates and discounts in training and building. 
  • At every difficulty level, Elytra can confidently beat Petra of the same level on all maps. Sometimes it can beat Petra of one or two levels above!
  • Elytra is more focused to economic development and larger scale attacks. It does less expansions and less harassments. 
  • Like 1
Link to comment
Share on other sites

Could you maybe teach the AI the difference between geographical distance and walking distance? I think it's related to what @alre posted above.

0ad-walktwicetheway.jpg.da6003fa6f1a78341431eba788eb118a.jpg

This also plays a role for efficient resource gathering. On maps like Cantabrian Highlands it's especially egregious. I specifically built a farmstead for my hunting cav at the bottom of the ramp, but this stupid no good for nothing rider still rather travels twice the distance to the CC.

  • Like 1
Link to comment
Share on other sites

4 hours ago, hyperion said:

That's the UnitAI, not the AI player

I wouldn't know the difference (at least not in detail). But since the title of the thread is broad enough:

- learn to ring the friggin bell; currently when an AI player is being raided they're good at garrisoning soldiers (when defensive buildings are in sight), but they happily leave out the women to be slaughtered.

Link to comment
Share on other sites

17 hours ago, Gurken Khan said:

@hyperion There's an eleven years old ticket: https://trac.wildfiregames.com/ticket/1468

Yeah the reason it's still not implemented is that it's much slower to compute some kind of proper distance than to assume euclidian / spherical cows.
The UnitAI part is the part that's the same between the AI and a regular player, but the AI has the same problems.

As far as I know the best solution for AI dev is to share things on the forum, and then we can consider actual patches in the future if it proves to be better.

--

You should note that nowadays, you can implement your own cheats in the AI by giving it custom modifiers. It doesn't have to be just the resource gathering. You can also use LOS data nowadays, but IIRC that needs to be implemented in entity.js

Link to comment
Share on other sites

One new update from me: 

enhancedAI.pyromod

This installer contains 2 improved AI programs. 

Venus is a more conservative upgrade that can't go wrong.
Elytra is stronger but may be subject to bug warnings. 
I added 4 more difficult levels to the hardest one. In these four levels, bots get buffs in combat and more economic benefits. 

Instructions: Download the pyromod installer, then open the installer with 0AD. Select the module difficultbots, double click to activate it (it will be moved to the grid at the bottom of the screen), then save the module settings and restart the game

 

To prevent ambiguity in the translated text, please refer to the original description:

venus 是个比较保守的升级版, 不会出错。
elytra 更强但是有可能会受到bug警告。 
在最难的基础上我加了4个更难的等级。 在这四个等级里,机器人会得到在战斗上的buff和更多的经济优惠。 

安装步骤: 下载pyromod安装包,然后用0AD打开安装包。 选择这个模组 difficultbots,双击来激活(会被移到屏幕下方的大格子里),然后保存模组设置并重启x游戏

  • Like 3
Link to comment
Share on other sites

Dude I was beating Very Hard AI consistently and Elytra kicks my ass in medium difficulty.

 

 

Good job!

 

Edit: I actually managed to beat it but it actually required a way more focused play on my part, booming more effectively and pushing forward bases. While I previously played it more like a city builder game haha

post-game.png.0fec2a5b8aaeeed04c7c4f23bec2e4eb.png

Generally speaking I usually get to build a couple of additional CC after Petra bot just falls apart and stops attacking after suffering a lot of strain to its ecnomy.

Very happy with this improvement. It feels like a proper challenge at least to me.

Edited by Sp00ky
update info
Link to comment
Share on other sites

  • 2 weeks later...
On 08/06/2023 at 9:07 PM, NitroVicky said:

This installer contains 2 improved AI programs. 

Venus is a more conservative upgrade that can't go wrong.
Elytra is stronger but may be subject to bug warnings. 

Hi :) thanks for sharing this! Elytra is a nice step from Petra. Is it possible to have a version for a27? Now that the RC1 has been released.
https://wildfiregames.com/forum/topic/107313-alpha-27-pre-releaserelease-candidate-build-testing/
https://trac.wildfiregames.com/wiki/PortA26ToA27

It output some errors so there are at least a few things to check.
I would like to playtest the RC and doing that against a better AI would be more fun :)

 

Edited by tuxayo
Add to like to porting documentation
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...