AI-Amsterdam Posted June 6, 2011 Report Share Posted June 6, 2011 (edited) Hey,I'm in a group of second year A.I. students from Amsterdam, and we would like to write an A.I. for 0 A.D.We would like to test this A.I. against JuBot, to see if it performs better. I already saw that there is an option in Atlas to run and speed up the game (which would come in handy with an A.I. vs A.I. battle), but when I press play, the other player doesn't use an A.I.Is it possible in some way to let 2 A.I.'s play against each other? We could maybe also try to make a three player map and put the human player on top of a cliff or something, but that wouldn't be the neatest way of going about this.Also, is there a function somewhere to actually attack an entity? Because I didn't see one in the entity in entity.js. Edited June 6, 2011 by AI-Amsterdam Quote Link to comment Share on other sites More sharing options...
Badmadblacksad Posted June 6, 2011 Report Share Posted June 6, 2011 here is an answer to your first question :You can already run the game like "pyrogenesis -quickstart -autostart=Oasis -autostart-ai=1:testbot -autostart-ai=2:testbot" to set up AIvAI, then use the 'time warp' mode in the game or do Engine.SetSimRate(10) etc in the console to speed it up. (It should give the same outcome each time since it's deterministic - I guess at some point I should let the random seed be changed.)for the second, you will have to add a new function to entity.js and entitycollection.js, like the move() one but with "attack" instead of "walk". If you don't want to attack a specific entity, the move() function should be fine (Jubot uses it). Quote Link to comment Share on other sites More sharing options...
AI-Amsterdam Posted June 6, 2011 Author Report Share Posted June 6, 2011 Hey, I tried the command you quoted, but got this error message:Paths.cpp(82): Function call failed: return value was -110301 (Error during IO)Function call failed: return value was -110301 (Error during IO)Location: Paths.cpp:82 (Root)Call stack:(0x74717a) pyrogenesis() [0x74717a](0x6fe310) pyrogenesis() [0x6fe310](0x6fef28) pyrogenesis() [0x6fef28](0x6fe802) pyrogenesis() [0x6fe802](0x544332) pyrogenesis() [0x544332](0x545d3b) pyrogenesis() [0x545d3b](0x54d2ff) pyrogenesis() [0x54d2ff](0x54fa9f) pyrogenesis() [0x54fa9f](0x41398d) pyrogenesis() [0x41398d](0x415133) pyrogenesis() [0x415133](0x7fa3c6ba0eff) /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xff) [0x7fa3c6ba0eff](0x411a79) pyrogenesis() [0x411a79]errno = 0 (?)OS error = ?(C)ontinue, (S)uppress, (B)reak, Launch (D)ebugger, or (E)xit?So were there any other things I had to do? I just ran it in home/user, should it be some other directory? Quote Link to comment Share on other sites More sharing options...
Rasunadon Posted June 6, 2011 Report Share Posted June 6, 2011 So press Continue. I pressed it twice and game starts.Then use Shift+D to open Developer setting and check Enable time warp. And press Space. Quote Link to comment Share on other sites More sharing options...
janwas Posted June 6, 2011 Report Share Posted June 6, 2011 That error indicates we're not finding the path to the executable; even argv[0] isn't usable.The game still runs because there's a second mechanism (XDG) to find the paths to the data files, but it'd be nice to find out what's going wrong.Would you be so kind as to trace into sys_ExecutablePathname, and also print argv[0] in main? Quote Link to comment Share on other sites More sharing options...
AI-Amsterdam Posted June 7, 2011 Author Report Share Posted June 7, 2011 Thanks for all your replies,@Badmanblacksad: The 2 AIvsAI works like a charm However ,we are currently editing/creating an AI in the public.zip, which seems to work.@janwas: I would be happy to help you but I don't know exactly how, if you could provide instructions I'll be happy to try.We've got a basic bot at the moment, but we still seem to have some troubles regarding the following;Is there a way to make a unit garrison into a building? I have noticed JuBot doesn't garrison his towers.For that matter, how does one make direct calls to the engine, if possible?Is it possible to read out the range of entities? I've seen the range overlay, but cant find a reference in the code for the life of me.@Badmanblacksad: Could you perhaps share how you would make such a function with "attack" ? I can't seem to find a proper way to do so.Thanks again, your replies are much appreciated,Team AI-Amsterdam Quote Link to comment Share on other sites More sharing options...
janwas Posted June 7, 2011 Report Share Posted June 7, 2011 @janwas: I would be happy to help you but I don't know exactly how, if you could provide instructions I'll be happy to try.Thanks! It'd be good to add as the first line of main():debug_printf(L"%hs\n", argv[0]);As to sys_ExecutablePathname, that's a bit more complicated. Please apply the attached patch(mutatis mutandis, I can't compile it here) to linux.cpp and post the resulting console output (the first line, and the one starting with "sep").Unfortunately I can't help with the other questions.debug_sep.patch Quote Link to comment Share on other sites More sharing options...
Badmadblacksad Posted June 7, 2011 Report Share Posted June 7, 2011 @Badmanblacksad: The 2 AIvsAI works like a charm greatIs there a way to make a unit garrison into a building? I have noticed JuBot doesn't garrison his towers.For that matter, how does one make direct calls to the engine, if possible?@Badmanblacksad: Could you perhaps share how you would make such a function with "attack" ? I can't seem to find a proper way to do so.I bet you didn't see this file did you try to do something along those lines ?in entitycollection.jsEntityCollection.prototype.attack = function(target) { Engine.PostCommand({"type": "attack", "entities": this.toIdArray(), "target": target, "queued": false}); return this; };in entity.jsattack: function(target) { Engine.PostCommand({"type": "attack", "entities": [this.id()], "target": target, "queued": false}); return this; }, and then the same with "garrison"Is it possible to read out the range of entities? I've seen the range overlay, but cant find a reference in the code for the life of me. var cmpRanged = Engine.QueryInterface(entity, IID_Attack);if (!cmpRanged) return;var range = cmpRanged.GetRange(type);hope thats help. never coded anything related to bots. Quote Link to comment Share on other sites More sharing options...
AI-Amsterdam Posted June 8, 2011 Author Report Share Posted June 8, 2011 thanks again for the replies,@badmadblacksad: the attack function works now, thanks a lot! We will try garrisoning in a few moments.@janwas: about the debugging, I'm not sure where the game code is located (I know, it's stupid, but I just work from a checkout of the source, and let someone else test it on windows). I just managed to locate the pyrogenesis executable, but that's it.Is there some way to easily add the line debug_printf(L"%hs\n", argv[0]); to the main without having to build the game?I presume it's the file in trunk/source/main.cpp, right? (a lot of other main files popped up too)I also tried to apply the patch, but I got this:patch <./Downloads/debug_sep.patch (Stripping trailing CRs from patch.)patching file linux.cppHunk #1 FAILED at 36.Hunk #2 FAILED at 45.Hunk #3 FAILED at 54.also... This API shows that there is a function isUnderAttack for buildings, but it turns out that this isn't implemented. Do you have any suggestions on how to implement this function.thanks!the team. Quote Link to comment Share on other sites More sharing options...
Ykkrosh Posted June 8, 2011 Report Share Posted June 8, 2011 If you're running the game like "pyrogenesis ...", then try "./pyrogenesis ..." instead. (The first version has to search through $PATH to find the executable, and the game doesn't bother searching $PATH when trying to find itself so it fails.)This API shows that there is a function isUnderAttack for buildings, but it turns out that this isn't implemented.That API design is ancient and was never implemented - the only documentation that's not wrong is this but it doesn't say very much so it's probably not too useful. But the "events" array should contain events with the name "Attacked" whenever a unit is attacked, so it should be possible somehow to detect and respond to those events (maybe with some extra code in common-api/base.js). Quote Link to comment Share on other sites More sharing options...
Jubalbarca Posted June 8, 2011 Report Share Posted June 8, 2011 Sounds like you'll be going a lot faster than me, I'm still part-stalled over exams. Can you share some results with me of your work? Also, remember that JuBot is not fully fledged by any means; it should not be hard to write a more developed bot, particularly if you've got experience in that area.Good luck! Quote Link to comment Share on other sites More sharing options...
AI-Amsterdam Posted June 11, 2011 Author Report Share Posted June 11, 2011 @Ykkrosh Thanks! Too bad the API is outdated/not complete...@Jubalbarca We're doing this as a 4 week project for our study and we're halfway now. We're using a behaviour tree so our A.I. is structured differently from yours. We'll definitely share the results when we're finished Quote Link to comment Share on other sites More sharing options...
gudo Posted June 12, 2011 Report Share Posted June 12, 2011 Do you intend to continue updating your AI once your class is finished? Quote Link to comment Share on other sites More sharing options...
AI-Amsterdam Posted June 14, 2011 Author Report Share Posted June 14, 2011 (edited) @gudo: We might, but there is also a little thing called summer break ;-). We will try to document our code and make everything as clear as possible, so other people (maybe even you?) can continue our work.We have another question: For several things we would like to check how many entities exist and are queued with a certain class. For example, we would like to see how many "Melee" units we have with the role "defenders".We already tried to write something like this (borrowing some code from JuBot's gamestate):countEntitiesAndQueuedWithClass: function(theClass) { var count = 0; this.getOwnEntities().forEach(function(ent) { if (ent.hasClass(theClass)) ++count; var queue = ent.trainingQueue(); if (queue) { queue.forEach(function(item) { var x = this.getTemplate(item.template).hasClass(theClass); RootBot.prototype.chat(x); if (x) count += item.count; }); } }); return count;but that doesn't seem to work. I'm also trying to write a function that takes a role argument too, to solve the query above, by doing this, but that might be wrong for the smae reasons:countEntitiesAndQueued: function(theClass, role) { var count = 0; this.getOwnEntities().forEach(function(ent) { if (ent.hasClass(theClass) && ent.getMetadata("role") == role) ++count; var queue = ent.trainingQueue(); if (queue) { queue.forEach(function(item) { var x = this.getTemplate(item.template).hasClass(theClass); RootBot.prototype.chat(x); if (x && item.metadata && item.metadata.role == role) count += item.count; }); } }); return count; },Oh, and what are the commands Engine.profileStart("some stuff") and Engine.profileStop() doingAgain, your help would be much appreciated ;-) Edited June 14, 2011 by AI-Amsterdam Quote Link to comment Share on other sites More sharing options...
AI-Amsterdam Posted June 14, 2011 Author Report Share Posted June 14, 2011 var cmpRanged = Engine.QueryInterface(entity, IID_Attack);if (!cmpRanged) return;var range = cmpRanged.GetRange(type);I wasn't able to read if a unit is under attack. So I tried to define being under attack as being within the range of an enemy unit. To find the range of an enemy I tried to use the code given above, but I get an error: IID_Attack is not defined. When I searched through different codes I found that no IID_foo was ever instantiated. What's going on here?thanks in advance,team-ai Quote Link to comment Share on other sites More sharing options...
Boo Posted June 17, 2011 Report Share Posted June 17, 2011 The biggest weakness of the current bot is:1. It attacks buildings and doesn't switch to units, so if it's attacking a house you can just use archers to kill it's units and they wont move to attack the units, they just carry on attacking the house.2. It's way to slow to attack, it never really does much offensive. Quote Link to comment Share on other sites More sharing options...
Sebovzeoueb Posted June 17, 2011 Report Share Posted June 17, 2011 1. It attacks buildings and doesn't switch to units, so if it's attacking a house you can just use archers to kill it's units and they wont move to attack the units, they just carry on attacking the house.I think this is more an issue with the current unit AI in general, as I find this annoying when your own units do this too. You send an army in to the enemy base, and while sending a second one, your first one has been wiped out by one or two infantrymen, because your units were attacking a building. Quote Link to comment Share on other sites More sharing options...
historic_bruno Posted June 17, 2011 Report Share Posted June 17, 2011 Oh, and what are the commands Engine.profileStart("some stuff") and Engine.profileStop() doingAgain, your help would be much appreciated ;-)Those would be profiling hooks, basically timers that give some idea of the performance in that part of the code. You can access profiling info with F11 or save it with Shift-F11 I believe.I wasn't able to read if a unit is under attack. So I tried to define being under attack as being within the range of an enemy unit. To find the range of an enemy I tried to use the code given above, but I get an error: IID_Attack is not defined. When I searched through different codes I found that no IID_foo was ever instantiated. What's going on here?I'm pretty sure the AI isn't allowed to directly access simulation components, which is why those aren't defined. Also the API which the AIs have access to is not nearly complete.If you look at simulation\components\AIProxy.js, there is an OnAttacked event that doesn't appear to be used by the AIs (it may not do anything in fact, but could be a starting point). Also AIProxy.prototype.GetFullRepresentation is worth investigating. Anything you figure out here should either go in the AI proxy or base-AI module so all AIs can use it, and it will be no doubt very appreciated.Edit: I see how those events work. Look at simulation\components\Attack.js in the CauseDamage method. It sends out an MT_Attacked message, which might well trigger the above OnAttacked event in the relevant AI. Quote Link to comment Share on other sites More sharing options...
AI-Amsterdam Posted June 19, 2011 Author Report Share Posted June 19, 2011 Thanks, we will try that.Meanwhile, we've been working on a module to attack the enemy. What we would like to know, is the following.Is there a way to see which unit has a bonus against which? For example, the infantry spearman has a bonus against cavalry units.Is there a function that does this, for example:vs(templateA, templateB){ if(templateA beats templateB) return 1; if(templateB beats templateA) return -1; return 0;}vs("units/{civ}_infantry_spearman_b", "units/{civ}_cavalry_swordsman_b") //returns 1What we would like to do is give entities one of our soldiers is good against a higher priority to be attacked. Quote Link to comment Share on other sites More sharing options...
Rasunadon Posted June 19, 2011 Report Share Posted June 19, 2011 What we would like to do is give entities one of our soldiers is good against a higher priority to be attacked.Hey, will your AI still be beatable with that? Quote Link to comment Share on other sites More sharing options...
Ykkrosh Posted June 19, 2011 Report Share Posted June 19, 2011 I'm pretty sure the AI isn't allowed to directly access simulation components, which is why those aren't defined.Indeed - they're not even running in the same JS runtime or thread. Since the attack range is a constant that's determined by the entity template files, it should be possible to modify EntityTemplate in entity.js to return this._template.Attack.Melee.Range and/or this._template.Attack.Ranged.MaxRange, which will hopefully give the desired data without interacting with the entities directly.Is there a way to see which unit has a bonus against which? For example, the infantry spearman has a bonus against cavalry units.There aren't any attack bonuses implemented yet - it just depends on the hack/crush/pierce attack and armour values: damage = max(1, max(0, attack.hack - armour.hack) + max(0, attack.crush - armour.crush) + max(0, attack.pierce - armour.pierce)) Quote Link to comment Share on other sites More sharing options...
historic_bruno Posted June 19, 2011 Report Share Posted June 19, 2011 Hey, will your AI still be beatable with that?Just sounds like developing strategy to me, nothing a human player couldn't do Quote Link to comment Share on other sites More sharing options...
AI-Amsterdam Posted June 19, 2011 Author Report Share Posted June 19, 2011 Guess you will have to counter the units countering your units then. Quote Link to comment Share on other sites More sharing options...
Rasunadon Posted June 20, 2011 Report Share Posted June 20, 2011 (edited) Guess you will have to counter the units countering your units then. But your AI will do the same. So I will then have to counter the units countering my counter units countering its counter units. Are you preparing your AI already for Alpha 6?EDIT: I have written this reply before you have written your one. Cool. Edited June 20, 2011 by Rasunadon Quote Link to comment Share on other sites More sharing options...
AI-Amsterdam Posted June 20, 2011 Author Report Share Posted June 20, 2011 (edited) Well Rasunadon, as you can see they have not implemented a rock-paper-scissors algorithm, so AI world domination is still a few releases away .We have another question. Garrisoning works like a charm, but we can't seem to find the command to ungarrison units. we tried something likeungarrison: function() { Engine.PostCommand({"type": "Ungarrison", "entities": [this.id()], "target": null, "queued": false}); return this; },but we got a message that the engine does not recognise the command. Ignoring unrecognized command type 'Ungarrison'We found a function called ungarrison in UnitAI, but this doesn't seem to work with the engine command.Please help Edited June 20, 2011 by AI-Amsterdam Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.