Counter Type Revision

I think I have now got to the point where I've done as much as I can to implement all the different counter types. As a disclaimer, this isn't implemented! (But hopefully will). Putting all the changes and additions into one easy place will also help other coders and scripters as there are lots of changes, though shouldn't have much of an impact to the player.
Nuts and Bolts
Magic.Model.MagicCounterType:
All counters are now included in this file, taken from the latest oracle text. This even includes the more bizarre counters such as scream and +0/+2 (Don't know which cards those are from? Here you go: Endless Scream and Frankenstein's Monster).
Also added are a score value for use by the AI (more of that later) and being able to pull the relevant counter if you have a String of its name via MagicCounterType.getCounterRaw(String), which allows certain Abilities and Costs to work.
Magic.Model.MagicAbility:
For card scripters, there's a streamlining of card Abilities, and some impact on the behind the scenes working. All have been modified to allow the new MagicComesIntoPlayWithCounterTrigger format (see below).
Added to MagicAbility.java:
Modified in MagicAbility.java:
Removed from MagicAbility.java:
Magic.Model.Event.MagicRuleEventAction:
This is the second section of streamlining for scripters. These Effects have been merged together to create two universal set of rules for counters.
Added to MagicRuleEventAction.java:
Removed from MagicRuleEventAction.java:
With the universal Rules for counters, specifying countertypes by separate rules is no longer necessary.
Magic.Model.Event.MagicPermanentActivation:
The final section for scripting, this time changes to the Costs.
Added to MagicPermanentActivation.java:
Modified in MagicPermanentActivation.java:
Removed from MagicPermanentActivation.java:
Individual costs for each CounterType are no longer necessary.
The Peripheries
The remaining file changes are mainly housekeeping and referring to newer formats, they are mainly behind the scenes, but may pop up in groovy scripting.
Brain and Engine
If you've got this far, I'm stunned
The final (honest!) changes are for some final mechanics to allow the more obscure power and toughness modifying counters to function, and to the AI to understand what the hell just happened to all these changes!
Magic.Model.mstatic.MagicPermanentStatic:
Adding all the CounterTypes also includes the full range of power and toughness adjusting counters. Things like +0/+1, +2/+0 and -2/-2. These new additions have been named following the pattern for the previous +1/+1. So that means that PlusZeroPlusOne is +0/+1 and PlusTwoPlusZero is +2/+0.
Glad that all makes sense. As the +1/+1 counter isn't called PlusOnePlusOne, the +2/+2 counter is called simply PlusTwo. The same goes for MinusTwo, being -2/-2.
Magic.ai.ArtificialScoringSystem:
The scoring system for the AI has been upgraded for the new CounterTypes. Previously the score for each charge counter was +1. Taking this as a base, all other counter types were given values of either 1, 0 or -1. The values hope to make sense on the effect the different CounterTypes can have on permanents.
The scores all assume that you are the owner and controller of the permanent that the counters are on, not the owner of the counters themselves.
Not all of the counters fall into these guidelines, but they are a good place to start if/when more counter types are added. Some of the current scores may change if the AI is acting strangely with them.
Card Scripts
I'm fairly sure I've managed to catch all the changes and edit card scripts accordingly, but if some have slipped through the net, all the above should be able to point in the right direction.
Icon Images
The current rendering of counter types, and ability symbols for that matter, are not always the best for readability. 16x16 images are always going to be tricky to distinguish, and trying to find things that can thematically express sometimes abstract concepts at such a small size is difficult.
I'm hoping that there won't be many bugs or strangeness occurring, and I've tried to break things playing the most counter-filled decks you've ever seen. My clone at https://code.google.com/r/shawnieboyuk- ... ter-types/ is available for scrutiny and testing. I can only hope I'm able to give a big contribution to this great program! Can't give enough praise for the work that Melvin does maintaining this

Nuts and Bolts
Magic.Model.MagicCounterType:
All counters are now included in this file, taken from the latest oracle text. This even includes the more bizarre counters such as scream and +0/+2 (Don't know which cards those are from? Here you go: Endless Scream and Frankenstein's Monster).
Also added are a score value for use by the AI (more of that later) and being able to pull the relevant counter if you have a String of its name via MagicCounterType.getCounterRaw(String), which allows certain Abilities and Costs to work.
Magic.Model.MagicAbility:
For card scripters, there's a streamlining of card Abilities, and some impact on the behind the scenes working. All have been modified to allow the new MagicComesIntoPlayWithCounterTrigger format (see below).
Added to MagicAbility.java:
- • EntersWithCounter ("enters with counter <CounterType> <n>") – This will be the main ability for use with counters. Will accept any counter type and add the relevant amount.
- • EntersXCharge ("enters with counter charge X") – An extension on EntersXPlus. Due to the functioning of the calculation of X, there's no simple way of being able to use any counter type (see MagicWhenComesIntoPlayTrigger). Currently, only charge and +1/+1 counters get added to cards X amount at a time.
- • Loyalty ("loyalty <n>") – Included to use loyalty counters, adds <n> loyalty counters as it enters the battlefield. Would prefer to use Loyalty as a card definition, but having definitions that create triggered events is beyond me for the moment. This more closely matches the cards than having to use "enters with counter loyalty <n>".
Modified in MagicAbility.java:
- • EntersXPlus ("enters with counter +1/+1 X") and Multicounter ("enters with counter +1/+1 for each kick") – Has now had its text changed to match the 'new' "enters with counter" format.
Removed from MagicAbility.java:
- • TapAddCharge ("tap add charge") – Could already be performed with 'pay

- • EntersCharged ("enters with counter <CounterType> <n>") – This has simply been renamed, script usage remains the same.
- • EntersMinus ("enters with -1/-1 <n>") and EntersPlus ("enters with +1/+1 <n>") – Individual counter types no longer need separate abilities.
Magic.Model.Event.MagicRuleEventAction:
This is the second section of streamlining for scripters. These Effects have been merged together to create two universal set of rules for counters.
Added to MagicRuleEventAction.java:
- • CounterOnSelf ("put <amount> <CounterType> counter(s) on SN.") – This will allow any amount of any type of counter to be placed on the permanent.
- • CounterOnChosen ("put <amount> <CounterType> counter(s) on <chosen>.") – The same as CounterOnSelf, but on any permanent. This also includes selecting the correct MagicTiming, MagicTargetPicker and MagicTargetHint. This it works out from the CounterType chosen, and the score of that CounterType (see Brain and Engine).
Removed from MagicRuleEventAction.java:
With the universal Rules for counters, specifying countertypes by separate rules is no longer necessary.
- • GrowSelf ("put <amount> +1/+1 counter(s) on SN.")
- • GrowChosen ("put <amount> +1/+1 counter(s) on <chosen>.")
- • ShrinkChosen ("put <amount> -1/-1 counter(s) on <chosen>.")
- • ChargeSelf ("put <amount> <type> counter(s) on SN.") – This looks at first glance to be able to do what CounterOnSelf achieves. However this puts charge counters on the permanent, and calls them by a different name.
Magic.Model.Event.MagicPermanentActivation:
The final section for scripting, this time changes to the Costs.
Added to MagicPermanentActivation.java:
- • "Remove <amount> <CounterType> counter(s) from SN" – This cost covers all CounterType payments.
Modified in MagicPermanentActivation.java:
- • "Sacrifice SN" – This now replaces


Removed from MagicPermanentActivation.java:
Individual costs for each CounterType are no longer necessary.
- • "{S}"
- • "{+1/+1}"
- • "{-1/-1}"
- • "{C}"
- • "{C2}"
- • "{C3}"
The Peripheries
The remaining file changes are mainly housekeeping and referring to newer formats, they are mainly behind the scenes, but may pop up in groovy scripting.
- • Magic.Model.Trigger.MagicWhenComesIntoPlayTrigger – Includes the new XChargeCounters trigger from the EntersXCharge ability from MagicAbility.java.
- • Magic.Model.Trigger.MagicComesIntoPlayWithCounterTrigger – This trigger no longer requires a 'description' string for the CounterType, this is automatically obtained from MagicCounterType.getName() instead.
- • Magic.Model.Trigger.MagicFadeVanishCounterTrigger – This took a while to get right. Instead of referring to a string describing the CounterType, the actual CounterType is referred. No functional change, but looks quite different now in code. Uses the relevant CounterType instead of charge counters
- • Magic.Model.Trigger.MagicCumulativeUpkeepTrigger – Now uses age counters instead of charge.
- • Magic.Model.Trigger.MagicLandfallTrigger – Now uses quest counters instead of charge. Also uses the renamed MagicSimpleMayChoice (see below).
- • Magic.Model.Choice.MagicSimpleMayChoice – The ADD_CHARGE_COUNTER has been renamed ADD_POS_COUNTER. Originally expecting to add ADD_NEG_COUNTER as well, before realising that if you had a choice to add a 'bad' counter to a permanent, you'd probably always choose not to. Who knows what future cards will bring…
- • Magic.Model.Event.MagicLevelUpActivation – Now refers to level counters instead of charge.
- • Magic.Model.Event.MagicPlaneswalkerActivation – Now refers to loyalty counters instead of charge.
- • Magic.Model.Condition.MagicConditionFactory – The conditions referring to specific counters have been removed as the CounterAtLeast condition already allows for any CounterType to be referred. (Conditions removed: ChargeCountersAtLeast and PlusOneCounterAtLeast)
Brain and Engine
If you've got this far, I'm stunned

The final (honest!) changes are for some final mechanics to allow the more obscure power and toughness modifying counters to function, and to the AI to understand what the hell just happened to all these changes!
Magic.Model.mstatic.MagicPermanentStatic:
Adding all the CounterTypes also includes the full range of power and toughness adjusting counters. Things like +0/+1, +2/+0 and -2/-2. These new additions have been named following the pattern for the previous +1/+1. So that means that PlusZeroPlusOne is +0/+1 and PlusTwoPlusZero is +2/+0.
Glad that all makes sense. As the +1/+1 counter isn't called PlusOnePlusOne, the +2/+2 counter is called simply PlusTwo. The same goes for MinusTwo, being -2/-2.
Magic.ai.ArtificialScoringSystem:
The scoring system for the AI has been upgraded for the new CounterTypes. Previously the score for each charge counter was +1. Taking this as a base, all other counter types were given values of either 1, 0 or -1. The values hope to make sense on the effect the different CounterTypes can have on permanents.
The scores all assume that you are the owner and controller of the permanent that the counters are on, not the owner of the counters themselves.
- • 0 = Ignore (for stat adjusting counters or counters that are used both positively and negatively, or counters that mark a rule change for that card while present)
- • 1 = Count (counters that are only used positively (e.g. Counting a spendable resource, negative impact if decreased to a certain value, positive impact if increased to a certain value))
- • -1 = Count (counters that are only used negatively (e.g. positive impact if decreased to a certain value, negative impact if increased to a certain value))
Not all of the counters fall into these guidelines, but they are a good place to start if/when more counter types are added. Some of the current scores may change if the AI is acting strangely with them.
Card Scripts
I'm fairly sure I've managed to catch all the changes and edit card scripts accordingly, but if some have slipped through the net, all the above should be able to point in the right direction.
Icon Images
The current rendering of counter types, and ability symbols for that matter, are not always the best for readability. 16x16 images are always going to be tricky to distinguish, and trying to find things that can thematically express sometimes abstract concepts at such a small size is difficult.
- • To aid with visibility, the counter number will only show if there's 2 or more counters on a permanent. The value of 1 is redundant if you can already see an image.
- • Hopefully some budding pixel artists can help! But if you do find a suitable image, take into account its original size. Shrinking a large image down to 16x16 pixels will regularly resemble a blurred mess.
- • The left-most half of an ability or counter icon is the most visible, so if there is some blank space around the image, pushing it to the left-most side will certainly help.
- • Big (well, you know, as big as 16 pixels will allow) and bold! I know that some of my submissions have been pretty poor for this, especially icons that share a colour with the colour-types in Magic (black on black isn't a good look).
I'm hoping that there won't be many bugs or strangeness occurring, and I've tried to break things playing the most counter-filled decks you've ever seen. My clone at https://code.google.com/r/shawnieboyuk- ... ter-types/ is available for scrutiny and testing. I can only hope I'm able to give a big contribution to this great program! Can't give enough praise for the work that Melvin does maintaining this

