Page 1 of 1

[waitlisted]Mogg Flunkies

PostPosted: 28 Nov 2013, 15:08
by HarlequinCasts
Describe the Bug:
I see several old reports about this in the old archives but its still a problem.

Mogg Flunkies can attack alone sometimes. In this case a Mogg Flunkies and a Duty-Bound Dead are alone on the battlefield and the AI can choose to attack with just the Mogg Flunkies. Players cannot perform this trick, only the AI.

Perhaps it is a problem with the 0 power exalted creature and how the AI uses it...

Which card did behave improperly ?
Mogg Flunkies

Which update are you using?(date,name)Which type(Duel,Gauntlet,Sealed Deck)
PtTv1

What exactly should be the correct behavior/interaction ?
Cannot attack alone.

Are any other cards possibly affected by this bug ?
Loyal Pegasus

Re: Mogg Flunkies

PostPosted: 28 Nov 2013, 16:27
by stassy
confirmed the "interaction" with exalted, if there is at least one exalted giving creature untapped, creatures with the "can't attack alone" ability will be able to attack alone, tested also with Noble Hierarch

Image

Image

However if all creatures but the "can't attack alone" creature are tapped, AI won't be able to use this trick.

Re: [confirmed]Mogg Flunkies

PostPosted: 10 Feb 2014, 11:22
by HarlequinCasts
Happened to notice this bug again in CIA v2 Jan 2014 patch.

In this case there were no exalted effects. The Mogg Flunkies just attacked on their own. Only other creatures were Goblin Chieftain and Goblin Piledriver (who did not attack).

Re: [confirmed]Mogg Flunkies

PostPosted: 10 Feb 2014, 11:31
by Korath
Can repro this reliably by giving the AI a Will-o'-the-Wisp and a Mogg Flunkies (the Will-o'-the-Wisp must exist first).

Also can't attack or block with two Mogg Flunkies and nothing else, and should be able to.

Re: [confirmed]Mogg Flunkies

PostPosted: 10 Feb 2014, 20:23
by HarlequinCasts
Is it something like: the AI sees that it has 2 creatures but for whatever reason does not want to attack with one of them and can sneak out of having to use it?

Like in my example, it Can attack with more than one, but its other two creatures could be blocked unfavorably so it does not want to.

The Will-o'-the-Wisp example and the Noble Hierarch are probably the same in that it sees it can attack with two, but doesn't want to bother using the 0/1 creature since it does no damage.

Re: [confirmed]Mogg Flunkies

PostPosted: 11 Feb 2014, 15:19
by Korath
(I brought up Will-o'-the-Wisp mainly to confirm that it had nothing to do with exalted.)

The way the AI picks which creatures to attack with... tentatively... is to check each to see whether it can attack and mark it as attacking; and then cull the ones it doesn't like. The problem is that everything gets marked as attacking in the first step, and attack legality isn't ever checked again afterwards. I don't think this is going to be fixable until combat AI is rewritten, which won't be soon.

Re: [waitlisted]Mogg Flunkies

PostPosted: 10 Dec 2015, 02:41
by Korath
Closely related:

Re: [confirmed]Mogg Flunkies

PostPosted: 08 Apr 2019, 03:22
by Korath
Korath wrote:The way the AI picks which creatures to attack with... tentatively... is to check each to see whether it can attack and mark it as attacking; and then cull the ones it doesn't like. The problem is that everything gets marked as attacking in the first step, and attack legality isn't ever checked again afterwards.
This was almost right, but not quite.

The way the AI chooses attackers (in the first half of the aptly-labeled ai_choose_attackers() function at 0x4b02c0 Magic.exe/0x41f5e3 Shandalar.exe):
  1. Make a list of the first 16 creatures that can attack and that don't have banding. (Creatures with banding are kept track of separately. Shandalar doesn't stop when it gets to 16 creatures, but still only has room to store 16, which is why it sometimes goes into an infinite loop or crashes during large creature stalemates.) This is the only point where can_attack() is checked; each non-banding creature that can attacked is marked STATE_ATTACKING, as an implementation detail; that's why the AI can attack with a lone Mogg Flunkies only if there's another creature before it. The STATE_ATTACKING bit is overwritten in step D below.
  2. If there's at least 8, then
    1. Remove the attacker with the highest power from consideration for each untapped creature the defending player controls (whether it can block or not).
    2. If the remaining potential attackers' total power is at least as high as the defending player's life, all of them attack.
    3. Otherwise, remove all of those creatures except the six with the highest power from consideration; then add back in all the ones that must attack (due to text like Juggernaut's), up to a maximum of, again, 16 potential attackers.
  3. Number the potential attackers from 0 to 15, and make them into a bitfield.
  4. Loop over each possible combination of those up-to-16 potential attackers. This is implemented as looping from 0 to (2^number_of_potential_attackers - 1) and flagging each attacker whose bit is set as attacking and the others as not attacking.
    1. If a potential attacker that's an Erg Raiders, a Juggernaut, or a creature marked as must-attack is marked as not attacking, skip this combination.
    2. Otherwise, go on to compute a relative desirability of that combination of attackers.
So, in order to prevent the AI from attacking with a single Mogg Flunkies, we'd need to add another step similar to D.a that looks at the combination of attacking creatures as a whole.

The relevant part of ai_choose_attackers() is easy to identify once you start looking for it; it looks like
pasted from magic.c | Open
Code: Select all
      v55 = -1;
      while (1)
        {
          ++v55;
          if (1 << v66 <= v55)   // v66 is number_of_potential_attackers
            break;
          v56 = 1;   // this combination ok by default
          dword_607CCC = 0;
          dword_60779C = 0;
          card = -1;
          while (1)
            {
              ++card;
              if (v66 <= card)
                break;
              v23 = get_card_instance(player, Dst[card]);
              LOBYTE(v23->state) &= 0xFBu;      // ~STATE_ATTACKING
              v59 = *(_DWORD*)&cards_data[v23->internal_card_id].id;
              if ((1 << card) & v55)
                {
                  LOBYTE(v23->state) |= STATE_ATTACKING;
                  WILDGUESS_ai_combat_attack_card[dword_607CCC] = Dst[card];
                  WILDGUESS_ai_combat_attack_power[dword_607CCC] = v88[card];
                  WILDGUESS_ai_combat_attack_toughness[dword_607CCC] = v89[card];
                  WILDGUESS_ai_combat_attack_abils[dword_607CCC] = v52[card];
                  WILDGUESS_ai_combat_attack_attack_rating[dword_607CCC] = v64[card];
                  WILDGUESS_ai_combat_WILDGUESS_blocking_choice[dword_607CCC] = v50[card];
                  WILDGUESS_ai_combat_attack_defensive_modifier[dword_607CCC] = dword_6078A4[card];
                  WILDGUESS_ai_combat_block_defensive_modifier[dword_607CCC] = dword_607718[card];
                  if (v59 == CARD_ID_COCKATRICE || v59 == CARD_ID_LURE)
                    dword_60779C |= 1 << dword_607CCC;
                  ++dword_607CCC;
                }
              else
                {
                  if (v59 == CARD_ID_ERG_RAIDERS || v59 == CARD_ID_JUGGERNAUT)
                    v56 = 0;
                  if ((1 << card) & v87)   // v87 is a bitfield of cards marked must-attack
                    v56 = 0;
                }
            }
          // insert new step here and set v56 = 0 if it fails
          if (v56)
            {
              // step D.b.
This doesn't address blocking at all, nor the human's choice of attackers. While it'll allow the AI to attack with two Mogg Flunkies and nothing else, the current implementation won't let the human do so.

Re: [waitlisted]Mogg Flunkies

PostPosted: 24 Oct 2020, 17:09
by Korath
Commit 180753d75 is relevant.