Online Dungeon Master

September 16, 2011

Guest Post from Paul Baalham: MapTool ongoing damage tracking macro

Filed under: 4e D&D, Advice/Tools, Guest posts, Macros — Tags: , , — OnlineDM @ 8:05 AM

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.

September 9, 2011

Guest post from @blindgeekuk: Becoming One of the Community

Filed under: 4e D&D, Guest posts — Tags: , — OnlineDM @ 7:36 AM

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.

Blog at WordPress.com.

Design a site like this with WordPress.com
Get started