I need a hex map

Tags:

My party of adventurers are sailing to the Lemurian Remanant as part of a quest imposed upon some of them so they could heal from the damage of an automaton. Think the some what misinterpreted way a clay golem in 1e AD&D does damage. In this case, in Hyperborea that interpretation is clear.

In any case, in their last session they fended off many attacks. From giant octopuses, giant squids, and a bunch of great white sharks. As it so happens, a shark was able to take a damaging bite out of their ship.

They had already planned to stop at an island on the charts to prepare for the crossing of a nasty part of the open sea, the River Okeanos. With the damaged ship, the stop has become imperative.

I was mostly going to handwave the stop for the most part. Now, I kinda want to plop down something and see if it I can distract them.

First, I needed to make a map of the island and I think it needed to be hexes since it's "wilderness".

That means two things:

  1. Inkscape
  2. Pelle Nilsson's hex map extension

So, once you have Inkscape installed as well as the extension you are head to make some hexmaps to your heart's content.

First I created a page full of 2.5" (flat side to flat side) hexes on US letter sized paper. In the Style table I have Rotate option checked. This have the hexes "pointy end" towards the top of the page.

screen capture of hexmap inkscape extension and a page of hexes

These hexes represent 25 miles per hex. For a bit finer detail I then wanted to add in some 5 mile hexes. I partly chose the 2.5" hex partly because it's easily divisible by 5. I also created a new layer so that each new hex size are independent from each other and I change the properties of them.

You will need to try and undo the number of columns and rows so that the hexes cover the page just enough.

screen capture of hexmap inkscape extension and a page of with smaller hexes

I had considered a third layer of .1 in hexes but that creates a lot of svg objects and it can bog down your computer a bit when you need to change properties or even group them together.

Once I had this base map I added the rough shape of the island from the Hyperborea map along with what I am interpreting to be breaks around it. Reefs or other navigation hazards for large ships.

I wasn't not satisfied with how the map was turning it.

I finally decided what I needed for the map the players will see is one large hex with smaller hexes inside that. The big hex being 25 miles and the smaller hexes being 5 miles.

So I created a monstrous 8" hex, 1.6" hexes inside that, and .12" hexes inside those. Yeah, I did just say that those are a pain and resource drain. However, I only made enough to just fit the big hex.

I then meticulously deleted everything outside the monster hex (uploaded as slightly different version since someone noted some weirdness with it and we'll see if this helps --edit 2020-09-22).

screen capture of hexmap with 1 large hex, many smaller hexes inside that, and even smaller hexes inside those

I changed the shading/"grayness" of the lines for each hex type. You do this under the "Fill and Stroke" submenu under the "Object" menu. The big, 25 mile hex is pure black: 255. The 5 mile hexes are a dark grey: 100. Finally the 1 mile hexes are a light grey: 25.

So, being a lazy DM I started looking through my various old school things I've bought over the years.

I reached for the Echoes from Fomalhaut(EFF) published by E.M.D.T. First Hungarian D20 Society. Gabor Lux is the force of nature behind this excellent zine. You can get pdf's from Drivethrurpg. However, do yourself a favor and get the paper version mailed to you from Hungary. When maps are provided with the zine the paper is top quality. Seriously, I like the paper used for these maps so much. You should also get the pdf version with your purchase (I will update this post if that is not the case).

I had thought about The Beekeeper from EFF #01 but kept scanning through the rest.

Terror from Tridentfish Island in EFF #03 really filled my need. It even has the same vibe and even some world hooks that work great in Hyperborea. I just need to smudge it a little and munge things to work with where it needed to go.

A little work later and I have something I can use. This is only the geography of the island. I can't show off the fun bits. You gotta get Gabor's excellent work to find out what my party might find on the island if they go exploring it instead of attending to the needed repairs.

hexmap of the tridentfish island geography mangled to fix the island shape

Thanks to Inkscape to making a tool that I'm capable of making a basic tool of the DM trade.

Thanks to Pelle Nilsson for making an extension to Inkscape so I can make hexmaps to my specifications.

Thanks to Gabor Lux for continually make some of the best old school content out there. When he posts he has something new to buy I don't think twice about rushing to purchase it.

Hyperborea: Amazon Carrack

Tags:

TL;DR: I need a deck plan for a ship. I didn't quite like what I found so I made my own.

So, my party decided to purchase a sailing vessel and hire a crew.

So I went searching on the web and asking on the Hyperborea Forums forums as well.

Serendipitously I have been watching a YouTube channel of a guy restoring an old, wooden sailing vessel. In a few episodes he goes about explaining how to read the prints for a ship. It did help a bit with this project. I didn't go too deep into an accurate deck plan. I wanted something good enough to work but also some semblance of "correct".

So, this is what I came up with.

scalar vector graphic of an amazon carrack deck plan

Amazon Carrack Deck Plan Key

  1. Forecastle
  2. Aftcastle or Sterncastle
  3. Galley
  4. Officers Cabin
  5. Captain's Cabin
  6. Passenger Cabin
  7. Passenger Cabin
  8. Officers Cabin
  9. Crew Quarters
  10. Crew Quarters
  11. Passenger Cabin
  12. Passenger Cabin
  13. Passenger Cabin
  14. Passenger Cabin
  15. Passenger Cabin
  16. Passenger Cabin
  17. Crew Quarters
  18. Cargo Deck
  19. Steerage Deck

So this is nice and all, but I needed something that I think is better to use in my campaign which is on Roll20.

The instructions are for roll20. I have a license for fantasy grounds but I haven't really used it. So, if you are a FG user you'll probably figure it out before I do.

Most of my maps on roll20 are 25x25 squares of 70pixels.

After uploading it I put it in the map layer.

I right click on the image, select Advanced -> Set Dimensions.

Set the dimensions given for the image (see below).

Right cick on image, Advanced -> Align to Grid

Click and drag a square, it doesn't really matter how big.

Then select the grid cell size to 35x35.

This should then align the grid of the deck to the grid of the vtt map.

Also, each grid on the deck plan is 5 feet, which is what I usually use for my games.

First, a mashup of the castles and main deck. The practical surface area for combat.

This map is 700x210 pixels.

image of deckplan to use for combat with a virtual table top campaign

This map is the main deck. It is 665x210 pixels.

image of main deckplan to use with a virtual table top campaign

This map is the lower deck. It is 665x175 pixels.

image of lower deckplan to use with a virtual table top campaign

I hope it's useful for those needing a ship in whatever system you use.

I might update this post with some screenshots of exactly what I do in Roll20 but this is what I have time for at the moment.

Happy gaming everyone and remember Rule 0: Have fun.

Roll20 character sheet import

Tags:

Intro

A long term project of mine was to find an easy way to import character sheets into Roll20.

There are tools for D&D 5e and such but nothing for my game of choice, Astonishing Swordsmen and Sorcerers of Hyperborea. Hyperborea for short.

Recently I did find an API using tool that would work. However, that requires you to have a paid account. Which I do. I still might use it.

However, I did find something that mostly works, Roll20 Character Import/Export.

I do have a program that can take a yaml file and populate a form fillable pdf. Taking that and banging my head against the wall for a few weeks. With some help from a friend to understand some javascript I was able to get it working as much I really need it to.

The Base Character Sheet

So, I'm trying out the idea of keeping character info a yaml or markdown file.

I've settled on something like this:

ST: 17
DX: 10
CN: 14
IN: 17
WS: 12
CH: 12
class: fire lord
level: 5

Race: Kelt

Gender: female

Age: 17

HP: 45

XP: 45,000

Gear:
  - <starter_pack>
  - Hunting horn
  - leather mask
  - <hm>dagger x3[w]
  - <a>small shield

Magic:
  - Hand Axe +2

Spells:
  - Flaming Missile
  - Flame Blade
  - Fireball

This has some syntax in it that I built up as I was making my pc generator for Hyperborea. There are many table lookups and such. I then dump the data into a Form Data Forma, (FDF) that I can use to create a Hyperborea character sheet.

I can take data from one format and munge into another.

Now to think about the next data format.

Roll20 Character Sheet

Roll20 has a lot of character sheets you can use in your game. A lot of them, you can even submit yours to be added to the repo.

To figure out what Roll20 has named each of the various attributes you will need to get a copy of your target character sheet. You can either clone their repo or you can find your character sheet in the repo and get that copy.

For HTML munging and extraction I reach for Mojo::DOM.

It doesn't take much to get what I want:

my ($html) = join('',<>);

my $dom = Mojo::DOM->new($html);

say $dom->find('[name]')->map(attr => 'name')->join("\n");

It's just using CSS selectors so it shouldn't be too hard to translate that to the language of your choice.

I then created a mapping to go from my program (centered around an FDF) to the roll20 names:

"Character Name": character_name
"Class": class
Level: level
Align: align

ST: ST
"ST Attack Mod": meleehitbonus
"ST Damage adj": meleedmgbonus 
"Test of ST": testst 
"Feat of ST": featst

Next is the hard part.

Import Character data into Roll20 Character Sheet

I did find something that was relatively easy...ish to import that data, ChatSetAttr.

However, most folks don't pay for roll20. I use it enough and I like to pay for useful things like it, but I still wanted a way to get character sheet data imported.

To be honest...I was looking at the problem off and on for probably a year before I found this Firefox plugin.

I have manually entered the character data in a test campaign I use for ideas I want to try out. I mention this because my initial attempts to import a character that I hadn't manually imported, nor used the ChatSetAttr API didn't work.

Eventually I hit upon exporting a character sheet that I had filled out manually. This gave me the format to import.

{
    "schema_version": 1,
    "name": "barb_test",
    "avatar": "",
    "bio": "",
    "attribs": [
        {
            "name": "reactionmod",
            "current": "1",
            "max": "",
            "id": "-M4dusSQdUOIdxhCvhKD"
        },

I was then stuck on that id.

I went to the roll20 forums and was pointed to some code.

This code creates a sort of UUID. The main thrust of it being something like:

return function() {
        var c = (new Date()).getTime() + 0, d = c === a;
        a = c;
        for (var e = new Array(8), f = 7; 0 <= f; f--) {
            e[f] = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".charAt(c % 64);
            c = Math.floor(c / 64);
        }

A revelation

So, now I needed to translate those functions into my weapon of choice, Perl.

A friend helped me with the translation so I could generate uuid's in the format that roll20 understands.

That bit of help broke open the damn...or...was just enough help to smash my head through the wall I was hitting against.

The repeating items problem

Being able to import basic player info was great.

Now I had to tackle what are in the html as repeating items. Things like gear, abilities, weapon info, spells, etc.

This was mostly a puzzle for my code. The uuid code does have something explicit for repeating items uuids.

{
            "name": "repeating_melee_-M4dusTPpXLZyuX3dipz_meleeweaponname",
            "current": "dagger",
            "max": "",
            "id": "-M4dusTP3-Ipr2NBQx-P"
        },
        {
            "name": "repeating_melee_-M4dusTPpXLZyuX3dipz_meleeclass",
            "current": "1",
            "max": "",
            "id": "-M4dusTQdb3JG38lovQM"
        },
        {
            "name": "repeating_melee_-M4dusTPpXLZyuX3dipz_meleeatkrate",
            "current": "1/1",
            "max": "",
            "id": "-M4dusTQEEylJV5QjKro"
        },
        {
            "name": "repeating_melee_-M4dusTPpXLZyuX3dipz_meleeatkmod",
            "current": "0",
            "max": "",
            "id": "-M4dusTQ7yLYX5ddp6oD"
        },
        {
            "name": "repeating_melee_-M4dusTPpXLZyuX3dipz_meleedamage",
            "current": "1d4+1",
            "max": "",
            "id": "-M4dusTRgK3BjoBRFvle"
        },

In the above snippet, this represents the info for a melee weapon. It's name, weapon close, attack rate, attack modifiers, and damage. There is a a field for notes which I didn't enter for this weapon.

Each html attribute name is of the format, "repeating_melee_ROWID_attrname". ROWID is replaced with a row id that is similar to the "normal" uuid. Each item in the same line has the same ROWID but different "id"s.

That is basically it.

I am still going through and adding things but now it's just an iterative process. I update the code, fix the syntax errors in my code because I mostly do this at the end of the day and I have very little brain for such task, and then do and import to see what it looks like.

So far the only thing that isn't really working is the equipment list. I'm ok with that. It can be added manually if needed. These programs take a lot of the pain out of this.

TL;DR

  • start with a beginning data format
  • munge to a target format
  • add another target format
  • extract HTML attribute names from an html file
  • use those names to map from initial format to new target format
  • create properly formatted json file
  • test import
  • check that it looks ok
  • lather
  • rinse
  • repeat as needed

Fin

And with that...I need to go to bed, maybe watch some WestWorld. Good night y'all.