HexTracks: A Mathy Procedural Hexagonal Racing Game

Quick Introduction
I recently started this project to make something for and with my 8 year old. It’s inspired by an old homework assignment from the 90s. The idea is that it’s a turn based, strategic racing game. On your turn, you will by default move your previous speed forward. You can nudge your speed up or down, but only to a limited extent, and you can rotate left or right 60°. Hit a wall and you’ll loose a turn and start over from 0 speed, so you need to walk a line between fast and agile.

I’m currently doing it in Unity, using pure C# for most of my business logic. As with everything involving hexagons in the past decade, a huge amount of thanks is owed to Red Blob Games’ page on Hexagonal Grids. Art was done in a mix of Blender and Asset Forge.

Planned Scope
In addition to the basic mechanics described above (which are pulled wholesale from that homework assignment) I want to include additional vehicle differentiation, so I’m eyeing several different vehicle traits. At the moment I have a loose constellation of:

  • Max speed
  • Max safe turn speed (trying to turn when moving above this speed will cause a rollover)
  • Acceleration profile? (e.g., maybe a car with a slow start requires two turns to go from 0 to 1, so you need to strongly prioritize not crashing)
  • Momentum (determines speed loss from driving through obstacles like crates and water barrels)
  • Offroad Speed (how fast you can go on “shortcut” roads)

One thing I want to specifically avoid is Mariokart style front-facing weapons and catch up mechanics (the latter don’t even make sense with this movement model). My solution at present is to pepper the course—especially straightaways—with one-shot obstacles that slow down anyone driving through them. So if a player has a wide lead, they either need to use extra turns juking to dodge obstacles or else slow down by traveling through them (and at the same time clearing the path for players behind them).

I’m also planning on lumping several (probably 4) courses into a single “game” with a point total determining the overall winner, and “reward” the winner of each individual race with a random cumulative penalty from the Wheel! Of! Penalties!

Proc Gen
The current courses are procedurally generated, but a top-down view of them makes the algorithm fairly clear:

I perform a random walk on a simple hex grid, and then explode each vertex of the path out into a hexagonal pool of road on a larger map. Paths of varying width connect the vertices, and then some paths get a “median” added, and I quasi-randomly look for big areas of open space that I can interrupt with islands of forest.

Long term I plan to combine this approach with some Bézier curve pathing as well as another few layers of post-processing to add obstacles, (limited) short cuts, and some dynamic obstacles like areas where boulders randomly roll across the road.

Next Steps
The immediate next step is implementing the full turn programming framework. Right now you can “free drive” a car around using the arrow keys and instantaneous car movement, but I want to move to the speed-based movement with animated transitions (probably also Bézier curves).

4 Likes

This looks great! I love the colour variation and I also like the proc gen spaces it makes.

Any plans for shortcuts? They could have interesting risk/reward ratios with a bit of mastery. Though this sounds like a good scope already…

So what I’m going to do is build a Dijkstra map between the start and finish lines and then poll all the road hexes that are next to wall tiles, and then have them look for any hexes within a certain radius (say, 7?) that have a Dijkstra value difference within some threshold- my plan is for a fast car to typically move 6 or 7 hexes in a given turn, so if a tile has a Dijkstra value that is… between 25 and 30 less than a tile 6 hexes away, I can assume that’s about 4-5 turns of travel to get from one to the other normally. Putting a narrow off-road path between them (with a twist or two to force people to go slowish) will give cars with lower top speeds but higher relative off-road speeds some catch-up time. It will take fine-tuning.

I’m trying to avoid explicit rubber-banding catch-up mechanics within a race (e.g., a hazard-free shortcut that “unlocks” once a car has reached a certain distance); there’s nothing to prevent a car that’s in the lead from taking advantage of the shortcut, too. But the Wheel! Of! Penalties! will probably cool them down in the long run.

Note that these shortcuts more or less require switchbacks on the map to exist, so that will probably go in as a level gen constraint, too.

This is reminding me of the board game Formula D. In that game, using the simple rule set you had gear shifting: lower gears used smaller dice that moved you fewer spaces, larger dice that moved you faster. Go too fast into a turn and you take damage, and if you lose all health you crash and burn. Gave a risk/reward element to blasting through tight turns.

1 Like

I haven’t played Formula D (I have played Downforce and recommend it in strongest terms if you like racing board games) but I have a background in board game design and and apart from the procedural track this project is a board game in all but implementation and takes strong influences from the field. I may develop a board game alongside,

2 Likes