Barrowlight / Design & development

Barrowlight.

A turn-based roguelike where the ground, the light, and the timing of a turn all matter.

MY ROLE
Game design, technical direction, playtesting
TECH
C++17, SFML 3, CMake
STATE
Released Windows build
Barrowlight encounter showing fire spreading across oil and lightning traveling through water
01 / COMBAT SYSTEM Fire spreads over oil; lightning travels through water.

THE DESIGN QUESTION

Make knowledge
matter.

Can a player do better on the next run because they understand the world, even before they gain more power?

Barrowlight is built around that question. Encounters use telegraphed attacks, light and darkness, and surfaces that combine. Fire ignites oil, cold freezes water, and lightning travels through wet tiles. The aim is to make the environment something players can read and use.

READ THE FULL DESIGN LOG ↗

FROM FEEL TO IMPLEMENTATION

Three decisions behind the game.

01 / PLAYER RULE

Consequences are visible.

Heavy attacks give the player a reaction window. Surfaces interact by rules that can be learned and reused across encounters.

02 / CODE RULE

Preview and cast agree.

Pure targeting functions drive both the on-screen preview and the actual cast, so the choice shown is the choice applied.

03 / TEST RULE

Runs can be replayed.

Rules are separate from rendering. A single seeded random stream makes bot-discovered bugs reproducible, alongside console and application tests.

PROCEDURAL GENERATION

Floors built
from modules.

Each floor is a 3×3 grid of cells that fit together like tiles: hand-made set pieces mixed with rooms generated on the spot.

Every cell has the same footprint and the same four doorways, so any cell can sit next to any other. A random spanning tree joins the grid, which guarantees the whole floor is connected, and most of the remaining doorways are opened too, so there is usually more than one route and monsters can arrive from more than one side.

So that no two floors share an outline, up to two cells are left as solid rock (an L, a U, a ring, never a floor cut in two), pairs of cells merge into big rooms such as a nave or a rift gallery, and doorways slide along their edges. Some rooms hold chasms: a well-timed shove drops a foe to the floor below.

About half the ordinary rooms are generated: pillared halls, rooms with several doorways, ruins, or cellular-automaton caverns, built around wherever their doorways fell. They must pass the same validator as the 28 hand-made rooms, so a generated room can never cut off a doorway. Landmark events, a boss arena or a sealed vault claim their own cells, and furniture is placed in whole arrangements, kept only if a flood fill shows nothing was cut off.

Some rooms bring their own fight. In the Rift Crossing, guards hold both bridges and archers fire from the far ledges; a guard never leaves its post, so you break through or knock it into the rift. In the Gauntlet, ambushers wait hidden in the side rooms and step out behind you, but revealing themselves costs their turn, so the ambush is felt but fair.

Barrowlight floor 4, Ruined Sanctum, seed 4: a generated map
02 / FLOOR GENERATOR

Floor 4, Ruined Sanctum, seed 4

  • Start
  • Door down (colour varies by floor)
  • Boss
  • Vault
  • Event
  • Encounter
  • Furniture
  • Guard post
  • Archer’s ledge
  • Hiding place
  • Italic names are generated rooms
Generation step 1: a 3 by 3 grid of empty cells
03 / HOW A FLOOR IS BUILT

1 / 9 A floor starts as a 3×3 grid of cells, each 21×13 tiles.

    HOW IT STAYS SOUND

    Random, but never broken.

    01 / CONNECTED BY CONSTRUCTION

    A tree first, loops second.

    Kruskal’s algorithm over the shuffled grid edges builds a spanning tree; each remaining edge then opens with a 65% chance. Doorways slide along their edges; behind them, a search that carves the fewest walls would join up anything cut off. With today’s rooms it has never had to, across 1,600 floors measured. The room farthest from the start holds the boss or the door down.

    02 / ONE SET OF RULES

    Generated cells obey the hand-made rules.

    Doorways open, every tile reachable, a clear centre for encounters, at least half floor. A generated cell that fails is repaired or rerolled, up to 40 times.

    03 / CHECKED AT SCALE

    Tested across seeds, seen at a glance.

    A console test flood-fills hundreds of floors and checks event rates. A viewer made for tuning draws any floor of the run from its seed, using the game’s own parameters.

    Barrowlight talent map showing affinity branches and a fireball tooltip with damage, cost and cooldown
    04 / TALENT SYSTEM The map and tooltips show how a build can branch before a player commits.

    CONTRIBUTION & PROCESS

    What I owned.

    I designed the systems, directed the architecture, and made the calls about what stayed, changed, or was cut.

    Much of the code was implemented with AI coding assistants under my direction. I playtested each system by hand. The repository records that process and the technical trade-offs; it includes 19 console test programs, two application test programs, and a playtest bot.