Marvel Heroic RPG MapTool framework – minor update

Just a quick post to let anyone who’s using my Marvel Heroic RPG framework know that you’ll probably want to re-download it. @SenatorChatty discovered that my Build Character macro totally left off the part where it’s supposed to ask you to pick specialties for your hero! Oops.

It’s fixed now. Thanks Christopher!

Earlier post on this topic – click here.

– Michael the OnlineDM

MapTool – Creating monster power macros with a macro

Strap in, macro lovers – you’re in for quite a ride!

As I mentioned in my last post, I’ve wanted for a while to create monster power macros using another macro. I’d like to be able to click an “Add Power” button, specify the details of the attack, and see a new button for that attack get created. And now, at long last, I’ve done exactly that.

It’s not a simple macro, to be sure. But I think it’s quite slick. Read on, if you dare! And note that you can download the macro here. My current D&D 4e campaign framework is available here.

First, some new properties

As I was going through this process, I realized that I would need to update my monster properties to better handle the tracking of encounter and recharge powers. I previously handled this with properties E1 through E7, which begin with a value of 1 and then get set to 0 once the encounter power is used, after which it can’t be used again. I did similarly with R1 through R5 for recharge powers.

Since my new macro is going to be creating encounter powers, it needs to know which encounter power slots are already taken. The cleanest way to do this was with pairs of JSON arrays as properties.

EncounterPowersCharged:'[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]’
EncounterPowersDeclared:'[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]’
RechargePowersCharged:'[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]’
RechargePowersDeclared:'[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]’

These are ten-item arrays, allowing for ten separate encounter powers and ten separate recharge powers. When I assign a new encounter power to one of the slots, I change the appropriate slot in the EncounterPowersDeclared array to 1. When that power is used up, it changes the appropriate slot in the EncounterPowersCharged array to 0, preventing it from being used again. And so on for recharge powers.

More on this later.

Macro structure

This macro has three main sections.

– There’s the first input box, where I ask for the name of the power, what range it targets, whether it’s standard or minor or whatever, what order I want the power to appear in, the usage (at-will, encounter, recharge), how many targets it has, whether it requires an attack roll and/or damage roll, and whether there are various other lines of text in the power (a Requirement line, a miss effect, etc.).

– There’s a second input box, where I ask about extra bonuses to the attack roll, what level of damage is being dealt, and what should appear in the various lines of text of the power.

– There’s the actual construction of the macro command text, which gets rather complicated.

First input box

I’ll present the code as a big dump, then explain it.

[h: listActionTypes = “2. Traits, 3. Standard Actions, 4. Move Actions, 5. Minor Actions, 6. Triggered Actions”]
[h: listDamageLevel = “Minion, Very Low, Low, Normal, High, Very High, Extreme”]
[h: listUsage = “At-Will, Recharge, Encounter, Not Applicable”]
[h: x = input(
“MacroName | NewPower| Power Name || WIDTH=20”,
“TargetRange | (M1) | Targets-Aura-Etc || WIDTH=10”,
“ActionType | ” + listActionTypes + ” | Action Type | LIST | VALUE=STRING SELECT=1″,
“SortOrder | 1 | Sort order || WIDTH=2”,
“Usage | ” + listUsage + ” | Usage | LIST | VALUE=STRING SELECT=0″,
“NumberOfTargets | Single-Target, Multi-Target, No Targets | Number of Targets | LIST | VALUE=STRING SELECT=0”,
“AttackRollRequired | 1 | Attack roll? | CHECK | “,
“DamageRollRequired | 1 | Damage roll? | CHECK | “,
“RequirementIncluded | 0 | Requirement line? | CHECK | “,
“PreAttackEffectIncluded | 0 | Pre-attack effect? | CHECK | “,
“MissEffectIncluded | 0 | Miss effect? | CHECK | “,
“AftereffectIncluded | 0 | After-save effect? | CHECK | “,
“PostAttackEffectIncluded | 0 | Post-attack effect? | CHECK | “,
“SpecialEffectIncluded | 0 | Special effect? | CHECK | ”
)]
[h: abort(x)]

The first three lines just set up some string lists that the user will be able to choose from for action type, damage level and usage. Then I have a big input box where I ask the user to make some choices. It’s probably easiest to just look at it in action:

The user is invited to type in the name of the power and any information about its range (such as M1 for melee 1 or AB1 in 10 for area burst 1 within 10 squares). A drop-down lets you pick whether it’s standard, minor, etc. The sort order only matters if you have multiple powers of the same action type – which standard action do you want first, then second, etc. The targets are either Single-Target, Multi-Target or No Targets. Then we have a series of check boxes that ask whether different possible parts of a power are present in this power. Note that the default options assume an attack roll and a damage roll and nothing else, but that’s all easy to edit with a click.

Second input box

[h: DefenseTargeted=’AC’]
[h: Enhancement=0]
[h: DamageLevel=”Normal”]
[h: DefaultDamageLevel=3]

Here I set up a few default values. These are useful in case I’ve said in the first input box that the power has no attack roll, in which case I won’t be picking a defense to target or a possible enhancement for critical rolls. That can be a problem later in the macro, so I need some defaults.

The DefaultDamageLevel is a variable that determines where the starting position in the damage drop-down will be. Position 3 is “Normal”. But in certain cases I want to default to things other than “Normal”:

[h, if(getProperty(“Role”)==”Brute”): DefaultDamageLevel=DefaultDamageLevel+1]
[h, if(Usage==”Recharge”): DefaultDamageLevel=DefaultDamageLevel+1]
[h, if(Usage==”Encounter”): DefaultDamageLevel=DefaultDamageLevel+2]
[h, if(NumberOfTargets==”Multi-Target”): DefaultDamageLevel=DefaultDamageLevel-1]
[h, if(getProperty(“SubType”)==”Minion”): DefaultDamageLevel=0]

Brutes deal more damage than other creatures. Recharge powers should do a bit more damage than normal, other things being equal. Encounter powers should do more still. Now, if the attack hits multiple targets, that should bring the damage down a bit. And of course if we’re building a power for a minion, we should use fixed minion damage.

Okay, now things start getting complicated.

[h: RechargeTargetInputString=if(Usage==”Recharge”,encode(“RechargeTarget | 2, 3, 4, 5, 6 | Recharge Target | LIST | VALUE=STRING SELECT=3″),””)]

What’s going on here? Well, I’m getting ready to build another input box. I want to be slick with this one, so it’s only going to ask the user for information that’s relevant. This means that if I’m building a recharge power, I want to ask for a recharge target number, but if I’m building an at-will or encounter power I don’t want to bother asking for a recharge number.

So, I create a string that will show up in the next input() command for the recharge target line. If I am building a recharge power, the string will be encoded to ask for a variable called RechargeTarget, which could range from 2 to 6. It will ask the user for a Recharge Target value in a drop-down list and save the choice as a string. The default selected in the drop-down will be at index 3 of the list which, because MapTool starts counting at 0, is actually the fourth item – which is the number 5, the most common recharge target.

However, if I’m NOT building a recharge power (Usage is anything other than Recharge) then instead of encoding this big string, I just set RechargeTargetInputString equal to “” – a blank string.

I then do similar things for lots of other possible inputs.

[h: DamageRollInputString=if(DamageRollRequired==1,encode(“DamageLevel | ” + listDamageLevel + ” | Damage Level | LIST | VALUE=STRING SELECT=” + DefaultDamageLevel),””)]
[h: EnhancementInputString=if(DamageRollRequired==1,encode(“Enhancement | 0 | Extra damage on crit? | CHECK | “),””)]
[h: ExtraAttackBonusInputString=if(AttackRollRequired==1,encode(“ExtraAttackBonus | 0 | Extra attack bonus | | WIDTH=2″),””)]
[h: JustEffectInputString=if(AttackRollRequired==0,encode(“JustEffect | . | Effect line | | WIDTH=50″),””)]
[h: DefenseInputString=if(AttackRollRequired==1,encode(“DefenseTargeted | AC, Fortitude, Reflex, Will | Defense targeted | LIST | VALUE=STRING SELECT=0″),””)]
[h: HitStringInputString=if(AttackRollRequired==1&&DamageRollRequired==1,encode(“HitStringWithDamage | damage | Hit line after damage roll | | WIDTH=50”),if(AttackRollRequired==1&&DamageRollRequired==0,encode(“HitStringNoDamage | . | Hit line | | WIDTH=50”),if(AttackRollRequired==0&&DamageRollRequired==1,encode(“EffectStringNoAttack | damage | Effect line after damage roll | | WIDTH=50″),””)))]
[h: RequirementInputString=if(RequirementIncluded==1,encode(“Requirement | . | Requirement | | WIDTH=50″),””)]
[h: TriggerInputString=if(ActionType==”6. Triggered Actions”,encode(“Trigger | . | Trigger | | WIDTH=50″),””)]
[h: PreAttackEffectInputString=if(PreAttackEffectIncluded==1,encode(“PreAttackEffect | . | Pre-Attack Effect | | WIDTH=50″),””)]
[h: MissEffectInputString=if(MissEffectIncluded==1,encode(“MissEffect | . | Miss Effect | | WIDTH=50″),””)]
[h: AftereffectInputString=if(AftereffectIncluded==1,encode(“Aftereffect | . | Aftereffect | | WIDTH=50″),””)]
[h: PostAttackEffectInputString=if(PostAttackEffectIncluded==1,encode(“PostAttackEffect | . | Post-attack effect | | WIDTH=50″),””)]
[h: SpecialEffectInputString=if(SpecialEffectIncluded==1,encode(“SpecialEffect | . | Special Effect | | WIDTH=50″),””)]

All of these things could be suppressed if the power in question doesn’t need them. I’ve tried to present them as intuitively as possible. I only ask for the damage level if there’s a damage roll (and the default selection was set up above). I ask if this power should have a little extra on the attack roll (like for a ranged artillery attack). If this power is just an effect (no attack, no damage – like a trait), then I ask for that. And so on.

Now it’s time to actually generate the input box that will ask for this stuff:

[h: x = input(
decode(RechargeTargetInputString),
decode(RequirementInputString),
decode(TriggerInputString),
decode(PreAttackEffectInputString),
decode(ExtraAttackBonusInputString),
decode(DefenseInputString),
decode(DamageRollInputString),
decode(EnhancementInputString),
decode(HitStringInputString),
decode(MissEffectInputString),
decode(AftereffectInputString),
decode(PostAttackEffectInputString),
decode(SpecialEffectInputString),
decode(JustEffectInputString)
)]
[h: abort(x)]

Yep – it’s all just a bunch of decoding of the stuff above. If the conditions are right, there will be an item in the input box. If not, the item will be skipped. For instance:

This is what I get if I pick a triggered recharge power with all of the check boxes checked. Conversely:

This is what I get if I choose the default options (single target at-will power with an attack and damage roll). And for the extreme simplicity case:

This is what I get if I pick a power with no targets, no attack roll, no damage roll and no boxes checked. It’s a pure text power – just an effect. Most move actions and traits will be this way, for instance.

Building the macro command

At this point, we have a lot of input from the user saved as variables. Now it’s time to use those variables and turn it all into command text for our new macro.

[h, switch(DamageLevel), code:
case “Minion”: {
[h: NumDice=0]
[h: DieSize=”MinionDamage”]
[h: DamageBonus=”MinionDamage”]
[h: Enh=1]
[h: CritDamageDie=”MinionDamage”]
};
case “Very Low”: {
[h: NumDice=”NumDice50″]
[h: DieSize=”DamageDie50″]
[h: DamageBonus=”DamageBonus50″]
[h: Enh=Enhancement]
[h: CritDamageDie=”DamageDie50″]
};
case “Low”: {
[h: NumDice=”NumDice75″]
[h: DieSize=”DamageDie75″]
[h: DamageBonus=”DamageBonus75″]
[h: Enh=Enhancement]
[h: CritDamageDie=”DamageDie75″]
};
case “Normal”: {
[h: NumDice=”NumDice100″]
[h: DieSize=”DamageDie100″]
[h: DamageBonus=”DamageBonus100″]
[h: Enh=Enhancement]
[h: CritDamageDie=”DamageDie100″]
};
case “High”: {
[h: NumDice=”NumDice125″]
[h: DieSize=”DamageDie125″]
[h: DamageBonus=”DamageBonus125″]
[h: Enh=Enhancement]
[h: CritDamageDie=”DamageDie125″]
};
case “Very High”: {
[h: NumDice=”NumDice150″]
[h: DieSize=”DamageDie150″]
[h: DamageBonus=”DamageBonus150″]
[h: Enh=Enhancement*2]
[h: CritDamageDie=”DamageDie150″]
};
case “Extreme”: {
[h: NumDice=”NumDice175″]
[h: DieSize=”DamageDie175″]
[h: DamageBonus=”DamageBonus175″]
[h: Enh=Enhancement*2]
[h: CritDamageDie=”DamageDie175″]
}
]

This rather inelegant piece of code does something simple in the end. It takes the indication of the damage level (from Minion to Very Low all the way up to Extreme) and sets some text variables that will show up in the final macro. I have properties in my campaign for number of dice, damage die size and damage bonus that are derived from a monster’s level. I also have tweaks from the 100% “normal” damage expressions to have 50% versions, 75%, 125%, 150% and 175%. That’s all I’m doing here – getting ready to tell the final macro what damage level to pull from the monster’s properties.

[h: AttackBonus=if(DefenseTargeted==’AC’,’DefaultAttackBonusVsAC’,’DefaultAttackBonusVsNAD’)]

This is a simple one. I have two monster properties for attack bonuses: One versus AC and one versus non-AC defenses (which is two points lower). I’m just telling the macro which one to use.

[h: MyCommand=””]
[h: MyCommand=MyCommand+encode(“<b>” + MacroName + “</b> ” + TargetRange + “<br>\\n”)]

As you saw in my last post, this is the way I build the “command” property that I’m setting for the new macro. I’m just adding the name and range at this point. The \\n at the end enters a new line (carriage return) in the macro itself, not in the output.

[h, if(RequirementIncluded==1): MyCommand=MyCommand+encode(“<i>Requirement:</i> “+Requirement+”<br>\\n”)]
[h, if(ActionType==”6. Triggered Actions”): MyCommand=MyCommand+encode(“<i>Trigger:</i> “+Trigger+”<br>\\n”)]
[h, if(PreAttackEffectIncluded==1): MyCommand=MyCommand+encode(“<i>Effect:</i> “+PreAttackEffect+”<br>\\n”)]

Here I add lines for Requirement, Trigger and Effect before the attack in the case that those exist for this power.

[h, if(AttackRollRequired==1), CODE: {
[h: MyCommand=MyCommand+encode(“[h: AttackBonus=” + AttackBonus + ” + ” + ExtraAttackBonus + “]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: Defense='”+DefenseTargeted+”‘]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: d20roll=d20]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: Enh=”+Enh+”]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: CritDamageDie=”+CritDamageDie+”]\\n\\n”)]
[h: MyCommand=MyCommand+encode(“[h, if(CritDamageDie > 0), CODE:\\n { [CritBonus=roll(Enh,CritDamageDie)] }; \\n { [CritBonus=0] }\\n ]\\n\\n”)]
[h: MyCommand=MyCommand+encode(“[h: AttackRoll=d20roll+AttackBonus]\\n”)]
}
]

These lines are only added to the macro if there’s an attack roll. The macro will have the attack bonus, the defense targeted, the result of a d20 roll, etc.

[h, if(DamageRollRequired==1), CODE: {
[h: MyCommand=MyCommand+encode(“[h: DamageString='”+HitStringWithDamage+”‘]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: NumDice=”+NumDice+”]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: DamageDie=”+DieSize+”]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: DamageBonus=”+DamageBonus+”]\\n\\n”)]
[h: MyCommand=MyCommand+encode(“[h: DamageRoll=roll(NumDice,DamageDie)]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: NumDice=”+NumDice+”]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: MaxDamage=NumDice*DamageDie+DamageBonus+CritBonus]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: RegularDamage=DamageRoll+DamageBonus]\\n\\n”)]
}
]

These lines only show up if there’s a damage roll. Pretty standard stuff.

[h, if(NumberOfTargets==”Single-Target” && AttackRollRequired==1), CODE: {
[h: MyCommand=MyCommand+encode(“<i>Attack:</i> [d20roll] + [AttackBonus] = <b>[AttackRoll]</b> versus [Defense]<br>\\n”)]
[h, if(DamageRollRequired==1), CODE: {
[h: MyCommand=MyCommand+encode(“[if(d20roll==20), CODE:\\n”)]
[h: MyCommand=MyCommand+encode(” {<font color=red>–CRITICAL HIT–</font><br>\\n”)]
[h: MyCommand=MyCommand+encode(” <i>Hit:</i> [NumDice*DamageDie] ([NumDice]d[DamageDie]) + [DamageBonus] + [CritBonus] = <b>[MaxDamage]</b> [DamageString]<br>\\n”)]
[h: MyCommand=MyCommand+encode(” };\\n”)]
[h: MyCommand=MyCommand+encode(” {<i>Hit:</i> [DamageRoll] ([NumDice]d[DamageDie]) + [DamageBonus] = <b>[RegularDamage]</b> [DamageString]<br>}\\n”)]
[h: MyCommand=MyCommand+encode(“]\\n”)]
};
{[h: MyCommand=MyCommand+encode(“<i>Hit:</i> “+HitStringNoDamage+”\\n”)]
}
]
};{}
]

And now we have the “punch line” part of the code for the single-target attack case. This part of the code displays the result of the attack and damage rolls in the chat window.

[h, if(NumberOfTargets==”Multi-Target” && AttackRollRequired==1), CODE: {
[h: MyCommand=MyCommand+encode(“[h: x=input(‘NumberOfTargets|0|Number of targets’)]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: abort(x)]\\n\\n”)]
[h: MyCommand=MyCommand+encode(“Attacking [NumberOfTargets] [if(NumberOfTargets==1,’target’,’targets’)].<br>\\n”)]
[h: MyCommand=MyCommand+encode(“[count(NumberOfTargets,'<br>’), CODE: {\\n”)]
[h: MyCommand=MyCommand+encode(” [h: d20roll=d20]\\n”)]
[h: MyCommand=MyCommand+encode(” [h: AttackRoll=d20roll+AttackBonus]\\n”)]
[h: MyCommand=MyCommand+encode(” <i>Target [r:roll.count+1]:</i> [d20roll] + [AttackBonus] = <b>[AttackRoll]</b> versus [Defense]\\n”)]
[h, if(DamageRollRequired==1), CODE: {
[h: MyCommand=MyCommand+encode(” [if(d20roll==20), CODE: {<font color=Red> –CRITICAL HIT–</font> [NumDice*DamageDie] ([NumDice]d[DamageDie]) + [DamageBonus] + [CritBonus] = <b>[MaxDamage]</b> [DamageString]};{} ]\\n”)]
[h: MyCommand=MyCommand+encode(” }\\n”)]
[h: MyCommand=MyCommand+encode(“]<br><br>\\n”)]
[h: MyCommand=MyCommand+encode(“<i>Hit:</i> [DamageRoll] ([NumDice]d[DamageDie]) + [DamageBonus] = <b>[RegularDamage]</b> [DamageString]<br>\\n”)]
};
{[h: MyCommand=MyCommand+encode(“<i>Hit:</i> “+HitStringNoDamage+”\\n”)]
}
]
}
]

Same thing, but for the multi-attack case.

[h, if(AttackRollRequired==0&&DamageRollRequired==1): MyCommand=MyCommand+encode(“<i>Hit:</i> [DamageRoll] ([NumDice]d[DamageDie]) + [DamageBonus] = <b>[RegularDamage]</b> [DamageString]<br>}\\n”)]

In the odd case where you have no attack roll but a damage roll (such as an auto-hit power that still rolls for damage), we need to display the appropriate string.

[h, if(MissEffectIncluded==1): MyCommand=MyCommand+encode(“<i>Miss:</i> “+MissEffect+”<br>\\n”)]
[h, if(AftereffectIncluded==1): MyCommand=MyCommand+encode(“<i>Aftereffect:</i> “+Aftereffect+”<br>\\n”)]
[h, if(PostAttackEffectIncluded==1): MyCommand=MyCommand+encode(“<i>Effect:</i> “+PostAttackEffect+”<br>\\n”)]
[h, if(SpecialEffectIncluded==1): MyCommand=MyCommand+encode(“<i>Special:</i> “+SpecialEffect+”<br>\\n”)]
[h, if(AttackRollRequired==0): MyCommand=MyCommand+encode(“<i>Effect:</i> “+JustEffect+”<br>\\n”)]

We now display the extra lines if they were included. Note that JustEffect is only displayed in the “no attack roll” case.

[h: FontColor=”green”]

Setting another default here; my at-will powers default to green,

[h, if(Usage==”Encounter”), CODE: {
[h: EncountersArray=getProperty(“EncounterPowersDeclared”)]
[h: FirstEmptyEncounter=-1]
[h, for(i, 9, -1, -1), CODE:
{[h: PowerCheck=json.get(EncountersArray,i)]
[h, if(PowerCheck==0): EncounterPowerNumber=i]
}
]
[h: FontColor=”red”]
[h: NewArray=json.set(EncountersArray, EncounterPowerNumber, 1)]
[h: setProperty(“EncounterPowersDeclared”, NewArray)]
[h: MyCommand=MyCommand+encode(“[h: PowerNumber=”+EncounterPowerNumber+”]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: PowersCharged=getProperty(‘EncounterPowersCharged’)]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: IsPowerAvailable=json.get(PowersCharged,PowerNumber)]\\n\\n”)]
[h: MyCommand=MyCommand+encode(“[h, if(IsPowerAvailable==0), CODE:\\n”)]
[h: MyCommand=MyCommand+encode(” {[assert(1==0,add(‘This power has already been expended.’),0)]};\\n”)]
[h: MyCommand=MyCommand+encode(” {[h: NewArray=json.set(PowersCharged,PowerNumber,0)]\\n”)]
[h: MyCommand=MyCommand+encode(” [h: setProperty(‘EncounterPowersCharged’, NewArray)]}]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: setMacroProps(getMacroButtonIndex(), ‘color=darkgray’) ]”)]
}
]

All right, this is admittedly a complicated piece of code. I’m proud of it, but you’ll have to bear with me.

The first line sets up that we’re only doing the remaining lines for Encounter powers. We then fetch the EncounterPowersDeclared array that I described earlier. This is the one that starts off as ten zeroes.

We then start with the last element of the array (element nine, since MapTool starts counting from zero) and check to see if that last element is a zero. If so, we set EncounterPowerNumber equal to the element number (9).

We then repeat with the next-to-last element of the array (item 8) and check to see if IT is zero. If so, we overwrite EncounterPowerNumber with 8. We keep going through the first element in the array (item 0). Whatever the last non-zero element of the array is, that becomes our new EncounterPowerNumber. And you’ll note that the FOR loop goes to -1 because it doesn’t execute an iteration where the iterator equals the end point. Yeah, it’s weird.

From here, we set the font color of the macro button to red (for an encounter power) and then set the token’s EncounterPowersDeclared array to put a 1 instead of a 0 in this new macro’s spot in the array.

I finish by adding the appropriate new lines to the macro I’m creating. These check to see if the appropriate slot in the array still has the power charged. If so, it de-charges it and moves on. If not, it throws off an error message, saying that the power is already expended.

[h, if(Usage==”Recharge”), CODE: {
[h: RechargeArray=getProperty(“RechargePowersDeclared”)]
[h: FirstEmptyRecharge=-1]
[h, for(i, 9, -1, -1), CODE:
{[h: PowerCheck=json.get(RechargeArray,i)]
[h, if(PowerCheck==0): RechargePowerNumber=i]
}
]
[h: FontColor=”purple”]
[h: NewArray=json.set(RechargeArray, RechargePowerNumber, 1)]
[h: setProperty(“RechargePowersDeclared”, NewArray)]
[h: MyCommand=MyCommand+encode(“[h: RechargeTarget=”+RechargeTarget+”]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: RechargeRoll=d6]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: PowerNumber=”+RechargePowerNumber+”]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: PowersCharged=getProperty(‘RechargePowersCharged’)]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: IsPowerAvailable=json.get(PowersCharged,PowerNumber)]\\n\\n”)]
[h: MyCommand=MyCommand+encode(“[h, if(IsPowerAvailable==0 && RechargeRoll<RechargeTarget), CODE:\\n”)]
[h: MyCommand=MyCommand+encode(” {[g: assert(1==0,add(‘Recharge roll = ‘, RechargeRoll, ‘. The power fails to recharge.’),0)]};\\n”)]
[h: MyCommand=MyCommand+encode(” {[h: NewArray=json.set(PowersCharged,PowerNumber,0)]\\n”)]
[h: MyCommand=MyCommand+encode(” [h: setProperty(‘RechargePowersCharged’, NewArray)]}]\\n”)]
[h: MyCommand=MyCommand+encode(“[h: setMacroProps(getMacroButtonIndex(), ‘color=gray’) ]”)]
}
]

This is the same kind of thing, but for recharge powers. The button font is purple instead of red. And when it comes time in-macro to see if the power has been expended, there’s also a recharge roll made. If the roll succeeds, then the power proceeds.

[h, if(Usage==”Not Applicable”): FontColor=”black”]

If we’re talking about a trait rather than an at-will or encounter or recharge power, then the button text should be black.

[h: MacroProps='{“autoexecute”:1, “label”:”‘+MacroName+” “+TargetRange+'”, “group”:”‘+ActionType+'”, “sortBy”:’+SortOrder+’, “fontColor”:”‘+FontColor+'”, “command”:”‘+decode(MyCommand)+'”}’]
[h: createMacro(MacroProps)]

And at long last, we actually build the macro! We stick together the JSON object that contains all of the macro properties, including decoding the MyCommand string that we’ve been building for the past 150 lines of code, and we then create a macro with those properties!

Whew – I need a drink or something.

I’m happy to say that this thing works really, really well for me so far. I’m sure I’ll tweak it over time, but I’m excited about it.

Congratulations if you’ve made it this far!

– Michael the OnlineDM

MapTool – Creating macros from macros, plus encode and decode

MapTool macros can apparently do just about anything, including BUILDING OTHER MACROS! They’re like nanobots; they’re going to take over the world with an army of macros. Save yourselves from the coming macro revolution!

Or take advantage of it by leveraging the power of MapTool macros to build other macros. Why might you want to do such a thing? Well, in my case it’s because I wanted a better way to build monster powers. My previous approach was to have template buttons for every type of macro I might want on a monster, and then delete the buttons I don’t need. That’s a pain in the butt; it would be much easier to just add the macros I need instead of deleting the macros I don’t need.

Thus, I learned about the createMacro() function. This is one of those “exactly what is says on the tin” macros – it creates another macro. I’d say that this is definitely an intermediate to advanced MapTool topic, at least by my standards. You’ll want to have a working knowledge of JSON objects before using createMacro.

Setting up the createMacro input JSON object

The arguments for createMacro are most easily put together in a JSON object. You can set pretty much anything you can think of for a macro button – its name, the colors of the text and background, what group you want it in, what sort order, whether players can edit it and so on. To do this, set up a JSON object with each of these properties set to the value you want.

For instance, let’s say that you want a macro called Longsword to show up in the Attacks group as the 3rd macro, and you want it to have green text. First, set up the JSON object with these properties:

[h: MacroProps='{“autoexecute”:1, “label”:”Longsword”, “group”:”Attacks”, “sortBy”:3, “fontColor”:”green”, “command”:””}’]

Then run the createMacro function with your new properties as the argument:

[h: createMacro(MacroProps)]

Voila! Problem solved. Well, that was a short article…

Oh right – we need some macro text to carry out, don’t we? This particular set of properties has no real instructions to carry out (that’s what “command”:”” means – a blank macro command box). If we’re going to be putting together strings that include macro instructions, we’re going to need to learn about encode() and decode().

encode() and decode()

The encode() function lets you create a string that contains quotes and brackets and so on. You’ll obviously need this sort of thing in your macro command, so it makes sense to encode the various lines of macro text, stick them together in a string list, and plop that into the “command” property of your JSON for createMacro. A useful trick I learned is that if you’re encoding a line break, you have to use \\n to represent it (for “new line”).

I don’t believe encode() is strictly necessary in all of these cases, but it’s getting the job done and I’m sticking with it!

When you’re ready to unpack what you’ve encoded, you can use decode().

A simple example

Let’s say I want to use a macro to create another macro that will roll a die and output the result with a little formatting and a friendly message. I’m going to call the created macro “New Macro 1”. I want it to roll a d6. And I’m going to pass my choice of a d6 to the macro as a variable.

[h: MacroName=”New Macro 1″]
[h: DieSize=6]

Here I’ve set a variable for the name of the macro and another for the die size that I want to roll. Now I’m going to start setting up the “command” text to pass to the createMacro() function.

[h: MyCommand=””]
[h: MyCommand=MyCommand+encode(“[h: DieToRoll=”+DieSize+”]\\n”)]

The first line above initializes a blank string as the variable MyCommand (not strictly necessary, but it helps me follow what’s going on). The second line takes whatever is in MyCommand (a blank string at this point) and adds some encoded text to it.

You’ll note that the text I’m encoding is in double-quotes, and when I want to add the value of my DieSize variable I close the quotes, add a plus sign, then the name of the variable that I want to be evaluted, then another plus sign and re-open the quotes. Note also that I’m encoding a full line of MapTool text, including square brackets, the h: roll option, and the \\n for a line break in the code itself (as opposed to <br>, which would output a line break to the chat window).

[h: MyCommand=MyCommand+encode(“Die Result = <b>[r: roll(1, DieToRoll)]</b> – Good job!”)]

I now add another line of code to the command sting I’m building up. This one is a full line of MapTool code within double quotes – no breaks to bring in variables from this macro, but there is a reference to a variable that exists in the new macro (DieToRoll).

[h: MacroProps='{“autoexecute”:1, “label”:”‘ + MacroName + ‘”, “fontColor”:”green”, “command”:”‘ + decode(MyCommand) + ‘”}’]
[h: createMacro(MacroProps)]

I now build the JSON object that I’ll be using for createMacro. I do want the macro to auto-execute, so I set that property to 1 (true). I’m calling on my MacroName variable for the name. And I’m decoding the MyCommand string as the command text for the new macro.

When I run the macro, I get a new button, labeled “New Macro 1” in green text. If I open up that macro to edit it, I see:

[h: DieToRoll=6]
Die Result = <b>[r: roll(1, DieToRoll)]</b> – Good job!

And when I execute New Macro 1, I get a message in the chat window:

Voila – a macro created from a macro!

Now what?

This is a proof-of-concept: You can indeed create a working macro using a macro. But what I really want to do is to create a macro that will ask me for input, and then use that input to create another macro. For instance, a macro that will ask me for the name of an attack, the damage, whether it’s at-will or encounter or recharge, etc., and then build a new power for a monster with those characteristics.

That, my friends, is the topic of my next post. I have built such a thing, and it is wondrous to behold!

Stay tuned.

-Michael the OnlineDM

Marvel Heroic RPG – MapTool Framework – Second Draft

The blog post about my first draft can be found here. You can download the new framework right here!

Over the weekend, I had some time to improve my MapTool framework for the Marvel Heroic Roleplaying game. @MattHawke provided the key assistance: He showed me how to use custom frames to create a very, very useful character sheet.

Frames in MapTool include the Selection frame (which holds the buttons with various macros for each token), the Chat frame (which shows the output of the chat window and macros), and the Campaign frame (which holds macros common to everyone in the campaign). You can also create your own frame to hold whatever you want.

The syntax for doing this is surprisingly simple: You just use the frame roll option, followed by the name you want to give this new frame (held inside quotation marks inside parentheses). You then fill up your new frame, largely using HTML. Since I wanted to create a frame called DataFile (the Marvel RPG name for a character sheet), I used the following code:

[frame("DataFile") : {

From there, I used a bunch of HTML to fill the frame:

<html>
 <head>
 <title>[r:getProperty("Name", MyToken)] ([r: getProperty("RealName", MyToken)])</title>
 </head>
<body>

The other awesome MapTool function that @MattHawke showed me is the macroLink function. This lets you create a link to a macro within your HTML frame. The macroLink function lets you provide the linked text, the function that’s linked to, and the people to whom the output of the function should be displayed.

This allowed me to make the DataFile frame into the entire character interface. My goal is to make it so that players will never have to use the Selection window except at the very beginning of the session, to open the DataFile frame. After that, all of the stuff they can do can be done via links in the Data File itself.

I also decided it would make my life easier if I created a library token to hold all of the macros, and then simply call those macros from the Data File.

I know that other MapTool frameworks already do a lot of cool stuff with custom frames; I never really understood them until now. This is a much better way to use a character sheet, rather than looking at the pop-up window that MapTool uses by default. I’d love to re-work my D&D 4e framework to take advantage of this, but man, that would be a lot of work at this point! For now, the Marvel RPG fans are the ones who will benefit.

Please check out this updated framework. It’s light-years better than what I started with in the first draft. Feedback is invited!

– Note that you’ll need to set your stack size in MapTool to at least 4 in order for this framework to work properly. I personally set mine to 10. This is an option in the pop-up window that opens when MapTool first starts. The default stack size of 2 doesn’t cut it.

– Michael the Online Dungeon Master

Marvel Heroic RPG – MapTool framework – First draft

Among the big, exciting news in the world of role-playing games this past month was the release of the Marvel Heroic Roleplaying Game from Margaret Weis Productions. Cam Banks (@boymonster on Twitter) was the design lead, and by all accounts he and his team had done a fantastic job with the game.

I’m not a comic book guy myself, so I wasn’t really planning to do anything with the game. However, I was asked by a couple of folks on Twitter (@MattHawke and @SenatorChatty) if I would be willing to put together a Marvel RPG framework in MapTool so that they and others could play the game online.

Hmm, intriguing! This is the closest I’ve come so far to doing “commission work” in role playing games (although I’m not getting paid or anything like that).

One stumbling block was that I did not own the PDF for this exciting new game. Now, it was only $12.99 on Drive Through RPG at the moment (now marked down to $9.74 for DM’s Day through March 7), but still. If I wasn’t going to play the game myself, I didn’t really want to have to pay money to do commission work.

Inspiration struck, though: Why not ask the game’s creator if he’d like me to put this together as a service to the online Marvel RPG community, and in exchange he could provide me with a copy of the PDF. Brilliant! Cam, being the awesome guy that he is, agreed.

And thus, the OnlineDM framework for the Marvel Heroic Roleplaying Game was born. You can download it right here.

How does it work?

I’m calling this particular version 0.11. It’s not at all polished yet, but it does work. Some instructions:

– The framework was created in version 1.3.b86 of MapTool, but it should work in any later version, too.

– There are three tokens: One for a hero (which can also be used for villains), one for The Watcher, and one for the Scene.

– The Hero token has all kinds of properties that will pop-up on a mouse-over; the Watcher and Scene are more limited, naturally.

– To build a Hero token, click the Build Character macro on the token itself and enter the various characteristics

– To build a dice pool, either click the Build Dice Pool macro or click the individual add/remove dice buttons

– To roll the dice pool or clear it, click the button labeled as such

– There are buttons to add and remove plot points from tokens (or from selected tokens if the Watcher wants to award them from the campaign panel)

– There are also buttons to set Stress, Trauma, Assets and Complications

Click to enlarge to see the framework's features in action

Room for improvement

Admittedly, this is not very pretty yet, and there are things I’d definitely like to tweak.

– Following a suggestion from @MattHawke, I’d like to use a custom frame instead of the pop-up character sheet to hold all of these properties. It really needs more formatting.

– In the dice pool building macro, I’d like to have drop-downs to pick the actual Distinctions and Powers and so on, rather than just typing in a number of dice

– And I’m sure that play-testing will reveal lots of things that need improvement!

Still, this version should be functional for play. All you really need are the dice pool and doom pool macros.

So, try out the new game and try out my framework – and let me know what suggestions you have for improvements!

– Note that you’ll need to set your stack size in MapTool to at least 4 in order for this framework to work properly. I personally set mine to 10. This is an option in the pop-up window that opens when MapTool first starts. The default stack size of 2 doesn’t cut it.

– Michael the OnlineDM

Dragons and tentacles and flying sleds – oh my!

I don’t write about my long-running Friday night War of the Burning Sky online game nearly enough. It’s time to correct that.

Spoilers ahead for EN World’s War of the Burning Sky campaign – specifically, the end of Adventure Six.

This past Friday night, I gathered via MapTool and Skype with my group for our regular D&D game. The party was at 18th level, and they found themselves high up  in a castle with a raging firestorm above it (which they had held back with a magic item). The top level of this castle contained a rift to a fiery plane. They were here in search of a powerful magical torch.

“Katy, bar the door!”

During the last session, the party had fought a legion of fiery undead soldiers and explored the rest of the top level of this castle, which was reachable only via a hydraulic lift. As this session began, they had finished most of their exploration, when they heard the lift start to rise. The wizard/swordmage decided to cast Arcane Lock on the elevator door. It takes 10 minutes to cast. Uh oh!

So, I began by asking everyone what they were doing while the wizard/swordmage was casting her ritual. Some were standing guard near her, while others were loading treasure and people into this magical flying sled they had discovered. At this point, a little halfling NPC who had seemed rather dumb for the whole adventure popped into the room through a wall and started animating a dragon skeleton. And wouldn’t you know it, the whole “dumb little halfling” look was an illusion; the creature revealed itself to be a tentacled monster called Deception (a trillith).

Let’s roll initiative!

The fight began with most of the party in or near the cart in the room with the Dark Pyre, while a couple of them were through the banquet hall and down the hallway leading to the elevator doors. The animated dragon and the tentacle monster rather neatly cut the party in half.

Now, keep in mind that most of the party was entirely out of healing surges at this point, with no significant daily powers left. Their goal was escdape: Use the magical flying sled to burst through a window-wall in the Dark Pyre room and fly to safety, all before whatever ba guys were in the elevator made it to the top.

Our brave dwarf fighter threw himself at the dragon to try to keep it at bay to give the cut-off characters a chance to get to the sled. Unfortunately, the tentacle monster phased through some walls and started dominating the swordmage.

I used the house-ruled version of Dominated in this game that I’ve been playing with for a few weeks (with great results in my opinion:

OnlineDM’s Domination

  • When a character becomes dominated (save ends), it immediately takes an at-will action of the dominator’s choice (including a charge, a move, dropping to the ground – or of course an at-will attack power).
  • The character is dazed. On its turn, it gets to take one action of its own choice, just as with a normal daze.
  • Whenever the character fails its end-of-turn saving throw against the domination, it immediate takes an at-will action of the dominator’s choice.
  • If the domination is not “save ends”, then the dominated character immediately takes the at-will action and then is just dazed until the domination wears off.
This way, the dominated character still gets to do some good stuff on their own turn, but they’re also potentially wrecking their allies at the same time (which, you know, is fun). It worked out really well, in my opinion.

“I teleport out the window!”

Anyway, after some near-blinding of the bad guys, the party made its way to the cart, with the dragon and Deception hot on their heels. The dragon’s breath weapon then tried to dominate a whole bunch of folks, including our genasi pyromancer. As a free action, he used a power that would remove him from play and let him reappear within 10 squares at the beginning of his turn – still dominated. He reappeared OUTSIDE the big window that the sled was going to smash through; this left him 100 feet off the ground, above an invading, hostile army.

He used his one action (since he was dazed, thanks to my domination) to swap in Feather Fall, which saved him from death, but put him on the giant bear skull sculpture above the castle entrance. Some of the army members were eladrin, who teleported up onto the skull with him. The pyromancer quickly surrendered, realizing he was in a bad spot.

Meanwhile, back up in the castle, the party expended tremendous effort to get the warlock’s hell hound pet out of the clutches of the tentacled Deception and into the sled. The swordmage/wizard Thunderwaved the monsters away and the dwarf rushed out of the cart, hauled the hound onto his shoulders (burning himself in the process) and rushed back in.

Our warlock hit the gas on the magical flying sled and smashed through the window-wall. Whee!

Someone asked, “Hey, does smashing through the wall cause rubble to fall down on the eladrin who’ve captured our pyromancer?”

Excellent idea! The rubble hit the pyromancer as well, and the sled spiraled down to a stop next to the captive. Some fast talking by the swordmage convinced the eladrin to hand over the badly-wounded genasi.

“Not without my wyvern!”

Only one problem remained: The party had left the dwarf’s wyvern mount tied up outside the castle when they came in, and poor Wendy was now trapped in a cage by the army. I decided this army was cruel, so I had a half-orc deal a killing blow to the wyvern, right in plain sight.

The PCs asked if they could fly the sled so that it would smash into the half-orc – oh heck yes! The evil soldier went flying off the edge of the cliff on which the castle was situated, plummeting to his death 1,000 feet below.

 

With the dragon in pursuit, it seemed clear that it was time to take off and fly away… but our fighter couldn’t just leave his poor mount’s corpse to the evil invaders, so he grabbed onto the cage.

“Where did that thing come from?”

No problem! But now the sled was flying at half speed, and the dragon was gaining on them. To make matters worse, it turned out that the tentacle monster had used a power when the sled was back in the castle that let him invisibly teleport into their midst on the sled, leaving an illusory duplicate of himself behind. And now that the sled was flying away with a huge cage full of wyvern body dangling behind it, a bunch of tentacles came out of nowhere and started grabbing the party.

Our swordmage decided to turn once again to Thunderwave, shoving the tentacled beast out of the sled – but oh crap, that thing can fly!

There was only one thing to do, with the tentacled Deception bearing down and the dragon coming on from a distance: Our fighter tossed the wyvern cage at Deception, sending the thing plummeting to its doom.

No longer weighed down by the cage, the sled was able to fly away (with our warlock keeping her pet outside of the sled itself so that it didn’t burn the whole party to death), seeking safety, an extended rest, and a level up to 19.

Whew! Have I mentioned that my players are awesome? Thanks everyone!

-Michael the OnlineDM

Interview with OnlineDM on Skyland Games

Here’s something fun: I was interviewed on another blog!

Thorynn over at Skyland Games reached out to me for an interview about online gaming. I thought he asked some great questions, and I enjoyed answering them.

 

Gee, I feel like such a celebrity now. <blushing>

-Michael the OnlineDM

Genghis Con 2012 Recap

As I sit down to write this post Monday morning, I’m exhausted and happy for the past three-plus days I spent over the weekend at Genghis Con 2012. The Denver Gamers Association puts on two conventions each year: Genghis Con over Presidents’ Day weekend, and TactiCon over Labor Day weekend. I think they’re very smart in having each convention begin Thursday night and end Sunday evening, with Monday off for all of us to recover before we have to go back to our day jobs on Tuesday after the holiday.

Last TactiCon, I decided to be a Marathon GM and run games in all nine time slots (Thursday evening; Friday morning, afternoon and evening; Saturday morning, afternoon and evening, and finally Sunday morning and afternoon). For Genghis this year, I decided I wanted to run just three sessions (of games I’d written myself) and then play the rest of the time. I signed up for two specific games to play in – a Dresden Files game and a Hero System game based on Dr. Horrible’s Sing Along Blog. I wanted to keep my options open for the rest of the time.

I received an email a few weeks before the convention that the Dr. Horrible game was canceled. Oh well. Then I got an email two weeks ago letting me know that the person who was supposed to have been coordinating the D&D 4th Edition games at the convention (mainly Living Forgotten Realms) had gone incommunicado, and lots of games needed DMs. I was asked to help out.

So, I went from running three slots to running seven. Seven slots, seven different games. Two of them were Ashes of Athas, and I knew next to nothing about Dark Sun. Two were paragon tier LFR games (one of which, thankfully, I had run before and so already had prepared in MapTool). A couple of weeks of frantic prep work followed, including taking last Thursday off work to get ready. And then away we go!

Thursday

I got to the convention at the Red Lion Hotel around 6:00 PM to pick up my badge. The awesome RPG coordinator had arranged for me to get a refund for the sessions I had originally signed up to play in but was now running instead. You rock, Linda!

This was one of the two times in the convention when I was a player rather than a DM. I jumped into an LFR game that could be run for characters of levels 1-10, but the table has to agree on a four-level band. I really wanted to play Factotum, my beloved bard, who was fifth level. Unfortunately, there were a couple of other players who really wanted to play their 9th and 10th level characters. And thus I turned to Rhogar, my first-ever LFR character – a half-elf paladin of Ilmater. I hadn’t played him since Genghis Con 2011.

The adventure itself was set in Elturgard, and I should have known better. Rhogar’s last adventure was the Paladins’ Plague adventure in Elturgard, and I ended up having the least fun ever with that adventure. This adventure was somewhat similar, in that it was a very dark adventure with some no-win plot choices at the end. I left feeling victorious in the adventure, but kind of bummed out at the same time.

Friday

Friday was the day I was originally scheduled to run games, and I brought my projector rig on down to the convention. I was running the Staff of Suha trilogy (The Stolen Staff, Tallinn’s Tower and Descent Into Darkness). This was the second convention in a row where I’d run all three games, and I was excited to see that I had three players who would be involved in all three games and everyone else would be involved in two of the three. A fun twist in this particular series is that one of the players needed a fifth level character to play, and I offered to let him play Factotum the bard, which he totally ran with.

Things went pretty well in The Stolen Staff. I was happy that this party became the first to find the secret entrance to the orcs’ keep via the garbage pit, and the encounter down there was fun. It did take a long time to get to that point, though, so I ruled on the fly that the secret entrance let the party bypass most of the skill challenge through the stronghold. The fight in the orc temple was also cool, as this party was the first to let the orc shaman live more than a couple of rounds, which made the other orcs much more deadly. The fight against the orc leader in the end was only so-so; I still need to work on making him more interesting.

Tallinn’s Tower went smoothly enough, with the party eventually figuring out how the puzzle on the first floor worked, and then disabling the trap on the second floor very quickly, which made that fight much easier. The third floor got a little bit brutal, but the party whomped on the leader in time to prevent folks from turning to stone. Barely.

Descent Into Darkness went just okay, I’d say. The party solved the rune puzzle quickly, but not so quickly as to be trivial. They were a little bit tempted by the decoy sword but moved on before getting into too much trouble. They also took more of a negotiation approach with the halflings before Factotum decided to attack. That battle was more lethal than I intended it to be with the thieves; I need to tweak those guys. The climax fight against the beholder was a little anti-climactic, as the beholder got held in Bigby’s Icy Grasp and stayed there for three rounds. The party fought well, though, grabbed the Shield and got out of there, leaving the beholder alive (as most parties have done).

There was one player at the table who wasn’t having as much fun as the rest, and I tried and failed to get him more excited about the game. This was a bummer, as I like the guy, but he wasn’t having a great time. Oh well; I can’t blame anyone but myself, since I wrote the modules!

Saturday

Saturday was Ashes of Athas day. I had prepped my two sessions a couple of days before the convention and had thoroughly read one of them, but I had to finish reading the second during the hour-long break between sessions. I got there, though!

The Ashes of Athas modules are definitely more role-play heavy than most LFR modules, and that demands the right sort of players (and a prepared DM, which I just barely was). Fortunately, I had an awesome table. They were really into Dark Sun and spent way more time in-character than I’ve ever experienced before in D&D. I could tell that they really saw the various NPCs as actual characters, not just names and stat blocks. I felt successful when I realized that they truly hated one NPC, grokked another’s focus on the bottom line (her quote about profits being down 18% became a recurring bit), felt sympathy toward another, etc. The combats were only so-so, but I don’t think anyone cared – they loved the world. They were actually possessive of me as their DM, too; when we were talking about the possibility of players having to get moved around to other tables in the afternoon, they insisted that they get to keep me. That’s a good feeling!

Unfortunately for them, I was not running the final part of the Ashes of Athas trilogy in the evening; instead, I was playing a Dresden Files game. I’ve heard lots of great stuff about the game and wanted try it out. As it turns out, the GM was actually running a game using the Dresden Files rules in a different setting. The abbreviation for the setting is UA, and I thought the GM said this stood for “unearthed arcana” but that doesn’t seem right. Anyway, it was a setting with an occult subculture, and our characters were insiders of that culture.

Impressively, we did world creation, character tweaking, and a full adventure in the course of a three-hour session! As a party, we established three groups in Denver that had secret occult plans:

  • A biker gang in Cheeseman Park that was seeking an item called The Devil Rose in order to summon the devil to serve them
  • A group of metaphysical book shop owners who were focused on cleaning up the Cherry Creek Reservoir (where occult groups would dump bodies) and wanted to find the Cagliostro Seal, which would allow them to unleash nature and destroy civilization
  • A group of LGBT activists who maintained Elitch Gardens amusement park as occult neutral ground. Led by RuPaul, they were seeking the Alchemical Eye, which would give them full knowledge of all goings-on in the city

And we’re off! My character managed to get himself firebombed when he tried to chat up a book shop owner to warn her about the biker gang, but he only sprained an ankle. I learned how the Fate system works, doing some role playing to earn fate points. Getting to play NPCs and establish in-world facts as being true was a very cool mechanic. I don’t think I’d want to play a “story game” like this all the time, but it would be a fun change of pace now and then. I will note, however, that you need a DYNAMITE GM in order to make this work. The GM has to be able to make up all kinds of stuff on the fly, and our GM definitely did not disappoint. He rocked.

Sunday

For the final day of the convention, there were only two sessions, and I was running paragon-level LFR games for both of them. The first, CORE 2-2, is a game I had run before at Enchanted Grounds. I arrived just before the start time and discovered that the mount for my projector had popped off. I only needed a screwdriver to fix it, but I didn’t have one. Fortunately, one of my players was nice enough to go out to his car to get one, and the game went off without a hitch. That guy definitely was awarded a bonus point! (And writing this has reminded me to go put a screwdriver in my projector bag.)

My afternoon game had a great table of players, a number of whom I had DMed for at past conventions (in a couple of cases, with the same characters). This was NETH 3-3, and I have to say that this was WAY more fun than I expected it to be. I loved running this module. The players did some creative thinking during a skill challenge, and the combats were super-interesting and very well balanced. The party could have played at either level 12 or level 14, and they were ultimately happy they chose 12 (14 might have killed them).

My favorite moment of the convention came in this game, where a fighter decided he wanted to climb onto a table, make a running leap onto a bookshelf 10 feet away and then drop down the far side in order to attack an enemy. The jump was a masterful success, but since he wasn’t trained in Acrobatics, the fall down the far side of the shelf left him on his butt. And just to be a rat-bastard DM (to a player I know and like and whose character was plenty tough enough to take it), I ruled that the fall off the shelf involved the PC moving through a threatened square without shifting (falling from two squares up, next to a bad guy, down to the ground), which provoked an opportunity attack. We had some great laughs at this table, and it was good to end the convention on a high note.

After the sessions are done, the organizers always have an appreciation ceremony for the GMs, and I managed to pick up a free copy of Masks, a book of NPC ideas from Gnome Stew. Good stuff, and I can’t wait to use it!

And now I can stop my frantic convention prep work and relax. Ahhh!

-Michael the OnlineDM

Madness at Gardmore Abbey: Session Two

Earlier sessions: Session One

My party of three recovered from their run-in with giant spiders in the feygrove of Gardmore Abbey and continued making their way toward the orc village. Before long, they came upon a spring populated by a number of eladrin warriors. The leader of the eladrin ordered his soldiers to surround the party, which they did via teleportation. The leader demanded to know who they PCs were and what business they had here.

Homer the elf hunter (played by my brother-in-law) quickly explained that the PCs had been sent by Lord Padraig of Winterhaven to scout the orc threat, and they meant the eladrin no harm. Deciding that enemies of the orcs couldn’t be all bad, the eladrin leader introduced himself as Berrian Velfarren and invited the party to come to the spring to join him in a glass of high-quality feywine.

Berrian explained that he had come to the region of Gardmore Abbey in search of his father, but that the trail had gone cold. Making matters worse, his sister Analastra had gone off on her own and hadn’t reported back yet. Berrian said that he would appreciate help in locating her, which the party agreed to do. Berrian explained that he planned to stay by the spring, trying to understand more about its magical properties.

Stasi the half-elf warpriest (played by my sister-in-law) talked to Berrian and examined the fountain and determined that drinking from it could give visions of the history of the region. Only Homer the hunter was brave enough to take a sip, and he experienced a vision of a valorous knight of Bahamut defending himself against an onrushing horde of ten orcs, slaying them all in swift order and emerging victorious. This vision of heroism left Homer with the ability to get some extra minor actions in a future battle.

The party then left the Font of Ioun and moved toward the orc village, eventually coming upon the sounds of struggle in the woods ahead. An eladrin woman was fleeing from a pair of displacer beasts, and the beasts caught up to her and knocked her to the ground, unconscious, as the PCs entered the grove. A dire stirge emerged from a nearby ruined bell tower, and the party moved to attack. Thus began Encounter 11: Bell Tower.

Since there are only three PCs in my party, scaling the battles down is always a little bit tricky. I decided to let this one be a challenge, and I only removed one dire stirge instead of removing a displacer beast (or a displacer beast AND a dire stirge). All I can say is wow, displacer beasts sure are annoying to fight! Rolling a 17 or 19 on the attack die and finding out that you missed is a major bummer.

I scaled things a little bit on the fly. I had a stirge go after a bloodied displacer beast. I had a surge die when it was knocked down to about 10 hit points, and I did something similar with one of the displacer beasts. I was planning on having the other displacer beast flee when it was badly bloodied, but the PCs REALLY wanted to kill that thing (it did eventually escape with 9 hit points). The battle ended with Stasi unconscious (but stable) and Homer only on his feat because he got a 20 on a death save. Whew!

After the battle, the PCs were able to revive Analastra, the fallen eladrin. She thanked them, but was clearly embarrassed to have needed their help. She asked them to come with her to meet her brother, whom the PCs revealed they had already met.

Berrian was grateful to see his sister again, and thanked the party by asking what he could do for them. They mentioned that they wanted information about the orcs, and Berrian obliged by telling them what he knew. He also let the party rest in his grove while his soldiers stood guard and Analastra regained her strength (an extended rest – they needed it!).

In the morning, Analastra escorted the party to the garden hedge maze that marked the end of the feygrove, from which point the party could see much of the orc village for themselves. They also noted the wizard’s tower, and the fact that the keep seemed to be the headquarters for the orcs, based on the foot traffic in and out.

As the adventurers made their way back through the feygrove to head back to Winterhaven, Berrian gave Sora the dragonborn swordmage (played by my wife, and the only PC to have made it through the displacer beast encounter without falling unconscious) with a Giantslayer Broadsword +2. Yay for Mordenkainen’s Magnificent Emporium (the first time I’ve actually used the book).

Back in Winterhaven, the party settled in at Wrafton’s Inn and sent word to Lord Padraig that they were back and ready to report. Padraig came to see them in the inn, and they showed him the map of the orc village they had created with their notes about the strength of the orc troops. I asked the party if they were telling Padraig about the eladrin the feygrove, and they said no.

Padraig expressed dismay at the size of the orc force and said that he would need allies in order to chase off the orcs. Still no mention of the eladrin. He asked about the wooded area on the map. Still mention of the eladrin.

Shrug.

Padraig did at least note that the wizard’s tower the party had seen would probably be of interest to Valthrun the Prescient. He also paid the party some gold as a reward for their scouting report.

After Padraig left, the party was approached by a paladin in full-on shiny armor with the device of Bahamut prominently displayed. He introduced himself as Sir Oakley and said that he had heard that the party had been to Gardmore Abbey. He explained that he was a direct descendant of Gardrin the Hammer, founder of the Abbey, and that he wanted to cleanse the Abbey of evil and set it as a beacon of good in the world before he died.  Also, he knew of a secret stair that would lead straight to the top of Dragon’s Roost, bypassing the orcs. He asked the heroes to help him, and they readily agreed.

They stopped off to talk with Valthrun before leaving town the next day, and he was excited to hear about the tower. He’d been researching the Abbey in the week the party had been gone, and he asked them to be on the lookout for a book bound in white dragon scales, which his research indicated had been owned by the last wizard to use the tower before the fall of Gardmore Abbey.

Thus ends session two. I hadn’t put together the encounters on Dragon’s Roost in MapTool yet, so we had to cut things a little bit short. We should be able to play again before the end of 2012.

Next session: Session three

Madness at Gardmore Abbey: Session One

At Christmas 2010, my wife’s brother and his wife came to visit us for a couple of weeks. During that time, I introduced them to Dungeons and Dragons, and they were hooked right away.

We started off with a Living Forgotten Realms module I had run at my friendly local game store, and they wanted to know what came next. So, I spent the next day crafting an LFR-style adventure that was the sequel (I really should post about my LURU 2-3 sequel one of these days – Deeper Into the Crypts). I ran it that night, and they loved it. I ran them through two or three more adventures that week before they had to go home. Good times.

Once they were back in Texas, they wanted to keep playing. No problem – MapTool to the rescue! I had heard such good things about Reavers of Harkenwold that I decided to run them through it next, followed by Cairn of the Winter King.

Now that we’re on the standard post-Essentials adventure path, I figured I might as well go with the next adventure: Madness at Gardmore Abbey. I got the box months ago, read through the first two books, and started building monsters in MapTool. Once we figured out when we’d actually be able to play again, I re-read the books, formatted the maps from WotC to fit to a 50 pixel grid, and put a few more monsters together. I randomly determined the positions of the cards from the Deck of Many Things and all of the consequences of those positions. And now, off we go!

SPOILERS AHEAD

Session one began with the party in Fallcrest, relaxing after their voyage to the Cairn of the Winter King. A messenger from Winterhaven rode to town, seeking the adventurers whose reputation was growing as problem solvers. Her name was Elaine (though no one asked). She knew the party by name: Sora the dragonborn swordmage (played by my wife), Homer the drow hunter (played by my wife’s brother) and Stasi the half-elf warpriest (played by my sister-in-law). The messenger explained that Lord Padraig of Winterhaven had a bit of an orc problem that needed solving, and his regular troops weren’t up to the task. He’d heard good things about the adventurers, and decided to send the messenger to hire them.

Being the easygoing, “Where’s the next fight?” group that they are, they eagerly agreed to travel with Elaine to Winterhaven. Lord Padraig had arranged for the party to be put up at Wrafton’s Inn at no charge during their time helping the town. They tried to catch a whiff of rumor about the orcs from the patrons who were there in the early afternoon (Rond Kelfem, Valthrun the Prescient, a few peasants and of course Salvana Wrafton), but their Streetwise was lousy. So, they waited for Padraig to show up.

The Lord came to the Inn around dinner time, and waved for Salvana to bring him his regular mug of ale. He bowed slightly to the party with a few words of flattery and asked to sit with them. He explained the orc problem and what he wanted the group to do (the Scout the Abbey quest from page 8 of book 2). Again, they readily agreed.

After Padraig left, the group tried to pick up some more information, which they got from Valthrun and Eilian the Old at a corner table. They learned about the sacking of Gardmore Abbey 150 years prior and the orcs who lived there ever since. Eilian had seen the ruins as a boy, but never ventured too close. Valthrun expressed interest in the grounds – surely there must be some intriguing mysteries within. He asked the party to let him know if they found anything mysterious.

And with that, they set off to Gardmore Abbey. After three days’ travel, they arrived at the place where a path left the King’s Road to head up to the wall around the abbey’s hill. Their keen eyes spotted some orcs manning (well, orcing) the guard towers by the main gate, so they decided to head south, where trees could be seen on the opposite side of the wall. Finding a gap in the wall, they decided to head on through.

At this point, I decided they needed a fight, so I tossed them into encounter 9 against the spiders (even though they weren’t coming at the Feygrove via the village). The three of them fought off five deathjump spiders without trouble.

During a short rest after the battle, the adventurers noticed an armor-clad skeleton tangled up in some webs in the trees. Armor might mean treasure, so they climbed up and cut the body down. They were able to figure out that this was the body of a paladin of Bahamut, and in addition to a faint magic aura from the paladin’s sword, they also discovered a thin plate of ivory, about the size of the palm of a hand, blank on one side, and with an etched image of key on the other side (which I described as being similar to scrimshaw). Stasi, the Arcana-trained warpriest, was able to figure out that this was a card from the Deck of Many Things, a legendary artifact known as a force for chaos in the universe. She was also able to determine what effect the Key card would have in battle. Intrigued, she decided to hang onto the card.

And thus ends session one. I’m excited about how things have gone so far. It didn’t take much encouragement for my group to decide to check out the Abbey, and now they’ve found one of the cards of the Deck of Many Things. They’re in the Abbey to scout the orcs, but have taken a circuitous route to get there – and that’s okay! Madness at Gardmore Abbey allows for a lot of freedom, which I appreciate.

Now I need to put some more encounters together – I only have 1 through 14 done!

Next session: Session two