It is currently 06 Nov 2025, 03:53
   
Text Size

Replacement Effects

Post MTG Forge Related Programming Questions Here

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

Replacement Effects

Postby Hellfish » 28 Dec 2011, 21:57

Heyo! Hope y'all had a merry christmas.I myself was blessed with a glut of work after spending all of winter unemployed, incidentally the reason I kind of disappeared for a while. :lol:

Now, getting back to the *important* business of Forge :mrgreen: , I will check up on the cloner problem soon, but first I wanted to submit something I've been tinkering with for scrutiny: Scriptable Replacement Effects. I'm mostly looking for feedback on rules accuracy for the time being but the issue of AI is also very important, seeing as there not being any AI is the current issue.I'm not even sure how the AI would evaluate the effects.

The structure is very similar to Triggers (So there's currently a little code duplication), there is a Handler class, a base class for Replacement effects and subclasses for each event that can be replaced. Before each replacable event elsewhere in Forge, we fill in a runParams HashMap, just as for triggers, and pass that to ReplacementHandler.run so it can determine which replacement effects, if any, apply and let the correct player(s) choose between multiples. If ReplacementHandler.run returns true, the event that was about to happen is aborted, as it has been replaced.

I've got it working for card draws currently, though other events are possible to add with a bit of copy pasting. Current future plans include more replacable events, of course, non-static replacement effects(Until EOT, if you would X, do Y instead.) and an equivalent to Triggered-variables for use in things like altered amounts (Akki Lavarunner,Boon Reflection) or maybe even redirection effects (Using AF_DealDamage's Source parameter,maybe?)

Examples: (Note, the Handler currently assumes that the replacement effect only functions on the battlefield)
Code: Select all
Name:Laboratory Maniac
ManaCost:2 U
Types:Creature Human Wizard
Text:no text
PT:2/2
R:Event$ Draw | ValidPlayer$ You | IsPresent$ Card.YouOwn | PresentZone$ Library | PresentCompare$ EQ0 | ReplaceWith$ Win | Description$ If you would draw a card while your library has no cards in it, you win the game instead.
SVar:Win:AB$WinsGame | Cost$ 0 | Defined$ You
End

Name:Obstinate Familiar
ManaCost:R
Types:Creature Human Wizard
Text:no text
PT:1/1
R:Event$ Draw | ValidPlayer$ You | Optional$ True | Prevent$ True | Description$ If you would draw a card, you may skip that draw instead.
End

Name:Thought Reflection
ManaCost:4 U U U
Types:Enchantment
Text:no text
R:Event$ Draw | ValidPlayer$ You | ReplaceWith$ DrawTwo | Description$ If you would draw a card, draw two cards instead.
SVar:DrawTwo:AB$Draw | Cost$ 0 | Defined$ You | NumCards$ 2
End
Patch for r12874 attached.
Attachments
RepEff 1.txt
(31.18 KiB) Downloaded 223 times
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
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Re: Replacement Effects

Postby friarsol » 29 Dec 2011, 03:09

Oooooh Scriptable Replacement effects? Count me in.
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Replacement Effects

Postby Sloth » 29 Dec 2011, 17:43

The biggest rules problems with replacement effects are created when the effects could create loops. We have to make sure all replacement effects can be applied only once. For example Thought Reflection does not replace its own draws, but a second Thought Reflection should (So two Thought Reflections would let you draw four cards per normal draw).

Effects that could be replaced have to "remember" what replacements they already went through.
User avatar
Sloth
Programmer
 
Posts: 3498
Joined: 23 Jun 2009, 19:40
Has thanked: 125 times
Been thanked: 507 times

Re: Replacement Effects

Postby Hellfish » 29 Dec 2011, 23:43

I was gonna say that I did take that into account, but there appears to be a glitch in that regard..

What it's doing is marking the ReplacementEffects as "Has Run" when they are selected to replace an event and only clear those marks at the appropriate, later, time. I currently clear the marks in checkStateEffects and I think that's part of the problem..
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
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Re: Replacement Effects

Postby Hellfish » 31 Dec 2011, 12:08

I'm implementing an improved system for interactions like double Tought Reflection that Sloth mentioned. It's still not right (Seems the second Thought Reflection only replaces the first draw of the first Thought Reflection) but I expect this is down to human error somewhere, because AFAICT it's theoretically sound.

Spoilered because jesus flippin' christ | Open
Terminology:
TR = Thought Reflection
RE object = The card's instance of the ReplacementEffect class.
  1. The ordinary draw reaches Player.doDraw(), where ReplacementHandler.run() is called.
  2. run() let's the player choose which TR replacement to apply first, and pushes that RE object onto a stack, then runs the TR's replacement draw.
  3. The first draw of the first TR reaches Player.doDraw(), see point 1.
  4. run() see's that the first TR's RE object is on the stack and does not allow it to run. Instead it automatically pushes the second TR's RE object on the stack and runs it.
  5. The first draw of the second TR reaches player.doDraw(), see point 1.
  6. run() sees the second TR's RE object on the stack and does no replacement.The draw resolves as normal. Same thing with the second TR's second draw.
  7. Now,after having completed the second TR's replacement draw, the code returns to run() to finish the method for the second TR.Here, the second TR's RE object is popped off the stack.
  8. Now run() returns to the doDraw() of the first draw of the first TR, which will abort because it was replaced. The calling method will loop around and call doDraw() again (because it was a Draw 2-ability). Now we go back to point 3, except for the second draw of the first TR. Once that's done, continue to the next point.
  9. Now we are at the doDraw() for the original card draw, which aborts because ReplacementHandler.run() returned true.
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
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Re: Replacement Effects

Postby Hellfish » 02 Jan 2012, 11:40

Welp, in one fell swoop, the problem was fixed and the extra stack mentioned in the spoiler was eliminated. Cool beans. Next up: replacing other events than draws and "Replaced-variables".
EDIT: New patch is for r12917.
Attachments
RepEff 2.txt
(32.23 KiB) Downloaded 214 times
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
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Re: Replacement Effects

Postby moomarc » 02 Jan 2012, 20:43

I saw in the 1.2.1 thread that you3e done with damage replacement effects. Does that include redirecting damage as well, or is that a whole different ballgame? I can't wait to add Kor creatures from Stronghold! Would finally be able to build the first deck I built with paper magic (although it definitely won't be as effective since I've learnt the proper rules)
-Marc
User avatar
moomarc
Pixel Commander
 
Posts: 2091
Joined: 04 Jun 2010, 15:22
Location: Johannesburg, South Africa
Has thanked: 371 times
Been thanked: 372 times

Re: Replacement Effects

Postby Hellfish » 02 Jan 2012, 21:00

I guess that's a matter of wording. This system can handle "If damage would be dealt to CARDNAME, that damage is dealt to <whatever> instead." It *can't* handle things like "{cost}:The next # damage that would be dealt to CARDNAME this turn is dealt to target creature instead."
Fake edit: If you mean things like Lancer en-Kor; no, sorry. :(
Real edit: Committed, r12924.
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
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Re: Replacement Effects

Postby SoulStorm » 03 Jan 2012, 10:25

Posted this in the bugs thread, but it's probably more appropriate here Hellfish. Your Phytohydra conversion is having growing pains. My 1/1 Phytohydra attacked with Caltrops on the Battlefield and promptly died.

Must say though that I'm excited to have scriptable replacement effects in the game. Been looking forward to this for a long time. Many thanks!
SoulStorm
 
Posts: 423
Joined: 24 Jun 2010, 22:48
Has thanked: 16 times
Been thanked: 11 times

Re: Replacement Effects

Postby Hellfish » 03 Jan 2012, 10:36

SoulStorm wrote:Posted this in the bugs thread, but it's probably more appropriate here Hellfish. Your Phytohydra conversion is having growing pains. My 1/1 Phytohydra attacked with Caltrops on the Battlefield and promptly died.

Must say though that I'm excited to have scriptable replacement effects in the game. Been looking forward to this for a long time. Many thanks!
Thank *you* :) Fixed the problem I had only made sure Replacement Effects were run for *player* damage >_>. Should be good in the next nightly :)
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
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Re: Replacement Effects

Postby SoulStorm » 03 Jan 2012, 14:29

Thanks for the fix Hellfish. I just added Phytohydra's big brother Vigor. That's one more Incarnation down. It looks like Hostility may be scriptable, maybe Personal Incarnation as well, but I'm not sure. I think Guile needs some more infrastructure though.

Thanks Again Hellfish!
SoulStorm
 
Posts: 423
Joined: 24 Jun 2010, 22:48
Has thanked: 16 times
Been thanked: 11 times

Re: Replacement Effects

Postby friarsol » 03 Jan 2012, 15:33

Hey Hellfish,

Instead of AllzoneUtil.matchesValid() that you made in r12937 any reason not to have these things inherit from the same abstract class that has that function to consolidate? This way we don't need the call outside the objects?
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Replacement Effects

Postby Hellfish » 03 Jan 2012, 15:37

No *good* reason, no.. :P
The only reason not to do that is what would the base object be called without being confusing? TriggerReplacementBase?
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
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Re: Replacement Effects

Postby friarsol » 03 Jan 2012, 15:43

Ohh my favorite part of programming, coming up with names for things!

BaseValidator?
BaseFiringEvent?
George?
friarsol
Global Moderator
 
Posts: 7593
Joined: 15 May 2010, 04:20
Has thanked: 243 times
Been thanked: 965 times

Re: Replacement Effects

Postby Hellfish » 03 Jan 2012, 16:06

:lol:
Will commit after doing the laundry. :)
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
User avatar
Hellfish
Programmer
 
Posts: 1297
Joined: 07 Jun 2009, 10:41
Location: South of the Pumphouse
Has thanked: 110 times
Been thanked: 169 times

Next

Return to Developer's Corner

Who is online

Users browsing this forum: No registered users and 71 guests

Main Menu

User Menu

Our Partners


Who is online

In total there are 71 users online :: 0 registered, 0 hidden and 71 guests (based on users active over the past 10 minutes)
Most users ever online was 9298 on 10 Oct 2025, 12:54

Users browsing this forum: No registered users and 71 guests

Login Form