Print Page

Monday, October 27, 2014

Restarting the Ed's Hobby Hovel site with a reposting of Rencounter

Finally got around to reposting my Rencounter skirmish rules to the web. Had started a bit of a site on Google Sites without any significant content, so getting Rencounter up is the first thing to make it worthwhile to reopen the doors.

Rencounter  Being a Set of Rules for Ambuscades, Skirmishes, Rencounters, Affrays and Divers Small Actions Conducted with Model Soldiers

Thanks to the Wayback Machine for being a more convenient archive than my dusty backup drive, and Walt O'Hara for the ePub copy he cobbled together awhile back.

Friday, October 24, 2014

Regular Expression Dialect Gotcha

I was recently updating a Rails application to Rails 4 and as part of that, went through and updated the regular expressions for checking some data inputs from /^ $/ for beginning and end to /\A \z/ to clean up the potential security hole in sneaky multiline inputs. This is fine in Ruby. JavaScript's Regular Expression engine shares the /^ and $/ but does not do the /\A \z/ style. I inadvertently introduced a bug by making that change in a JavaScript regexp that was not tested again until the user used it today. Fixed now, D'oh.

Sunday, October 19, 2014

How To Host a Dungeon

I've been playing a game of Tony Dowler's How to Host a Dungeon today and posting it in stages on G+. Will probably collect them together as a post here, but for now, if you are interested in a solo game for generating those classic side views of megadungeons with a history to them, check out my G+ posts or some of the various playthroughs and completed maps by other folks. Currently I am approaching the end of the Age of Civilizations, with the Demons having gone out in a blaze of war with the Angels and the Dwarves reaching the apogee of their civilization and bad portents of hubris looming. Here are some of the photos. The odd lighting and some of the fuzziness after the Primordial Age comes from putting the Primordial Age page on a lightbox and tracing over it in the Age of Civilization while still drawing on full thickness art paper, not tracing paper. Sorry, first one is sideways in the handy file. Will have to download and edit it or pull in a bit of CSS to rotate it.

Friday, October 10, 2014

The Boarcroc in 5e

The dinosaur hunting Boarcroc (link is to my previous post) needs to be a 5e monster. Because, Boarcroc. It's a pretty simple to introduce them. Take the Giant Crocodile - Monster Manual p324, and adjust the movement rates for the longer, fully terrestrial adapted legs, faster on land, slower swimming. Speed 45, swim 35.

That grapple mechanic needs something more to feel like the crocodilian death roll which is entirely more violent than simple restraint. The victim should be knocked prone like in Pathfinder, and suffer continuing damage (automatic or advantaged following attack rolls by the croc?) until the grapple is broken. I would probably roll ongoing damage as the bite damage, but split it between piercing and bludgeoning, since a lot of it comes from being smacked around like a rag doll. Add drowning effects too if in water.

With the longer legs and serious claws, I'd give it the option to swap in a claw attack in place of the tail attack, one target - grappled or other, +8 to hit, reach 5 ft, 2D8 + 5 slashing. Either tail or a claw in a particular turn.

I'd make it CR5 like parent Giant Crocodile or bump up to CR6 for faster terrestrial speed, more potent grapple rule and claw attack option. Would have to play a lot more before I know if those enhancements are worth a CR point.

One last horrifying thought for your PCs. Crocs can and do climb trees. Google it, it was all over the news last February. Probably disadvantaged while climbing with its claws busy holding on, but so are most fleeing PCs.

And I'm still waiting for a boarcroc model. May have to try sculpting one myself, maybe by adapting a 6" long toy croc by doing longer legs and the pairs of bigger teeth.

Wednesday, October 8, 2014

Megadungeon Level 1 Map

I'm planning to have three entry levels, with this being the main one. It's really big, so only legible if you click into it.

Who's On Deck? Expanding Wandering Monster Checks

Some months ago I read a post with a brilliant set of tables for converting some wandering monster checks into foreshadowing with lots of details and two stages of foreshadowing. I'll have to hunt it down again to cite it properly.

Here is a simpler rule of thumb approach in the same general direction.

When doing old school wandering monster checks where a six would normally send you to the game's generic wandering monster chart or your dungeon's custom wandering monster table, invert the order of things a bit. Before any action gets going roll twice on your wandering monster tables.
The first roll is to identify who is lurking or hunting nearby. Besides the creatures lairing closest, this monster will be the first responder to noises made, magic emanations, and tracks made by the PCs. The second for a monster or group that has passed this way but is not an active threat. This info is just to prime you so you can think in background about suitable hints and signs, and in the case of the active monster, what's the right moment and approach for a dramatic entry.

When the time comes for a wandering monster check, roll the traditional D6:

4 - the PCs find a sign of the presence that the inactive monster has passed this way or is in the neighborhood. This could be things like tracks, scat, dried blood, dropped possessions, dried up bits of a victim/meal, shed hair or skin, or a faint and distant noise. Initiating tracking on the basis of this sign should be difficult or impossible, but the PCs get some hint of what they might face and maybe tension ratchets up a little. It's probably a red herring if acted on. Reroll now for the next inactive monster to be hinted at the next 4 rolled.

5 - the PCs get fresher and more direct sign, sound, or glimpse of the active monster. A tracker acting on it is likely to be able to track it with normal chances of success.

6 - The active monster attacks or engages with the party. Resolve the encounter as usual. If the PCs are at heightened alertness from a previous 5 roll for this monster, reduce the chances they are surprised. Roll to identify the next active monster when it's convenient.

Since you know the nearest wandering monster in advance, if the right moment to spring it becomes obvious, don't wait for the 6. But in fairness, that probably means skipping the next 6, turning it into a 5.

If going off of general random "could be anything" tables, record the inactive monsters and make it more likely than a completely random check off the table of turning up again, since they now have an instantiated history of having been present. Eventually as this list grows, it can become the list of likely wandering monsters (aside from statically placed ones that go roaming) for the dungeon level. Start using a lead in roll that opts between using the history list and generating a new, completely random monster that gets added to the history, which eventually favors the history list. At first it's 1 in 6 comes off the history list of previous inactive or (survived) active monsters. As the list grows, bump that up, until it is eventually 5 in 6 off the history list, with just the odd newcomer, bumping back down as unique ones get killed off. The history list should probably be seeded at the beginning with the types of monsters that are actually placed. Depending on your realism level, a wandering monster of the same type as a placed monster is that individual, so it potentially already dead or wounded if the PCs visit its lair or another unaccounted for "quantum" individual, so the lair is unaffected.

Pink trail of slime found on a 5.
The rubber band bits were a quick expedient for illustration, but the recent DM Craft video on water gives me an idea for doing various moveable slime trail tokens that should look awesome.

Sunday, October 5, 2014

Great Hall map

There are still some more digital edits I want to do to this one, but better to get a version of it up here now than wait any more. Previously posted versions in the relevant G+ groups.

Saturday, October 4, 2014

D&D 5e prep

Had a busy day preparing to run D&D 5e. Spent some time at the cafe with notebook working on the beginnings of a random dungeon generation scheme and some encounter notes. Then monopolized the dining room table again to put in some time scraping mold lines and cleaning sprue off a bunch of dungeon dressings. Cleared that mess away as the bits went outside for priming. Then picked out 4 figures to set up characters for test run, and wrote up their character sheets. Took about an hour per character for the full writeup but I wasn't rushing it. It's the traditional F/MU/C/TH party, with some minor wrinkles in the details of the characters.

Started with a cave entrance and the beginning of a Dwarven Forge dungeon, and my daughter sat down and laid out the rest of the dungeon behind the door from the pile of pieces for her own amusement. I'll go with her dungeon design, though I'll be adding some monsters, since she only had the little Cthulhu statues that were in the bag of DF pieces.

Leila and her dungeon

The party enters the cave with a balance of greed and trepidation.

Then they stop for portraits just before breaching the first door.

Gnigel the Gnome Rogue Raconteur - He'll be an Arcane Trickster if he survives to 3rd level. Upgrading his sling's performance to approach real world numbers may be my first 5e house rule. RPGs always underrate slings for range and damage while ignoring their real downsides. As a former slinger and student of the weapon, its one of my pet peeves.

Llewella of Kinholm - Noble Human Fighter in  mostly sensible armor. Greatsword armed and starting with the tanking feat Heavy Armor Master via the human starting feat option. Great weapon fighting is the obvious Fighting Style for her.

Ban Gundenson - Sage Mountain Dwarf Wizard - given his heritage, he'll either soon have armor under this robe or change to a more traditional dwarf figure. A wizard that can wear medium armor and has dwarf weapon training should be an interesting hybrid character.
Brother Kadros - Human Cleric, Acolyte of a war god. Shield and warhammer not depicted. Given the war god leanings that evolved with the character, and martial weapons proficiency, he'll probably move on to another figure soon.

Starting their adventure now as my shakedown cruise with the rules, then back to stitching together a megadungeon out of all those maps. Have the location picked out on the campaign map for Night's Dark Terror.

First fight with 5 goblins ended totally in the party's favor. After two combat rounds, they were unscratched, four goblins were down and dying and one running away. Got a better sense of how some of the rules interacted and sketched out house rulings on morale checks for the goblins, fumble handling, random displacement by successfully dodging a Sacred Flame spell, etc.

Tuesday, September 30, 2014

Paperclip 4.11 / Climate_control 0.3 problem with Jenkins - postmortem

In case we need to deal with this again or somebody else bumps into it...

Having just completed manual testing on a branch of our Proposals application that moves it from Rails 3.2 to 4.0.9, with other gems upgraded. Ruby is still on 1.9.3 in this project, with Ruby upgrade probably next on the list before dealing with remaining deprecations to lift Rails into the 4.1s or 4.2s. I merged the Rails4 branch into the dev branch and pushed, which means for us that as a deployment candidate, it starts getting run by the Jenkins continuous integration server. All the tests were succeeding there except for a set that had to do with file uploads using Paperclip. Paperclip and its dependencies from the Gemfile.lock:

    paperclip (4.1.1)
      activemodel (>= 3.0.0)
      activesupport (>= 3.0.0)
      cocaine (~> 0.5.3)

    cocaine (0.5.4)
      climate_control (>= 0.0.3, < 1.0)

   climate_control (0.0.3)

Representative error (43 more like it, testing various things about attachments):

 [1000D [?25l [31m1229/1464: 1.2k/1.4k, 83%, 2.4/s, elapsed: 00:05:54, ETA: 00:01:39
sh: file: No such file or directory
 [31mERROR [0m SupportingFileTest#test_supporting_file_passes_validation_with_unique_filename (0.07s) [K
  Errno::EINVAL:   Invalid argument - setenv
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/climate_control-0.0.3/lib/climate_control/modifier.rb:57:in `[]='
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/climate_control-0.0.3/lib/climate_control/modifier.rb:57:in `block in revert_changed_keys'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/climate_control-0.0.3/lib/climate_control/modifier.rb:56:in `each'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/climate_control-0.0.3/lib/climate_control/modifier.rb:56:in `revert_changed_keys'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/climate_control-0.0.3/lib/climate_control/modifier.rb:17:in `process'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/climate_control-0.0.3/lib/climate_control.rb:6:in `modify'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/cocaine-0.5.4/lib/cocaine/command_line/runners/process_runner.rb:44:in `with_modified_environment'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/cocaine-0.5.4/lib/cocaine/command_line/runners/process_runner.rb:21:in `call'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/cocaine-0.5.4/lib/cocaine/command_line.rb:122:in `execute'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/cocaine-0.5.4/lib/cocaine/command_line.rb:79:in `run'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/helpers.rb:31:in `run'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/file_command_content_type_detector.rb:18:in `type_from_file_command'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/file_command_content_type_detector.rb:10:in `detect'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/content_type_detector.rb:61:in `type_from_file_command'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/content_type_detector.rb:57:in `block in calculated_type_matches'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/content_type_detector.rb:57:in `select'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/content_type_detector.rb:57:in `calculated_type_matches'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/content_type_detector.rb:33:in `detect'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/io_adapters/file_adapter.rb:14:in `cache_current_values'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/io_adapters/file_adapter.rb:5:in `initialize'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/io_adapters/registry.rb:29:in `new'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/io_adapters/registry.rb:29:in `for'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/attachment.rb:98:in `assign'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/vendor/ruby/1.9.1/gems/paperclip-4.1.1/lib/paperclip/has_attached_file.rb:66:in `block in define_setter'
  /scratch/rails/.hudson/jobs/wip_bb/workspace/test/unit/file_attachments/supporting_file_test.rb:14:in `setup'

Reading the trace and inspection of code around the error did not get me too far. Standard rake test from the workspace directory worked correctly, so it had something to do with Jenkins or its configuration.

Insertion of debug "puts" statements showed that the problem in climate_control revert_changed_keys where it was restoring potentially changed enviroment variables cropped up against an environment variable at the head of the array of keys, that had the key of "", which setenv behind ENV[]= could not handle. So where does the weird empty string key come from? This env var had PATH-like contents, but a lot at a level that appeared to be for Jenkins and not for our application. When we looked at the environment variables listing from the most recent Jenkins build of the app, it showed up at the head of the list, above the _ one. Looking at the environment variables lists for earlier runs it does not show up. So apparently it is there for Jenkins and only displays for the most recent run. Got Jenkins to run green again by hacking the vendored climate_control gem (bundle install --path vendor is a build step before running tests).

Here is the change to the gem that fixed it:
climate_control(v0.0.3)/lib/climate_control/modifier.rb line 56:

  (@original_env.keys - keys_changed_by_block).each do |key|
changed to
(@original_env.keys - [""] - keys_changed_by_block).each do |key|

Thanks to David Hays who paired with me on sorting this one out.

Tuesday, September 16, 2014

Aiming for D&D 5e with B10 Night's Dark Terror

After a lot of reading and wrestling with alternatives I have settled on how to get started at running 5th Edition. This time around I am going to be a lazy bastard and use the old Night's Dark Terror module as a wilderness sandbox with assorted bits reworked or bolted on as needed, and nestle a couple dungeons of my own creation into the map, giving me a target for populating some of these inked maps I've been knocking out since last Fall, and keeping the scope of the task manageable.

I'll aim to do something with it for upcoming conventions, and start running some sessions, probably on Sundays in person or on Roll20.

For a bit of graphics in my Wall'oText, here is a tiny dungeon I don't think I've posted yet. I like the experiment with the stairs but it's a bit out of place on this map, and a candidate for digital erasure.