Stat-Agnostic Skills

After getting the bullet behaviors in DET-33 into a good place, the next system to crack was skills: the active abilities a player picks up as they level. I’d built ability systems before and always regretted the same thing, so this time I restructured them to be stat-agnostic from the start. The mistake I keep making The tempting way to define a skill is to reach into player stats. “Healing scales with your wisdom, damage scales with your level.” It feels right and it ruins you later. Every skill becomes coupled to the stat model, balancing one thing ripples into everything, and you can’t reason about a skill in isolation. Years ago I wrote about balancing game mechanics by drawing the tree of which stats feed which. The lesson I took from doing that is that the fewer edges in that tree, the better, and skills reading stats directly add a lot of edges. ...

November 16, 2025 · 2 min

Composable Bullet Behaviors

This fall I started building a new game: a bullet-hell roguelike called DET-33, built on Phaser 3 and Vue. It’s the kind of game where the whole appeal is hundreds of projectiles on screen doing wildly different things, which means the weapon code becomes the heart of the project very quickly. Mine started as one weapon.js file, and it did not stay manageable for long. The problem is the obvious one. A bullet that travels in a straight line, a bullet that spirals, a bullet that boomerangs back, a bullet that splits on impact, and a bullet that drops an acid pool are all “a bullet,” but the branching to support them in one file gets ugly fast. So I tore weapon.js apart and rebuilt the projectiles as composable behaviors using the strategy pattern. ...

October 19, 2025 · 3 min

Composition Over Configuration in Compass

The individual generators in compass (the arroyos and rivers, the caverns and meanders) are the fun part to show off, but they aren’t what makes the library usable. The part I’m actually proud of is the composition layer that sits on top, and it owes a lot to the runtime pipeline patterns I wrote about a while ago. Shapes times features Every room is described as a shape combined with a feature. There are 24 shapes: squares and circles, but also blobs, crystalline caverns, crescents, capsules, and a handful of hallway types. There are 18 features: pillars, islands, stepping stones, pools, moats, chasms, rubble, and four kinds of river. Any shape can pair with any feature, which is 432 distinct room configurations before you’ve placed a single one. A feature is just two functions: an initialize step that works out the geometry (the meandering river feature, for example, generates a sine-wave centerline and expands around it), and a content step that decides the terrain type for each tile inside the shape. Keeping those two responsibilities separate is what lets the same river feature drop into a square room or an L-shaped hallway without caring which it landed in. ...

October 13, 2024 · 3 min

Runtime Pipeline Patterns

Introduction Pipeline patterns are most commonly used for simple data workflows like general functional composition or user registration processes. After briefly describing the basics, this article focuses on a couple of behavioral software design patterns under the strategy pattern we’ll refer to as “runtime patterns” for use with pipelines. Their power in modern applications is allowing pipelines to expand or contract dynamically. Whether it be through behavior modeling with ai, blueprint fulfilling or more basic conditional pipeline adaptation, the runtime patterns are helpful and with forethought can be simply understood and implemented. ...

February 25, 2019 · 4 min