auto-destruct/surrender/quit

auto-destruct/surrender/quit

Here is where ideas can be collected for the skirmish AI in development

Moderators: hoijui, Moderators

Post Reply
Sahtor
Posts: 7
Joined: 17 Sep 2006, 17:03

auto-destruct/surrender/quit

Post by Sahtor »

I'd like to see AIs self-destruct if they lost all construction units and factories and possibly less than 10 units left on the map.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

That wouldnt be fun for the player though
User avatar
1v0ry_k1ng
Posts: 4656
Joined: 10 Mar 2006, 10:24

Post by 1v0ry_k1ng »

How about an AI that upon that level of defeat taunts "OH, YOU DIDNT KNOOOW!" then the ai cheats and spawns 5 commanders in random spots across the map.
Arco
Posts: 75
Joined: 17 Jun 2006, 16:28

Post by Arco »

AF wrote:That wouldnt be fun for the player though
I disagree. First off, this would of course be optional, so anyone that did think it ruined their fun could turn it off. However, I enjoy playing against the AI, I love blowing stuff up all over the place, and ensuring my complete victory.

What I don't like is that I don't "win" until I manufacture a hundred radar/sonar planes and set up an intricate patrol route covering the entirety of the map* so that I can spot the six underwater mexes or whatnot that happen to be left behind and blow them up. No player would let them just sit there preventing the end of the game. It's a waste of time. After I know I've won, I tend to just exit the game, but I'd rather get that feeling of completion and the screen with the graphs and such. (Everyone loves graphs.)

It's one thing if the enemy still has a huge mobile army and could potentially win even though they lost their base, but I never see that happen. I just see a small collection of mexes, random support buildings, often unpowered LLTs, and so on. Also (frustratingly, although this is much less of a problem after recent AA changes to impulse) land-only units that have been shot into small (but deep) puddles, cannot move or fire, and can only be attacked with nukes or a very lucky torpedo shot. It's usually easier to build a whole nuke silo to kill them than anything else. I've only seen this occur on a handful of maps, though; most lack small, deep puddles.

Anyhow, a self-destruct built into AIs would be fantastic and fix everything at once.

*Thankfully no longer so bad now that the planes can be given an "area attack" command across the map.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

If you could write us a function that determined if a given unit was in such an awkward position and if at end game should be selfdestructed then I'd be fine witht hat.

But every algorithm I can think of atm would result in issus with "yay my mavericks are pwning the AI, oo I blew up all its factories and builders eeek where did it go?! I was pwning it!"

Or the horrible AoE AI tactic of suddenly dissapearing midgame after surrendering despite nobody atatcking it because its enemies are bigger.

Other than that i can think of a few algorithms that would actually be too strict and may only catch half of these scenarios...


As always write out the algorithm in pseudocode so we can all ellaborate on it untill it's sufficiently detailed to transfer into code.
Arco
Posts: 75
Joined: 17 Jun 2006, 16:28

Post by Arco »

AF wrote:As always write out the algorithm in pseudocode so we can all ellaborate on it untill it's sufficiently detailed to transfer into code.
I'm not sure how the whole AI loop works, so it's more like a list of checks than pseudocode.

1. First off, see if there is at least one builder (unit or factory).

2. If true, see if there is some metal and energy income.

3. If 2 is true, AI is still active. If 2 is false, check to see if there are at least enough spare resources to build a resource unit of some type. (This runs into a problem only if there are, say, energy-making structures that cost no energy or metal to make; you'd always be able to make more of them, but never gain any metal if metal extractors cost at least some metal to make and the AI is at 0 metal. But that seems like a really unrealistic mod design.) If it can't, the AI is dead. If it can, it should build said resource structure and start the check again.

4. If there is no builder, the AI is probably dead--but perhaps not! Maybe it (somehow) still has tons of energy production, plenty of defenses, and some attack units that it could potentially kill the player with. This is the tricky bit. The AI should immediately attack with available mobile units; if they're stuck they should be disregarded from the check. (Detecting stuck units is a separate problem.) If they're not stuck, it's a matter of waiting to see if the player dies before they do or not. The AI is still "active" during this time. If the units are destroyed it will have to run the check again based on more remote possibilities of success.

5. For instance, the AI might have no mobile units, but may have long-range assault structures capable of killing a player, and defenses and energy production sufficient to hold the player at bay for a long time. This is perhaps the trickiest situation--determining if its weaponry could actually kill off a remaining side or not. It's a little easier with a maphack--seeing if there are any enemy units that simply cannot be hit with any of its weapons. Without one, I guess it would only know for sure that it's failed if the game is still ongoing, yet no shootable enemy units can be detected. I.e., none of its weapons can reach any detected enemies (easy to calculate just considering range, but it would also have to be able to determine whether terrain is a permanent obstacle or not), or there are simply no detected enemy units. Since it has no mobile units, it will never be able to detect the enemy base and will never be able to shoot at it regardless of whether its weapons are physically capable or not. (Caveat: if a mod were created in which a side could completely cloak/stealth their base, but with some weakness like the invisibility goes away for a while if a unit is hit with a stray shot, then this would still be a normally "winnable" situation that this algorithm would not properly detect. However, I have a feeling that no existing AI would be able to play such a mod in the first place, so it's kind of a moot point.)

Some theoretically generated outcomes that are a bit weird: if the enemy has, say, a scout plane, it would be able to use it to spot for artillery (and then it comes down to range/line-of-fire checks). If this scout were destroyed, the AI might find it has no more mobile units and cannot detect any enemy units. So the AI would be active so long as the little scout plane were left alone, but shooting it down would cause the AI to self-D its entire base. Something of a butterfly effect. This behavior seems a little extreme, but it isn't really wrong.

One other approach would be to allow the AI to continue as long as it has any weapons remaining and sufficient energy to fire. However, a single solar and LLT hidden away in some remote recess of the map would keep such an AI active even though it comes down to the usual "send radar planes all over the entire goddamn map just to find a solar and LLT" problem, so I don't support that method. Even though the LLT could theoretically kill all the units a player sends at it, it could NEVER destroy the player's base.

The only time this algorithm really seems to make bad choices is in games involving more teams. Team A's few remaining defensive structures might be able to kill Team B's assault force, which B intended to use to kill A and then kill Team C. Meanwhile, Team C launches all its units at Team B's base. If Team A (an AI) self-D's, Team B is cleared to send all its units at Team C without having to worry about Team A's defenses as all. Perhaps in this situation, Team B triumphs by killing C before C kills B's base. However, if Team A did not self-D, A's defenses might cause enough damage to B's units to give C the upper hand. Either way, A won't legitimately win, but its self-D behavior can still affect the outcome of a game.

This is also an obvious effect regarding allied teams--an ally with defenses but no assault units is still valuable to your alliance. However, this doesn't present a big problem for the algorithm since it merely needs to be extended to account for the capabilities of the entire alliance rather than just its own team. As such, only the previous example seems to be a significant fault, and it's such a rare situation that I think the benefit of the algorithm considerably outweighs this fault.

Edit: note that even though this check is probably quite CPU intensive, it can get away with running VERY rarely--even once a minute would be sensible, and once every three minutes would even be tolerable. And throughout most of the game, the check would exit very quickly as there would be an active builder found right away.

It'd also be nice if the AI announced that it was self-destructing, so it doesn't leave the player wondering, "what just killed that AI? Does that mean there are other enemies over there?"
User avatar
overkill
Posts: 500
Joined: 02 Sep 2006, 01:15

Post by overkill »

1v0ry_k1ng wrote:How about an AI that upon that level of defeat taunts "OH, YOU DIDNT KNOOOW!" then the ai cheats and spawns 5 commanders in random spots across the map.
that is a realy good idea
User avatar
overkill
Posts: 500
Joined: 02 Sep 2006, 01:15

Post by overkill »

1v0ry_k1ng wrote:How about an AI that upon that level of defeat taunts "OH, YOU DIDNT KNOOOW!" then the ai cheats and spawns 5 commanders in random spots across the map.
that is a realy good idea
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

Nobody has proposed an effective system for taunts, one that doesnt present itself as scripted and predictable.


Arco could you restructure that from prose into pseudocode? I find it much easier to visualize an algorithm in pseudocode than a large block of prose...

if artillery
goto hill
else
return to base

versus

If it's an artillery unit then tell it to go to the nearest hill otherwise go to the ai base.

For the AI interface:

https://taspring.clan-sy.com/wsvn/filed ... rev=0&sc=0

That file will provide you with the interface spring calls in an AI for events.
Arco
Posts: 75
Joined: 17 Jun 2006, 16:28

Post by Arco »

AF wrote:Arco could you restructure that from prose into pseudocode? I find it much easier to visualize an algorithm in pseudocode than a large block of prose...
You asked for it.

This presents the algorithm as a boolean function returning true if the AI should self-D and returning false otherwise. It should be done this way so the main loop this is contained in can wait for an arbitrary (even dynamic) time period before calling it again, and can wait for as many true returns as deemed necessary to actually hit the self-D switch. I've only used Java extensively so this code is going to more of that flavor. I made up the resource variables since they weren't in the interface and I have no idea what they really are. This code is super-ugly since it contains some of the higher-order AI logic in it (i.e., because this is the reason why you're close to dead, do this). As a side note, to allow for the scout-plane situation previously described, mobileCombatUnits includes scouts.

Code: Select all

if (builders > 0) {
  if (metalIncome > 0 && energyIncome > 0) { return false; }
  if (currentMetal > metalForCheapestResourceStructure 
     && currentEnergy > energyForCheapestResourceStructure) { buildCheapestResourceStructure(); return false; }
  if (mobileCombatUnits > 0) { attackWith(mobileCombatUnits); return false;}
  else if (longRangeAttackStructures > 0 && detectedEnemyUnits[].size > 0) {
    for (i=0; i < detectedEnemyUnits[].size; i++) {
      if (hittable(detectedEnemyUnits[i])) { return false; }
    return true;
    }
  return true;
}
return true;
There, that's much easier to understand, I'm sure. It doesn't include any of the stuff I said regarding more complex team situations; to fix that you'd just have to look at the results this would give if run on all the allied players, and if any of them return "false", don't destroy anything. I could have written that as a small recursive for loop, but that would generate an infinite recursion, so it would actually have to reference the most recent cached values instead. The whole format of this would have to change to support that which would kill readability, but basically it has to be generalized so any team can run it on any other allied team. Ideally the cached values could be stored more globally to minimize the performance hit on a game with multiple such AIs, but that's another thing that would make this example way more complicated, and I don't even know how it's done.
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Post by hughperkins »

You can increase the abstraction level to make it easier to read:

Code: Select all

bool ShouldSurrender()
{
   return !CanBuild() && !CanAttack();
}
User avatar
yuritch
Spring 1944 Developer
Posts: 1018
Joined: 11 Oct 2005, 07:18

Post by yuritch »

Accounting for allies is easy. If there are allied players, then give everything to them (maybe to the one with the most powerful forces) instead of Self-Ding everything.
Or even better (but this requires allied AI players communicating between each other or having some sort of central team coordination AI): run the defeat check for each player in a team and only surrender if it returns true for all of them (thus all of the defeated team goes down at once).
User avatar
hughperkins
AI Developer
Posts: 836
Joined: 17 Oct 2006, 04:14

Post by hughperkins »

Or even better (but this requires allied AI players communicating between each other or having some sort of central team coordination AI): run the defeat check for each player in a team and only surrender if it returns true for all of them (thus all of the defeated team goes down at once).
Having allied chat between AIs could be really fun.

GlobalAI0: How ya'all doing guys?
GlobalAI1: I'm dead
GlobalAI2: I'm dead
GlobalAI0: Alright, gg

GlobalAI0: How ya'all doing guys?
GlobalAI1: I'm dead
GlobalAI2: I'm ok
GlobalAI0: Alright, good job GlobalAI2

Not on-topic, but this works for attack too. The lowest-numbered GlobalAI nominates himself for leader, and pings his team-mates:

GlobalAI0: Hi guys, you all speak aiprot1?
GlobalAI1: Hi GlobalAI0. aiprot1 good to go.
GlobalAI2: Hi GlobalAI0. aiprot1 good to go.

Building metal extractors:

GlobalAI1: Building mex at 300.125, 600.124

Attacking, globalAI0 commands:

GlobalAI0: Reorg 1600, 1400

When teams in position:
GlobalAI1: Team in position 1600, 1400
GlobalAI2: Team in position 1600, 1400
GlobalAI0: Attack 1800, 1600

When enemy too strong:
GlobalAI0: Reorg 1600, 1400

When teams back up to strength:

GlobalAI0: Attack 1900, 1700

When enemy factory goes down:

GlobalAI0: enemy vehicle factory destroyed, good work team
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

AI chat messages arent the same as player chat messages, they're direct outputs to the console and dont use any network code, so only the person hosting the bot sees the message.

Also AI messages arent parsed for commands and modifiers so a: hello would appear to the person on that machine as 'a: hello' and nobody else would see it and it wouldnt be an ally message.

Also I'm not aware of any AI interface calls that allow AIs to hand over a unit like humans can. And the AI itnerface has no provisions whastoever for resource sharing, or information sharing, thus 2 AIs on different computers that're allied cannot share information or communicate in any way.

Arco your algorithm seems fine save for 1 big flaw:

if (hittable(detectedEnemyUnits))

The AI interface doesnt provide such a high level function so you need to do more pseudocode to figure out how this function will be implemented.
Arco
Posts: 75
Joined: 17 Jun 2006, 16:28

Post by Arco »

AF wrote: your algorithm seems fine save for 1 big flaw:

if (hittable(detectedEnemyUnits))

The AI interface doesnt provide such a high level function so you need to do more pseudocode to figure out how this function will be implemented.

Like I said, I don't know what can be done or how difficult it is. Checking hittability is first a matter of range, and then a matter of terrain in the way. Range is easy, and it seems the engine already calculates whether a given weapon can hit a target due to terrain or not--I don't know if the AI can access that information. If it can't, it should be able to, because the only alternative seems to be the mythical terrain analysis function, which is far too complicated for me to even create pseudocode for.
Last edited by Arco on 08 Nov 2006, 18:23, edited 1 time in total.
User avatar
FLOZi
MC: Legacy & Spring 1944 Developer
Posts: 6241
Joined: 29 Apr 2005, 01:14

Post by FLOZi »

Some good documentation on just WHAT the AI interfaces expose would be rather useful, surely?
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

look in /trunk/RTS/External AI/ at the files starting with 'I', command.h UnitDef.h and WeaponHandler.h (the weapondef class), and that will be pretty mcuh self explanatory as to what AIs can expect from the interface.

If someone could take the IAICallback.h and UnitDef.h command.h and WeaponDef class and put them in the wiki, then I and maybe other AI devs will add comments to them on what they do and howto use them and any tricks that can be done.
Post Reply

Return to “AI”