All Devlog Posts
Ecology Over Taxonomy cover

The standard way to populate a dungeon room with enemies is to maintain a list of enemy types associated with that dungeon tier, pick from the list based on some weighting, and place the selected units in the room. This produces rooms that are technically varied but often feel like grab-bags: three unrelated enemy types occupying the same space with no coherent relationship to each other or to the room's context.

We call this the taxonomy problem: the enemies are categorized by what they are (flying, armored, ranged) rather than by what they do in the context of a particular encounter. When the system places enemies taxonomically, the resulting room feels like a museum display rather than a living space. You see specimens from different categories, not a group of creatures that belong together.

The ecological approach we use in Ruinveil starts from a different question: what roles need to be filled in this encounter, and what creatures are suited to fill them?

The Five Ecological Roles

In Ruinveil's ecology system, every enemy instance placed in a room occupies one of five roles. These roles define how the enemy functions in the context of the other enemies in the same room, not just how it behaves in isolation.

Predator: the primary threat. High damage output, direct aggression toward the player. A room may have one or two predators at most. They are the enemies the player must prioritize.

Harasser: secondary pressure. High mobility, lower individual damage. Harassers exist to split the player's attention while predators attack. They are rarely a serious threat on their own; their value is in coordination.

Sentinel: positional control. Holds a fixed position or patrols a defined route. Creates space constraints by making certain areas of the room dangerous to enter. Sentinels do not chase; they reinforce.

Anchor: resilient, slow. High health pool, significant damage mitigation. Anchors are not the most threatening enemy in a room but they are the hardest to remove. Their role is to occupy the player's attention long enough for predators and harassers to punish.

Support: modifies other enemies' effectiveness. Can buff allies, heal, or create environmental changes (summon additional instances, alter room terrain). Support enemies are rare and placed only in rooms of sufficient complexity to justify them.

How the Ecology System Assembles an Encounter

When the generation pipeline reaches the content assignment pass for a combat room, it does not ask "what enemies go here." It asks "what ecological composition does this room call for," based on the room's role, depth, spatial footprint, and the content specification provided by the level grammar.

A small combat room at low depth receives a simple ecological composition: one predator, one or two harassers. No sentinel, no anchor, no support. The room is small enough that positioning complexity would exceed the space available to express it, and the depth context calls for something learnable rather than challenging.

A large combat room at depth three might receive: one anchor, two harassers, one sentinel. The anchor draws the player's attention and occupies space. The harassers create pressure from the flanks while the player is dealing with the anchor. The sentinel controls one exit corridor, forcing a routing decision. This composition produces a room that feels like a coherent tactical problem: there is a reason these enemies are together.

The specific enemy units that fill each ecological role are drawn from a pool of units that have been tagged with role compatibility. A unit tagged as predator-compatible can fill predator slots. Some units are multi-compatible: a high-tier crawler might fit both predator and anchor slots depending on the room's needs. The ecology system selects from compatible units weighted by dungeon depth and the run's current difficulty factor.

Why This Produces Better Rooms

The ecological approach produces better rooms for a reason that players rarely articulate but feel immediately: the enemies in a room appear to belong to the same context. When a room has an anchor holding the corridor entrance while harassers move through the flanking gaps, the arrangement communicates something about how this space is controlled. It implies that these creatures operate together, even though "operates together" in the game engine just means "was assigned complementary roles by the ecology system."

The cognitive effect on the player is meaningful. An ecologically composed room invites tactical reading: the player can look at the setup and think about how to approach it. A taxonomically composed room just presents obstacles. The difference between a room that says "here are three hard enemies" and a room that says "here is a tactical situation" is partly the enemy types themselves and partly their relational context.

We are not claiming that every room we generate achieves this. Some room compositions under the current system still feel like grab-bags, usually when the depth context is low enough that the composition is intentionally simple and the ecological framing does not add much. At shallow dungeon depths, simple is often correct. The ecology system earns its value in the middle and late dungeon, where room compositions have enough complexity that the relational logic between enemies becomes the dominant experience.

The Limit of the Current Ecology Model

The ecology model as currently implemented assigns roles at encounter assembly time and does not re-evaluate those roles during a fight. An anchor that is about to die does not switch roles; a support enemy that has exhausted its buffing ability does not fall back into a secondary role. The roles are static labels that shape the initial behavior tree assembly, not dynamic states that respond to combat progression.

This matters because encounters are not static situations. The tactical context of a room changes as enemies die. A room designed around a predator-anchor-harasser composition loses its strategic logic the moment the anchor falls, leaving the predator unsupported and the harassers operating without the attention-splitting benefit they were designed to provide. The remaining enemies do not reconfigure to form a coherent new composition; they just continue executing their individual behaviors.

Adding dynamic role reassignment is on our design list. It would require real-time evaluation of the encounter's ecological balance, detection of role gaps (a room that has lost its anchor needs a new attention-holder), and behavioral adaptation to fill those gaps. That is a significant system change and we are not confident we have the right design for it yet. The current static approach is good enough to produce readable rooms at the start of encounters; it gets less intentional as encounters develop. We are gathering data on whether this is a significant experience problem or a theoretical gap that players do not notice in practice.

A Note on Ecological Variety Across Runs

Because the ecology system draws from unit pools and not fixed encounter scripts, the same room type at the same dungeon depth can have meaningfully different compositions across runs. A large combat room at depth three might have a predator-anchor-harasser composition in one run and a sentinel-harasser-support composition in another. The tactical problems presented are genuinely different: one requires dealing with direct threat plus positional disruption, the other requires navigating spatial control plus buffed secondary units.

This is the intended behavior: the ecology system is one of the layers that produces run variety at the encounter level, working in parallel with the level grammar's spatial variety and the behavior tree system's individual enemy variety. Each layer varies independently; the combination produces an encounter space that is much larger than any single layer could generate on its own.

We do not have a complete characterization of how large that space is in practice. Our variety metrics, which we covered in an earlier post, track layout uniqueness and enemy set overlap across runs but do not yet fully model encounter-level ecological variety. That is a measurement gap we intend to close.