How to implement new cards
Post MTG Forge Related Programming Questions Here
Moderators: timmermac, Agetian, friarsol, Blacksmith, KrazyTheFox, CCGHQ Admins
13 posts
• Page 1 of 1
How to implement new cards
by fissionessence » 22 Apr 2011, 04:52
I only recently started playing with Forge, and even more recently noticed the openness of the card scripting. I read up on how to script a card, and made one of my own, but I don't know how to actually implement it in the program. I read all of the documentation I could find that I thought might answer this, but they all talk about how to script a card, and not so much how to actually make it fully implemented.
Is it possible for me to write and implement my own cards on my computer, or do all cards have to be written into the program? Do I need to use the java to modify the program? The cardsfolder kind of made it just look like I could throw a new .txt in there and it would work . . . but it didn't show up in the deck editor.
I'm not looking to program in existing Magic cards that aren't yet in Forge; I want to insert my own custom cards, so this is for personal use.
Sorry if the answer is obvious. If you could just direct me to where I can read up on this, I'd be happy to do so
Is it possible for me to write and implement my own cards on my computer, or do all cards have to be written into the program? Do I need to use the java to modify the program? The cardsfolder kind of made it just look like I could throw a new .txt in there and it would work . . . but it didn't show up in the deck editor.
I'm not looking to program in existing Magic cards that aren't yet in Forge; I want to insert my own custom cards, so this is for personal use.
Sorry if the answer is obvious. If you could just direct me to where I can read up on this, I'd be happy to do so
- fissionessence
- Posts: 4
- Joined: 22 Apr 2011, 04:42
- Has thanked: 0 time
- Been thanked: 0 time
Re: How to implement new cards
by Hellfish » 22 Apr 2011, 07:23
Hello and welcome! 
Indeed, you should be able to put a correctly formatted text file in cardsfolder and have Forge pick up on it. There may be some errors in it that are hard to spot if you havn't scripted a lot so if you could post the card script we could take a look.
The wiki is probably the best place for info, along with various forum topics and asking people, but I believe you knew that.
Indeed, you should be able to put a correctly formatted text file in cardsfolder and have Forge pick up on it. There may be some errors in it that are hard to spot if you havn't scripted a lot so if you could post the card script we could take a look.
The wiki is probably the best place for info, along with various forum topics and asking people, but I believe you knew that.
So now you're
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
Screaming for the blood of the cookie monster
Evil puppet demon of obesity
Time to change the tune of his fearful ballad
C is for "Lettuce," that's good enough for me
-

Hellfish - Programmer
- Posts: 1297
- Joined: 07 Jun 2009, 10:41
- Location: South of the Pumphouse
- Has thanked: 110 times
- Been thanked: 169 times
Re: How to implement new cards
by fissionessence » 22 Apr 2011, 15:34
Thanks for replying! Here is my card:
~
- Code: Select all
Form of the Kraken
ManaCost:5 U U U
Types:Enchantment
Text:no text
T:Mode$ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, put eight 3/3 blue Tentacle creature tokens with reach onto the battlefield.
SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 8 | TokenName$ Tentacle | TokenTypes$ Creature,Tentacle | TokenOwner$ You | TokenColors$ Blue | TokenPower $ 3 | TokenToughness$ 3 | TokenKeywords$ Reach
T:Mode$ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ When CARDNAME leaves the battlefield, sacrifice all Tentacles you control.
SVar:TrigSac:AB$DestroyAll | Cost$ 0 | ValidCards$ Tentacle
SVar:Rarity:Mythic Rare
End
~
- fissionessence
- Posts: 4
- Joined: 22 Apr 2011, 04:42
- Has thanked: 0 time
- Been thanked: 0 time
Re: How to implement new cards
by friarsol » 22 Apr 2011, 15:55
Take a look at one of the other cards in cardsfolder/ you are missing the first parameter of the very first line
Name:Form of the Kraken
Name:Form of the Kraken
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: How to implement new cards
by Chris H. » 22 Apr 2011, 15:59
`fissionessence wrote:Thanks for replying! Here is my card:At first, when I tried to load the program it gave me an error. After a couple iterations of fixes, the program loads fine with this version. The problem I'm having is that when I go into the deck editor, the card doesn't show up
- Code: Select all
Form of the Kraken
ManaCost:5 U U U
Types:Enchantment
Text:no text
T:Mode$ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, put eight 3/3 blue Tentacle creature tokens with reach onto the battlefield.
SVar:TrigToken:AB$Token | Cost$ 0 | TokenAmount$ 8 | TokenName$ Tentacle | TokenTypes$ Creature,Tentacle | TokenOwner$ You | TokenColors$ Blue | TokenPower $ 3 | TokenToughness$ 3 | TokenKeywords$ Reach
T:Mode$ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigSac | TriggerDescription$ When CARDNAME leaves the battlefield, sacrifice all Tentacles you control.
SVar:TrigSac:AB$DestroyAll | Cost$ 0 | ValidCards$ Tentacle
SVar:Rarity:Mythic Rare
End![]()
~
Try adding the card name label before the cards name. The first line of you card should look like this:
- Code: Select all
Name:Form of the Kraken
-

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: How to implement new cards
by fissionessence » 22 Apr 2011, 18:30
What an embarrassing brain fart
Thanks, guys!
Now, will that card automatically appear in quest reward packs and the shop, or is there more stuff I need to make that happen?
Now, will that card automatically appear in quest reward packs and the shop, or is there more stuff I need to make that happen?
- fissionessence
- Posts: 4
- Joined: 22 Apr 2011, 04:42
- Has thanked: 0 time
- Been thanked: 0 time
Re: How to implement new cards
by friarsol » 22 Apr 2011, 19:20
It's pretty plug and play, although with how many cards we have the probability of actually getting 1 of your cards is... slim. Just be careful with custom cards, if you move to the next version you need to bring your custom cards forward, otherwise you may have decks that will be be unusable without them.fissionessence wrote:What an embarrassing brain fartThanks, guys!
Now, will that card automatically appear in quest reward packs and the shop, or is there more stuff I need to make that happen?
- friarsol
- Global Moderator
- Posts: 7593
- Joined: 15 May 2010, 04:20
- Has thanked: 243 times
- Been thanked: 965 times
Re: How to implement new cards
by Chris H. » 22 Apr 2011, 19:21
`fissionessence wrote:Now, will that card automatically appear in quest reward packs and the shop, or is there more stuff I need to make that happen?
I believe that as long as the card has a rarity value in the card file that it will be included as a possible card that could appear in a pack, card shop or as a special reward if the card is a rare.
-

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: How to implement new cards
by lazylockie » 22 Apr 2011, 21:20
I think this used to work, but doesn't anymore. I used to play with a Standard only pool this way, but since revision 7000 (I guess) putting a # on SetInfo doesn't work anymoreChris H. wrote:`fissionessence wrote:Now, will that card automatically appear in quest reward packs and the shop, or is there more stuff I need to make that happen?
I believe that as long as the card has a rarity value in the card file that it will be included as a possible card that could appear in a pack, card shop or as a special reward if the card is a rare.
- lazylockie
- Posts: 508
- Joined: 13 Jul 2010, 22:44
- Has thanked: 74 times
- Been thanked: 15 times
Re: How to implement new cards
by Chris H. » 22 Apr 2011, 23:01
`lazylockie wrote:I think this used to work, but doesn't anymore. I used to play with a Standard only pool this way, but since revision 7000 (I guess) putting a # on SetInfo doesn't work anymore
The recent work on sets is an ongoing project. I think that everyone including the dev will be happy to see this finished.
-

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: How to implement new cards
by fissionessence » 23 Apr 2011, 00:34
I kind of got lost in the back-and-forth here . . . so the cards will not appear in the quest packs, shop, and rewards?
Also, I have a couple other questions:
Why do some of the card files I look at have just card text, but no 'rules programming'? But they still work fine in the game. Jace, the Mind Sculptor doesn't even have any text in the file, but an AI deck was using him!
Also, for the cards I put in, I also put images in the pics folder. They show up in the deck editor, but when I play with them, they're black, as if there were no picture
How can I fix this?
Also, I have a couple other questions:
Why do some of the card files I look at have just card text, but no 'rules programming'? But they still work fine in the game. Jace, the Mind Sculptor doesn't even have any text in the file, but an AI deck was using him!
Also, for the cards I put in, I also put images in the pics folder. They show up in the deck editor, but when I play with them, they're black, as if there were no picture
- fissionessence
- Posts: 4
- Joined: 22 Apr 2011, 04:42
- Has thanked: 0 time
- Been thanked: 0 time
Re: How to implement new cards
by Chris H. » 23 Apr 2011, 01:24
`fissionessence wrote:I kind of got lost in the back-and-forth here . . . so the cards will not appear in the quest packs, shop, and rewards?
Some recent code additions are adding set info to each and every card file. This part of the project is ongoing and is not yet finished. This might explain a few of the noticed oddities.
`Why do some of the card files I look at have just card text, but no 'rules programming'? But they still work fine in the game. Jace, the Mind Sculptor doesn't even have any text in the file, but an AI deck was using him!
Some cards are scripted. The lines starting with a K, T or A is script. A portion of the code will analyze the script and this script tells the computer how to handle the card in game terms.
Some cards are hard coded. The code for Jace, the Mind Sculptor looks like this:
- Code: Select all
//*************** START *********** START **************************
else if (cardName.equals("Jace, the Mind Sculptor")) {
final int turn[] = new int[1];
turn[0] = -1;
final Ability ability1 = new Ability(card, "0") {
@Override
public void resolve() {
turn[0] = AllZone.Phase.getTurn();
card.addCounterFromNonEffect(Counters.LOYALTY, 2);
Player targetPlayer = getTargetPlayer();
PlayerZone lib = AllZone.getZone(Constant.Zone.Library, targetPlayer);
if (lib.size() == 0) return;
Card c = lib.get(0);
if (card.getController().equals(AllZone.HumanPlayer)) {
StringBuilder question = new StringBuilder();
question.append("Put the card ").append(c).append(" on the bottom of the ");
question.append(c.getController()).append("'s library?");
if (GameActionUtil.showYesNoDialog(card, question.toString())) {
AllZone.GameAction.moveToBottomOfLibrary(c);
}
} else //compy
{
PlayerZone humanPlay = AllZone.getZone(Constant.Zone.Battlefield, AllZone.HumanPlayer);
CardList land = new CardList(humanPlay.getCards());
land = land.getType("Land");
//TODO: improve this:
if(land.size() > 4 && c.isLand()) ;
else {
AllZone.GameAction.moveToBottomOfLibrary(c);
}
}
}
@Override
public boolean canPlayAI() {
return card.getCounters(Counters.LOYALTY) < 13 && AllZone.Human_Library.size() > 2;
}
@Override
public boolean canPlay() {
return AllZone.getZone(card).is(Constant.Zone.Battlefield)
&& turn[0] != AllZone.Phase.getTurn()
&& Phase.canCastSorcery(card.getController());
}//canPlay()
};
ability1.setDescription("+2: Look at the top card of target player's library. You may put that card on the bottom of that player's library.");
StringBuilder stack1 = new StringBuilder();
stack1.append(card.getName()).append(" - Look at the top card of target player's library. You may put that card on the bottom of that player's library.");
ability1.setStackDescription(stack1.toString());
ability1.setBeforePayMana(CardFactoryUtil.input_targetPlayer(ability1));
ability1.setChooseTargetAI(CardFactoryUtil.AI_targetHuman());
card.addSpellAbility(ability1);
final Ability ability2 = new Ability(card, "0") {
@Override
public void resolve() {
turn[0] = AllZone.Phase.getTurn();
card.getController().drawCards(3);
Player player = card.getController();
if(player.equals(AllZone.HumanPlayer)) humanResolve();
//else
// computerResolve();
}
public void humanResolve() {
PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, AllZone.HumanPlayer);
CardList putOnTop = new CardList(hand.getCards());
if(putOnTop.size() > 0) {
Object o = GuiUtils.getChoice("First card to put on top: ", putOnTop.toArray());
if(o != null) {
Card c1 = (Card) o;
putOnTop.remove(c1);
AllZone.GameAction.moveToLibrary(c1);
}
}
putOnTop = new CardList(hand.getCards());
if(putOnTop.size() > 0) {
Object o = GuiUtils.getChoice("Second card to put on top: ", putOnTop.toArray());
if(o != null) {
Card c2 = (Card) o;
putOnTop.remove(c2);
AllZone.GameAction.moveToLibrary(c2);
}
}
}
@Override
public boolean canPlayAI() {
return false;
}
@Override
public boolean canPlay() {
return AllZone.getZone(card).is(Constant.Zone.Battlefield)
&& turn[0] != AllZone.Phase.getTurn()
&& Phase.canCastSorcery(card.getController());
}//canPlay()
};
ability2.setDescription("0: Draw three cards, then put two cards from your hand on top of your library in any order.");
StringBuilder stack2 = new StringBuilder();
stack2.append(card.getName()).append(" - Draw three cards, then put two cards from your hand on top of your library in any order.");
ability2.setStackDescription(stack2.toString());
card.addSpellAbility(ability2);
final Ability ability3 = new Ability(card, "0") {
@Override
public void resolve() {
turn[0] = AllZone.Phase.getTurn();
card.subtractCounter(Counters.LOYALTY, 1);
if(AllZone.GameAction.isCardInPlay(getTargetCard())
&& CardFactoryUtil.canTarget(card, getTargetCard())) {
AllZone.GameAction.moveToHand(getTargetCard());
}//if
}//resolve()
@Override
public boolean canPlay() {
return card.getCounters(Counters.LOYALTY) >= 1
&& AllZone.getZone(card).is(Constant.Zone.Battlefield)
&& turn[0] != AllZone.Phase.getTurn()
&& Phase.canCastSorcery(card.getController());
}
};
ability3.setDescription("-1: Return target creature to its owner's hand.");
StringBuilder stack3 = new StringBuilder();
stack3.append(card.getName()).append(" - Return target creature to its owner's hand.");
ability3.setStackDescription(stack3.toString());
ability3.setBeforePayMana(CardFactoryUtil.input_targetCreature(ability3));
card.addSpellAbility(ability3);
final Ability ability4 = new Ability(card, "0") {
@Override
public void resolve() {
turn[0] = AllZone.Phase.getTurn();
card.subtractCounter(Counters.LOYALTY, 12);
Player player = getTargetPlayer();
PlayerZone lib = AllZone.getZone(Constant.Zone.Library, player);
PlayerZone hand = AllZone.getZone(Constant.Zone.Hand, player);
CardList libList = new CardList(lib.getCards());
CardList handList = new CardList(hand.getCards());
for(Card c:libList)
AllZone.GameAction.exile(c);
for(Card c:handList) {
AllZone.GameAction.moveToLibrary(c);
}
player.shuffle();
}
@Override
public boolean canPlayAI() {
int libSize = AllZone.Human_Library.size();
int handSize = AllZone.Human_Hand.size();
return libSize > 10 && (libSize > handSize);
}
@Override
public boolean canPlay() {
return card.getCounters(Counters.LOYALTY) >= 12
&& AllZone.getZone(card).is(Constant.Zone.Battlefield)
&& turn[0] != AllZone.Phase.getTurn()
&& Phase.canCastSorcery(card.getController());
}
};
ability4.setDescription("-12: Exile all cards from target player's library, then that player shuffles his or her hand into his or her library.");
StringBuilder stack4 = new StringBuilder();
stack4.append(card.getName()).append(" - Exile all cards from target player's library, then that player shuffles his or her hand into his or her library.");
ability4.setStackDescription(stack4.toString());
ability4.setBeforePayMana(CardFactoryUtil.input_targetPlayer(ability4));
ability4.setChooseTargetAI(CardFactoryUtil.AI_targetHuman());
card.addSpellAbility(ability4);
card.setSVars(card.getSVars());
card.setSets(card.getSets());
return card;
}//*************** END ************ END **************************
Some cards are a combination of both code and script.
`Also, for the cards I put in, I also put images in the pics folder. They show up in the deck editor, but when I play with them, they're black, as if there were no pictureHow can I fix this?
Rob might be able to answer this one as he is closer to this portion of the code base.
-

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: How to implement new cards
by Rob Cashwalker » 25 Apr 2011, 17:16
Probably just the lack of SetInfo. Since it's not a real card, there is no set code listed in the SetInfo.java file. I guess you could give it the "Media Insert Promo" set code "MBP".Also, for the cards I put in, I also put images in the pics folder. They show up in the deck editor, but when I play with them, they're black, as if there were no picture How can I fix this?
So add this line in there:
- Code: Select all
SetInfo:MBP:Mythic:http://your.own.url/your_image/path.jpg
The Force will be with you, Always.
-

Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
13 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 17 guests