D&D Encounters – Lost Crown of Neverwinter – Week 8

Edit 10/1/2011: Apparently WotC is NOT changing their policy of requiring that D&D Encounters be run on Wednesday nights, as I had originally mentioned in this post. My mistake.

I ran D&D Encounters at my friendly local game store, Enchanted Grounds, all summer long, and I loved it. I love the mini-sessions for prep purposes, I enjoyed the story, and most of all I enjoyed helping new players learn the game. One of the people I met via encounters is now good friends with my wife and I, along with his wife.

Thus, I was sad to have to give up DMing Encounters this fall when my Wednesday night bowling league started up. I agreed to serve as a backup DM in case any of the regular folks were out of town, though, and this week I got the call. Put me in, coach – I’m running a game!

My party consisted of four PCs – two warpriests, a bladesinger and a thief. They began the session by taking a short rest in a boat house in a swamp, where they had come in search of the Dead Rats gang. The boat house held only a table and a rug, and a sharp-eyed PC noticed the rug sagging in the middle. Pulling it aside revealed a stone pipe with metal rungs forming a ladder down into darkness.

The adventurers successfully negotiated crumbling ceilings, narrow ledges, tough climbs and tricky tracking with no problem and eventually emerged into the sewers proper. They noticed some movement in the water – two pairs of eyes staring at them from just above the water’s surface. As the dwarf warpriest pushed forward, the eyes revealed themselves to be attached to a pair of crocodiles, and a swarm of hundreds of rats poured out of some pipes in the walls to join the fun. The PCs could also hear noises inside a larger pipe, as if something else was making its way toward them.

The party thief decided to try to jump across the sewer channel but failed, landing in the water next to the large pipe – which was revealed to contain a dire rat. The rat bit the thief (one exposure to Dire Rat Filth Fever) and was soon joined on the other side by a crocodile who clamped its jaws around the poor thief’s leg. Ouch!

The rest of the party was dealing with the swarm and the other crocodile, but the drow warpriest did wade into the muck and drop a cloud of darkness to help the thief get away. No luck, though – the crocodile’s next turn of grinding its jaws down on the delicious thief left the sneaky bugger unconscious (and getting more exposure to disease from the dirty water).

Eventually the thief was healed and got himself out of harm’s way and the rest of the party started taking care of the bad guys one by one – first the dire rat, then the swarm, then finally the crocodiles. And there was much rejoicing!

At the end of the encounter, since the thief had been exposed three times to Dire Rat Filth Fever (twice from rat bites and once from bleeding in the dirty water) I invoked my house rule: He only had to make one saving throw to avoid infection, but because of the two extra exposures, the saving throw was at a -2 penalty. It was a moot point, as he rolled a 7 on the die and found himself infected.

In prepping for the game, I realized that it would be a pain in the butt for a typical Encounters player to have to deal with a disease. “Wait, what do I have to roll to get better? And what happens if I get worse?” So, I used the awesome Power2ool to create disease cards to hand out to any players who get infected:

While it was only a one-week return to the Encounters DM table, I had a lot of fun. It was also nice to have more people compliment me on my projector setup + MapTool for my in-person games. The encounter itself wrapped up within an hour, so I was even able to make it to bowling on time.

Best of all, the coordinator at the store is thinking about moving Encounters to Tuesday nights in the future, since WotC has given store owners more flexibility about when they run the program. That would be awesome, since I’d be able to get involved again!

Edit: However, it looks like this is not a new WotC policy after all, and Encounters is still required to be run on Wednesday. Well, poop.

OnlineDM’s house rules – Part 1

Every DM has some house rules that they like to use at their table, so I thought I’d share some of mine here on the blog.

If a creature is force-moved into hazardous terrain (fire, off a cliff, etc.) they get a saving throw to fall prone instead of going into the hazard. This is a standard rule. However, it’s annoying when a character has a power that force-moves the creature multiple squares, but a single saving throw negates those extra squares entirely.

  • House Rule: If a forced movement power would move a creature extra squares into hazardous terrain, the extra squares of movement can be applied as a penalty to the creature’s saving throw. Thus, if a creature is at the edge of a cliff and you push it three squares, you can push it one square (off the cliff) and give the creature a -2 penalty to the saving throw to avoid going over the edge (so it needs a 12 or better to save itself).
A related issue comes up with diseases from creatures like rats and lycanthropes. If you are hit by one of these creatures’ diseased attacks, you make a saving throw at the end of the encounter to avoid contracting the disease. It doesn’t matter how many times you were exposed to the disease; a single saving throw will save you.
  • House Rule: If a creature is exposed to a disease multiple times in an encounter, each exposure beyond the first imposes a -1 penalty to the creature’s saving throw against contracting the disease at the end of the encounter. Thus, if a creature is bitten four times by Dire Rats in a combat, the creature will make a saving throw with a -3 penalty at the end of the encounter to avoid contracting Dire Rat Filth Fever (needing a 13 or better to avoid the disease).
Lots of people have complained about action-denying conditions like Dazed, Stunned and Dominated. I have my own way of running the Dominated condition:
  • House Rule: If an effect would dominate a creature, instead that creature takes a free action to move up to its speed (provoking no opportunity attacks along the way) and then use any at-will ability of the dominator’s choice against a target of the dominator’s choice. Any attacks made in this way have a +2 bonus to hit and +5 bonus per tier to any damage (+5 at heroic tier, +10 at paragon, +15 at epic). If the dominated condition is “save ends”, then the creature still makes a saving throw at the end of its turn to end the condition. If it fails the saving throw, it takes another free action at that point to move and use an at-will ability of the dominator’s choice with the appropriate bonuses. It can still take opportunity attacks and flank and does not grant combat advantage (basically, the domination only applies while it is taking its dominated action).
I’m always looking for other suggestions for cool house rules to make the game more fun, so if you have any that you like, please share them in the comments!

Running online D&D: Weekly prep

I’ve talked a fair amount on my blog about macros that I’ve programmed in MapTool for my online games and recaps of adventures that I’ve run, but I realized that I haven’t spent any time talking about the prep process. Preparing to run a game online has a lot in common with an in-person game with vinyl mats and minis, but it definitely has its differences.

1 week before the game

I figure out what I’m going to be running. For my longest-running online game, this is easy; we’re running EN World’s War of the Burning Sky campaign and have been for over a year. I do still need to make sure I’ve read far enough ahead in the campaign to know what’s coming in the broad sense, but I try to be good about staying ahead of things there.

For my other online games, this might mean picking out a one-shot game (like a Living Forgotten Realms adventure) or actually writing my own adventures (a topic for another blog post).

This is also the time that I reach out to the online players about any changes they need to make to their characters. For instance, if they’ve leveled up after the last session, I remind them to tell me what choices they’re making for their characters. This is a difference between an online game and an in-person game; online, I have to maintain the tokens for the PCs and add new powers, adjust stats, etc. I also talk about magic items that the party acquired in the previous session and see which PC is going to be using them (so I can update their tokens).

3 days before the game

I send out an email to the group, announcing that there will be a session at our usual time (6:00 PM Mountain Time on Friday night for me and the person in South Dakota; 5:00 PM for the person in California; 7:00 PM for the people in Indiana and Texas, 8:00 PM for the people in New Jersey and Florida, and 9:00 AM Saturday for the person in Japan), asking who will be able to attend. I usually get a couple of responses right away and the rest trickle in over the next couple of days. Sometimes I’ll get a “maybe” (there’s a possible schedule conflict, but they might be able to come – this is usually a “no” in the end). I have a total of seven players, and we usually have 4-5 show up each week. One of the seven is almost never there, and four are almost always there; the other two are there most of the time, but not all of the time. This works for us, though I know some DMs don’t like it if players are absent irregularly. This is why I have seven players! We can still game even if three people are unavailable.

1-2 days before the game

I do my actual prep work (sometimes I get this done earlier, of course). This involves a few things:

  • Updating PC stats if the players have sent them to me after a level-up
  • Updating PC treasure if the players have decided on what they’re using
  • Setting up the maps for the next few encounters (easy for War of the Burning Sky, since decent JPG versions of the maps are available)
  • Building monsters for the next few encounters using my handy-dandy monster construction macro

For some reason, I used to procrastinate more about the PC stuff than the map and monster stuff. When the PCs hit paragon tier, I actually canceled a session so I could use that four-hour time slot to work on their PC tokens. It’s gotten better since I’ve changed my PC properties to be easier to level up (defenses now scale automatically with level, for instance), but there was a time when I almost wanted to stop running online games just because of the extra layer of work on the DM to update PC tokens. It’s better now, though.

The new monster macro has made building the monsters way easier and actually more fun. I also enjoy the process of using TokenTool to create cool-looking monster tokens from images I find online. I’m sure lots of these images are copyrighted and such, but I’m only using them in my own game (this is part of the reason I don’t distribute lots of monster tokens on my blog – well, that and laziness).

The day of the game

Since our game starts at 6:00 PM my time, I go to work early so I can leave at 4:00 PM. It only takes me 15 minutes to get home, at which point I’ll chat with my wife briefly and help take care of household tasks (feed the cats, figure out dinner). This usually leaves me at the computer by around 5:00, giving me time for last-minute prep. If there are any monsters I haven’t done yet, I’ll try to put those together quickly. If I already have a good image for the monster, it tends to take about 5 minutes per monster type to assemble.

If all goes well, I like to spend the time from 5:30 onward re-reading the material I’ll be running that evening. War of the Burning Sky is a very story-heavy adventure, and I want to make sure I understand the various NPCs and the branching points of the tale so that it all makes sense during the game.

At 5:45, I start up the MapTool server so that my players can connect. It’s not at all unusual for one or two people to be ready to go right at that time, and we might chat a bit in the text window of MapTool until start time, or they might say, “Hi, I’m here, but I’m going to be busy with something else for the next few minutes.” I also might say, “Okay, the server is up, but I’m still preppping! Please talk amongst yourselves. I’ll give you a topic: A half-elf is neither a halfling nor an elf. Discuss.”

At 6:00, assuming we have at least 3 players on MapTool, I’ll start the Skype audio call so we can talk to each other… and away we go!

Game on!

After that, we play D&D for four hours. Honestly, the online experience is darn near as good as the in-person experience for me. We still get to know each other out-of-game and chat as friends. Role-playing still happens. Combat is still exciting – and pretty quick, too, thanks to the software handling a lot of the math. It’s a ton of fun, and while I also enjoy in-person games, my online game is my longest-running campaign by far.

I’ll talk in later posts about the process of running a session, but I hope this window into the online game prep process helps to show you what it’s like. Give online D&D a try sometime – it’s a ton of fun!

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.

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. 🙂

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.