Are you, in fact, a pregnant lady who lives in the apartment next door to Superdeath's parents? - Commodore

Create an account  

 
AI

(December 13th, 2016, 08:16)GermanJoey Wrote: The only one going in circles is yourself, twisting the issue like a wet towel and then whip-slashing men of straw. But, well, it's your game, dude, you don't need to answer to me. If you're not even interested in acknowledging such an extreme exploit as this, I won't bother you anymore.

I acknowledged the problem, two of them in fact, but you don't seem to acknowledge we don't have a good enough solution to either of them.

Mana Milking is a generic problem that's impossible to solve. Carefully weighting decisions on mana and units is something only a human can do, there is no clear formula or list of conditions for this, especially not on the level of complexity possible for the AI. (and honestly even I make bad decisions pretty often in this, it's really hard to tell which is more important, the mana or the unit. By the way if this was an easy decision the game would be much more boring.)

Wave of Despair for killing a centaur being a suboptimal choice is the second problem. And WoD is still more cost effective than most other ways to kill a centaur so disabling it just makes it worse. I only see two potentially better choices, Weakness and Black Sleep. Aside from the problem of how to give these higher priority than one of the strongest nuke in the game without breaking the entire system, neither of these are actually an adequate solution. Phantom Warriors are immune to both. Fire Elemental and Catapult aren't really hurt much by Weakness. Both of these spells are bad choices if the summon is the last creature, as ending the combat by killing it is better, etc.
Reply

The problem with WoD being used on summoned centaurs I think is more that the AI permits a lone swordsmen to engage its lone ghoul.

If the positions were reversed, how would the human solve it? Once the combat has started, usually the human player has already done things to solve the situation of the swordsmen. Instead if trying to solve the problem in combat, why not try to solve the problem outside of combat? For instance, if the AI sees that lone swordsmen, attack it with the largest stack in range. That way it will win much faster, disallowing the mana drain as a side effect, and its ghouls that are moving to a stack point aren't threatened.

If the overland problem can be solved, then you can either ignore the in combat problem because its rare, or if its rare but still problematical you can put more controversial solutions on, like 'if this stack is too weak compared to my average unit, don't cast any spells trying to defend it.' For instance, if most creatures its using are death knights, then trying to save a single ghoul is a waste.


Note my examples are just examples. Seravy has shown many times to have a stronger grasp of the AI decision structure than I do; I'm simply trying to see if we can attack the problem from a different angle.
Reply

Another possible example of the kinds of things im imagining: if combats are weighted too heavily in the AI favor, do not cast spells at the start of the AI combat turn. Instead wait until all AI ranged units have attacked, in case they kill all the player units instantly.
Reply

The AI already considers every enemy unit on the map as a potential target, and it seems it isn't enough to prevent this, for three reasons.
-Distance : If the human player has a city adjacent to an AI stack, they can immediately attack after it is produced. (it doesn't have to be a lone ghoul, in fact ghouls are ranged which is suboptimal. The best target is a stack of any size containing no ranged or fast moving units, typically weak enough not to attack the city itself.)
-The reverse being worse for the AI : if his ghoul attacks the swordsmen (which it will, a ghoul is a stronger unit than a swordsmen) then the human player gets the first turn. Even if the AI could kill the swordsmen on turn 1, it cannot if they are not the one going first in the battle.
-Distance 2 : Whichever stack selects the swordsmen as the target might be anywhere on the continent. There is no guarantee it will reach in a reasonable time. Fortunately one of the AI improvements, namely, allowing the AI to send multiple stacks at the same target if the target is at a distance of 4 or less tiles helps this problem quite a bit but only if they have a stack in that range. If not then the far away stack needs to get there first. The AI is only capable of finding the ideal target for each of their stacks individually, but not a set of pairings between targets and stacks that is overall most optimal. If there is only one target but 50 stacks that can attack it, the first one will attack as it finds that the far away only target is the "closest" as it's the only one.

Quote:if combats are weighted too heavily in the AI favor, do not cast spells at the start of the AI combat turn. Instead wait until all AI ranged units have attacked, in case they kill all the player units instantly.

I wish I could do that. Unfortunately a "when to cast" logic is not present at all. I'm afraid the complexity of such a decision would be above what an AI is capable of anyway, although your suggestion is a simple one so if we restrict it to that it would be doable.  (I found 120 free bytes in the segment, which is enough for this)
Quite a few spells are better to use after a certain unit attacked or moved, especially if the unit is a caster itself. Like, using Black Prayer from a hero before casting Banish with the wizard. Wave of Despair is also more effective if used later after killing some units. Or, some units are not worth nuking because an attack can kill it easier. Sadly such complex ways of thinking are far beyond what can be done.
Anyway, back to your suggestion, since the space seems to allow it, the next is, we have to consider the expected effects and decide if it's worth implementing.

1. Can not casting a spell reduce the damage output of the units, thus making the AI fail to kill the enemy units on the first turn when it otherwise could? How often does that problem come up?
Unfortunately, it can. Not casting Prayer, Supreme Light, Blazing March, Black Sleep, Warp Creature, or pretty much anything in the buffs or curses category reduces damage output or increases damage taken. Most of these spells have the highest priority for use when the AI is at an advantage so it would happen often, too. Even direct damage spells often do more damage to full health units than already damaged ones. Wave of Despair might actually be the only spell that is better to cast after attacking.
2. How much mana can not casting a spell save? Is it significant enough to help the problem?
If the army wins on turn 1, it saves the price of one spell. Even at a 3x modifier this is rarely more than 200 mana crystals, which might seem a lot but high level AI has income in the thousands.
If the army does not win on turn 1, no savings happen on turn 1, the AI casts a spell after the units move. Savings happen on the last turn only - or none at all if the spell finishes the last enemy unit off, and not an attack. Saving in this case is even lower on average.

3. Are there other benefits or drawbacks of casting later? How much?
Yes, there are. Casting later means the mana pool of heroes and magicians is used first, increasing the chance of already having curses on possible targets which might be helping (mind storm+resistance based spell) or wasting the first spell (confusion etc on a unit before a Doom Bolt) or missing out on using a high save bonus on a hero (as the hero casts the global enchantment the AI otherwise would). Overall effect is all over the place, it can't be said whether it's an advantage or not.
4. Does the benefits outweight the advantages?
I'm afraid not. Missing out on Prayer/Black Sleep/etc before attacking is generally more harmful than wasting 50-200 mana crystals.
5. Is there a way to prevent the problems in "1."?
In theory yes. Checking which spell the AI intends to cast and then delaying the casting if and only if the spell is not on a list of spells safe to cast later solves the problem. Unfortunately this is impossible to do because casting contains a random element, and attacks change the combat situation and thus the chosen spell too. The AI might think "I was about to cast Wave of Despair now so let's attack first" but after attacking, casts Black Sleep anyway and then then player will think the AI is stupid for not doing it in the other order - they have no way of knowing that AI did not cast Wave of Despair and saved mana, they'll only know the AI used Black Sleep at a wrong timing. Also,  there aren't really enough combat spells that are better to use after attacking. Most buffs, direct damage, curses, even summoning and dispelling are more beneficial if used before attacks which is most likely why the AI always casts first. Spells that only matter during enemy turns such as Guardian Wind and Magic Immunity are better if not used early and that's pretty much the only case - and Wave of Despair as it hits harder on fewer targets.
Reply

Yup, I'd really only do it if some arbitrary formula like average damage of AI ranged attacks against the actual present human units is at least twice as high as required to kill all player units, and immunities are checked.

The only real reason to even do this is to stop 'mass lone spearman attacks' - in other words, if a human attacks 4 storm giants with 1 unbuffed spearmen.. 18 times in the same turn.

But given the immunity check, I'm not even sure it would be doable in the space you have.
Reply

I'm not nearly as concerned about the AI attacking the swordsman with one ghoul.

In that case, the AI is draining the players mana, which is a completely legitimate tactic. Sure the AI might not do it for that purpose, but that's usually how it actually plays out, which is fine.

For the problem presented by Germanyjoey, I would definitely only be concerned about when the human is attacking the AI, and trying to abuse the mana drain.
Reply

(December 13th, 2016, 18:04)Nelphine Wrote: But given the immunity check, I'm not even sure it would be doable in the space you have.

Yes, that's way too complex for 120 bytes. Even without an immunity check, checking the ranged stats, hit, figures, hit points etc of all units is longer by itself.
Reply

Hum. What about if we take to hit and to defend out, simply assume +3 on both, and increase average needed to times 3; and only check magic immunity and missile immunity (don't check the attackers ranged type, just assume for this check either immunity will negate it).

We'd still want to simplify the defense rolls of the human players.

So.. AI ranged attack total - human defense total (how big is this when you have to calculate each unit since some are different numbers of figures?) > human health total*9. And check 9 units for 2 immunities.

Nope, probably still too big, since my 'how big' question applies to all 3 numbers. Ah well, the thought was there.

Note: since assuming both to hit and to defend are +3, I actually divide both those numbers by 3. Its a little off, but thats why i increased the amount needed to times 3. But to save space, I multiply everything by 3, so the attack and defense numbers are simply not divided or multiplied, while the HP number is multiplied by 9.
Even then its off, since it assumes dead figures can still defend against later attacks. But can't help that because of instances where the AI is against a magic spirit.
Reply

(December 13th, 2016, 18:22)Nelphine Wrote: Nope, probably still too big, since my 'how big' question applies to all 3 numbers. Ah well, the thought was there.

Pretty much this.
The loop on the units itself, plus the check for the owner, the status of the unit (must be living) already uses like half the space and then we haven't done any calculations whatsoever, not to mention the call to the actual spellcasting procedure, storing the result in a variable, checking it after the turn, and calling casting again if there was no spell used before.

Immunities would be more than 2 as well : Invisibility also provides "immunity" to missiles, as does defense significantly higher than the ranged attack itself, not to mention Invulnerability.  Having 9 units with a ranged attack of 10 each will still fail to win if the enemy army has one 20 armor unit and 8 with 2 armor.

PS : There is a procedure that calculates the total ranged power of a player which can be called but it won't help because there is no way to calculate enemy health, defense and immunities. Existing AI decisions based on this compare AI ranged total with human ranged total which is not what we need for this. There is also one for total army strength which even compares the two sides, but since movement says melee units can't reach the enemy in most cases, that is also useless for this purpose.
Reply

(December 13th, 2016, 09:57)Seravy Wrote:
(December 13th, 2016, 08:16)GermanJoey Wrote: The only one going in circles is yourself, twisting the issue like a wet towel and then whip-slashing men of straw. But, well, it's your game, dude, you don't need to answer to me. If you're not even interested in acknowledging such an extreme exploit as this, I won't bother you anymore.

I acknowledged the problem, two of them in fact, but you don't seem to acknowledge we don't have a good enough solution to either of them.

Mana Milking is a generic problem that's impossible to solve. Carefully weighting decisions on mana and units is something only a human can do, there is no clear formula or list of conditions for this, especially not on the level of complexity possible for the AI. (and honestly even I make bad decisions pretty often in this, it's really hard to tell which is more important, the mana or the unit. By the way if this was an easy decision the game would be much more boring.)

I'll try to explain one more time.

To a certain extent, I've agreed repeatedly that I also think that the AI blowing way too much mana in battle is impossible to "solve." However, the current solution of "give the AI a lot of extra free mana" does a pretty good job of faking it being solved. We know this is true because the game is still challenging - for example, we've both made recent posts about us losing games.

Thus, "mana milking" does not mean just getting the AI to spend a bunch of mana. That is not the problem I am patiently trying to get across to you. I mean, that's been the case the whole time, why would I suddenly bring it up as some crucial problem in this specific instance after playing dozens of full games of CoM so far? 

The problem lies with the fact that the AI having WoD in this specific scenario -  if you can have cheap/throwaway units that it won't target, as well as a cheap combat summon spell that it will - the game completely breaks down because it becomes way too easy/fast/efficient to drain the AI of all its mana without the AI accomplishing anything. This is different from your other examples, where you're actually spending significant resources with no guarantee that you'll make the AI pay more than at least 4X the difference. For instance, using your example of chaos-channeled flying swordsmen, you're only getting 1 out of 3 as flying, and the other 2 are pretty much useless. So that's 90h plus 3gpt. Then you've got to find an AI target that can't target flying. On top of that, you're counting on the AI deciding to not just kill your unit, as you're somehow expecting to last 25 turns. However, there are cheap commons in each realm that can easily kill your flying swordsman. (star fires in white, web and fairy dust in green, fire bolt in red, black sleep in black). The idea that the AI will instead decide to summon 8x paladins and then cast lionheart and invulnerability on each one, instead of just killing the unit, seems extremely wrong from my experience. If it was so extremely easy to manipulate the AI this way, then the game would not be difficult or interesting. 

Going back to WoD. My discovery of this tactic did indeed ruin the difficulty and interestingness of the game I was playing in which I discovered it. It had been an intense and thrilling game, but it was turning towards a loss. My best units were getting wrecked and I was losing the cities I was counting on to eventually produce stuff that would let me win. The exploit allowed me to turn the game around, but felt cheap, hollow, and unsatisfying. I wasn't really playing the game anymore, but manipulating the AI through a loophole so that it was unable to play. Worse yet, it wasn't even through a spell I had myself, that I had done work to research and develop, but the AI's spell. The exploit is a problem not only because mana milking is possible with this tactic at an extremely efficient ratio for the player, but also with very little time wasted IRL. (I try to avoid tediousness when I can, but perhaps I'm in the minority). On top of that, it allows victory in battles that should not be otherwise possible (due to the AI wasting its skill). 

Thus, I see the WoD behavior as an exploit. 

Seravy Wrote:Wave of Despair for killing a centaur being a suboptimal choice is the second problem. And WoD is still more cost effective than most other ways to kill a centaur so disabling it just makes it worse. I only see two potentially better choices, Weakness and Black Sleep. Aside from the problem of how to give these higher priority than one of the strongest nuke in the game without breaking the entire system, neither of these are actually an adequate solution. Phantom Warriors are immune to both. Fire Elemental and Catapult aren't really hurt much by Weakness. Both of these spells are bad choices if the summon is the last creature, as ending the combat by killing it is better, etc.

We've boiled the problem down to WoD targeting single summons, of which there are 5 units it can target.  We are stuck at the fact that WoD is desirable against 2 of them, but not so against 3 of them, without a good way to differentiate them.

Singular Air Elemental - ok to target
Singular Earth Elemental - ok to target
Singular Centaur - bad to target
Singular Fire Elemental - bad to target
Singular Catapult - bad to target

I honestly don't know how the decision code works, or why you could easily say "exclude single summons from the WoD decision" but not "exclude single single summons, except for AE and EE, from the WoD decision." Furthermore, even this isn't the most ideal rule; for example, it would be fine to ignore this new rule if the distance was short, so that the AI could protect its own shaman and engineers, or if the summons was the last unit left in the battle, so that the battle could be immediately ended. Still, excluding all 5 is still a vastly superior solution than excluding none of them, because "being slightly less likely to win some battles" is a better outcome then "quickly become a completely helpless lame duck both in that battle as well as all future battles and then getting banished."

An alternative is to give the 3 "bad targets" (the FE/Centaur/Catapult) Cold Immunity on their base unit, so that WoD won't even be attempted against them, seems like another way to solve the problem, because there's only what, 4 total sources of cold damage in the game? (Fairy Dust, Ice Bolt, Blizzard, WoD) Thus these 3 units won't really be helped substantially by their additional immunity. However, that still leaves your issue of Death not having a good way to insta-kill Centaurs, as Black Sleep will only work 70% of the time on a summoned centaur, and I guess that's not acceptable, nor is Reaper Slash, which will only insta-kill at 73% probability. In that case, you could nerf Centaurs further - that unit is already way too good. You could lower their hits by one, or their resistance by 1, etc. Or you could make the base unit more expensive in hammers (and the summon more expensive in mana) so that it's more costly to spam them. Or whatever.

I don't know what you think is best or what exactly is possible, I am just throwing out ideas because you said there were some technical problems with my previous suggestions. I'd just like the exploit patched. That's it.
Reply



Forum Jump: