Jump to content

Recommended Posts

I've been discussing with Philip about a possible rewrite of the AI code, so it uses an event/hook system.

I did a quick code example of how I thought it would work, here:

http://pastie.org/1553793

The idea is that it'll allow AI to be event driven, rather than checking every case.

e.g. on('unit.attacked', function(unit) { defend(unit); });

The system would be thread safe (as each AI runs in it's own thread), and it wouldn't need any serialization of the AI state, as the save game would just start firing off events again, which the AI would respond to.

It would also allow users to write their own scripts, which could listen to those hooks, and act on them.

e.g. on('unit.built', function(unit) { if (unit.hero) { Chat.post('Watch out, I just built a hero!'); });

This type of thing could open up ways to all sorts of cool assistant scripts, like alerting you to an attacker, and showing a dialog to jump to it.

e.g. on('unit.attacked', function(unit) { GUI.prompt('Jump to a unit being attacked?', function() { GUI.jumpto(unit) }) });

Anyone have any thoughts or concerns on the matter?

Link to comment
Share on other sites

  • Replies 84
  • Created
  • Last Reply

Top Posters In This Topic

Is there an example of another AI that uses a similar system to the one you're proposing? Would there be any performance benefits?

I spent a bit of time over the weekend tweaking the current AI's javascript to see what I could get it to do, it's really easy to understand at this early stage, especially with Ykkrosh's helpful notes.

Edit: BTW plumo your sig is a bit broken. I use this:

[url="http://www.pledgie.com/campaigns/14160"][img=http://www.pledgie.com/campaigns/14160.png][/url]

Edited by Pureon
Link to comment
Share on other sites

Is there an example of another AI that uses a similar system to the one you're proposing?
Not that I know of. I didn't go searching for one. I based my AI approach similar to how a browsers DOM model triggers events like mouseover, and onclick.
Would there be any performance benefits?
I'm not entirely sure, but I'd say it'd speed it up. As I undersand it, if you leave the current AI implementation just staying there, it has to loop over units each turn seeing what has changed and respond accordingly. It's more code, and more processing. And while not severely more, maybe enough to show notable different?

With the event/hook system, the AI would get the info it needs. And as shown in the Pastie i sent in an earlier post, it'd only send events if the event is being listened for, so if there is no event, then nothing happens. A blank AI file would then have no extra drag on the system, and events would be much simpler for the AI writer to plug into.

Of course, the current system could be easier maintained, and run alongside the event/hook system. But I would prefer to do it event based, as it'd make the AI much more responsive to things that happen.

e.g. Imagine a unit is being attack, a unit just died, a building is being attack, and a unit just run out of resources to mine

In the current implementation, you'd need to loop over every single unit, and check if their health is decreased (which means storing a list of previous units). That uses memory and time.

With the event system, you get that info delivered to you from C++ when it executes that action, so you don't have to check, it'll know and tell you when.

At least, that's how I hope it'll work. IT'd be great to have Philip comment on how it could actually be designed, instead of theoretical code...

Link to comment
Share on other sites

Hello,

I am currently trying out the AI system.

It is really easy compared to the AI system of Spring. You can write 200 lines of code and your AI can already harvest resources and train workers.

But without the TestBot I would have had a hard time to get the right functions to get the AI to do what I want.

I like the idea of an AI event system it makes it easier to respond to game environment events and as you wrote the AI can also continue it's work in the middle of a game (save games, reload AI scripts save).

So, are there any progress on the AI event system idea?

Link to comment
Share on other sites

So, are there any progress on the AI event system idea?
Hopefully soon. The AI is on hold at the moment. There are a few other things that need finishing off before the AI system is worked on again.
IS good way to change difficult of AI.
There is no difficulty setting in game. But AI will be made that are harder. They won't be in the next release though.
Link to comment
Share on other sites

I can tune the TestBotAI to play better. I have a working AI which beats the TestBotAI (exception: on some maps bug #740 stops the expansion of the AI).

It scales better: Determines the distance between resource and dropsides (at the moment doesn't work 100% correct). Builds houses on need. Builds barrack(s). Uses starting units. Reassigns idle attacking units.

I am rewriting my AI at the moment. It will use an agent-system and will not relay on static settings like template names, squad attack size.

Link to comment
Share on other sites

I spent a bit of time over the weekend tweaking the current AI's javascript to see what I could get it to do, it's really easy to understand at this early stage, especially with Ykkrosh's helpful notes.

Sounds good :). I guess there's still lots of things that aren't easily understandable without searching through the code - would some documentation be helpful at this stage? If so, what kinds of things would be most useful to document? (The data that common-api/base.js receives from the engine? The way the simulation components send data to the AI scripts? The way common-api exposes entity data? The way testbot does its stupid broken planning thing? How to get started with writing and running scripts? etc)

without the TestBot I would have had a hard time to get the right functions to get the AI to do what I want.

Same question probably applies here - hopefully documentation would make it easier to do what you want, but what specific things need documenting?

I have a working AI which beats the TestBotAI (exception: on some maps bug #740 stops the expansion of the AI).

(#740 should be fixed now). Sounds great :). I don't really like the design of TestBot at all, but I'm not really sure how to design it much better, so it's good for me if someone else can do the work to make a decent AI :)

I've been discussing with Philip about a possible rewrite of the AI code, so it uses an event/hook system.

The implementation is already fundamentally event-based (since that's necessary for performance). The data that the engine sends to the AI scripts every turn looks like:

{
"entities": {
"7683": {
"id": 7683,
"template": "units/hele_support_female_citizen",
"position": [
97.58279418945312,
73.37493896484375
],
"hitpoints": 75,
"owner": 1,
"idle": false,
"resourceCarrying": []
}
"7741": {
"position": [
447.17420959472656,
133.0516815185547
]
},
"8603": {
"hitpoints": 72,
"position": [
419.1849822998047,
397.58448791503906
]
},
},
"events": [
{
"type": "Attacked",
"msg": {
"attacker": 8613,
"target": 8603
}
}
],
"map": /* terrain/obstruction data */,
"passabilityClasses": /* stuff for interpreting obstruction data */
"players": ...,
"timeElapsed": ...
}

In the "entities" section, 7683 is a new entity (so it includes all the relevant state data for that unit); 7741 is an old unit that has moved since the last turn (so it only sends the new position value - the AI scripts are responsible for remembering the previous turn's entity state and applying these new changes); 8603 is an old unit that has moved and also been attacked (so it has a new position and hitpoints). The "events" section is a list of various events that occurred in the previous turn (currently Create, Destroy, Attacked, ConstructionFinished, TrainingFinished, PlayerDefeated).

TestBot uses common-api/base.js to process this data - it maintains the current entity state (in this._rawEntities) and updates it based on the new "entities" data from the engine. Most of the items in the "events" list just get ignored, since TestBot didn't need to use them. If you do want to use them, probably a good approach is to make a copy of common-api and edit base.js to do whatever you want (e.g. maintain a list of event handlers and let the AI subclass set up the handlers in its constructor) and experiment with an event-based API that way - there shouldn't need to be any changes to the engine code, it's all just relatively straightforward scripting.

(The goal of common-api is to provide a useful base for all AI scripts, so ideally any successful experiments would get merged back into it; but there's no obligation to use common-api at all, and it's easier to play around with a separate copy to avoid breaking any other AI scripts.)

So I think you should be able to do what you want by just editing the scripts. If you need the engine to send more gameplay events then I can probably add those (they just need updates to the component scripts), and if the engine API needs to be document then I can do that; otherwise I think I don't need to be involved :) (and I'd prefer not to have to be, since I'm still not sure how to do a good event-based AI design so it's better handled by people who believe in it :P)

It would also allow users to write their own scripts, which could listen to those hooks, and act on them.

e.g. on('unit.built', function(unit) { if (unit.hero) { Chat.post('Watch out, I just built a hero!'); });

I think that players writing 'assistant' scripts is a separate topic - they're more part of the GUI system than the AI system, and there's different requirements on security and performance etc, so the implementation would be completely different. It's an interesting idea (and probably worth discussing more) but I don't think it'd have any effect on the AI design so it's not particularly relevant here.

I would prefer to do it event based, as it'd make the AI much more responsive to things that happen.

e.g. Imagine a unit is being attack, a unit just died, a building is being attack, and a unit just run out of resources to mine

In the current implementation, you'd need to loop over every single unit, and check if their health is decreased (which means storing a list of previous units). That uses memory and time.

With the event system, you get that info delivered to you from C++ when it executes that action, so you don't have to check, it'll know and tell you when.

I think my concern is: What would you do with that information? I expect you don't want to send your whole army rushing after a single enemy archer who pinged one of your outpost towers - you probably want to do some kind of threat calculation based on the rate of damage and the concentration of enemy forces, so you're forced back to looping over lists of entities, and you don't want to do all that looping every single time a unit gets injured, so you'll just run the calculation every few seconds, and the event-based system doesn't seem to give any real benefit to this process.

Link to comment
Share on other sites

The implementation is already fundamentally event-based (since that's necessary for performance). The data that the engine sends to the AI scripts every turn looks like:

That information certainly looks like it'd work, so there won't be a need for a callbacks system inside the C++ code, but it's still a low level interface for JS API.So now it needs JS to parse that info and send out events as needed.

I expect you don't want to send your whole army rushing after a single enemy archer who pinged one of your outpost towers - you probably want to do some kind of threat calculation based on the rate of damage and the concentration of enemy forces, so you're forced back to looping over lists of entities

You just pass the relevant information through the events system. For example, if you want to test a unit was killed really quickly, for the above information you posted (+some more info would be needed), and with a decent event system, this'd work:

on('unit.attacked', function(info) {
if (info.unit.health_last_turn == info.unit.max_health && info.unit.health == 0) {
// unit was killed so quickly! serious threat?
Chat.post("Grr!", info.attacker);
}
});

It's still a pretty basic example, but basically, they should be able to have access to inspect anything related to the event (so a unit who is attack send who attacked them, where they got attacked, their old health, their new health as shown in the code example above).

Link to comment
Share on other sites

Sounds good :). I guess there's still lots of things that aren't easily understandable without searching through the code - would some documentation be helpful at this stage? If so, what kinds of things would be most useful to document? (The data that common-api/base.js receives from the engine? The way the simulation components send data to the AI scripts? The way common-api exposes entity data? The way testbot does its stupid broken planning thing? How to get started with writing and running scripts? etc)

You're so nice to us :)

I mostly mod AIs without ever reading any documentation (not that commercial releases come with AI documentation). I didn't poke around in the common-api files, just experimented with the testbot javascript to see how easy it was to mod. Any documentation should make it easier for experienced developers like yourself to expand the AI. Could someone like marsha develop the AI further using the current implementation, or is the AI system likely to change?

Link to comment
Share on other sites

I think the engine/script interface isn't likely to change much, since it seems to basically work and I'm not sure there's much that needs to be added (except some more events). common-api might change quite a bit depending on what the higher-level scripts want it to do, but I don't have any current plans so it'll depend on feedback and further experimentation. TestBot should probably be pretty much entirely rewritten.

If people write AIs now then there's no guarantee of compatibility and they'll probably break at some point; but if people don't write AIs now then we'll have no experience to base the design on so it'll never become stable. So I think now's a good time to try writing some :)

Link to comment
Share on other sites

Once Alpha4 is released hopefully we'll get more feedback about the AI, and we'll probably see a few more AI scripters show up once they've seen an AI is now functioning within the game. I've managed to create an AI that works independently from TestBot, cunningly named PureBot, so it's very possible for the community to experiment with what we have. Whilst watching TestBot in action, these were some random thoughts:

1) If food sources are nearby, such as animals or bushes, these should be gathered prior to multiple fields being built.

2) Field building should be limited to flat land, or we'll need to rethink how fields are modelled (can model props conform to landscape height?). Testbot was building fields on hilly terrain which didn't look very good.

3) Can AIs be given extra resources or have a resource gathering multiplier/limiter? (Cheating AI)

4) Soldier gatherers should aid in gathering resources until they are required to attack. Maybe only relevant when larger attacking forces are employed. PureBot had an attacking force of over 40 units, which meant it got very crowded around the AI's CC :D

5) Attack-move will have a big impact - It'll stop the attacking army being picked off all the way to the CC by long range units.

6) Running an AI on Miletus causes errors (Because the AI only has ships to start with). Perhaps Miletus shouldn't be the default choice map for Alpha4.

I'll stop there :)

Link to comment
Share on other sites

2) Field building should be limited to flat land, or we'll need to rethink how fields are modelled (can model props conform to landscape height?). Testbot was building fields on hilly terrain which didn't look very good.
We should implement terrain decals, so that things like farms and foundations can use textures that follow the terrain. Also we should limit the maximum terrain height variation when you're placing a building, so you can never build it on a steep hill and make it look silly. Also we probably should automatically flatten the terrain underneath non-terrain-decal buildings once you do place them, to smooth out small variations.
3) Can AIs be given extra resources or have a resource gathering multiplier/limiter? (Cheating AI)
No, that would be cheating :P. I think we should try to make fair AIs that are as good as possible, before giving up and giving them artificial gameplay advantages.
6) Running an AI on Miletus causes errors (Because the AI only has ships to start with). Perhaps Miletus shouldn't be the default choice map for Alpha4.
I think I fixed the errors, but we should change the default map to something where the AI can do a slightly-less-terrible job. Suggestions? :)
Link to comment
Share on other sites

Played against the AI a little bit. It's great to see what it did. Pretty cool. A few things:

- Shift-queue building seems broken.

- The AI females were chasing deer all over the map. Should probably focus them on berries instead and cavalry upon the deer.

- The AI didn't seem to know what to do with the starting units.

- The AI needs to learn where to place dropsites. ;)

- When a group of enemy spearmen marched toward my base and were attacked by my soldiers, the AI soldiers didn't seem to know what to do.

- My units no longer seem to auto-gather after building a dropsite.

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