Wednesday, December 9, 2009

Shock and Royal Assassin – Part 3

Today I’m going to talk about Incantus and MagicWars. Both programs enforce the rules and allow you to play against other people over the Internet. Even though these two projects are completely separate, they encode Magic cards in a similar way. Each card is very short and is written in either Python or Java. Incantus was written in Python while MagicWars uses Java.

Incantus is the current king-of-the-hill when it comes to supporting the most cards. Incantus currently has more than 6,000 cards which is phenomenal. Of all of the freeware Magic programs, Incantus has the best user interface with all of the eye candy that you would ever want. Incantus has very readable, short card code that is written in Python. Currently the source code of Incantus is semi-private. It isn’t an open source project but you can get the source by reading through the Incantus forum.

MagicWars is newer than Incantus and has more than 550 cards including all 145 cards from Alara Reborn, go cascade!! MagicWars uses Groovy to encode Magic cards. The Groovy homepage says that it:

-- Builds upon the strengths of Java but has additional power features inspired by languages like Python, Ruby and Smalltalk.
-- Makes modern programming features available to Java developers with almost-zero learning curve.
--Supports Domain-Specific Languages and other compact syntax so your code becomes easy to read and maintain.

Groovy compiles to Java bytecode, so it can run anywhere that Java can. The MagicWars blog also says that “A Groovy Closure is like a ‘code block’ or a method pointer. It is a piece of code that is defined and then executed at a later point.” So Groovy is short like a domain specific language (see my previous article) and yet powerful enough to be a full-fledged language all by itself. Right now I don’t know anything about Groovy but it seem very interesting.

MagicWars also has a very nice blog that describes how it specifically uses Groovy. The blog encourages non-programmers to learn some syntax and to create their own favorite card.

Incantus:
Screenshot
Forum


MagicWars:
Screenshot - game in progress
Screenshot - deck editor

Download
Forum
Blog

Groovy

Incantus - Royal Assassin
name = 'Royal Assassin' 
cardnum = 0
expansion = ''
types = characteristic('Creature')
supertypes = no_characteristic()
subtypes = characteristic('Assassin', 'Human')
cost = '1BB'
color = characteristic('B')
power = 1
toughness = 1
text = ['T: Destroy target tapped creature.']

play_spell = play_permanent()

#################################

@activated(txt=text[0])
def ability():
def effects(controller, source):
cost = yield TapCost()
target = yield Target(isCreature.with_condition(lambda c: c.tapped))
target.destroy()
yield
return effects
abilities.add(ability)


Incantus - Shock
name = 'Shock'
cardnum = 0
expansion = ''
types = characteristic('Instant')
supertypes = no_characteristic()
subtypes = no_characteristic()
cost = 'R'
color = characteristic('R')
text = ['Shock deals 2 damage to target creature or player.']

#################################

@play_instant()
def effects(controller, source):
cost = yield source.cost
target = yield Target(isCreatureOrPlayer)
source.deal_damage(target, 2)
yield
play_spell = effects



MagicWars – Royal Assassin
name = "Royal Assassin"
types = ["Creature","Human","Assassin"]
manacost = "1 B B"
text = ["{T}: Destroy target tapped creature."]
power = 1
toughness = 1
prints = [
["M10", "R", 191318, 110],
["10E", "R", 129708, 174],
["9E", "R", 83235, 159],
["8E", "R", 45323, 159],
["4E", "R", 2124, 41]
]

script = '''\
addAbilityTap({
destroyTarget($target, $this)
}, "0")

setSpecificTarget("Select target
tapped creature to destroy.",
{
return $permanent.isCreature() &&
$permanent.isTapped()
})'


MagicWars - Shock
name = "Shock"
types = ["Instant"]
manacost = "R"
text = ["Shock deals 2 damage to target creature or player."]
prints = [
["10E", "C", 129732, 232],
["9E", "C", 83261, 220],
["ONS", "C", 39482, 227]
]

script = '''\
addSpell({
dealDamage($target, 2, $this);
})
setTarget("Creature|Player")
'''

14 comments:

Silly Freak said...

take it as a compliment that even spam bots visit your site ;)

Anonymous said...

This is a really fun program and I like the interface. Here are my suggestions for improvement.

-Multiple instances of lifelink should stack but they don't in Forge.

-Arashi's does not have its ability in Forge.

-Uril's bonuses didn't seem to work in the game I played with it.

-There needs to be step where priority is passed as the opponents attack step begins. E.g. computer has a Mulldrifter and attacks with it, I have Stillmoon Cavalier and mana open, but I can't block because Forge only lets me give the SC flying after the attack.

-You have said in your posts that this is for casual players. Cube Draft and EDH are two formats loved by casual players. Do you think you could add a highlander option to the draft editor, quests, and possibly support EDH rules? Or even EDH quests?

-I think these cards would be valuable additions to the cardbank of Forge (and interesting to try and program): Balance, Force of Will, Mana Drain, Tombstalker, Living Death, Recurring Nightmare, Fireblast, Sneak Attack, Form of the Dragon, Wildfire (Burning of Xinye), Genesis, Jitte, SoFI and SoLS.

telengard said...

I thought that M10 rules got rid of Lifelink stacking?

Forge said...

It is hard to keep track of all of the rules. I keep thinking "comes into play" instead of "enters the battlefield". I still don't completely understand the "new" combat rules. I'm still trying to get version 2 playable and it will have the "new" combat.

Forge said...

I left this as a comment on my previous post also.

I thought the problem how to encode Magic cards but I think the real problem is the complicated rules engine.

The first problem is that you have to understand the rules in order to program them, duh I know but it is hard to know ALL of the complexities. And the second problem is that the rules engine is just going to be complicated no matter how you slice it.

Fran said...

You are true Telengard, lifelink doesn't stack under M10 rules

wololo said...

I love it when old-school players email me with things such as "dude, your game doesn't follow the rules, I don't get manaburn, and my manapool is emptied at each phase".

I love it when people report bugs that don't exist. It's much more satisfying to tell someone to read the rules again, rather than adding an extra bug in the bugs list :D

DennisBergkamp said...

I agree, it means one fewer bug to fix :)

Fran said...

I agree with you both ;)

Forge said...

Wololo - "I love it when old-school players email me"

I know of people who play casual Magic in real life but haven't learned about the new rules system. When the rules change (battlefield, new combat) it is really hard to change your "internal rules".

telengard said...

Hehe, I'm one of those "old schoolers", although I haven't bugged you about it. :)

I'm OK with most of the changes but the mana burn one was a surprise to me. It had flavor and made for a few neat deck ideas.

I do realize it opened up the design space for them, i.e. Landfall.

~telengard

rising fruition said...

@telengard
How did it open up Landfall?

nantuko84 said...

they could create Lotus Cobra and make it very expensive ;)

telengard said...

Lotus Cobra was what I was trying to recall, which uses Landfall. Not all Landfall abilities are affected by no more mana burn.

Thanks nantuko84 for reading my mind. :)

~telengard