It is currently 11 Sep 2025, 22:01
   
Text Size

Groovy - script language that runs on JVM

Post MTG Forge Related Programming Questions Here

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

Re: Groovy - script language that runs on JVM

Postby Marek14 » 18 Dec 2009, 13:20

Chain of Acid - Yes, the copy may itself be copied until either there are no valid targets left or (more usual) until one player no longer wants to make a copy (while the copy allows you to destroy one of your opponent's permanents, it also opens you up to retaliation).

Isochron Scepter: The only way you could do that (with current rules) would be with a split card that is instant on one side and creature on the other. Imprint is now ability word, so no copy effects can force Isochron Scepter to cast a card that wasn't exiled by its first ability.

Since there are no split cards of this type, the question is academic. You might argue that instant card cannot enter the battlefield, or you might notice that state-based effects claim that a copy of spell or card will be removed from anywhere except stack or battlefield... I don't think there's a "best" answer. If Wizards ever make split cards like that (and they narrowly avoided doing so in Zendikar, as one of MaRo's articles show, so the chance is not good), my guess is they would give them special rules section anyways.

P.S. Does that mean Incantus will be able to copy spells now? If you make a new version, I'll be certainly glad to have a look at it. I contribute ideas to several projects, but Incantus is the only one I can actually implement cards for :D And new capabilities would allow me to implement much more of them...
Marek14
Tester
 
Posts: 2773
Joined: 07 Jun 2008, 07:54
Has thanked: 0 time
Been thanked: 303 times

Re: Groovy - script language that runs on JVM

Postby nantuko84 » 18 Dec 2009, 15:01

Incantus> could you please explain the way you implement Lorwyn Commands.
I've seen spell code, it uses some @modal keyword

Code: Select all
@modal(mode_1, mode_2, mode_3, mode_4, choose=2)
def effects(controller, source):
what is it and how is handled in game engine?

p.s. In MagicWars Commands were implemented as optional spells with flag saying that you can choose two - so when you play it, it will be played as two separate spells (that was ok for counterspells as they countered sourceCards, but not for copying mechanism). now every SpellAbility has addChain method that allows to stick any spell to another, so I'm planning to use it for commands
nantuko84
DEVELOPER
 
Posts: 266
Joined: 08 Feb 2009, 21:14
Has thanked: 2 times
Been thanked: 9 times

Re: Groovy - script language that runs on JVM

Postby Marek14 » 18 Dec 2009, 16:41

nantuko84 wrote:Incantus> could you please explain the way you implement Lorwyn Commands.
I've seen spell code, it uses some @modal keyword

Code: Select all
@modal(mode_1, mode_2, mode_3, mode_4, choose=2)
def effects(controller, source):
what is it and how is handled in game engine?

p.s. In MagicWars Commands were implemented as optional spells with flag saying that you can choose two - so when you play it, it will be played as two separate spells (that was ok for counterspells as they countered sourceCards, but not for copying mechanism). now every SpellAbility has addChain method that allows to stick any spell to another, so I'm planning to use it for commands
Could that method be also used for Splice onto Arcane?
Marek14
Tester
 
Posts: 2773
Joined: 07 Jun 2008, 07:54
Has thanked: 0 time
Been thanked: 303 times

Re: Groovy - script language that runs on JVM

Postby zerker2000 » 19 Dec 2009, 02:42

Marek14 wrote:There is also a class of cards that copy CARDS and let you cast those copies. In those cases, the announcement is done normally, so all normal choices can be made for the spell. This class contains Eye of the Storm, Isochron Scepter, Jhoira of the Ghitu Avatar (Vanguard), Maelstrom Archangel Avatar (Vanguard), Panoptic Mirror, Reversal of Fortune, Spellbinder, Spellweaver Helix and Spellweaver Volute.
And also all suspend cards.
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: Groovy - script language that runs on JVM

Postby Incantus » 19 Dec 2009, 04:38

nantuko84 wrote:Incantus> could you please explain the way you implement Lorwyn Commands.
I've seen spell code, it uses some @modal keyword

Code: Select all
@modal(mode_1, mode_2, mode_3, mode_4, choose=2)
def effects(controller, source):
what is it and how is handled in game engine?
To understand how the modal spells work, you have to understand the way basic spells/abilities function. I've slightly modified the functionality, so the new modal spells will look closer to the modal triggered spells. But as an example of the new framework, take a look at Profane Command:

Code: Select all
name = 'Profane Command'
cardnum = 0
expansion = ''
types = characteristic('Sorcery')
supertypes = no_characteristic()
subtypes = no_characteristic()
cost = 'XBB'
color = characteristic('B')
text = ['Choose two - Target player loses X life; or return target creature card with converted mana cost X or less from your graveyard to play; or target creature gets -X/-X until end of turn; or up to X target creatures gain fear until end of turn.']

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

@sorcery(txt=text[0])
def ability():
    def mode_1(controller, source):
        '''Target player loses X life'''
        payment = yield NoCost()
        target = yield Target(isPlayer)
        target.life -= payment.X
        yield

    def mode_2(controller, source):
        '''Return target creature card with converted mana cost X or less from your graveyard to play'''
        payment = yield NoCost()
        target = yield Target(isCreatureCard.with_condition(lambda c: c.cost <= payment.X), zone="graveyard", player="you")
        target.move_to(controller.play)
        yield
   
    def mode_3(controller, source):
        '''Target creature gets -X/-X until end of turn'''
        payment = yield NoCost()
        target = yield Target(isCreature)
        until_end_of_turn(target.augment_power_toughness(-payment.X, -payment.X))
        yield
   
    def mode_4(controller, source):
        '''Up to X target creatures gain fear until end of turn'''
        payment = yield NoCost()
        targets = yield MultipleTargets(isCreature, number=payment.X, up_to=True)
        for target in targets:
            until_end_of_turn(target.abilities.add(fear()))
        yield
    return modal_effects(mode_1, mode_2, mode_3, mode_4, choose=2)
abilities.add(ability)
Basically each mode is implemented as a separate effect, and the modal_effects function takes all the mode functions as arguments and basically multiplexes them together in the effects function that's actually run by the rules engine. Here's the implementation of modal_effects:
Code: Select all
def modal_effects(*modes, **kw):
    choose = kw['choose']
    def effects(controller, source):
        selected = controller.make_selection([(mode.__doc__,mode) for mode in modes], choose, prompt='Select %d mode(s):'%choose)
        if choose > 1: chosen = tuple((mode(controller, source) for mode in selected))
        else: chosen = (selected(controller, source), )
        # get the costs
        # We need to have a "payment = yield NoCost" in the mode to pass
        # back the cost in case the mode needs to reference is (see Profane Command)
        empty_costs = tuple((mode.next() for mode in chosen))                                               
        payment = yield source.cost

        # get the targets - demultiplex them
        targets = tuple((mode.send(payment) for mode in chosen))
        demux = [len(target) if type(target) == tuple else 1 for target in targets]
        targets = yield tuple(flatten(targets))
        if not hasattr(targets, "__len__"): targets = (targets, )
        yield tuple((mode.send(t) for t, mode in zip(tuple(unflatten(targets, demux)), chosen))
)
    return effects
As you can see, it wraps the modes that are passed in as arguments, and handles the plumbing to ask the player which ones to choose, pulls out the targets to pass to the rules engine, and gets back the resulting target objects and passes them into the modes that were selected. Since the underlying rules engine can only handle a list of targets, flatten and unflatten handles multiplexing to respective mode functions. I hope that makes sense.
Incantus
DEVELOPER
 
Posts: 267
Joined: 29 May 2008, 15:53
Has thanked: 0 time
Been thanked: 3 times

Re: Groovy - script language that runs on JVM

Postby Marek14 » 19 Dec 2009, 08:37

zerker2000 wrote:
Marek14 wrote:There is also a class of cards that copy CARDS and let you cast those copies. In those cases, the announcement is done normally, so all normal choices can be made for the spell. This class contains Eye of the Storm, Isochron Scepter, Jhoira of the Ghitu Avatar (Vanguard), Maelstrom Archangel Avatar (Vanguard), Panoptic Mirror, Reversal of Fortune, Spellbinder, Spellweaver Helix and Spellweaver Volute.
And also all suspend cards.
Huh? No. Suspend cards are normally cast when their suspend runs out - they go on stack, then to graveyard. They don't copy anything.

And they are not cast when suspended and copied later either. No normal announcement choice is made when you suspend a card.

BTW, Incantus, does the modal code now support things like Branching Bolt?
Marek14
Tester
 
Posts: 2773
Joined: 07 Jun 2008, 07:54
Has thanked: 0 time
Been thanked: 303 times

Re: Groovy - script language that runs on JVM

Postby zerker2000 » 20 Dec 2009, 04:50

Scratch that: I think I veered of in some weird direction of cards that are cast without mana, sorry.
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: Groovy - script language that runs on JVM

Postby Incantus » 20 Dec 2009, 06:58

Marek14 wrote:BTW, Incantus, does the modal code now support things like Branching Bolt?
Unfortunately not yet. The choose option only works for exactly N options. It would probably be possible to add an "up-to" option to let you select from 1..N modes.
Incantus
DEVELOPER
 
Posts: 267
Joined: 29 May 2008, 15:53
Has thanked: 0 time
Been thanked: 3 times

Previous

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 36 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 36 users online :: 0 registered, 0 hidden and 36 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: No registered users and 36 guests

Login Form