IPB Style© Fisana

Jump to content


A New A.i.?


  • Please log in to reply
70 replies to this topic

#1 AI-Amsterdam

AI-Amsterdam

  • Community Members
    Pip

  • Discens
    (19 posts)

Posted 06 June 2011 - 10:14 AM

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 by AI-Amsterdam, 06 June 2011 - 10:30 AM.


#2 Badmadblacksad

Badmadblacksad

  • WFG Programming Team

  • Discens
    (33 posts)

Posted 06 June 2011 - 11:34 AM

here is an answer to your first question :

Ykkrosh said:

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).
Martin F [ aka Badmadblacksad ]

Wildfire Games Programmer
Contact me: badmadblacksad@wildfiregames.com


Support Wildfire Games!

#3 AI-Amsterdam

AI-Amsterdam

  • Community Members
    Pip

  • Discens
    (19 posts)

Posted 06 June 2011 - 12:13 PM

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?

#4 Rasunadon

Rasunadon

  • Community Members
    Pip

  • Discens
    (79 posts)

Posted 06 June 2011 - 01:59 PM

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.

#5 janwas

janwas

  • 0 A.D. Department Leader

  • Primus Pilus
    (2,733 posts)

Posted 06 June 2011 - 06:42 PM

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?
Jan Wassenberg [aka janwas]

Wildfire Games General Programming lead and code monkey
Contact me: jan@wildfiregames.com

#6 AI-Amsterdam

AI-Amsterdam

  • Community Members
    Pip

  • Discens
    (19 posts)

Posted 07 June 2011 - 07:37 PM

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

#7 janwas

janwas

  • 0 A.D. Department Leader

  • Primus Pilus
    (2,733 posts)

Posted 07 June 2011 - 08:24 PM

Quote

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

Attached Files


Jan Wassenberg [aka janwas]

Wildfire Games General Programming lead and code monkey
Contact me: jan@wildfiregames.com

#8 Badmadblacksad

Badmadblacksad

  • WFG Programming Team

  • Discens
    (33 posts)

Posted 07 June 2011 - 09:53 PM

View PostAI-Amsterdam, on 07 June 2011 - 07:37 PM, said:

@Badmanblacksad: The 2 AIvsAI works like a charm :)
great

View PostAI-Amsterdam, on 07 June 2011 - 07:37 PM, said:

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?
@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.js
EntityCollection.prototype.attack = function(target) 
 { 
 	Engine.PostCommand({"type": "attack", "entities": this.toIdArray(), "target": target, "queued": false}); 
 	return this; 
 };

in entity.js
attack: function(target) { 
 		Engine.PostCommand({"type": "attack", "entities": [this.id()], "target": target, "queued": false}); 
 		return this; 
 	},  

and then the same with "garrison"

View PostAI-Amsterdam, on 07 June 2011 - 07:37 PM, said:

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.
Martin F [ aka Badmadblacksad ]

Wildfire Games Programmer
Contact me: badmadblacksad@wildfiregames.com


Support Wildfire Games!

#9 AI-Amsterdam

AI-Amsterdam

  • Community Members
    Pip

  • Discens
    (19 posts)

Posted 08 June 2011 - 10:42 AM

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.cpp
Hunk #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.

#10 Ykkrosh

Ykkrosh

  • WFG Programming Team

  • Primus Pilus
    (4,869 posts)

Posted 08 June 2011 - 04:06 PM

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

Quote

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).
Philip Taylor [aka Ykkrosh]

Wildfire Games Programmer
Contact me: philip@wildfiregames.com

#11 Jubalbarca

Jubalbarca

  • WFG Programming Team

  • Discens
    (98 posts)

Posted 08 June 2011 - 09:20 PM

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! :)
Posted Image

#12 AI-Amsterdam

AI-Amsterdam

  • Community Members
    Pip

  • Discens
    (19 posts)

Posted 11 June 2011 - 06:19 PM

@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 :)

#13 gudo

gudo

  • Community Members
    PipPipPip

  • Duplicarius
    (228 posts)

Posted 12 June 2011 - 02:16 AM

Do you intend to continue updating your AI once your class is finished?
Did you contribute to 0 AD?
Make sure you're in the credits!


AI Players
JuBot | RootBot | SplitBot | qBot | Marilyn | arBot

#14 AI-Amsterdam

AI-Amsterdam

  • Community Members
    Pip

  • Discens
    (19 posts)

Posted 14 June 2011 - 11:57 AM

@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() doing
Again, your help would be much appreciated ;-)

Edited by AI-Amsterdam, 14 June 2011 - 01:26 PM.


#15 AI-Amsterdam

AI-Amsterdam

  • Community Members
    Pip

  • Discens
    (19 posts)

Posted 14 June 2011 - 02:25 PM

Quote

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

#16 Boo

Boo

  • Community Members
    Pip

  • Discens
    (11 posts)

Posted 17 June 2011 - 11:08 AM

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.

#17 Sebovzeoueb

Sebovzeoueb

  • Community Members
    Pip

  • Discens
    (88 posts)

Posted 17 June 2011 - 12:43 PM

View PostBoo, on 17 June 2011 - 11:08 AM, said:

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.
Sebastian Boutin Blomfield.

this is pretty much what I do.

#18 historic_bruno

historic_bruno

  • WFG Programming Team

  • Primus Pilus
    (1,980 posts)

Posted 17 June 2011 - 09:51 PM

View PostAI-Amsterdam, on 14 June 2011 - 11:57 AM, said:

Oh, and what are the commands Engine.profileStart("some stuff") and Engine.profileStop() doing
Again, 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.

View PostAI-Amsterdam, on 14 June 2011 - 02:25 PM, said:

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.
Ben Brian [ aka historic_bruno ]

Wildfire Games Programmer
Contact me: ben@wildfiregames.com

#19 AI-Amsterdam

AI-Amsterdam

  • Community Members
    Pip

  • Discens
    (19 posts)

Posted 19 June 2011 - 03:24 PM

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 1

What we would like to do is give entities one of our soldiers is good against a higher priority to be attacked.

#20 Rasunadon

Rasunadon

  • Community Members
    Pip

  • Discens
    (79 posts)

Posted 19 June 2011 - 07:12 PM

View PostAI-Amsterdam, on 19 June 2011 - 03:24 PM, said:

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?




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users