User Tools

Site Tools


blog

News

Catacombs of Wrath

Several years ago I started our first Pathfinder campaign using the Rise of the Runelords adventure path, and so far I've been running one or two chapters a year. We've just started on chapter five - Sins of the Saviors, with characters up to twelfth level.

Each chapter has been played slightly differently, as my understanding of the Pathfinder rules have changed over the years. For the previous chapter I switched to using Roll20 for managing things on the GM's side, with players still using pen and paper (well, PCGen in some instances) character sheets and real dice.

For this chapter I'm doing much the same, though the use of my API scripts from my purely Roll20 Magnimar campaign are streamlining some of the combat. I've also switched to almost entirely using miniatures. Previously we used a mix of Pathfinder Pawns and other things. This time I made the effort to make sure I have a figure for almost all of the creatures in the adventure. Painting them all took longer than expected, so I may not do that next time around.

Having miniatures on the board does look good though, along with the dry-erase dungeon tiles for mapping. Though I can throw a digital map up on the TV, I prefer to use this mostly for record keeping for me, and have the actual positions of everyone on the real table.

2018/05/08 22:08 · sam

Bumpy Worlds

I've been playing with the Javascript 3D library three.js to generate textured globe images for my WorldGen application. This allows me to relatively simply wrap a map texture around a globe, and have it rotating on a web page.

It also has a bump map feature, so applying a height map means it is possible to simulate differing heights for different parts of the world, and have them rendered on the globe. This is currently being used to show up coastlines, mountains and craters on the world as having varying heights.

Three.js also has the concept of a distortion map, which allows true height differences to be shown. Since most worlds are pretty flat at the scales shown, I'm not using this for now, though it seems like a good option for small bodies which aren't entirely round.

The original map for the world uses an icosahedral projection, which means it is non-contiguous (it has gaps inserted at regular intervals along the poles, to account for the reduced circumference at higher latitudes). Since it is made up of triangles, craters appear as obvious triangles or hexagons (as does the shading and coastlines), but I rate the benefits of triangles tiling perfectly into the icosahedron to be a bigger advantage. It would be possible to make the triangles smaller, but previous experience with world mapping has shown me that lower resolutions are easier (and quicker) to generate. Getting continents which actually look like real continents is easier at low resolution. High resolution fractal maps always ended up looking artificial without a lot of post-processing.

To generate the texture map, it's necessary to stretch the map to make it contiguous. It's a simple process to take each row, remove any background pixels, and then stretch the remaining pixels to fit the whole width of the map. As can be seen in the stretched image, the poles are quite heavily distorted, whereas the equatorial regions are left more or less intact.

This is a problem present on any rectangular real-world map - how to minimise the distortion at the poles in a way that is most beneficial.

Finally, there is the height map. Possibly due to me not fully understanding 3D graphics, my original attempts at bump mapping resulted in a large number of black lines all over the map, wherever there was a height difference. Since the height scale ranges from 1 to 100, every triangle was a different height to its neighbours, it looked like a mess. When the height map is first generated, it uses a semi-fractal algorithm which guides the creation of continents, and is used to produce shading.

After that though, it is flattened. Seas, craters and rifts are given a height of 1, the highest mountains a height of 100 and everything else is set to 50. This produces a very flat looking height map, but it seems to create better bump mapping effects than the more gradual scaling did.

By combining these various maps, I can display a practical flat map showing the world surface, as well as a more graphical textured globe for seeing what the world actually looks like. It should be relatively trivial to add in cloud effects, and even colouring according to the local starlight. The brightness of the globe is actually affected by the proximity to the local star, which is currently making hot worlds very bright. Whether that is accurate or not is something I need to check.

2018/02/25 13:54 · sam

D6 Adventure

I just finished running a one-off game (over half a dozen sessions) using the D6 Adventure system. Though I've played (and run) plenty of Star Wars D6 in the past, this was the first time I've tried using the D6 system for another setting.

Published by West End Games in 1996, D6 Adventure (along with D6 Fantasy and D6 Space) is a set of rules tailored for a specific genre. Though they share a lot of the core mechanics (roll a number of D6 equal to your skill, try and beat a target number), there are some differences in terms of the names given to attributes and skills. The Adventure rules are aimed at 'contemporary' settings - sometime around the 20th century.

My own game was based on the idea that the PCs were members of German military intelligence (the Abwehr) in 1927 (so prior to Hitler grabbing power, and at the height of the roaring twenties), hunting down a rogue agent who was selling secrets to French communists. It was relatively pulp, and wasn't entirely based in the real world since they soon found some glass tablets that allowed them to see a live map of the surrounding area (including being able to see people moving around, or zooming out to see the whole Earth). A chase from France to Russia and finally Sumatra led them to discovering a way to a post nuclear-war future, and evidence that they were living in a fake world running in a simulation (though they didn't quite understand that part, being from the 1920s). We ended the game with them getting hold of nuclear weapons, and planning a way to ensure Germany didn't lose the next war.

A few things I found useful were Youtube videos of the time period. Since most people were unfamiliar with the period (myself included), it was helpful to stick some videos of the various cities up on the TV (thanks to Chromecast) when they got there, so they had an idea of what they were seeing. I also shared pictures of people and artefacts in this way.

For the system, I had some difficulty balancing the combat system. Players were a lot more effective than I first assumed, so I had to scale up combats a bit towards the end to make them a bit more challenging. I played it far more narrative than I normally would though, so it wasn't too bad. There were some options though we had to 'fix' pretty early on though (+3 to difficulty to get a head shot doing +12 damage, when most guns were rolling 3D6 for damage felt very broken) in order to make things a bit more interesting.

When 2nd edition Star Wars came out, and introduced the wild die, my natural inclination at the time was to ignore it. We tried using it in this game, and personally I wouldn't use the wild die again. Rolling multiple D6 is already sufficiently random that it doesn't need any more, and you lose the consistency of high skill rolls that you got in Star Wars (there's still a chance of rolling 6 1s, but the chance of a really bad (or really good) roll goes down as your skill goes up).

On the whole though the system worked reasonably well. I chose it because I knew the base system, and leaving out the advantages/disadvantages options left a really simple system that was quick to roll up characters for and to play. Everyone seemed happy enough to be willing to use it again, possibly with a few modifications as mentioned above.

As a GM, I felt that the start and end of the game went quite well, though the middle of it dragged a little bit, mostly because I hadn't really figured out what to do with it. I had an idea for how to start things, and I had a vague idea of where things were ending up, but no good idea of how to get from A to Z. Given that it was a one-off game, it was never really meant to be an open sandbox, so was deliberately quite linear in the way it played out (though the PCs were sensible enough in their precautions at various points to sidestep some of the possible complications).

I think D6 is a good enough system that I also wouldn't mind giving it another go at some point, maybe with a setting closer to the present day. I'd definitely need to play with the combat system some more though, to figure out a better balance to add in a bit more danger for the PCs.

2018/02/14 19:39 · sam

Surprised Mooks

Initiative Tracker

I've made some updates to my Roll20 combat scripts, to automate some of the initiative handling. The initial option was a command to add multiple tokens to the initiative track. I already had this, but now it performs a number of other features:

* Clears any current initiatives. * Automatically creates a start of round marker, for tracking number of rounds. * Determines initiative for all tokens, and adds them to the track already sorted. * Marks them as being flat footed, unless they have an ability to prevent that.

To complicate things, there is also an option to make a Perception check for all tokens, and add them as surprised if they fail the given difficulty. 'Surprised' and 'Have Surprise' are now two token states that I've added. A surprise state is automatically removed when a token's turn comes up, as is flat footed (once they are no longer surprised). I did try a feature to automatically skip surprised tokens, but that caused problems with the event handler.

It's also possible to add new tokens to an existing combat, adding them as surprised or having surprise (in case you want to build up a list of participants by hand). They are automatically sorted into the combat in initiative order.

Delayed Actions

There is also some support for delayed and readied actions, making use of colour tints on the tokens themselves to make it obvious who has a delayed or readied action. This information is also shown in the initiative tracker itself. A token can undelay or unready at any point, in which case they will be added to the top of the initiative track, either after or before the current token (depending on whether it was a delay or ready).

Additionally, some house keeping is automatically performed when a token's initiative turn comes up. As well as un-flat footing them, an unconscious token will get an immediate stabilisation check, and regenerating or fast healing tokens will have that applied. There is also a new Weakened status that halts any regeneration for a round, that is automatically removed on a token's turn (I'm not certain this is correctly following the rules, but it's simple and consistent). Dead tokens are also automatically removed from the initiative track.

Finally, I've added a modification to how Mooks are handled at negative hitpoints. One issue I've had is that in a low level campaign like I've been running, many creatures have greatly more negative hitpoints than they have positive. A goblin with 4 hitpoints, can survive down to -11, so their hitpoint bar stretches off to the left, several times larger than the token itself. They also tend to stick around for ages.

To resolve this, a token's negative hitpoint limit is now capped at half their maximum hitpoints (normally it is their constitution score). Creatures with twice as many hitpoints as they have constitution are unaffected, and this only applies to a token which doesn't have the vision property set. The result is that low level critters should die a lot quicker once they are 'down', removing them from the initiative and need to worry about them.

2018/02/11 11:41 · sam

Improving World Maps

Some of the work that I've done on WorldGen recently has been around improving how world maps look. I'm still sticking to a few basic planet types for now, and the most ecologically advanced so far is the EoGaian world. These worlds are similar to what Earth was like billions of years ago. They are warm, wet worlds which have methane atmospheres, and the most advanced form of life that they have is bacteria, which only inhabits the seas.

This particular world shows barren land, ice caps and mats of bacterial organisms covering much of the ocean surface in the equatorial regions. This latter feature would be a potential random feature this type of world could have. Some fraction of worlds will have one or more special features that make them standout from typical worlds of their kind. The descriptive writeup of the world would include a description of the feature, as well as displaying its effects on the map.

What has also been added is a fractal height map, which is used to provide shading to the surface. Since I've also started looking at the three.js 3D Javascript library, this height map may be useful for creating a bump map to give the world's surface a more 3D feel to it (though realistically, even the highest mountain is going to appear like a smooth plain from orbit.

2018/01/19 19:21 · sam

Star System Map

Work on the world generator is coming along slower than planned, but I'm currently starting work on generating the surface maps for worlds. In the meantime, there's also solar system maps which display the current positions of each of the planets in the system.

What is shown here is a system modelled on Sol, with several inner worlds, and asteroid belt and a couple of outer gas giants. Since the software is a simulation as well as a generator, the current position of the planets is shown according to the current time. At the moment, all planets follow circular orbits, with no real plans to expand on that. Though the map display only copes with a single star in the system at the moment, the back end database copes with binary and triple systems, so there is a plan to add in support for that at some point.

The asteroid belts are randomly generated (but using a fixed seed, so it's the same random belt each time). Individual asteroids orbit with their own period, since that's pretty trivial to do.

The labels show the planet number (I, II, III etc), the planet type and it's distance from the star. There's only a small number of planet types at the moment. Hermian worlds are hot barren worlds similar to Mercury, EuArean worlds are dry desert worlds with thin atmospheres similar to Mars. Junic and Saturnian worlds are different types of gas giants.

Generating maps and unique features of these basic planet types is what I'm currently working on. Actually producing populations and civilisations for the worlds is still some way off.

2017/11/30 20:49 · sam

Sub Sectors

In the Traveller RPG, a sub-sector of space is a 2D region of space measuring 8 x 10 parsecs. 16 of these make up a sector (32 x 40 parsecs). Each parsec is represented as a hex, which may contain a single star system. Similar to my previous version of WorldGen, I'm generating details on multiple worlds and stars in each system - a system can be a binary or triple system, and each planet can be multiple moons.

So far I've added the framework for creating basic star systems with a few planets - just enough to be able to test the sector maps. The first version of the maps is a REST API for creating a static map, an example of which is shown here.

I'm trying to display a bit more information about the star system than classic Traveller maps do. Information on the number and type of stars is shown. The star size determines it's luminosity - D for a white dwarf, VII for a brown dwarf, VI - Ia for dwarf stars up to super giants etc), the colour it's spectral type (red, orange, yellow, blue etc). The planets in the system are also shown - small or large dots for terrestrial or jovian worlds, lines for asteroid belts etc.

Since there's nothing yet to actually populate any of these worlds with a civilisation, none of the world civilisation data is shown. A summary of this will be displayed for the system's 'Main World' (probably based on population and star port type) when I get that far. How much data is shown will probably depend on the scale the map is displayed at.

The next step is a choice between drawing a map of the star system, or starting to write some proper planet generators (by far the biggest task, at least until I get to the economic model). In the meantime, here's some of what's in the database for the map shown ('sss' is a view onto the sectors, systems and stars table).

mysql> select * from planets where name like 'Oyysa%';
+--------+-----------+-----------------+-----------+---------+----------+--------+--------------+
| id     | system_id | name            | parent_id | is_moon | distance | radius | type         |
+--------+-----------+-----------------+-----------+---------+----------+--------+--------------+
| 145754 |    145752 | Oyysa Alpha I   |    145753 |       0 |      162 |   1054 | Selenian     |
| 145755 |    145752 | Oyysa Alpha II  |    145753 |       0 |      177 |     16 | AsteroidBelt |
| 145756 |    145752 | Oyysa Alpha III |    145753 |       0 |      220 |  29000 | SubJovian    |
+--------+-----------+-----------------+-----------+---------+----------+--------+--------------+
3 rows in set (0.00 sec)

mysql> select * from sss;
+----------+---------------+---+----+------------+------+
| sector   | system        | x | y  | luminosity | type |
+----------+---------------+---+----+------------+------+
| Sector 1 | Imu           | 1 |  2 | VII        | T8   |
| Sector 1 | Edytre        | 1 |  3 | V          | F9   |
| Sector 1 | Tupi Minor    | 1 |  5 | VII        | T5   |
| Sector 1 | Ghuquistanu   | 1 |  6 | VI         | M8   |
| Sector 1 | Uman          | 1 |  7 | VI         | M9   |
| Sector 1 | Ghahir Minor  | 1 |  8 | VII        | T9   |
| Sector 1 | Sticanume     | 2 |  2 | VII        | L8   |
| Sector 1 | Thikytsa      | 2 |  4 | VII        | L6   |
| Sector 1 | Epsilon Acylo | 2 |  5 | VII        | L1   |
| Sector 1 | Otu           | 2 |  6 | D          | D8   |
| Sector 1 | Otu           | 2 |  6 | VII        | T6   |
| Sector 1 | Unu Yepy      | 2 |  9 | VI         | L4   |
| Sector 1 | Ghotod Prime  | 2 | 10 | D          | D5   |
| Sector 1 | Alpha Adud    | 3 |  1 | VII        | L6   |
| Sector 1 | Irehi         | 3 |  3 | VI         | L4   |
| Sector 1 | Naditi        | 3 |  5 | D          | D8   |
| Sector 1 | Naditi        | 3 |  5 | VII        | T2   |
| Sector 1 | Beta Hotonu   | 3 |  8 | D          | D8   |
| Sector 1 | Beta Hotonu   | 3 |  8 | VII        | T1   |
| Sector 1 | Oye           | 4 |  1 | VII        | L0   |
| Sector 1 | Anardu        | 4 |  4 | VI         | M0   |
| Sector 1 | Hyxuktat      | 4 |  5 | VI         | M8   |
| Sector 1 | Fity Ybew     | 4 |  7 | VII        | L2   |
| Sector 1 | Ane           | 4 |  8 | VI         | M7   |
| Sector 1 | Dahu          | 4 |  9 | VI         | M2   |
| Sector 1 | Little Eteh   | 5 |  1 | VI         | M3   |
| Sector 1 | Tayensa       | 5 |  4 | VII        | T4   |
| Sector 1 | Iquatu        | 5 |  6 | VII        | Y2   |
| Sector 1 | Oyysa         | 5 |  8 | VII        | T5   |
| Sector 1 | Oyysa         | 5 |  8 | D          | D6   |
| Sector 1 | Shaxifih      | 5 |  9 | VI         | L1   |
| Sector 1 | Noweh         | 6 |  3 | VI         | L2   |
| Sector 1 | Ebuvo         | 6 |  6 | VI         | M0   |
| Sector 1 | Sanabi        | 6 |  7 | II         | M4   |
| Sector 1 | Pheref Mege   | 6 |  9 | VII        | T5   |
| Sector 1 | Satiqugo      | 7 |  1 | VI         | M5   |
| Sector 1 | Ibe Seya      | 7 |  2 | V          | F0   |
| Sector 1 | Ahohu         | 7 |  3 | II         | M7   |
| Sector 1 | Ihodok        | 7 |  4 | VI         | L5   |
| Sector 1 | Ridefteri     | 7 |  6 | VII        | T3   |
| Sector 1 | Epsilon Yda   | 7 | 10 | VII        | L0   |
| Sector 1 | Ghotohihyyi   | 8 |  1 | VI         | M5   |
| Sector 1 | Shenana       | 8 |  2 | VII        | L6   |
| Sector 1 | Hahutuno      | 8 |  4 | VII        | L4   |
| Sector 1 | Wenahlu       | 8 |  6 | VII        | Y8   |
| Sector 1 | Wenahlu       | 8 |  6 | D          | D6   |
| Sector 1 | Odopayot      | 8 |  9 | VI         | M1   |
| Sector 1 | Nefuxdami     | 8 | 10 | V          | G7   |
+----------+---------------+---+----+------------+------+
48 rows in set (0.00 sec)
2017/09/10 16:13 · sam

Generating Star Maps

I'm starting to re-write my Traveller-style star system mapper, and my current step is allowing the creation of a galaxy (or at least, part of a galaxy) from a simple density map. The idea is that you can draw what you want your star map to roughly look like by creating a grey scale image which shows the relative densities of star systems in different areas. Black areas have very few star systems, white areas are densely populated with star systems.

The mapping software will then take that and generate a distribution of star systems across Sectors of space using this density map. The sample image shows dark regions which represent an underpopulated rift, with a bright densely populated region at the top right. The probability of any given hex having a star system ranges from 1% to 95%.

The centre of the image is overlaid with a grid of Sectors that shows the actual generated star systems, with the core Sector (0,0) right in the centre. Using a density map allows the geography of local space to be easily sketched out, and then procedural generation can do the rest.

Though the shown map uses quite distinct levels of grey for testing purposes, any shade of grey can be used, and the map can be as uniform or clumpy as you want (after all, it's just an image).

A similar technique could be used to define different civilisations, types of stars or level of colonisation according to image colour or intensity.

2017/08/28 14:32 · sam

Character Information

Roll20 can be great at allowing the GM to track information on characters and monsters, but I've found that accessing that information can be tricky at times. Having to find the token, open up it's character sheet, and navigate to the correct tab to find some information can be time consuming, and as a GM I'd prefer to have that information available immediately.

Over the last few years that I've spent GMing on Roll20, I've written a number of API scripts to try and make that process simpler. Recently I've been tidying up these scripts to make them more consistent, and also to make better use of the Pathfinder Character Sheets that didn't exist when I started.

There's two main API commands for getting information about a token - !pfdescribe and !pfinfo. The first is designed to output information to the chat window for players. I find putting information here, rather than in another dialog, to be quicker and easier. Running !pfdescribe on a selected token will output the name, avatar image and bio of that creature, merging information from both the graphic token and character. As a bonus, it will also check for status markers on the token, and output condition information about it. For instance, the Goblin shown here is both heavily wounded and dazzled.

The !pfinfo command is for use by the GM, and displays some basic stats about the creature, which also includes any condition effects that apply to it, just like the description. If the creature has special qualities, such as SR or DR, or attack or defence notes, these will be mentioned. It's also possible to add a note to the character sheet which will appear highlighted for abilities which are really important to remember (but which I'm likely to forget in the middle of a game), such as everyone having to make fear checks as soon as they see it.

The !pfdescribe commands also works for non-combat related things. It has three different modes, for three different use cases. If the graphics token has a character associated with it, then it displays information on the character as above. However, if the token isn't linked to a character it can be used to share other types of information to players.

The first is if the token has the same name as a handout, in which case any graphics and text from the handout are displayed instead. In this example, The Celwynvian Charge is a point of interest on a map. My current campaign is set in the city of Magnimar, and so one page consists of a map of the city. Various icons on the map can be clicked on by players to get information on the site.

If the token doesn't match a handout name, then the notes from the token are displayed. This was mainly designed for putting room descriptions on the map for dungeons and the like. It's also possible to reference images from the description, in order to show a picture. For basic text, I don't want to have to create a handout for every room, so instead just have a simple token (in the GM layer) with some text that I can run a macro against. This outputs the room description to the chat window. This allows me to give a quick freeform description of the room, and use the text for a more formal description which the players can read at their leisure.

I haven't got around to putting the scripts into the official list yet, but PfInfo and PfDescribe are currently available on GitHub. PfInfo is the core script which is depended on by PfDescribe.

2017/06/04 21:21 · sam

Icosahedrons

A while back I wrote a mapper for the Traveller SF universe. By mapper I mean mapping every planet and moon in that universe. I went through various methods of generating world maps (aiming for quantity and descriptive accuracy, rather than quality), eventually settling on Icosahedral maps for simplicity.

These are similar in style to the original Traveller world templates, but using triangles rather than hexes for the internal grid. Basically, the Icosahedron (a twenty sided solid) crudely approximates a sphere, but is easier to flatten into a 2D map. Each of the twenty faces is a large triangle, and in turn I split these up into smaller triangles.

The last iteration of that code hardcoded splitting each face into 4 rows of smaller triangles. I got sidetracked for a few years after that, and now I've started looking again at re-writing things from scratch. I've started with the world mapper, and now have a basic generic framework that allows me to generate maps of any resolution. Those shown here start at 5 rows/face, going up through 8 rows, 12, 24 and 48.

The larger the number of triangles, the better the end result should look, but the harder it will be to auto-generate a consistent world map.

I'll probably start with gas giants, since I only need to create cloud formations. Barren ice or desert worlds are a bit harder, and Earth-like worlds are the hardest. As before, I'll want to be able to generate a textual description of the world alongside the map, so simply creating a random fractal map (which most world generators do) isn't the easiest option, since they're hard to describe.

2017/05/25 18:09 · sam
blog.txt · Last modified: 2019/07/30 22:50 by sam