It is currently 12 Sep 2025, 19:24
   
Text Size

Added some cards

Post MTG Forge Related Programming Questions Here

Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins

Added some cards

Postby BinarySpike » 05 Mar 2010, 06:35

Hello, I am new to the forum and I just recently learned how to compile Forge and add some of my own cards in the Java code.

First, I am having trouble understanding all the data types (aka classes) but I was able to piece together cards from other ones to make working cards. I mainly added these cards to simulate a token deck I am building, it works nicely whenever Beastmaster ascension works (It doesn't work half the time ](*,) so I have to visualize an army of +11/+11 insect creatures and +12/+12 wolves) Here is the list:

Howl of the Night Pack
Beacon of Creation
Khalni Heart Expedition
Echoing Courage
Harrow (halfway working)

Khalni and Harrow I just copied Kodama's Reach and switched some code around.
Howl of the Night Pack was easy, and then Beacon of Creation was a copy except I added "shuffle back into deck" effect from another Beacon card. Echoing Courage has a brother that does the opposite.

Second, I noticed a couple bugs in the downloadable source code (from google code). Mainly Bushido can be multi-proc'd for infinite creature size. Useful in quest mode ^_^ And Beastmaster Ascension doesn't seem to work when the opponent blocks. If someone could find a better way to program the Beastmasters ability I would also add Coat of Arms (because it works under a similar principle)

Finally, I can provide source for those cards upon request, and if anyone has any mono-green token card suggestions that need programming I could take a kick at it.

Thoughts?
BinarySpike
 
Posts: 3
Joined: 02 Mar 2010, 19:44
Has thanked: 0 time
Been thanked: 0 time

Re: Added some cards

Postby DennisBergkamp » 05 Mar 2010, 06:55

Welcome to the forums, BinarySpike!
We could always use the help.... I didn't know Beastmaster Ascension only works half the time, I'll look into it (by the way, is it the counter adding, or the pump ability that's not working correctly?)

I can guess what happens with the Bushido bug... does it by any chance happen when using abilities during the step that's right after the Declare Attackers step?
Same will probably hold for exalted...

As for the cards you coded (thanks!), I could either give you committer privileges on the SVN (and you could just submit your code directly), or you could paste your code in this thread and I would just add it manually. First way is probably easier (just pm me your email address), but I don't mind adding the code myself either.

As for mono green cards suggestions... check out this thread: viewtopic.php?f=26&t=2091&start=0
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: Added some cards

Postby DennisBergkamp » 05 Mar 2010, 17:25

I've tested Beastmaster Ascension a bunch of times... I didn't see it fail once. Are you aware that it's supposed to only give +5/+5 once (and not +5/+5 for each 7 Quest counters) ?
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: Added some cards

Postby BinarySpike » 05 Mar 2010, 20:23

For the Bushido bug, it's when you declare it as a blocker. "To Block, click your Opponents attacker first, then your blocker(s)"

Once you select the creature with bushido a Bushido effect goes on the stack, you hit Okay to resolve it, and then you can select that same devoted retainer to block again, the effect goes on the stack, and you can block again, and again, and again.

Beastmaster ascension sometimes doesn't pump, it's wonky because if I have 2 or 3 out, sometimes it works and sometimes it doesn't. I retested in a fresh download of Forge and it works perfectly (squirrel nest/earthcraft combo) so I am stumped, maybe I can debug in Eclipse.

As for the SVN commit, please no, my code is extremely sloppy, I directly copied Kodama's Reach to Khalni Heart Expedition and Harrow, and I had no idea what serialVersionUID was so I just made it up. Here are my first three:

Howl of the Night Pack
6 G
Sorcery
Put a 2/2 green Wolf creature token onto the battlefield for each Forest you control.
howl_of_the_night_pack.jpg http://gatherer.wizards.com/Handlers/Im ... &type=card
Code: Select all
//*************** START *********** START **************************
            else if (cardName.equals("Howl of the Night Pack"))
            {
               SpellAbility spell = new Spell(card)
                {
                private static final long serialVersionUID = 0000000000000000001L;

                public void resolve()
                  {
                   PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController());
                    CardList land = new CardList(play.getCards());
                    land = land.getType("Forest");
                    makeToken();
                      for(int i = 1; i < land.size(); i++)
                           makeToken();
                  }//resolve()
                
                public void makeToken()
                {
                   CardFactoryUtil.makeToken("Wolf", "G 2 2 Wolf", card, "G", new String[]{"Creature", "Wolf"}, 2, 2, new String[] {""});
                }
                };
                card.clearSpellAbility();
                card.addSpellAbility(spell);
             }//*************** END ************ END **************************
Beacon of Creation
3 G
Sorcery
Put a 1/1 green Insect creature token onto the battlefield for each Forest you control. Shuffle Beacon of Creation into its owner's library.
beacon_of_creation.jpg http://gatherer.wizards.com/Handlers/Im ... &type=card
Code: Select all
//*************** START *********** START **************************
            else if (cardName.equals("Beacon of Creation"))
            {
               SpellAbility spell = new Spell(card)
                {
                private static final long serialVersionUID = 0000000000000000002L;

                public void resolve()
                  {
                   PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController());
                    CardList land = new CardList(play.getCards());
                    land = land.getType("Forest");
                    makeToken();
                      for(int i = 1; i < land.size(); i++)
                           makeToken();
                  
                    // shuffle back into library
                  PlayerZone library = AllZone.getZone(Constant.Zone.Library, card.getController());
                  library.add(card);
                  AllZone.GameAction.shuffle(card.getController());
                  
                  }//resolve()
                
                public void makeToken()
                {
                   CardFactoryUtil.makeToken("Insect", "G 1 1 Insect", card, "G", new String[]{"Creature", "Insect"}, 1, 1, new String[] {""});
                }
                };
                card.clearSpellAbility();
                card.addSpellAbility(spell);
             }//*************** END ************ END **************************
Echoing Courage
1 G
Instant
Target creature and all other creatures with the same name as that creature get +2/-+2 until end of turn.
echoing_courage.jpg http://gatherer.wizards.com/Handlers/Im ... &type=card
Code: Select all
//*************** START *********** START **************************
    else if(cardName.equals("Echoing Courage"))
    {
      final SpellAbility spell = new Spell(card)
      {
      private static final long serialVersionUID = 3154935854257358023L;

      public boolean canPlayAI()
        {
          CardList c = getCreature();
          if(c.isEmpty())
            return false;
          else
          {
            setTargetCard(c.get(0));
            return true;
          }
        }//canPlayAI()
        CardList getCreature()
        {
          CardList out = new CardList();
          CardList list = CardFactoryUtil.AI_getHumanCreature("Flying", card, true);
          list.shuffle();

          for(int i = 0; i < list.size(); i++)
            if((list.get(i).getNetAttack() >= 2) && (list.get(i).getNetDefense() <= 2))
              out.add(list.get(i));

          //in case human player only has a few creatures in play, target anything
          if(out.isEmpty() &&
              0 < CardFactoryUtil.AI_getHumanCreature(2, card, true).size() &&
             3 > CardFactoryUtil.AI_getHumanCreature(card, true).size())
          {
            out.addAll(CardFactoryUtil.AI_getHumanCreature(2, card, true).toArray());
            CardListUtil.sortFlying(out);
          }
          return out;
        }//getCreature()


        public void resolve()
        {
          if(AllZone.GameAction.isCardInPlay(getTargetCard()) && CardFactoryUtil.canTarget(card, getTargetCard()) )
          {
            final Card c = getTargetCard();
           
            c.addTempAttackBoost(2);
             c.addTempDefenseBoost(2);

             AllZone.EndOfTurn.addUntil(new Command()
             {
            private static final long serialVersionUID = 1327455269456577020L;

            public void execute()
                {
                   c.addTempAttackBoost(-2);
                   c.addTempDefenseBoost(-2);
                }
             });

            //get all creatures
            CardList list = new CardList();
            list.addAll(AllZone.Human_Play.getCards());
            list.addAll(AllZone.Computer_Play.getCards());

            list = list.getName(getTargetCard().getName());
            list.remove(getTargetCard());
             
            if (!getTargetCard().isFaceDown())
               for(int i = 0; i < list.size(); i++)
               {
                  final Card crd = list.get(i);
                  
                  crd.addTempAttackBoost(2);
                  crd.addTempDefenseBoost(2);
                  
                  AllZone.EndOfTurn.addUntil(new Command()
                    {
                  private static final long serialVersionUID = 5151337777143949221L;

                  public void execute()
                       {
                          crd.addTempAttackBoost(-2);
                          crd.addTempDefenseBoost(-2);
                       }
                    });
                  //list.get(i).addDamage(2);
               }
                
          }//in play?
        }//resolve()
      };//SpellAbility
      card.clearSpellAbility();
      card.addSpellAbility(spell);

      spell.setBeforePayMana(CardFactoryUtil.input_targetCreature(spell));
    }//*************** END ************ END **************************
BinarySpike
 
Posts: 3
Joined: 02 Mar 2010, 19:44
Has thanked: 0 time
Been thanked: 0 time

Re: Added some cards

Postby BinarySpike » 05 Mar 2010, 21:24

As with the beastmaster ascension, the execute() command for it seems stop being called. I noticed some things though. First, I can play a second Beastmaster and it will cause the other to proc, and my Squirrel's get +5/+5. Second, if I have 7 squirrels attack right after I put the card down, it procs.

Using deduction I found that this is the process that it should envolve:
Declare Attackers: Select creature..
Declare Attackers: Play Instants and Abilities...
Declare Blockers: Play Instants and Abilities...
(from freshly downloaded forge)

HOWEVER, the Declare Attackers: Play Instants and Abilities is not being used in the source version I downloaded a couple days ago and edited. This is the step that the +5/+5's are getting applied. Maybe something I added changed functionality, when I have time later today or tomorrow morning I will do a fresh source and maybe SVN and try compiling those. (eclipse is a pain)
BinarySpike
 
Posts: 3
Joined: 02 Mar 2010, 19:44
Has thanked: 0 time
Been thanked: 0 time

Re: Added some cards

Postby DennisBergkamp » 05 Mar 2010, 21:49

Alright cool! I'll just add these in myself, thanks for coding them!
I wouldn't worry about sloppy code though, most of forge's code is very very sloppy :mrgreen: The Serial version ID stuff is something you can have Eclipse do automatically (check out how in this thread: viewtopic.php?f=52&t=1801 )

About Beastmaster Ascension: yes, I did change quite a bit of the combat code (and added that new phase), so it might be that it was bugged a few versions ago but fixed in this latest version.

I'll try to fix the Bushido blocking thing.
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: Added some cards

Postby jim » 06 Mar 2010, 14:11

I'm in a similar situation to BinarySpike. I've been coding a few cards in a local copy of Forge and wondering if they were worth submitting or not. Since this is my first attempt at Java code and I don't understand all the classes, the answer is probably not, but I'm happy to take pointers on how to improve. I'd be especially interested to know if I could have done this with one of the new keywords somehow.

Assuming BinarySpike doesn't mind me chiming in on his thread, here's my attempt at Wall of Reverence. I based the code on Eldrazi Monument. I've tested it as the human player but I haven't seen the AI use it yet.

Code: Select all
   public static void endOfTurn_Wall_Of_Reverence()
   {
      final String player = AllZone.Phase.getActivePlayer();
      final PlayerZone playZone = AllZone.getZone(Constant.Zone.Play, player);
      CardList list = new CardList(playZone.getCards());
      list = list.getName("Wall of Reverence");
      
      Ability ability;
      for (int i = 0; i < list.size(); i++)
      {
         final Card card = list.get(i);
         ability = new Ability(list.get(i), "0")
         {
            public void resolve()
            {
               CardList creats = new CardList(playZone.getCards());
               CardList validTargets = new CardList();
               creats = creats.getType("Creature");
               for (int i = 0; i < creats.size(); i++) {
                  if (CardFactoryUtil.canTarget(card, creats.get(i))) {
                     validTargets.add(creats.get(i));
                  }
               }
               if (validTargets.size() == 0)
                  return;
               
               if (player.equals(Constant.Player.Human))
               {
                  Object o = AllZone.Display.getChoiceOptional("Select creature for Wall of Reverence life gain", validTargets.toArray());
                  if (o != null) {
                     Card c = (Card) o;
                     int power=c.getNetAttack();
                     PlayerLife life = AllZone.GameAction.getPlayerLife(player);
                     life.addLife(power);
                  }
               }
               else//computer
               {
                  CardListUtil.sortAttack(validTargets);
                  Card c = creats.get(0);
                  if (c != null) {
                     int power = c.getNetAttack();
                     PlayerLife life = AllZone.GameAction.getPlayerLife(player);
                     life.addLife(power);
                  }
               }
            } // resolve
         }; // ability
         ability.setStackDescription("Wall of Reverence - "
               + player + " gains life equal to target creature's power.");
         AllZone.Stack.add(ability);
      }
            
   }

I added an explicit call to this routine in EndOfTurn.java in the executeAt() routine, right after the code for Pestilence:
GameActionUtil.endOfTurn_Wall_Of_Reverence();
and here's the standard stuff for cards.txt:
Wall of Reverence
3 W
Creature Spirit Wall
At the beginning of your end step, you may gain life equal to the power of target creature you control.
1/6
Defender
Flying
wall_of_reverence.jpg http://www.wizards.com/global/images/ma ... erence.jpg
jim
 
Posts: 46
Joined: 19 Feb 2010, 01:46
Location: Sunny New England
Has thanked: 0 time
Been thanked: 0 time

Re: Added some cards

Postby DennisBergkamp » 06 Mar 2010, 20:32

Jim,

I think Wall of Reverence is good (looking through the code, I probably would've coded it exactly the same), there's unfortunately no way currently to code it through keywords.
Thanks for adding it! I will merge it into my local version.
User avatar
DennisBergkamp
AI Programmer
 
Posts: 2602
Joined: 09 Sep 2008, 15:46
Has thanked: 0 time
Been thanked: 0 time

Re: Added some cards

Postby jim » 06 Mar 2010, 21:49

Dennis,

Thanks very much for looking it over: it's good to know I didn't miss anything obvious. I greatly appreciate you adding it to your local version, and I'll be happy not to have to re-integrate it when the next beta comes out.

I was curious -- is there a way to test cards out other than playing them? Not that I mind playing games of Magic, but coding a card and then waiting for it to come up in the game seems kind of hit and miss. :) Is there some other way to test, especially for the AI?
jim
 
Posts: 46
Joined: 19 Feb 2010, 01:46
Location: Sunny New England
Has thanked: 0 time
Been thanked: 0 time

Re: Added some cards

Postby zerker2000 » 06 Mar 2010, 22:14

Well, there aren't any restrictions on deck size, nor many of the keywords, so I suppose if you add
Code: Select all
Mana Tap
0
Artifact
NOTE:This is not a real card :)
T: add WWUUBBRRGG
Untap:0
to your cards.txt and make a deck along the lines of:
Code: Select all
--TEST-nightpack
[general]
constructed
[main]
1 Mana Tap
1 Howl of the Night Pack
1 Fastbond
2 Forest
1 Dryad Arbor
1 Breeding Pool
[sideboard]
Namely, 7 cards, of which 1 is the "Mana Tap" and the rest are the cards whose interaction you're testing. Then, turn of millloss, and you're good to go.
O forest, hold thy wand'ring son
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.


--Eladamri, the Seed of Freyalise
zerker2000
Programmer
 
Posts: 569
Joined: 09 May 2009, 21:40
Location: South Pasadena, CA
Has thanked: 0 time
Been thanked: 0 time

Re: Added some cards

Postby Chris H. » 06 Mar 2010, 22:16

jim wrote:I was curious -- is there a way to test cards out other than playing them? Not that I mind playing games of Magic, but coding a card and then waiting for it to come up in the game seems kind of hit and miss. :) Is there some other way to test, especially for the AI?
`
We tend to create small < 60 cards decks with just enough cards to run the test. Mox can be used as mana sources as they go into play quickly. Currently I am working on modifying the VanillaEquipment keyword. Here is the test deck that I am using: :)


You can also design a very small deck for the computer to use. As I was modifying some existing code so that we could have the Windstorm spell, I designed these two decks for testing:


and ...

User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times

Re: Added some cards

Postby jim » 06 Mar 2010, 22:49

Thanks guys,

This makes perfect sense, once I get past the mindset of testing with 60-card decks. Thanks!
jim
 
Posts: 46
Joined: 19 Feb 2010, 01:46
Location: Sunny New England
Has thanked: 0 time
Been thanked: 0 time

Re: Added some cards

Postby Chris H. » 07 Mar 2010, 00:38

jim wrote:Thanks guys,

This makes perfect sense, once I get past the mindset of testing with 60-card decks. Thanks!
`
Oh, and make sure that you uncheck the check boxes for:

Stack AI Land
Milling = Loss Condition


:wink:
User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times

Re: Added some cards

Postby zerker2000 » 07 Mar 2010, 02:06

Actually, I think Stack AI Land has error catching, so in the case there isn't enough land it merely shuffles; milling oneself is the real problem for such decks.
O forest, hold thy wand'ring son
Though fears assail the door.
O foliage, cloak thy ravaged one
In vestments cut for war.


--Eladamri, the Seed of Freyalise
zerker2000
Programmer
 
Posts: 569
Joined: 09 May 2009, 21:40
Location: South Pasadena, CA
Has thanked: 0 time
Been thanked: 0 time

Re: Added some cards

Postby Chris H. » 07 Mar 2010, 02:13

zerker2000 wrote:Actually, I think Stack AI Land has error catching, so in the case there isn't enough land it merely shuffles; milling oneself is the real problem for such decks.
`
I just ran a test deck by the computer and it only had creatures. The computer loaded the deck with no problems.

Dennis must have made a change to the code. In the old days before the stack AI land check box was implemented, things were different. I remember times when the game would not go past the New Game window ... unless the computer had at least 7 basic lands in it's deck. :)
User avatar
Chris H.
Forge Moderator
 
Posts: 6320
Joined: 04 Nov 2008, 12:11
Location: Mac OS X Yosemite
Has thanked: 644 times
Been thanked: 643 times

Next

Return to Developer's Corner

Who is online

Users browsing this forum: Google [Bot] and 34 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 35 users online :: 1 registered, 0 hidden and 34 guests (based on users active over the past 10 minutes)
Most users ever online was 7967 on 09 Sep 2025, 23:08

Users browsing this forum: Google [Bot] and 34 guests

Login Form