It is currently 26 Apr 2024, 09:55
   
Text Size

How do you handle static abilities?

General Discussion of the Intricacies

Moderator: CCGHQ Admins

How do you handle static abilities?

Postby Incantus » 25 Mar 2009, 14:21

As far as I can see, there are 2 ways:

1. At each "moment" of game time (basically whenever the game considers an atomic action to have occurred), you go through all curently active static abilities (in play, in the graveyard (Riftstone Portal)) and perform their modification. This is very straightforward (reset all cards at each point, add any relevant changes from static abilities) and is more correct from a rules standpoint, but seems very inefficient (especially if you build a search based AI). One side benefit is that timestamps are properly maintained, and conditional static abilities are pretty easy ("[cardname] gains +1/+1 while it is red")

2. Static abilities add or remove their modifications to cards at definite times in the game (for example, when coming into play or leaving play, if the static ability modifies other cards, then it is notified whenever a new card matching its criteria enters or leaves play). This requires an event system (but then again, you need one for triggered abilities). This might lead to some tricky timing or ordering issues (depending on how the event system is setup), and is also less straightforward to implement. One side effect is that getting this right makes triggered abilities fairly easy (the logic is pretty much the same, except instead of creating a continuous effect, you put something on the stack that resolves later).

Incantus currently uses the second approach. It took a while to get the timing right, but now it works pretty well.

What do the other programs do? Anybody have other approaches?
Incantus
DEVELOPER
 
Posts: 267
Joined: 29 May 2008, 15:53
Has thanked: 0 time
Been thanked: 3 times

Re: How do you handle static abilities?

Postby MageKing17 » 25 Mar 2009, 20:32

The second approach also gives you a psuedo-dependency, because whenever something changes a static ability's controller (for example), it changes the order in which its effects are evaluated (relative to other static effects). This is somewhat good (using Confiscate on a Control Magic enchanting a creature enchanted by two Control Magics gives you control of the creature), but nonetheless incorrect (if whatever caused the "dependency" disappears, the other effect doesn't revert to its original timestamp).
User avatar
MageKing17
Programmer
 
Posts: 473
Joined: 12 Jun 2008, 20:40
Has thanked: 5 times
Been thanked: 9 times

Re: How do you handle static abilities?

Postby BlackMamba » 25 Mar 2009, 22:04

Didn't implement those yet :) I'll listen carefully to what you say!

In Mox, I plan to have some sort of "stack" of modifiers for each property. A static ability will add a modifier to that stack, which will retrigger the computation of the "final" value (and possibly of other properties that depend on it). That modifier would listen to the game events that can affect its outcome. That "modifier stack" would also handle dependency layers, timestamps, etc...
BlackMamba
 
Posts: 23
Joined: 17 Sep 2008, 01:24
Has thanked: 0 time
Been thanked: 0 time

Re: How do you handle static abilities?

Postby frwololo » 26 Mar 2009, 02:07

For Wagic I do it in the most dirty way ever: each time I refresh the screen (which is basically what I decided to consider as an atomic event in my initial design).
This is wrong in two ways:
1) the checks are called many times when nothing actually happened
2) There might be two different event triggered at a same time, not taking each other into account (race conditions).

Now, it was very convenient to do it this way when I started working on my project, and so far it works alright, except in very extreme cases that I decided not to care about (but that a professional MTG player would hate me for). As a programmer I should hate myself for introducing these race conditions in the first place, but I haven't had any real issues so far with it.

Also, the 1) issue is not really one given the very "small" environment we work in.Statistically, there is very little chance to have more than, say 10 static abilities in play at a given time. Also, I have efficient data structures involving hashes for that. Even 100 cards would be fine I guess, but if I had 100 cards on the PSP screen, static abilities would not be my main problem, UI design would be :lol: .

That being said, I started implementing events in my engine and will probably progressively switch to that.
A good point with refreshing at every frame is that I don't really have to care about what is an atomic event or not, I am not afraid of forgetting something. But an Event mechanism is probably the way to go (the only real issue being to avoid infinite loops, I guess...that and not forgetting an event)
frwololo
DEVELOPER
 
Posts: 265
Joined: 21 Jun 2008, 04:33
Has thanked: 0 time
Been thanked: 3 times

Re: How do you handle static abilities?

Postby MageKing17 » 26 Mar 2009, 20:49

BlackMamba wrote:In Mox, I plan to have some sort of "stack" of modifiers for each property. A static ability will add a modifier to that stack, which will retrigger the computation of the "final" value (and possibly of other properties that depend on it). That modifier would listen to the game events that can affect its outcome. That "modifier stack" would also handle dependency layers, timestamps, etc...
That's basically how we handle characteristics and overridden functions (we even call them stacked_characteristics and stacked_functions).
User avatar
MageKing17
Programmer
 
Posts: 473
Joined: 12 Jun 2008, 20:40
Has thanked: 5 times
Been thanked: 9 times

Re: How do you handle static abilities?

Postby mtgrares » 15 Apr 2009, 19:53

My 2 cents isn't worth much, but here it is. MTG Forge actually uses method 1. To begin with I had no idea how to implement even simple static abilities like Glorious Anthem so I just wrote MTG Forge with the hopes that I could solve the problem in the future. MTG Forge uses method 1 because it was the only way I knew how to add Glorious Anthem and the implementation is still a little bit hacky since I use static class variables. Getting static abilities like Glorious Anthem to work together with pump spells like Giant Growth has been a problem but was fixed with a simple layering system of two ints. If you pumped up a creature with Giant Growth, Glorious Anthem would "reset" the creature's attack. The same problem is trying to pump up Nightmare because Nightmare's code would reset its power and toughness.

I say use whichever method that works for you and if you current method isn't working, change it.
mtgrares
DEVELOPER
 
Posts: 1352
Joined: 08 Sep 2008, 22:10
Has thanked: 3 times
Been thanked: 12 times


Return to Magic Rules Engine Programming

Who is online

Users browsing this forum: No registered users and 16 guests


Who is online

In total there are 16 users online :: 0 registered, 0 hidden and 16 guests (based on users active over the past 10 minutes)
Most users ever online was 4143 on 23 Jan 2024, 08:21

Users browsing this forum: No registered users and 16 guests

Login Form