Jump to content

qBot (yet another AI)


Recommended Posts

Not sure if it always happen, but i've had this crash while making an entity collection attack:

ERROR: JavaScript error: simulation/ai/Marilyn/entitycollection-extend.js line 10
InternalError: recursive object
([object Object])@simulation/ai/Marilyn/entitycollection-extend.js:10
([object Object],[object Object],[object Object],[object Array])@simulation/ai/Marilyn/attack_plan.js:252
([object Object],[object Object],[object Array])@simulation/ai/Marilyn/headquarters.js:1545
()@simulation/ai/Marilyn/marilyn.js:128
([object Object])@simulation/ai/common-api-v2/base.js:122
@:0

(It's using Marilyn but the code is the same in qBot, as far as entity collection attack() is concerned).

Replacing it by this fixed it:


EntityCollection.prototype.attack = function(unit)
{
var unitId;
if (unit.id()) {
unitId = unit.id();
}else{
unitId = unit;
}
var idArray = this.toIdArray();
Engine.PostCommand({"type": "attack", "entities": idArray, "target": unitId, "queued": false});
return this;
};

Edited by wraitii
Link to comment
Share on other sites

I've got to say, I didn't really try to reproduce it... It's a weird bug for sure, I didn't either notice anything that would have caused a recursion... Perhaps it was a special case cause by something I did that was unexpected in Javascript...

I'm really unsure what the circumstances of that particular crash were, though it was when an entityCollection tried to attack a gaia unit (iirc). Unless it comes up again, I think you can ignore it.

Edited by wraitii
Link to comment
Share on other sites

I've got to say, I didn't really try to reproduce it... It's a weird bug for sure, I didn't either notice anything that would have caused a recursion... Perhaps it was a special case cause by something I did that was unexpected in Javascript...

I'm really unsure what the circumstances of that particular crash were, though it was when an entityCollection tried to attack a gaia unit (iirc). Unless it comes up again, I think you can ignore it.

Philip said that it is probably due to the unitId parameter being passed as the target. I will change the function so that the type of 'unit' must be an entity object.

From this I would guess that your change to detecting unit.id() is what fixed it. The previous method of using typeOf probably failed for some case so an object (containing a circular reference) would have been passed.

Thanks for the information.

Link to comment
Share on other sites

Yeah, typeof seems dodgy with anything that isn't explicitly a javascript type, that's why I replaced it with some other check... I'm not sure I understand Philip's explanation, but I guess he knows enough :) . Anyway, it's good it's fixed now.

Link to comment
Share on other sites

"InternalError: recursive object" is emitted by SpiderMonkey's structured clone operation, which is what Engine.PostCommand uses to safely copy its argument data from the AI thread to the engine thread. The cloned data mustn't have any objects that include references to themselves (e.g. "var x = {}; x.foo = x;"), so you get the error message in that case. (I think newer versions of the HTML5 structured clone algorithm, implemented in newer versions of SpiderMonkey, don't have that restriction.) In this particular piece of code you were probably accidentally passing some complex recursive object instead of an entity ID.

Link to comment
Share on other sites

  • 2 weeks later...

Some findings about current SVN about qbot:

  • it builds a lot of fortress, even one near the other;
  • it builds no market;
  • when I was attaching him with 10 ballistas their citizen soldiers continued collecting resources rather than killing my ballistas.

Link to comment
Share on other sites

I see you've added the "gatherer swap" function to qBot. Neat improvement, however, a few things you might consider adding when you find time:

-distance is a factor, as is the duration of gathering. If you swap, and then right when each unit arrive at their new resource they're tasked to a third resource, you'll have lost the benefit of the swap. To avoid that, you might want to prevent the unit from being reassigned for some time when swapping, which you could roughly estimate as "distance/speed*2" or something. And prevent the swap if the cost would be too high (it would require 10 minutes to be actually profitable or something).

BTW, this is my opinion, but I believe it is time to start adding difficulty levels to qBot. It's getting strong for beginners, economically.

Link to comment
Share on other sites

Something to toss in for the later stages of the game might be to have qbot build mills near sizable groups of trees if that group is outside their territory, they seem to get stuck sending civies a quarter way across the map to get wood. While you're at it I'd see about having them ignore cherry trees, berry bushes, etc that are outside their territory. Maybe mines as well. I've gotten them quite a few times by just camping in front of that spot with some archers or by building one of my evil lil modded outposts, garrisoning it, and then building a palisade all around the resource. After I've done that I just send my team back to work and let the outpost pick the enemy off gradually. I've modded it so that no one can simply build a CC wherever they want, they have to first claim the territory with outposts that are set up to build in allied/neutral territory and grant a decent amount of territory. It's set up so the firing range of the garrisoned outpost is just short of it's LOS and the territory is just short of that, no sense in granting territory you can't actually control after all. All this because jubot kept building CCs right on top of mine despite the fact that they clearly haven't scouted the area. Blasted omniscient AI.

Link to comment
Share on other sites

Well the techs are still pretty new, can't really expect much there for awhile. Trading and bartering would be a good thing to implement soon tho, I'm sure my enemies have enuf darn wood. Sea maps are.....sea maps.....you'd almost need an entirely different AI setup for those. I've yet to see any of our AIs garrison a building let alone a ship so they'd be stuck on the one island for life.

Link to comment
Share on other sites

  • 2 weeks later...

I play tested qbot on several maps . here are my findings .

1. The game slows down to a crawl on every map around the 35 minutes mark . If you weaken qbot by killing many of its soldiers the game jumps to double or triple speed and remains so for about 2 to 3 minutes . Then it slows down to normal speed . I guess qbot has something to do with it .

2. Qbot only attacks when you have very few units around your civilization center the moment you have 25 plus units qbot stops attacking . Qbot does however attack at least once every game .

3. Qbot does not defend building or even civilization centers from being attacked by catapults . I destroyed qbot's civilization center while nearly 50 of qbots citizen soldiers were just standing around their civilization center .

Link to comment
Share on other sites

  • 1 month later...

Hi, a friend and I have been looking around the qBot code and making some small adjustments / trying out stuff.

We've made a list of some ideas you may want to consider. Our input is based on your code from about a month ago, so perhaps you may have changed a thing or two. We invite you (and anyone else reading this) to let us know what you think of the ideas.

Siege weapons: when creating an army to be sent to the opponent Civ Center, there should be more siege weapons. It would make it more challenging to defend against qBot's attacks. Right now its fairly easy to garrison inside buildings and kill off the enemy soldiers whilst they take an eternity to destroy a fortress/civ center.

Garrison: related to the above, it would be great if qBot sent units into towers/fortresses/Civ Centers when under attack. That would increase their resistence to the player's attack. However, if there are siege weapons assaulting the buildings, then the garrisoned units should scramble out and destroy the siege weapons.

Female evasion: female citizens should run away from enemy soldiers. Basically the sort of behaviour currently observed by some animals - I believe the deer run away from all human units?

Target selection: in defence.js you assign defenders to a random enemy in the attacker's group. We thought it would be better if non-ranged units would select the nearest enemy (in the same attacking group). This would give them a better chance of inflicting some damage as you might get situations where a swordsman needs to cross a whole group of enemies to hit his randomly selected target. Ranged units on the other hand could select the strongest enemy. We used your built in getUnitStrength function to determine the strongest enemy. In case of multiple strongest enemies, just select the one who is nearest.

Training units: currently you train units of which the population has the lowest amount of. I assume this assures a nice variety of unit types (no one likes to fight against an elephant spammer...). However, we thought it would be nice if the AI tried to focus on training the stronger units. We attempted to use the getUnitStrength function here too, but since this part of the code deals with templates instead of entities we weren't able to succesfully implement it.

Females vs males: in economy.js, you set the limit of females in a population to one third. My friend and I debated that in the beginning of a game you'd like to have lots of females to quickly gather resources and transfer into the city phase. However once you're done building your city and have started focusing on training an army, we reckon the 1/3 limit should decrease so that qBot can create more soldiers. In other words, we suggest a flexible female citizen population limit; high in the beginning, lower after entering the city phase.

Key buildings: right now you only set Civ Centers to be key buildings (in defence.js). When unassigning defenders, you send them back to the nearest key building (currently only Civ Centers). Maybe you could add fortresses to the list of key buildings?

Entry points: in terrain-analysis.js, you calculate the entry points. These are defined on a block placement radius of 45 from the Civ Center. We noticed that on smaller maps, this distance is too big (for example Fast Oasis). A radius depending on the size of the map would be more suitable. Instead of 45, we divided the shortest side (width or height) of the map by 6 and it seems to give decent results:


if(this.width < this.height) {
blockPlacementRadius = Math.floor(this.width/6);
} else {
blockPlacementRadius = Math.floor(this.height/6);
}

Patrols: finally, we had a go (but failed) at incorporating patrolling behaviour. Our idea was that we would use the entry points as a patrolling route. A group of soldiers (probably elite soldiers) would walk from one point to the other, guarding the territory. The group could wait a set amount of time at each point (say 10 seconds) and then move on to the next entry point. Eventually qBot will build fortresses on these entry points, at which point the patrol group(s) would simply be walking from fortress to fortress. I think it would be a neat defensive behaviour, as apposed to simply standing still somewhere. Further patrolling points could be Civ Centers and other important buildings.

Link to comment
Share on other sites

I don't have much time right now so I will only make a few quick comments until later. These are mainly negative because comments on things I agree with need more thought :).

Females vs males: in economy.js, you set the limit of females in a population to one third. My friend and I debated that in the beginning of a game you'd like to have lots of females to quickly gather resources and transfer into the city phase. However once you're done building your city and have started focusing on training an army, we reckon the 1/3 limit should decrease so that qBot can create more soldiers. In other words, we suggest a flexible female citizen population limit; high in the beginning, lower after entering the city phase.

The 1/3 limit is based on the total possible population for the game, not the current population, so this won't have any effect early in the game. The priorities for different training types probably aren't well optimised at the moment though.

Entry points: in terrain-analysis.js, you calculate the entry points. These are defined on a block placement radius of 45 from the Civ Center. We noticed that on smaller maps, this distance is too big (for example Fast Oasis). A radius depending on the size of the map would be more suitable. Instead of 45, we divided the shortest side (width or height) of the map by 6 and it seems to give decent results:


if(this.width < this.height) {
blockPlacementRadius = Math.floor(this.width/6);
} else {
blockPlacementRadius = Math.floor(this.height/6);
}

The problem with this approach is that since fortresses are placed at the entry points on very large maps this will give qBot problems when trying to build defensive fortresses. The whole approach is pretty crude currently and could be much better, I don't think a simple map size/6 is the best way to go though.

Link to comment
Share on other sites

Now a fuller reply. The only changes within the last month were trying to get the AI not to gather resources which it shouldn't so everything should still be relevant.

Siege weapons: when creating an army to be sent to the opponent Civ Center, there should be more siege weapons. It would make it more challenging to defend against qBot's attacks. Right now its fairly easy to garrison inside buildings and kill off the enemy soldiers whilst they take an eternity to destroy a fortress/civ center.

Siege definitely need to be better as you say. Part of the problem is that qBot doesn't know how to use siege effectively and often walks it into a melee. I haven't tested siege properly since the attack priorities got implemented so hopefully they work better now than they did before. Increasing the priority is an easy fix to do for now, I will try that. Some special code for handling siege units is definitely necessary, though this might not be easy.

Garrison: related to the above, it would be great if qBot sent units into towers/fortresses/Civ Centers when under attack. That would increase their resistence to the player's attack. However, if there are siege weapons assaulting the buildings, then the garrisoned units should scramble out and destroy the siege weapons.

We chatted about this on irc a bit. To briefly summarize, garrisoning is desirable but implementing it without introducing serious exploits is non trivial.

Female evasion: female citizens should run away from enemy soldiers. Basically the sort of behaviour currently observed by some animals - I believe the deer run away from all human units?

Again this would be good. I'm not sure modelling deer is quite what should be done. It is very important to keep resource gathering going strongly. I played this strategy personally in AoE2 to counter rushes. The principle to keep in mind is always that you need it to cost the enemy more resources than it cost you. In this case the cost to the enemy is the production value of the soldiers whereas you spent the resources making your economy stronger. This means you have to rely on the strength of the buildings which provide a safe zone around your CC so the enemy can't catch up to your workers since they have to take a long way round. Construction of towers provides more safe zone, though garrisoning is also necessary for the safe zones to be properly effective. Also the bot should be producing soldiers while the raid is ongoing which should be possible since the defenders economy will be stronger if they have been playing equally well.

Target selection: in defence.js you assign defenders to a random enemy in the attacker's group. We thought it would be better if non-ranged units would select the nearest enemy (in the same attacking group). This would give them a better chance of inflicting some damage as you might get situations where a swordsman needs to cross a whole group of enemies to hit his randomly selected target. Ranged units on the other hand could select the strongest enemy. We used your built in getUnitStrength function to determine the strongest enemy. In case of multiple strongest enemies, just select the one who is nearest.

This would help with defence. One thing which I think is more important with defence though is to get the defenders to work in a group. Currently they head straight for the enemy so often they arrive gradually and get picked off one by one. Strength of numbers is a large factor in battles. Especially with ranged the damage dealt is proportional to the number of units. So for example if you send 2 groups of 5 they will deal just over half of the damage (assuming they focus fire) vs a group of 10 compared with sending one group of 10.

Training units: currently you train units of which the population has the lowest amount of. I assume this assures a nice variety of unit types (no one likes to fight against an elephant spammer...). However, we thought it would be nice if the AI tried to focus on training the stronger units. We attempted to use the getUnitStrength function here too, but since this part of the code deals with templates instead of entities we weren't able to succesfully implement it.

Key buildings: right now you only set Civ Centers to be key buildings (in defence.js). When unassigning defenders, you send them back to the nearest key building (currently only Civ Centers). Maybe you could add fortresses to the list of key buildings?

Patrols: finally, we had a go (but failed) at incorporating patrolling behaviour. Our idea was that we would use the entry points as a patrolling route. A group of soldiers (probably elite soldiers) would walk from one point to the other, guarding the territory. The group could wait a set amount of time at each point (say 10 seconds) and then move on to the next entry point. Eventually qBot will build fortresses on these entry points, at which point the patrol group(s) would simply be walking from fortress to fortress. I think it would be a neat defensive behaviour, as apposed to simply standing still somewhere. Further patrolling points could be Civ Centers and other important buildings.

Training could be improved. The game has not yet been balanced though so any system should be flexible enough to easily handle changes to the template data, so don't bother with lots of manual testing obviously. The templates contain all of the necessary information so you should be able to get this working. I could try and help if you still have problems. It might be necessary to modify the getUnitStrength function a bit.

Adding fortresses to the key buildings list sounds pretty reasonable. If you implement patrols this might become a bit redundant though.

We talked about patrols on irc as well. I think they are fine to do with units that would be idle anyway. I consider it to be low priority but patches are welcome. One thing which I thought of is that the entry points are only around the original base. It would be good to defend expansions as well. The fortress building logic could be improved in this respect as well.

Link to comment
Share on other sites

  • 2 weeks later...

starting about midgame qBot has many idle units standing around resource dropsites (the units that return when a resource runs out)

it fact so many that it blocks of the dropsite and other units can’t drop their resources...

(I saw about 20 idle units blocking the dropsite and another 20 that can’t drop; thats not good for the bot’s economics)

qBot should do one of the following to resolve that

  • (better) retask the soldiers to attack and the females to gather some other resources
  • (at least a fix) task the idle units to walk a bit away so that they don’t block the dropsite

(I’m using the latest dev autobuild: "Jul 18 2012 - 12143-development")

Edited by luziferius
Link to comment
Share on other sites

  • 3 weeks later...

Hey quantumstate, my friend and I have been busy with other stuff, including holiday, but we wanted to thank you for the reply.

Regarding the siege weapons, I think once qBot has a fortress (ie is able to produce siege weapons) it would make sense that a large portion of the attack group it deploys consists of siege weapons.

Maybe even evaluate the opponent's forces, like a balance between his soldiers and defence towers/fortresses. If he has more of the latter, then focus on training more siege weapons. If his defence consists of primarily units, then obviously less siege weapons are needed.

Female citizens could continue working in the presence of enemies, but I'd reckon it would be more realistic if they started fleeing as soon as the enemy attacks one of the nearby female citizens. At that point its clear the enemy is going to attack them so fleeing would be reasonable behaviour.

Defensive coordination would be neat. But there might be situations where you'd rather not walk as a group to defend. For example, if the group has some mounted units, would you really want them to move at the speed of of the slowest unit in the group? We hadn't thought of the effects of focus fire, although if the ranged units go after the 'strongest' enemy I guess focus fire happens automatically.

My friend and I still think patrolling behaviour would be great to have in 0 A.D. Although there is a slight problem, in that qBot 'cheats' a fair bit by using information it shouldn't have (from the perspective of a human player). If qBot can see where enemies are at any given moment, then patrolling wouldn't be the best defensive strategy - instead the AI could position all of its defensive units on the route the enemy.

I'm not saying cheating is bad, as it does make it significantly easier to implement stronger AI, but I'm interested what your view is on this. Do you think in the final release of the game it would be better to have an intelligent but fair AI? Or would the 0 A.D. community not really care how the AI works as long as it provides a challenge?

Link to comment
Share on other sites

My friend and I still think patrolling behaviour would be great to have in 0 A.D. Although there is a slight problem, in that qBot 'cheats' a fair bit by using information it shouldn't have (from the perspective of a human player). If qBot can see where enemies are at any given moment, then patrolling wouldn't be the best defensive strategy - instead the AI could position all of its defensive units on the route the enemy.

I'm not saying cheating is bad, as it does make it significantly easier to implement stronger AI, but I'm interested what your view is on this. Do you think in the final release of the game it would be better to have an intelligent but fair AI? Or would the 0 A.D. community not really care how the AI works as long as it provides a challenge?

I think it is better to have A.I that cheats rather than an A.I which is unable to provide a challenge . I would also recommend the A.I be allowed to use cheat codes in-order to generate resources or troops when it is besieged this will make it even more challenging . This could be a stop gap measure till the 0ad team implements a stronger A.I .

  • Thanks 1
Link to comment
Share on other sites

  • 3 weeks later...

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...