Royce Townsend
AboutBlog

Weather Hex-crawl

I was inspired by Daniel Sell’s method for generating weather by rolling a six-sided-dice to move around on a hex grid containing the possible weather results. I am a programmer, so naturally I wanted to turn it into a React app! rolls eyes

Hexagonal grid math

Last time I made a hexagonal board for a game, I used a cartesian coordinate system. The code to move to an adjacent is a bit weird. Sometimes you increment/decrement x. Sometimes you don’t. It depends on the value of y. Is this implementation obviously correct?

var steps = {
ne: function (coord) {
return [coord[0] + (coord[1] % 2 ? 1 : 0), coord[1] - 1]; // highlight-line
},
e: function (coord) {
return [coord[0] + 1, coord[1]];
},
// ...
nw: function (coord) {
return [coord[0] - (coord[1] % 2 ? 0 : 1), coord[1] - 1]; // highlight-line
},
};

This time I’m using a cubic coordinate system. A cool property of a cubic coordinate system is that x + y + z = 0.

export const directions: CubeCoord[] = [
[1, 0, -1],
[1, -1, 0],
[0, -1, 1],
[-1, 0, 1],
[-1, 1, 0],
[0, 1, -1],
];

Icons

Daniel’s method uses colour and a legend to represent different weather. This is an excellent approach: it allows the DM to focus on gameable weather and it is simple - so very simple.

Coloured hexes in a grid (radius of 3) representing weather

I decided to add svg icons to the mix. React-Icons has a set of clouds and suns and lightning. It’s almost prefect for my purposes. Some of the weather combinations that I want are missing, so I have stitched them together using the pieces of the original SVGs. Here are my custom icons!

Everything else.

  • React hooks and functional components. I do not miss class components at all!
  • Recoil. I still like it more than Redux.
  • Snapshot testing. This was an exploratory project so there is no correct functionality, but I still want to know if I accidentally break something. See options.test.ts.
  • Typescript. Sometimes it’s annoying. There are places — particularly when using lodash — where it fails to infer the correct type. I like being able to use strings as constants/enums and not having to worry about typos.
  • Lodash. As a result of limitation of babel-plugin-lodash (“Chain sequences aren’t supported. See this blog post for alternatives”), I tried using lodash/fp and flow (instead of _.chain).

Here is the final widget in all it’s inelegant glory!

All the code is on github at github.com/Royce/weather-hex

© 2021 Royce Townsend