Guest Post from Paul Baalham: MapTool ongoing damage tracking macro

Editor’s note from OnlineDM: Today we are lucky to have another guest post, this one from Paul Baalham (@paulbaalham on Twitter; you can also find him at Daily Encounter).

Tracking ongoing damage and conditions with MapTool for 4E

As a DM that wants to use MapTool to handle all the boring stuff of D&D fights, to leave the players and me more tim for the fun stuff, I realised very early on that I wanted to create a system that would track ongoing damage and conditions so that we wouldn’t forget about the ongoing damage or that the slowed condition actually ended on the PC’s last turn. I managed to get the ongoing damage tracked quite easily so here is what I have done. Could it be improved? Almost certainly. If you can improve it then PLEASE let me know in the comments.

Campaign Properties

The code in this post require the following properties for the tokens that will be using it (i.e. players and monsters).

Acid:0
Cold:0
Fire:0
Force:0
Lightning:0
Necrotic:0
Poison:0
Psychic:0
Radiant:0
Thunder:0
Untyped:0
SEAcid:0
SECold:0
SEFire:0
SEForce:0
SELightning:0
SENecrotic:0
SEPoison:0
SEPsychic:0
SERadiant:0
SEThunder:0
SEUntyped:0
IsWarden:0

The SE variables are to help determine whether there is a Save Ends condition. I think there is probably a way of eliminating these, but I haven’t thought of a way yet (it works currently so I don’t want to break it!) The ISWarden may look out of place, but as Wardens can save against ongoing damage at the start of their turn, this variable helps in keeping track of the initiative.

The “Place Ongoing Damage” Button

I created a button for placing ongoing damage to tokens. This was situated on my Campaign macros window, but where you put it is up to you,

First of all, in the States section of the Campaign Properties the following states should be present:

Acid
Cold
Fire
Force
Lightning
Necrotic
Poison
Psychic
Radiant
Thunder
Untyped

Each one of these states should be in the Group called “Damage”.

This allows us to collect together all of the ongoing damage types like this:

[h: dmgList = getTokenStates(",","Damage")]

We then need to get a list of all of the tokens that are on the map:

[h: tokenList=getExposedTokenNames()]
[h: imgList = tokenList]
[h: Num = listCount(imgList)]

We need to create a list of token names and create a list of images to display.

[h,COUNT(Num),CODE:
{
  [h:tokenName=listGet(imgList,roll.count)]
  [h,token(tokenName): image=getTokenImage()]
  [h:imgList=listReplace(imgList,roll.count,tokenName+" "+image)]
}]

Next we display a pop up window that shows a list of targets (including images) as well as a list of the types of damage. Finally the value of the ongoing damage needs to be typed in by the DM.

[h:status=input(
"Target|"+imgList+"|Select Target|LIST|SELECT=0 ICON=TRUE ICONSIZE=30",
"damageType|"+dmgList+"|Select Type of Damage|LIST|SELECT=0 VALUE=STRING",
"amount| |Enter amount of damage"
)]
[h:abort(status)]

We now know the name of the target so we can switch the focus to that token:

[h:targetName = listGet(tokenList,Target)]
[h:switchToken(targetName)]

The following looks at what type of damage it was, sets the value of the appropriate variable and then creates a string to be dsiplayed at the end. This is the bit of code I think is the most likely that someone could improve upon.

[h,switch(damageType),code:
  case "Acid": {
    [h: Acid=amount]
    [h: SEAcid=1]
    [h: stringToShow= targetName+ " has ongoing Acid damage"]
  };
  case "Cold": {
    [h: Cold=amount]
    [h: SECold=1]
    [h: stringToShow= targetName+ " has ongoing Cold damage"]
  };
  case "Fire": {
    [h: Fire=amount]
    [h: SEFire=1]
    [h: stringToShow= targetName+ " has ongoing Fire damage"]
  };
  case "Force": {
    [h: Force=amount]
    [h: SEForce=1]
    [h: stringToShow= targetName+ " has ongoing Force damage"]
  };
  case "Lightning": {
    [h: Lightning=amount]
    [h: SELightning=1]
    [h: stringToShow= targetName+ " has ongoing Lightning damage"]
  };
  case "Thunder": {
    [h: Thunder=amount]
    [h: SEThunder=1]
    [h: stringToShow= targetName+ " has ongoing Thunder damage"]
  };
  case "Necrotic": {
    [h: Necrotic=amount]
    [h: SENecrotic=1]
    [h: stringToShow= targetName+ " has ongoing Necrotic damage"]
  };
  case "Psychic": {
    [h: Psychic=amount]
    [h: SEPsychic=1]
    [h: stringToShow= targetName+ " has ongoing Psychic damage"]
  };
  case "Poison": {
    [h: Poison=amount]
    [h: SEPoison=1]
    [h: stringToShow= targetName+ " has ongoing Poison damage"]
};
  case "Radiant": {
    [h: Radiant=amount]
    [h: SERadiant=1]
    [h: stringToShow= targetName+ " has ongoing Radiant damage"]
  };
  case "Untyped": {
    [h: Untyped=amount]
    [h: SEUntyped=1]
    [h: stringToShow= targetName+ " has ongoing damage (untyped)"]
  }
]

Almost finished! We need to put the damage on the token.

[h:Condition=damageType]
[h:setState(Condition,1)]

And finally show the string that we formatted earlier that tells everyone who has been tagged with ongoing damage, the type and how much.

[r: stringToShow]

Now we have a way of placing the ongoing damage on a token, we need a way of automating the subtraction of the damage from tokens at the start of their turn and reminding them to save at the end of their turn.

The “Next Initiative” Button

I created a button that I placed on the Campaign group called Next Initiative which passes the initiative to the next person on the list. But before it does this it checks to see if the current token has any save ends conditions on it (I have only pasted the ongoing damage here as conditions will be in another post).

First of all, we need to determine who the current token is and switch the focus to that token:

[h: id = getInitiativeToken()]
[h: switchToken(id)]
[h: targetname=getName(id)]

Next we need to see if the token has ongoing damage it needs to save against. It will then ask if the token has saved against it. The DM will see a popup window asking if the player saved against the condition. The player should still be able to roll for the save while the pop up is on the DM’s screen.

[h:saveList=""]
[h,if(SEAcid), code: {
  [h:stringToShow="Did " + targetname + " Save against ongoing Acid damage? (1=yes, 0=no)"]
  [h:status=input("hasSaved|0|"+stringToShow)]
  [h:abort(status)]
  [h,if(hasSaved), code: {
    [h:SEAcid=0]
    [h:Acid=0]
    [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Acid damage! :D"]
    [h:state.Acid=0]
  };
  {
    [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Acid damage! :("]
  }]
}]

[h,if(SECold), code: {
  [h:stringToShow="Did " + targetname + " Save against ongoing Cold damage? (1=yes, 0=no)"]
  [h:status=input("hasSaved|0|"+stringToShow)]
  [h:abort(status)]
  [h,if(hasSaved), code: {
    [h:SECold=0]
    [h:Cold=0]
    [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Cold damage! :D"]
    [h:state.Cold=0]
  };
  {
    [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Cold damage! :("]
  }]
}]
[h,if(SEFire), code: {
  [h:stringToShow="Did " + targetname + " Save against ongoing Fire damage? (1=yes, 0=no)"]
  [h:status=input("hasSaved|0|"+stringToShow)]
  [h:abort(status)]
  [h,if(hasSaved), code: {
    [h:SEFire=0]
    [h:Fire=0]
    [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Fire damage! :D"]
    [h:state.Fire=0]
  };
  {
    [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Fire damage! :("]
  }]
}]
[h,if(SEForce), code: {
  [h:stringToShow="Did " + targetname + " Save against ongoing Force damage? (1=yes, 0=no)"]
  [h:status=input("hasSaved|0|"+stringToShow)]
  [h:abort(status)]
  [h,if(hasSaved), code: {
    [h:SEForce=0]
    [h:Force=0]
    [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Force damage! :D"]
    [h:state.Force=0]
  };
  {
    [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Force damage! :("]
  }]
}]
[h,if(SELightning), code: {
  [h:stringToShow="Did " + targetname + " Save against ongoing Lightning damage? (1=yes, 0=no)"]
  [h:status=input("hasSaved|0|"+stringToShow)]
  [h:abort(status)]
  [h,if(hasSaved), code: {
    [h:SELightning=0]
    [h:Lightning=0]
    [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Lightning damage! :D"]
    [h:state.Lightning=0]
  };
  {
    [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Lightning damage! :("]
  }]
}]
[h,if(SENecrotic), code: {
  [h:stringToShow="Did " + targetname + " Save against ongoing Necrotic damage? (1=yes, 0=no)"]
  [h:status=input("hasSaved|0|"+stringToShow)]
  [h:abort(status)]
  [h,if(hasSaved), code: {
    [h:SENecrotic=0]
    [h:Necrotic=0]
    [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Necrotic damage! :D"]
    [h:state.Necrotic=0]
  };
  {
    [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Necrotic damage! :("]
  }]
}]
[h,if(SEPoison), code: {
  [h:stringToShow="Did " + targetname + " Save against ongoing Poison damage? (1=yes, 0=no)"]
  [h:status=input("hasSaved|0|"+stringToShow)]
  [h:abort(status)]
  [h,if(hasSaved), code: {
    [h:SEPoison=0]
    [h:Poison=0]
    [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Poison damage! :D"]
    [h:state.Poison=0]
  };
  {
    [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Poison damage! :("]
  }]
}]
[h,if(SEPsychic), code: {
  [h:stringToShow="Did " + targetname + " Save against ongoing Psychic damage? (1=yes, 0=no)"]
  [h:status=input("hasSaved|0|"+stringToShow)]
  [h:abort(status)]
  [h,if(hasSaved), code: {
    [h:SEPsychic=0]
    [h:Psychic=0]
    [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Psychic damage! :D"]
    [h:state.Psychic=0]
  };
  {
    [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Psychic damage! :("]
  }]
}]
[h,if(SERadiant), code: {
  [h:stringToShow="Did " + targetname + " Save against ongoing Radiant damage? (1=yes, 0=no)"]
  [h:status=input("hasSaved|0|"+stringToShow)]
  [h:abort(status)]
  [h,if(hasSaved), code: {
    [h:SERadiant=0]
    [h:Radiant=0]
    [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Radiant damage! :D"]
    [h:state.Radiant=0]
  };
  {
    [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Radiant damage! :("]
  }]
}]
[h,if(SEThunder), code: {
  [h:stringToShow="Did " + targetname + " Save against ongoing Thunder damage? (1=yes, 0=no)"]
  [h:status=input("hasSaved|0|"+stringToShow)]
  [h:abort(status)]
  [h,if(hasSaved), code: {
    [h:SEThunder=0]
    [h:Thunder=0]
    [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Thunder damage! :D"]
    [h:state.Thunder=0]
  };
  {
    [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Thunder damage! :("]
  }]
}]
[h,if(SEUntyped), code: {
  [h:stringToShow="Did " + targetname + " Save against ongoing Untyped damage? (1=yes, 0=no)"]
  [h:status=input("hasSaved|0|"+stringToShow)]
  [h:abort(status)]
  [h,if(hasSaved), code: {
    [h:SEUntyped=0]
    [h:Untyped=0]
    [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Untyped damage! :D"]
    [h:state.Untyped=0]
  };
  {
    [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Untyped damage! :("]
  }]
}]

[h:stringToList(saveList, " ")]
[h:number=listCount(saveList)]
[r,if(number>0),code:{
  [r,foreach(var,saveList),code:{
    [r:var]
    <br>
  }]
}]
<br>

Pass the initiative onto the next token.

[h: nextInitiative()]

And here is where it starts to get a bit messy. My wife plays a Warden in the game. Wardens get to save against conditions at the START of their turn.

Get the token that now has initiative and switch the focus to them.

[h: id = getInitiativeToken()]
[h: switchToken(id)]

If they are a Warden then repeat the code from up above:

[h,if(isWarden==1),code: {
  [h:saveList=""]
  [h,if(SEAcid), code: {
    [h:stringToShow="Did " + targetname + " Save against ongoing Acid damage? (1=yes, 0=no)"]
    [h:status=input("hasSaved|0|"+stringToShow)]
    [h:abort(status)]
    [h,if(hasSaved), code: {
      [h:SEAcid=0]
      [h:Acid=0]
      [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Acid damage! :D"]
      [h:state.Acid=0]
    };
    {
      [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Acid damage! :("]
    }]
  }]
  [h,if(SECold), code: {
    [h:stringToShow="Did " + targetname + " Save against ongoing Cold damage? (1=yes, 0=no)"]
    [h:status=input("hasSaved|0|"+stringToShow)]
    [h:abort(status)]
    [h,if(hasSaved), code: {
      [h:SECold=0]
      [h:Cold=0]
      [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Cold damage! :D"]
      [h:state.Cold=0]
    };
    {
      [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Cold damage! :("]
    }]
  }]
  [h,if(SEFire), code: {
    [h:stringToShow="Did " + targetname + " Save against ongoing Fire damage? (1=yes, 0=no)"]
    [h:status=input("hasSaved|0|"+stringToShow)]
    [h:abort(status)]
    [h,if(hasSaved), code: {
      [h:SEFire=0]
      [h:Fire=0]
      [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Fire damage! :D"]
      [h:state.Fire=0]
    };
    {
      [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Fire damage! :("]
    }]
  }]
  [h,if(SEForce), code: {
    [h:stringToShow="Did " + targetname + " Save against ongoing Force damage? (1=yes, 0=no)"]
    [h:status=input("hasSaved|0|"+stringToShow)]
    [h:abort(status)]
    [h,if(hasSaved), code: {
      [h:SEForce=0]
      [h:Force=0]
      [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Force damage! :D"]
      [h:state.Force=0]
    };
    {
      [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Force damage! :("]
    }]
  }]
  [h,if(SELightning), code: {
    [h:stringToShow="Did " + targetname + " Save against ongoing Lightning damage? (1=yes, 0=no)"]
    [h:status=input("hasSaved|0|"+stringToShow)]
    [h:abort(status)]
    [h,if(hasSaved), code: {
      [h:SELightning=0]
      [h:Lightning=0]
      [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Lightning damage! :D"]
      [h:state.Lightning=0]
    };
    {
      [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Lightning damage! :("]
    }]
  }]
  [h,if(SENecrotic), code: {
    [h:stringToShow="Did " + targetname + " Save against ongoing Necrotic damage? (1=yes, 0=no)"]
    [h:status=input("hasSaved|0|"+stringToShow)]
    [h:abort(status)]
    [h,if(hasSaved), code: {
      [h:SENecrotic=0]
      [h:Necrotic=0]
      [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Necrotic damage! :D"]
      [h:state.Necrotic=0]
    };
    {
      [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Necrotic damage! :("]
    }]
  }]
  [h,if(SEPoison), code: {
    [h:stringToShow="Did " + targetname + " Save against ongoing Poison damage? (1=yes, 0=no)"]
    [h:status=input("hasSaved|0|"+stringToShow)]
    [h:abort(status)]
    [h,if(hasSaved), code: {
      [h:SEPoison=0]
      [h:Poison=0]
      [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Poison damage! :D"]
      [h:state.Poison=0]
    };
    {
      [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Poison damage! :("]
    }]
  }]
  [h,if(SEPsychic), code: {
    [h:stringToShow="Did " + targetname + " Save against ongoing Psychic damage? (1=yes, 0=no)"]
    [h:status=input("hasSaved|0|"+stringToShow)]
    [h:abort(status)]
    [h,if(hasSaved), code: {
      [h:SEPsychic=0]
      [h:Psychic=0]
      [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Psychic damage! :D"]
      [h:state.Psychic=0]
    };
    {
      [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Psychic damage! :("]
    }]
  }]
  [h,if(SERadiant), code: {
    [h:stringToShow="Did " + targetname + " Save against ongoing Radiant damage? (1=yes, 0=no)"]
    [h:status=input("hasSaved|0|"+stringToShow)]
    [h:abort(status)]
    [h,if(hasSaved), code: {
      [h:SERadiant=0]
      [h:Radiant=0]
      [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Radiant damage! :D"]
      [h:state.Radiant=0]
    };
    {
      [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Radiant damage! :("]
    }]
  }]
  [h,if(SEThunder), code: {
    [h:stringToShow="Did " + targetname + " Save against ongoing Thunder damage? (1=yes, 0=no)"]
    [h:status=input("hasSaved|0|"+stringToShow)]
    [h:abort(status)]
    [h,if(hasSaved), code: {
      [h:SEThunder=0]
      [h:Thunder=0]
      [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Thunder damage! :D"]
      [h:state.Thunder=0]
    };
    {
      [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Thunder damage! :("]
    }]
  }]
  [h,if(SEUntyped), code: {
    [h:stringToShow="Did " + targetname + " Save against ongoing Untyped damage? (1=yes, 0=no)"]
    [h:status=input("hasSaved|0|"+stringToShow)]
    [h:abort(status)]
    [h,if(hasSaved), code: {
      [h:SEUntyped=0]
      [h:Untyped=0]
      [h:saveList=saveList+" ,"+targetname + " has saved against the ongoing Untyped damage! :D"]
      [h:state.Untyped=0]
    };
    {
      [h:saveList=saveList+" ,"+targetname + " did not save against the ongoing Untyped damage! :("]
    }]
  }]
}]

[h:stringToList(saveList, " ")]
[h:number=listCount(saveList)]
[r,if(number>0),code:{
  [r,foreach(var,saveList),code:{
    [r:var]
    <br>
  }]
}]

Next. we display the name of who has initiative and display the current conditions effecting them.

[r: getName(id) + " has Initiative"]
[r:strlist = "and currently has"]

The next line just sees whether there is any ongoing damage at all (this could probably be used further up, but I haven’t done this yet).

[h:OD=Acid+Cold+Fire+Force+Lightning+Necrotic+Poison+Psychic+Radiant+Thunder+Untyped]

If there is ongoing damage then cycle through the damage types and subtract the value from the token’s HP.

[h,if(OD>0),code:{
  [h,if(Acid>0):strlist=strlist+" ,"+ string(Acid)+" Acid damage"]
  [h,if(Cold>0):strlist=strlist+" ,"+ string(Cold)+" Cold damage"]
  [h,if(Fire>0):strlist=strlist+" ,"+ string(Fire)+" Fire damage"]
  [h,if(Force>0):strlist=strlist+" ,"+ string(Force)+" Force damage"]
  [h,if(Lightning>0):strlist=strlist+" ,"+ string(Lightning)+" Lightning damage"]
  [h,if(Necrotic>0):strlist=strlist+" ,"+ string(Necrotic)+" Necrotic damage"]
  [h,if(Poison>0):strlist=strlist + " ," + string(Poison)+" Poison damage"]
  [h,if(Psychic>0):strlist=strlist+" ,"+ string(Psychic)+" Psychic damage"]
  [h,if(Radiant>0):strlist=strlist+" ,"+ string(Radiant)+" Radiant damage"]
  [h,if(Thunder>0):strlist=strlist+" ,"+ string(Thunder)+" Thunder damage"]
  [h,if(Untyped>0):strlist=strlist+" ,"+ string(Untyped)+" Untyped damage"]
  [h:HP=HP-Cold]
  [h:HP=HP-Fire]
  [h:HP=HP-Force]
  [h:HP=HP-Lightning]
  [h:HP=HP-Necrotic]
  [h:HP=HP-Poison]
  [h:HP=HP-Psychic]
  [h:HP=HP-Radiant]
  [h:HP=HP-Thunder]
  [h:HP=HP-Untyped]
  [h:strlist=strlist + ", and now has " + HP + " HP"]
  [state.Dying = 1 - max(0,min(1,HP))]
  [state.Bloodied = 1 - max(0, min(1,HP - Bloodied))]
  [setBar("Health", HP/MaxHP)]
}]

Finally display the ongoing damages that the token is suffering from.

[h:stringToList(strlist, " ")]
[h:number=listCount(strlist)]
[r,if(number>1),code:{
  [r,foreach(var,strlist),code:{
    [r:var]
    <br>
  }]
}]

I hope someone finds this useful. I am not a software programmer by trade (although I do have to occasionally write code), so I am sure this code could be improved. It would be awesome if someone took this and made it better and allowed OnlineDM to post it on his site.

How should a DM handle a monster who’s marked?

Most of my RPG experience so far has been with Dungeons and Dragons 4th Edition, and I believe 4e was the first edition to introduce the concept of “marking” a monster. Defenders all have some type of marking mechanic, in which a marked monster takes a -2 penalty to attack anyone other than the defender who has marked it (unless it’s part of an attack that includes multiple PCs, and the defender is one of them).

Defenders also have some type of “punishment” mechanic attached to the mark, which will have an additional negative effect on the monster if it “breaks” the mark by attacking someone other than the defender. Sometimes the punishment is built into the marking ability itself; sometimes it’s a separate ability that says “When a creature marked by you is naughty, you get to beat it up.”

The usefulness of these marking and punishment mechanics depends to a large degree on the dungeon master and how the DM plays the monsters. There are two extremes the DM could follow (as well as points between): Ignore the mark, and always obey the mark.

Mark? What mark?

On this end of the spectrum, the DM has the monsters act as if they’re completely oblivious to the existence of a mark. Maybe they’ll attack the defender, or maybe they’ll attack someone else. The mark has no bearing on their actions. It’s a pretty stupid way for a monster to act, especially after it gets punished a few times, but hey, some monsters are stupid.

You must obey!

This other end of the “mark obedience spectrum” is where I fell when I first started DMing. In this mindset, the monster knows that it’s marked and that bad things will happen if it attacks someone other than the defender without also attacking the defender, so it attacks the defender. In this way, the defender is doing its job of keeping the scary monsters from attacking the rest of the party. Yay, right?

Don’t ALWAYS obey

Well, no. It was an article on Neuroglyph Games that got me thinking about this a few months ago. The author of the article ranked the Battlemind’s punishment mechanic as being outstanding compared to other defenders. The Battlemind, as you may know, has the ability to punish an adjacent enemy that deals damage to the Battlemind’s ally by dealing an equal amount of damage to that enemy. You hit my friend; I hit you. Bam.

Now, it’s true that this punishment mechanic can deal a whole lot of damage to a monster, especially compared to some of the other punishment mechanics out there. But the problem for me as a DM is that I had been running a game for several levels where the defender was a Battlemind, and her punishment mechanic never, ever did anything.

Why not? Well, she had to be adjacent to the monster in order to punish it. And if she was adjacent, the monster would obey the mark and attack her! The only time the monster ever broke the mark was if the Battlemind wasn’t adjacent, in which case there was no punishment involved.

It’s fun to disobey!

Defenders feel good about themselves when they protect their squishy allies, true. But they also feel good about themselves when they get to beat the crap out of a monster for daring to go after their allies. If the defender’s punishment mechanic never triggers, the defender’s player is having less fun than they could have. And I do believe that the DM should try to help the players have as much fun as possible.

The evolved approach: Role-play the monsters

So what’s the right answer? Remember that this is a role-playing game, and role-play the monsters!

A mindless zombie or single-minded beast is likely to act stupidly or instinctively. This might mean attacking the closest PC or attacking the PC that hurt them the worst or going after the PC who hit it most recently. This monster will fall on the “ignore the mark” end of the spectrum to start with. However, after it gets punished once (or twice, in the case of a really dumb bad guy) it will probably realize that ignoring the defender hurts, and it will start focusing on the defender instead.

Most monsters won’t know exactly how a defender’s punishment mechanic work, and I run it this way even if the rules as written technically say that the monster DOES know (as in the case of a mark power where the punishment is part of that same power). Most monsters at my table will say, “Hm, that fighter is calling me out. But I don’t feel like trying to chew through that armor, so I’m going to eat this tasty-looking wizard instead. OUCH! The fighter hit me when I tried to eat the wizard! Well that does it – you’re gonna get it now, armor boy!” They learn what the punishment mechanic does after it hits them (or one of their nearby allies).

Now, some monsters will be intelligent and may even have experience with battling adventurers. If you have a master tactician going against the players, it can be reasonable for that tactician to instruct its allies to avoid breaking the defender’s mark unless it’s really worth it. If that’s the case, it’s important for the DM to role-play this out at the table. “Ah, I see that your pathetic warden has tried to convince my hell hound to attack it instead of the dazed cleric. Do not be fooled, my minion! Destroy that horrid Pelor-worshipper, no matter the cost!”

The bottom line

Throw the defender a bone now and then by letting monsters discover what the defender’s punishment mechanic can do. Allow the monsters to learn from experience. And if the monster is really smart, have it show the players how smart it is by only breaking marks when it’s advantageous to do so – and make it clear that this is happening because the ENEMY is a tactical genius, not because the DM is.

Guest post from @blindgeekuk: Becoming One of the Community

Editor’s note: My post on my feelings about my place (or lack thereof) in the online RPG community from Wednesday sparked a fair amount of discussion, most of which made me feel better! As part of that discussion, Adam Page (@blindgeekuk on Twitter and a contributor to Daily Encounter) asked if he could put up a guest post here on Online Dungeon Master talking about his feelings regarding the online RPG community. I was pleased that he asked. His post follows.

Becoming One of The Community

I wanted to write this post to tie it into OnlineDM’s comments from Wednesday, touch on my experiences, and emphasise why an existing member of the D&D community, like @ThadeousC getting the job at WotC is not only important, but is crucial.

I’ve been a gamer for 20 years. I was writing my own 2e and SLA Industries stuff before I knew that mailing lists and BBS hosted fan books existed for these games. It was only when I got a data connection for my cheap nokia phone, that let me dial up to the internet at a staggering 9.6 kbps that I was enlightened.

I only recently got involved in the D&D 4e community, but for most of the 00’s was a major figure in the SLA industries fan scene, publishing, at my last count, about 600 pieces of material for that game, and helping to form Team8, a group of UK rpg’ers that support the hobby. At the time, that community was effectively lead by a couple of well known names, and the goal of Team8 was to publish material without the stigma of a name attached to it… everything would be anonymous… The theory lasted 1 issue of our fanzine, before the names stepped in again to promote it and take control of the group. I left/was forced out, and to be honest, it was one of the best moves I made, because it showed me that I wasn’t after the glory or recognition, I just wanted to support my favourite game.

Having missed most of 3e, and the rumours of 4e, I checked it out when it hit the torrent site’s and I loved it, and have picked up pretty much everything since, spending several thousand dollars on minis and books in the 3 years i’ve been DM’ing. I reformed my old 2e group, I started up a roleplaying group at my FLGS because there was nothing for gamers there, and I heavily promoted that. In order to do so, I built a website…

And suddenly, unbeknownst to me, I was part of the community, people would google stuff and end up at my site, which I had intended just to be for my local players. When the rumours about Dark Sun started to hit, I collected them, and people like @Alphastream linked to them. I posted some rough ideas for content on there as well.

But it was the Encounters program, with it’s Twitter buffs that was the final transition. I’d checked out @wilw’s timeline a few times, and watched #gencon tweets flood in each year, but Encounters convinced me to create an account, and follow a few well known uk tweeters like @symatt and @greywulf. From there, the #ff system gained me followers, AND people to follow, and Twitter is all about the interaction with these people. I was starting to tweet to people whose blogs I read, and they were tweeting back… I was becoming one of their community.

After a year of this, I suffered a serious case of depression, and I decided to stop tweeting as me, and tried an experiment: was quantity, or quality a factor in getting recognised in the community, and how quickly could someone get accepted as being a contributing member of the community. I created a fake persona, twitter account, email, wordpress blog, and started filling it with content, from themes, to mundane descriptions to encounter summaries. I was surprised by the response. While it wasn’t the amazing ‘welcome to the community’ I was hoping for, some content did get discussed by people that most of us consider to be important tweeters (e.g @ChrisSSims).

I ended the blog early, scared of the implications if people found out, and because @SarahDarkmagic gave me a perfect opportunity. She had finally gotten the recognition she deserves with Lost City, and articles in Dragon, and she was discussing how she had become accepted into the community by basically introducing herself to people. My fake persona, and the real me grilled her on this, and we came to the summary that to be acknowledged in the community you need to:

“you have to write a regular schedule of good quality material, which shows attention to detail and a clear understanding of the game world/rules, it needs to show your passion for the game, you have to promote yourself in various places including twitter, the forums (enworld and wotc) and be heard on podcasts, and you need to build relationships with other bloggers by guest posting for them”

I closed down the persona, and started up my own blog, again, posting content until another bout of depression saw me slim down my online presence. However, prior to that, I was spotted doing stuff with Hirst Arts bricks by @mikemearls, opening up the chance to make the 3d version of Lair Assault.

Since closing down my own blog, I’ve taken that summary to heart. I’m posting here, there, and everywhere. While I don’t want the massive recognition, or to be named as one of the top ten D&D twitter people, I’d like to know that what I write is read and appreciated, and if anything, that’s something we fail in as a community, thanking each other and praising each other on a good blog post.

So yeah, thats my summary of how I became a member of the D&D community.

OnlineDM’s comments about not feeling part of the community mirror my own feelings until very recently. To me, there seems to be 3 levels in the community. You have your big names: @NewbieDM, @SlyFlourish, @SarahDarkmagic, people whose opinions are listened to and who are respected. Then there’s a middle tier, full of people who post regularly, but who don’t get the recognition they deserve: @ObsidianCrane, @PaulBaalham, @WastexGames. Finally, there is an outer tier, which is where many like OnlineDM feel they are. In this tier, you post but people never seem to respond, you tweet replies at people and never get re-tweeted etc. To me, it is important that people in here are supported, because there are a lot more of them than there are big names, and often, it’s these people who have the best content, but it’s just never seen…

At the start, I mentioned that I think a member of our community, like @thadeousc being WotC’s new social/community manager is important… There are lots of reasons why someone who understands twitter should get the job, but Thad is a known member of the community, and trusted by us all. If it came down to a situation that the community had reacted to, such as the announcement of Essentials, him saying ‘Trust me about this’ in a tweet would probably calm most of the raving fans down.

WotC have acknowledged that they lost touch with the fan base, that they have failed to communicate with us properly, and I think that reaching out to the community and hiring someone from there, who knows how we perceive things, and has the contacts amongst the twitterverse and blogosphere is the right thing to do.

Updated adventures: The Stolen Staff and Tallinn’s Tower

Edit 9/15/2011: Based on some play-testing feedback from an awesome reader named Jeff, I have made some improvements to Tallinn’s Tower (mostly just clarifications and clean-up edits; nothing transformative). Thank you, Jeff!

Edit 9/8/2011, evening: I changed the low-level monsters in the first encounter of Tallinn’s Tower to something more interesting. I guess I’ll never be done tweaking these adventures!

After running my own adventures at TactiCon last weekend, I’ve finished tweaking them based on my play testing. The new versions are formatted much better and should be easier to use at the table.

I’ve renamed the first adventure in the trilogy from The Staff of Suha to The Stolen Staff. This is because I’ve decided The Staff of Suha makes more sense as a name for the whole trilogy, while the Stolen Staff is just the first part. I’ve also totally revamped the skill challenge into a series of scenes that I think you’ll find easier to run and more fun for your players. There’s also an alternate encounter for entering the stronghold.

As for Tallinn’s Tower, the main changes are to the formatting; the core content is mostly the same.

The third adventure… well, I’ve decided that I’m going to submit Descent Into Darkness to Dungeon Magazine because, hey, why not? But since they won’t accept anything that’s been previously published elsewhere, I can’t post it on my blog if I want it to have a chance of being accepted.

Based on the odds, I’m guessing they’ll reject it, at which point I’ll publish it here. But until that happens, I’m going to hold off.

Download The Stolen Staff PDF.

Download Tallinn’s Tower PDF.

Maps for the adventures are below, scaled to a 50-pixel grid for use in programs like MapTool (both with and without a grid).

If you run either or both of these adventures, please let me know how it goes! And if you want to playtest the third adventure, drop me a line at mailto:onlinedungeonmaster@gmail.com.

Stolen Staff - Lair Exterior - Gridded

Stolen Staff - Lair Exterior - No Grid

Stolen Staff - Garbage Tunnels - Gridded

Stolen Staff - Garbage Tunnels - No Grid

Stolen Staff - Shrine - Gridded

Stolen Staff - Shrine - No Grid

Stolen Staff - Grak Chamber - Gridded

Stolen Staff - Grak Chamber - No Grid

Tallinn's Tower Level 1 - Gridded

Tallinn's Tower Level 1 - No Grid

Tallinn's Tower Level 2 - Gridded

Tallinn's Tower Level 2 - No Grid

Tallinn's Tower Level 3 - Gridded

Tallinn's Tower Level 3 - No Grid

Tallinn's Tower Level 4 - Gridded

Tallinn's Tower Level 4 - No Grid

TactiCon 2011 – LURU 2-4 Need to Know

LURU 2-4 Need to Know – Spoilers ahead

The final adventure I ran at TactiCon 2011 was LURU 2-4 Need to Know. I had a full table of six players, including my friend Nate, another couple of players who I knew from Enchanted Grounds, a player I knew from other convention games, and a couple whom I hadn’t met before.

I began by asking the players to introduce their characters to one another, and Nate led things off by doing so in-character. This set the tone nicely for the rest of the table, as all of the PCs came to life. All of them mentioned their race (although the changeling in the party explained that she claimed to be an eladrin, hinting that she wasn’t really), though most did NOT mention their class. Instead, they let this become clear from the way they behaved in battle. One introduced himself as an actor (later revealed to be a hybrid bard-warlock), one as just an adventurer (later revealed to be a rogue), one as bloodthirsty bug (a ranger) and one as a princess (a hybrid bard-warlord).

The princess in the party is my favorite PC I’ve seen so far in an LFR game. She rode around on a Tenser’s Floating Disk and made excellent use of Direct the Strike to boss people around and make them attack. It worked really well. She was also able to leverage her “royal status” to bluff her way into a guarded city along with some of her allies during the adventure.

The best part of this adventure was the opening combat encounter, which took place in an inn that was soon set on fire. The growing fire and the lava elementals that arose from it were a ton of fun.

The final encounter was less fun, as it involved a beholder in a pretty boring 10 square by 10 square room (with an attached sewer area). Every time a player started their turn, they were subject to an eye ray attack (unless they ran into the sewers). They couldn’t flank the beholder, nor could they take opportunity attacks against it when it used its eye rays.

It got frustrating, but having learned my lesson from an earlier adventure I started changing the beast up a little bit. I tried to cut way back on the most devastating control effects from the beholder – the sleep ray knocked out the fighter for several rounds, and the petrification ray took away at least two PCs’ entire turns. The adventure made it clear that you need to go easy on those during the beholder’s turn, which I did, but when it rolls a random ray at the beginning of a PC’s turn, the odds are good that a controlling power is going to come up. So, I switched to more damage and less control later in the combat, even on the random rays.

Ultimately, everyone had a good time, and using MapTool and the projector to project the spreading fire onto the map in the first encounter was a big hit. It was a good way to end an awesome TactiCon.

TactiCon 2011 – MyRealms adventures

MyRealms adventures – Spoilers follow

All day Friday at TactiCon 2011 was devoted to my MyRealms adventure trilogy: The Staff of Suha in the morning, Tallinn’s Tower in the afternoon, and Descent Into Darkness in the evening. I only had one player who played in all three adventures, but my tables were full throughout.

I feel confident in saying that these were a hit. I’m constantly tweaking my own adventures, and I was taking notes as I ran them, but they were all little things to tweak here and there – nothing that needed a complete reworking.

My favorite moment of the convention came in the final battle of Descent Into Darkness, which involves facing a beholder in a room that includes a river of magma. The party was doing their best to keep the beholder locked down, and at one point a rogue decided to jump onto the beholder’s back. He stayed aboard for four rounds.

In the first round, the beholder was stunned, so the rogue stabbed away.

In the second round, the beholder got up from prone and tried to shoot an eye ray at the rogue (tough to do when he’s on top of the beholder) and missed.

In the third round, the beholder flipped upside down and flew just over the surface of the magma, but the rogue made a great Athletics / Acrobatics check to scramble around the ball of eyes as it rotated and avoided the magma.

In the fourth round, the beholder had had enough of this nonsense, decided that it could handle the magma better than the fragile humanoid on its back, and dove into the river and back out. The beholder and the rogue both took 30 fire damage and ongoing 10 fire damage (save ends).

The rogue’s player asked me, “So what happens if that takes me below zero hit points?”

The whole table replied with “Oooooh….”

Yes, he fell unconscious while in the river of magma, which meant that he lost his grip and floated just below the surface. The beholder survived the bath, but the party ran out of options to rescue the rogue without killing themselves. Thus passed the short-lived rogue, may he rest in peace.

I’m not much of a killer DM, but PC do die at my table from time to time. In this particular case, it was worth it. I knew that was true Sunday evening when some players at a different game I was running said they had already heard that story about the beholder and the rogue and the magma river. When your players are telling stories about your games to their other friends at the convention, you’ve done something right! Well, unless they were saying, “This jerk of a DM killed my character…”

TactiCon 2011 – CORE 2-4 Lost on the Golden Way

CORE 2-4 Lost on the Golden Way – Spoilers Follow

I ran three sessions of CORE 2-4 Lost on the Golden Way at TactiCon 2011 – Thursday evening, Saturday morning and Sunday morning. My biggest worry was that there wouldn’t be enough players for the Sunday morning game, thus denying me the Iron Man achievement, but no worries there – I had a full table. Actually, the Thursday evening table was the only non-full table I ran all weekend (only four players). Saturday morning’s table actually had seven players!

I hadn’t run this adventure before TactiCon, but by the end I was quite a natural with it. It’s a fun little adventure, where the party has to track a missing caravan into the feywild, dealing with a thieving elf who accidentally got the caravan into trouble. They rescue the captive drivers and caravan workers from gnomes who were planning to deliver them as slaves to some eladrin – and then fight off the eladrin as they try to escape from the feywild.

The first table decided to take a different approach to the final encounter. Rather than dashing for the portal out of the feywild, they decided to literally circle the wagons and shelter in place. No problem – I adapted the existing maps I’d prepared in MapTool, and they fought from within the wagon circle.

The second table, with seven players, had four people who had never played LFR before. As my regular readers know, I LOVE introducing new people to D&D, so this was a great time for me. The highlight was when one player, having thrown his only (non-magical) dagger at a foe in an earlier round, decided to try to take out the enemy by springing off one standing stone to kick the bad guy off another stone. Good Athletics and Acrobatics led to success, with the PC standing atop the stone and the bad guy prone at its foot, taking decent falling damage, after which he was soon dispatched. Awesome.

The third table had my friend Nate as a player (yay!) as well as a father-son pair who had approached me on Thursday or Friday, admiring my projector setup and asking about the game. I told them that the Saturday morning and Sunday morning games would be ideal for new players, so they signed up!

This was a solid little adventure, and I could see using it as a good introductory adventure for new players in the future. Also, I found myself using character voices in this adventure – something I don’t usually do much of as a DM. The thieving elf Harelahur somehow developed his own voice, which I think made the players feel a bit sympathetic toward him (they all let him run away instead of turning him over to the authorities at the end). The cold eladrin leader’s voice was fun to do, too. I’m not usually a big “voices” guy, but I could see doing a little more here than I have in the past, if the character is right for it.

TactiCon 2011 – SPEC 3-2 Roots of Corruption – Dark Seeds

SPEC 3-2 Roots of Corruption – Dark Seeds – Spoilers follow

I’ve already written extensively about my experience running this adventure at TactiCon. In a nutshell, it was a mostly-fun paragon tier adventure that my party decided to take on at a high challenge level. This came back to bite them in the final encounter against a hydra, which they eventually had to retreat from. This meant that they received a negative story award, which left them with a lousy feeling about the game. And it led to my only non-perfect DM evaluation scores of the convention (two people gave me a 9 out of 10).

I did learn later that the hydra’s attacks and defenses and damage should not have been scaled upward by 1 according to the adventure, so I made a mistake there (but the boss monster in the other adventure branch does have instructions to adjust his attacks and defenses and damage, so it was an understandable confusion on my part). And ultimately I should have changed whatever seemed unfun to me as we went along at the table (a lesson I took to heart in the last game I ran a the convention).

I guess I’ll have to shoot for perfect scores next time instead. 🙂

TactiCon 2011 is in the books

And on the fifth day, OnlineDM rested.

TactiCon 2011 started Thursday evening at 6:00 and wrapped up Sunday evening at 6:00. 72 hours from open to close for me (plus a little extra time at the end for the DM appreciation ceremony). I spent 36 of those hours at the game table, running games.

And I had a blast!

I got some dubious looks when I said I wanted to Iron Man the con (running games the whole time), but I can honestly say that I came out of it feeling energized, not exhausted. I did run a little short on sleep over the course of the convention (I had a 30 minute drive each way, so that cut into my sleep time a bit), and I’ll admit that I feel asleep at 9:00 PM last night and slept until 8:00 this morning, but I wasn’t getting headaches or feeling drained or anything like that.

Ultimately, TactiCon was a lot of fun. I was running games at tables in more public areas for most of this convention (in the past I’ve often been in individual hotel rooms), which meant that a lot more people got to see my MapTool / projector setup in action. It was a great feeling to have people stop by to say how cool they thought it was, or to ask questions about how they could build something similar themselves. Some of them even brought friends back later to show my setup off to them.

I’m looking forward to the next convention!

Individual game recaps

I’ve decided to break my detailed recaps into separate posts, rather than putting it all in one massive post. The links to those posts are below.

Lost on the Golden Way (Thursday evening, Saturday morning, Sunday morning)

MyRealms adventures (all day Friday)

Roots of Corruption – Dark Seeds (Saturday afternoon and evening)

Need to Know (Sunday afternoon)

Annoyed at SPEC 3-2 Roots of Corruption – Dark Seeds

I’m most of the way through my attempt to Iron Man TactiCon (I’m running nine slots – 36 hours of games over a 72-hour period). I’ve had a lot of fun, and I’m especially pleased that the adventures I wrote myself were well-received on Friday.

This afternoon and evening (Saturday) I ran a two-slot game of SPEC 3-2 Roots of Corruption – Dark Seeds. This is a paragon-level adventure, and I ran it with a party of mostly 11th level characters and a couple of 13th level characters. They chose to run it at level 14 (so yes, they opted for extra challenge).

It was a fun and challenging adventure for the first four hours, and when we came back from our dinner break we went into the last encounter.

It was silly-hard. Spoilers follow.

In the particular path my party chose, the adventurers have to fight against a hydra and two spore demons at the end. The spore demons were mildly annoying, but not much of a real threat. The hydra was insane.

It can’t be flanked, much to the frustration of the two rogues in the party.

It makes ranged attacks without provoking attacks of opportunity.

It has threatening reach in a 2-square radius (on a Huge creature).

It gets two free attacks against any PC that ends its turn within 2 squares.

Now, the PCs had spent a lot of resources in the next-to-last encounter, and only two of the six of them had action points for the last battle. There weren’t too many daily powers left (though there definitely were some).

The party had a really hard time with this battle, and they eventually retreated and declared defeat.

My annoyance comes in that, by running the adventure as written, I made the players have a less-good time than they otherwise would have. The final battle ended in defeat, and the party got a negative story award because of it (it makes them more vulnerable to diseases in the future). It was pretty miserable at the end.

And I have to admit that part of my annoyance is that two of the six players docked me a point on the GM evaluation sheet for the question, “How much fun did you have?” I still got great scores, but I’d be lying if I said I didn’t care about the awesome possibility of getting perfect scores while Iron Manning the con. I really wanted that, and I failed.

Ultimately, this is on me. When the adventure as written has unfun things happening, I should deviate. I should follow my own judgment, and I didn’t. I should have had the hydra spread his attacks around more, rather than focus on one PC until it drops as the adventure says it should do. I could have changed things so that the hydra’s ranged attacks at least provoked opportunity attacks, or made it so that it only got a single bite attack against PCs that end their turns near it.

But I didn’t make any of those changes, and my players had less than optimal fun because of it. This doesn’t mean that every fight has to be a victory for the party, but if something feels unfair and I have the ability to change it, I should change it! I didn’t, and my players had less fun because of it.

Lesson learned. If something seems unfun, change it.