It is currently 23 Jul 2019, 13:52
   
Text Size

Epic ability makes the game crash

Moderators: Xander9009, CCGHQ Admins

Epic ability makes the game crash

Postby thefiremind » 12 Oct 2016, 11:11

After participating in the interesting topic about impossible cards here, I decided to see for myself if epic spells are possible or not. I tried to code Eternal Dominion like this:
Eternal Dominion (crashing) | Open
Code: Select all
<?xml version="1.0"?>
<CARD_V2 ExportVersion="1">
  <FILENAME text="ETERNAL_DOMINION_199087593" />
  <CARDNAME text="ETERNAL_DOMINION" />
  <TITLE>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Eternal Dominion]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Domination éternelle]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Dominio eterno]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Ewige Herrschaft]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Dominio Eterno]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[永遠の統制]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Eternal Dominion]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Eternal Dominion]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Soberania Eterna]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="zh-CN"><![CDATA[不朽霸权]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="zh-HK"><![CDATA[Eternal Dominion]]></LOCALISED_TEXT>
  </TITLE>
  <MULTIVERSEID value="199087593" />
  <ARTID value="199087593" />
  <ARTIST name="Shishizaru" />
  <!--CASTING_COST cost="{7}{U}{U}{U}" /-->
  <CASTING_COST cost="{U}" />
  <TYPE metaname="Sorcery" />
  <EXPANSION value="SOK" />
  <RARITY metaname="R" />
  <SPELL_ABILITY>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Search target opponent’s library for an artifact, creature, enchantment, or land card. Put that card onto the battlefield under your control. Then that player shuffles his or her library.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Cherchez dans la bibliothèque de l’adversaire ciblé une carte d’artefact, de créature, d’enchantement ou de terrain. Mettez en jeu cette carte, sous votre contrôle. Ce joueur mélange ensuite sa bibliothèque.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Busca una carta de artefacto, criatura, encantamiento o tierra en la biblioteca del oponente objetivo. Pon esa carta en juego bajo tu control. Luego ese jugador baraja su biblioteca.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Durchsuche die Bibliothek eines Gegners deiner Wahl nach einem Artefakt, einer Kreatur, einer Verzauberung oder einem Land. Bringe diese Karte unter deiner Kontrolle ins Spiel. Dieser Spieler mischt dann seine Bibliothek.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Passa in rassegna il grimorio di un avversario bersaglio e scegli una carta artefatto, creatura, incantesimo o terra. Metti in gioco quella carta sotto il tuo controllo. Poi quel giocatore rimescola il proprio grimorio.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[対戦相手1人を対象とし、そのプレイヤーのライブラリーからアーティファクト・カード1枚かクリーチャー・カード1枚かエンチャント・カード1枚か土地カード1枚を探す。 そのカードをあなたのコントロール下で場に出す。 その後、そのプレイヤーは自分のライブラリーを切り直す。]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Search target opponent’s library for an artifact, creature, enchantment, or land card. Put that card onto the battlefield under your control. Then that player shuffles his or her library.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Search target opponent’s library for an artifact, creature, enchantment, or land card. Put that card onto the battlefield under your control. Then that player shuffles his or her library.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Procure no grimório do oponente alvo por um card de artefato, criatura, encantamento ou terreno. Coloque aquele card em jogo sob o seu controle. Depois, aquele jogador embaralha seu próprio grimório.]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="zh-CN"><![CDATA[从目标对手的牌库中搜寻一张神器,生物,结界,或地牌, 并将该牌在你的操控下放置进场。 然后该牌手将其牌库洗牌。]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="zh-HK"><![CDATA[Search target opponent’s library for an artifact, creature, enchantment, or land card. Put that card onto the battlefield under your control. Then that player shuffles his or her library.]]></LOCALISED_TEXT>
    <TARGET tag="CARD_QUERY_CHOOSE_OPPONENT" definition="0" compartment="0" count="1" />
    <TARGET_DEFINITION id="0">
    local filter = ClearFilter()
    filter:SetFilterType(FILTER_TYPE_PLAYERS)
    filter:Add( FE_TEAM, OP_NOT, EffectController():GetTeam() )
    </TARGET_DEFINITION>
    <RESOLUTION_TIME_ACTION>
    local opponent = EffectDC():Get_Targets(0):Get_PlayerPtr(0)
    if opponent ~= nil then
       local filter = ClearFilter()
       filter:SetZone(ZONE_LIBRARY, opponent)
       local subFilter = filter:AddSubFilter_Or()
          subFilter:Add(FE_TYPE, OP_IS, CARD_TYPE_ARTIFACT)
          subFilter:Add(FE_TYPE, OP_IS, CARD_TYPE_CREATURE)
          subFilter:Add(FE_TYPE, OP_IS, CARD_TYPE_ENCHANTMENT)
          subFilter:Add(FE_TYPE, OP_IS, CARD_TYPE_LAND)
       EffectController():ChooseItem( "CARD_QUERY_CHOOSE_CREATURE_TO_PUT_ONTO_BATTLEFIELD", EffectDC():Make_Targets(1) )
    end
    </RESOLUTION_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    local target = EffectDC():Get_Targets(1) and EffectDC():Get_Targets(1):Get_CardPtr(0)
    if target ~= nil then
       target:PutOntoBattlefield( EffectController() )
    end
    </RESOLUTION_TIME_ACTION>
    <RESOLUTION_TIME_ACTION>
    local opponent = EffectDC():Get_Targets(0):Get_PlayerPtr(0)
    if opponent ~= nil then
       opponent:ShuffleLibrary()
    end
    </RESOLUTION_TIME_ACTION>
  </SPELL_ABILITY>
  <SPELL_ABILITY>
    <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Epic]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="fr-FR"><![CDATA[Épique]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="es-ES"><![CDATA[Épico]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="de-DE"><![CDATA[Episch]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="it-IT"><![CDATA[Epopea]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="jp-JA"><![CDATA[歴伝]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ko-KR"><![CDATA[Epic]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="ru-RU"><![CDATA[Epic]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="pt-BR"><![CDATA[Épica]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="zh-CN"><![CDATA[历传]]></LOCALISED_TEXT>
    <LOCALISED_TEXT LanguageCode="zh-HK"><![CDATA[Epic]]></LOCALISED_TEXT>
    <RESOLUTION_TIME_ACTION>
    local source = EffectSourceLKI()
    local thisSpellDC = source:GetDataChest()
    if thisSpellDC:Get_Int(10) ~= 1 then
       local delayDC = EffectDC():Make_Chest(2)
       delayDC:Set_PlayerPtr( 0, EffectController() )
       delayDC:Set_CardPtr(1, source)
       delayDC:LKIShield_CardPtr(1)
       local copySpellDC = delayDC:Make_Chest(2)
       copySpellDC:CopyFrom(thisSpellDC)
       copySpellDC:Set_Int(10, 1)
       MTG():CreateDelayedTrigger(1, delayDC)
    end
    </RESOLUTION_TIME_ACTION>
    <CONTINUOUS_ACTION layer="8">
    local player = EffectController()
    if player ~= nil then
       player:GetCurrentCharacteristics():Bool_Set(PLAYER_CHARACTERISTIC_CANT_CAST_SPELLS, 1)
    end
    </CONTINUOUS_ACTION>
    <DURATION>
    return EffectController() == nil
    </DURATION>
  </SPELL_ABILITY>
  <TRIGGERED_ABILITY resource_id="1">
    <TRIGGER value="BEGINNING_OF_PLAYERS_STEP">
    return TriggerPlayer() == EffectDC():Get_PlayerPtr(0) and MTG():GetStep() == STEP_UPKEEP
    </TRIGGER>
    <RESOLUTION_TIME_ACTION>
    local player = EffectDC():Get_PlayerPtr(0)
    local spell = EffectDC():Get_CardPtr(1)
    if player ~= nil and spell ~= nil then
       local copy = player:CopySpell( spell, EffectDC():Get_Chest(2) )
       player:ChooseNewTargets(copy)
    end
    </RESOLUTION_TIME_ACTION>
    <CLEANUP>
    return EffectDC():Get_PlayerPtr(0) == nil
    </CLEANUP>
  </TRIGGERED_ABILITY>
  <HELP title="MORE_INFO_TITLE_EPIC" body="MORE_INFO_BODY_EPIC" zone="ZONE_ANY" />
  <AI_BASE_SCORE score="1500" zone="ZONE_HAND" />
</CARD_V2>
(Cost has been reduced for testing purposes)
and tested it in Magic Duels (the only engine I keep installed). Unfortunately, the game crashes while the spell is about to resolve, or at the start of the opponent's turn (if I comment some things out). My guess is that the AI's evaluation of the card gets stuck over the possibility of the spell copying itself over and over again, even if my intent was to block that possibility through that register #10 set to 1 on the copies. But even if I put a WasCast() check (which would skip the epic part on any copy of the spell, even when copied through other means, and would be guaranteed to work), the game crashes anyway.

Any ideas?
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 717 times

Re: Epic ability makes the game crash

Postby Xander9009 » 12 Oct 2016, 11:23

Try making it only copy once with a one-off cleanup and see if that fixes the issue. At least we'll know if the endless copying is in fact the issue.

Another thought (I'm tired, so sorry if this is obviously wrong): are you certain you can copy a spell that's not on the stack?
_______________________________
Community Wad - Community Wad Website - How to Help and Report Bugs
Discord: discord.gg/4AXvHzW
User avatar
Xander9009
Programmer
 
Posts: 2887
Joined: 29 Jun 2013, 07:44
Location: Indiana, United States
Has thanked: 119 times
Been thanked: 437 times

Re: Epic ability makes the game crash

Postby thefiremind » 12 Oct 2016, 11:49

Xander9009 wrote:Try making it only copy once with a one-off cleanup and see if that fixes the issue.
I already tried that. Nothing changed.

Xander9009 wrote:are you certain you can copy a spell that's not on the stack?
I don't know, this would be the first time.
< Former DotP 2012/2013/2014 modder >
Currently busy with life...
User avatar
thefiremind
Programmer
 
Posts: 3515
Joined: 07 Nov 2011, 10:55
Has thanked: 118 times
Been thanked: 717 times

Re: Epic ability makes the game crash

Postby Splinterverse » 21 Jul 2019, 14:57

I've been going through the Impossible Cards list and trying a few things to see if cards that are listed there are possible or approximate-able.

For epic, I tried a simplified testing version of Endless Swarm. I just put its basic ability on and then tried to see if a triggered ability would work from the graveyard to copy the spell. It did fire, but did nothing and did not produce any kind of error.

Here's the simple code I used (again not the full code, just for testing if it would even work):
Code: Select all
<TRIGGERED_ABILITY active_zone="ZONE_GRAVEYARD">
      <LOCALISED_TEXT LanguageCode="en-US"><![CDATA[Epic]]></LOCALISED_TEXT>
      <TRIGGER value="BEGINNING_OF_PLAYERS_STEP" simple_qualifier="controller">
         return MTG():GetStep() == STEP_UPKEEP
      </TRIGGER>
      <RESOLUTION_TIME_ACTION>
         EffectController():CopySpell(EffectSource())
      </RESOLUTION_TIME_ACTION>
   </TRIGGERED_ABILITY>
A couple of thoughts come to mind on how we could maybe approximate this . . .

1. The rules state that the "copy" of the spell is created and put on the stack, but is not cast. I don't know of any cards that specifically target or trigger off something being a copy, so I don't think the "copy" component is critical here. We might be able to ignore that to make these cards work. Not copying might also be preferable as it would not try to copy the Epic part as well.

2. We should make sure the effect goes on the stack since that is part of the rules and things that go on the stack can be targeted, interrupted, etc. For that, we might be able to use a triggered ability with a may condition. If we use multiple choice, we could simply ignore the "no" option. The reason I suggest this is that triggered abilities do not go on the stack unless they are optional. With this approach (and agreeing to number 1), we could simply make the effect live on the card itself and active in zone_graveyard, zone_library, and zone_exile provided that a check is made to ensure that it was cast once during the game. (In other words, we wouldn't want the effect to trigger if it was simply discarded into the graveyard, put into the library, or exiled from the hand.)

3. I think 1 and 2 would allow us to get the job done. If we insist on the copy component, we could look at the Aftermath cards. Those use concepts similar to flip cards to create token copies of each card half and prep them for use. We could use a similar technique to make a copy of the card available. However, with Aftermath, we're using an activated ability to put that copy on the stack. The Aftermath cards are very complicated and so if this is the approach we want to take, I probably would leave it for someone else.

4. If we don't care about the "copy" component OR the stack, we have tons of other options including emblems and managers.

What do you guys think? Do you like any of these ideas or have any others?
---------------------------------------------
The DOTP2014 CW is updated nightly between 11 PM and 12 AM EST.
Impossible Cards List | Update Your Land Pools | Multiplayer Tips
Splinterverse
 
Posts: 859
Joined: 04 Sep 2016, 13:32
Has thanked: 111 times
Been thanked: 57 times


Return to Programming Talk

Who is online

Users browsing this forum: No registered users and 1 guest


Who is online

In total there is 1 user online :: 0 registered, 0 hidden and 1 guest (based on users active over the past 10 minutes)
Most users ever online was 287 on 31 Mar 2019, 04:11

Users browsing this forum: No registered users and 1 guest

Login Form