Rulemods: What they are, and the awesome stuff they can do.
by Incantus
Moderator: CCGHQ Admins
Rulemods: What they are, and the awesome stuff they can do.
by MageKing17 » 27 Jun 2010, 04:36
I'm going to do something uncharacteristic of me and explain one of the not-well-explored features of Incantus, "rulemods".
What is a rulemod?
A rulemod is nothing but a .py file; a python script, nothing more, nothing less. However, being placed in the data/rulemods folder will grant this python script incredible power: the GameKeeper will execute its code before loading cards, and in the same environment cards use, meaning it can define new things (or change existing things) that cards can then go on and use. Obviously, this is a very powerful feature, and also one not terribly useful for real cards, since their mechanics should be defined in the regular source code.
So why would you use a rulemod?
Well, as I may have mentioned, I enjoy making custom cards; and if there's one thing custom card-makers like more than twisting an existing mechanic to suit their purposes, it's making entirely new mechanics. You can use rulemods to define totally new keywords, helper functions (like the existing chroma and domain functions), and even entirely new card types.
So how would I make and use a rulemod, then?
Well, first we need something we want to make a rulemod out of. Since I've recently been working on one of my custom card sets, let's take a bit of a difficult card out of one and see if we can make it easier with a rulemod.
Here's one of my custom cards:
Now, you may be thinking, "That's easy! It's just chroma without a specific color." Well, that's what makes it difficult; chroma is simple because it looks for a specific color. It doesn't have to worry about where a hybrid symbol begins or ends because it just has to count the occurrences of that color. With this bad boy, however, we do need to worry about such complexities. So, without further ado, let's kick in the rulemod!
And there you have it! We have successfully added a function to the CardEnvironment we can use to implement Fraelin. Let's code his card, now.
The only step left to put this card in Incantus is making the image 200x285 pixels. Let me run that image through my handy-dandy image-resizing tool and see what we come up with...Oh yeah. We're in business now.
What is a rulemod?
A rulemod is nothing but a .py file; a python script, nothing more, nothing less. However, being placed in the data/rulemods folder will grant this python script incredible power: the GameKeeper will execute its code before loading cards, and in the same environment cards use, meaning it can define new things (or change existing things) that cards can then go on and use. Obviously, this is a very powerful feature, and also one not terribly useful for real cards, since their mechanics should be defined in the regular source code.
So why would you use a rulemod?
Well, as I may have mentioned, I enjoy making custom cards; and if there's one thing custom card-makers like more than twisting an existing mechanic to suit their purposes, it's making entirely new mechanics. You can use rulemods to define totally new keywords, helper functions (like the existing chroma and domain functions), and even entirely new card types.
So how would I make and use a rulemod, then?
Well, first we need something we want to make a rulemod out of. Since I've recently been working on one of my custom card sets, let's take a bit of a difficult card out of one and see if we can make it easier with a rulemod.
Here's one of my custom cards:
Now, you may be thinking, "That's easy! It's just chroma without a specific color." Well, that's what makes it difficult; chroma is simple because it looks for a specific color. It doesn't have to worry about where a hybrid symbol begins or ends because it just has to count the occurrences of that color. With this bad boy, however, we do need to worry about such complexities. So, without further ado, let's kick in the rulemod!
- Code: Select all
global count_colored_symbols
import characteristics
def count_colored_symbols(cost):
if isinstance(cost, characteristics.stacked_variable): cost = cost.current
if not isinstance(cost, (MultipleCosts, ManaCost, str)): return 0
if isinstance(cost, MultipleCosts):
costs = cost.costs[:]
costs = cost.consolidate(costs)
if isinstance(costs[0], ManaCost): cost = costs[0].cost
else: return 0
elif isinstance(cost, ManaCost): cost = cost.cost
total = 0
in_hybrid = False
current_hybrid = 0
max_hybrid = 0
for sym in cost:
if sym in '({':
in_hybrid = True
elif sym == '/':
current_hybrid = 0
elif sym == ')}':
in_hybrid = False
total += max_hybrid
max_hybrid = 0
current_hybrid = 0
if sym in "WUBRG":
if in_hybrid:
current_hybrid += 1
if current_hybrid > max_hybrid: max_hybrid = current_hybrid
else:
total += 1
return total
- Code: Select all
global count_colored_symbols
- Code: Select all
import characteristics
- Code: Select all
def count_colored_symbols(cost):
- Code: Select all
if isinstance(cost, characteristics.stacked_variable): cost = cost.current
- Code: Select all
if not isinstance(cost, (MultipleCosts, ManaCost, str)): return 0
- Code: Select all
if isinstance(cost, MultipleCosts):
- Code: Select all
costs = cost.costs[:]
costs = cost.consolidate(costs)
- Code: Select all
if isinstance(costs[0], ManaCost): cost = costs[0].cost
else: return 0
- Code: Select all
elif isinstance(cost, ManaCost): cost = cost.cost
- Code: Select all
total = 0
in_hybrid = False
current_hybrid = 0
max_hybrid = 0
- Code: Select all
for sym in cost:
- Code: Select all
if sym in '({':
in_hybrid = True
- Code: Select all
elif sym == '/':
current_hybrid = 0
- Code: Select all
elif sym == ')}':
in_hybrid = False
total += max_hybrid
max_hybrid = 0
current_hybrid = 0
- Code: Select all
if sym in "WUBRG":
- Code: Select all
if in_hybrid:
current_hybrid += 1
if current_hybrid > max_hybrid: max_hybrid = current_hybrid
else:
total += 1
- Code: Select all
return total
And there you have it! We have successfully added a function to the CardEnvironment we can use to implement Fraelin. Let's code his card, now.
- Code: Select all
name = 'Fraelin, Ancient One'
cost = '4UB'
supertypes = Legendary
types = Creature
subtypes = Vampire, Wizard
power = 3
toughness = 3
text = ["2UB, T: Scry 2, then put the top card of your library into your graveyard. Put a +1/+1 counter on ~ for each colored mana symbol in that card's mana cost."]
#################################
@activated(txt=text[0])
def ability():
def effects(controller, source):
cost = yield ManaCost("2UB") + TapCost()
target = yield NoTarget()
controller.scry(2)
yield
for card in controller.library.top(1):
counters = count_colored_symbols(card.cost)
card.move_to("graveyard")
yield
source.add_counters(PowerToughnessCounter(1, 1), number=counters)
yield
return effects
abilities.add(ability)
--------------- Fraelin, Ancient One
The only step left to put this card in Incantus is making the image 200x285 pixels. Let me run that image through my handy-dandy image-resizing tool and see what we come up with...Oh yeah. We're in business now.
- Fraelin_Ancient_One_custom_card.zip
- And here's a ready-to-download-and-use archive with all this stuff ready to roll.
- (22.32 KiB) Downloaded 510 times
-
MageKing17 - Programmer
- Posts: 473
- Joined: 12 Jun 2008, 20:40
- Has thanked: 5 times
- Been thanked: 9 times
1 post
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 13 guests