Official development blog

Furnishing a/the Dungeon

Most traditional roguelikes are pretty barren, especially those of the subterranean variety where a map is composed of rooms empty except for monsters, items, and a small selection of interactive props or obstacles (e.g. altars, plants, pools of some liquid). This reflects, and highlights, the genre’s focus on tactics and strategy. If an object doesn’t have some direct affect on gameplay choices, then we don’t care about it. Traditional roguelikes take place just as much in the imagination as they do in the visible space, so players are used to seeing only what information they need to make decisions.

Some might argue that the limits of ASCII mean we only have just enough symbols to represent important interactive parts of the map, but this isn’t really true given the number of possible color and glyph combinations (especially once you add extended ASCII) as well as foreground and background colors. See Dwarf Fortress for an example in the extreme.

Cogmind’s 7DRL prototype, being a simple game focused purely on its core mechanic, had absolutely no props despite its uncharacteristically large rooms and corridors (to make room for long-ranged combat and more robots). To an extent that has now changed with the addition of machines, though the game still very intentionally leaves much of its map area as empty “periods” (‘.’). While this lack of furnishing makes for more boring static screenshots, I believe it’s important to preserve the clarity of the player’s field of vision for tactical purposes. (The only exception being dark gray debris left from destruction--to inform the player where something happened as well as positive reinforcement for the good old “hell yeah, I blew something up!” feeling.)

That’s not to say there’s no diversity to the maps. As you’ll see below, on their own machines already do a good job of indicating what a given area is for. And with that we arrive at the meat of this post: Now that we have these beautiful procedurally generated maps, what do we decide to put where, and how?

Furnishing Types

“Furnishings” refers mostly to machines. One advantage of Cogmind machines is that they always occupy more than one cell (space), and are always represented by ASCII line art. These characteristics mean they won’t be confused with robots or items, and enables significantly greater variety than if each had to be represented by a single ASCII glyph. This is made possible by the fact that maps are large and open, and big machines give the map content a better sense of scale--roguelikes are an abstraction, but when possible it’s nice that objects which should take up more space actually do.

More on each of the three categories of furnishings below.

Interactive Machines

These have been discussed several times before in terms of their functionality and hacking. Interactive machines are those which can be accessed via a special window to perform certain actions, including terminals, fabricators, scanalyzers, recycling units, and repair stations. There are plans to add some special interactive machines with unique features, though those haven’t been added yet.

cogmind_terminals1_sprites

The sprite sheet for low-level terminals. All interactives are drawn in grayscale and the game applies color automatically depending on their type. Each is surrounded by a faint rectangle and the props definition file specifies the coordinates of the top-left corner so the game can find the right sprite. (That first terminal is the one exception to the “machines always occupy more than one space” rule.)

There are three levels for each interactive machine, which generally offer increasing rewards at the cost of hacking higher security. Each visual style is associated with a specific type of operating system version, and Cogmind gains familiarity with each system based on the number of times each is accessed, somewhat limiting the number of possible styles (they need to be recognizable). Recognizable styles also means that meta knowledge can be helpful here as some of the terminals are always easier to hack than others.

Non-Interactive Machines

Machines Cogmind cannot hack (because their function wouldn’t serve the gameplay) are categorized as “non-interactive.” These all appear on the map in grayscale to denote their non-interactive nature.

cogmind_machines_noninteractive

A sample selection of “research”-themed non-interactive machines as seen in the sprite sheet.

In addition to lending the maps more atmosphere, these machines also serve to break up large spaces. This is important because Cogmind now has even larger open areas than seen in the 7DRL, and there really needs to be something to hide behind in the largest of them to make a stealthier approach possible, or simply to put something between you and an attacker.

More information on non-interactive machines in the next post.

Stockpiles

Being a collection of items, “stockpiles” are not a permanent dungeon fixture, but act somewhat as a furnishing since they occupy more than one space and you often won’t want the entire batch so some/all of it will remain in place. They are therefore placed along with machines during the “furnishings” stage of map generation.

In Cogmind items are frequently found in groups rather than individually. A single stockpile contains a random number of items (from 3 to 9), divided among 1-3 types. Thus it is common to find multiples of the same item, a design decision that pairs nicely with Cogmind’s mechanics since you can (and often want to) equip more than one of the same item, or carry spares for when one is blown off.

cogmind_stockpile

A typical early-level stockpile containing a couple wheels and some storage units.

Object Placement

The object placement process is largely data-driven, relying on a substantial number of interrelated arrays to describe object count, relative frequency, type of location, amount of padding between walls and other objects, etc. The details are way beyond the scope of a blog post (and also fairly boring), so I’ll describe the process here in a general sense.

Objects are placed according to a “composition” system that determines how to decorate a room or hall (open area). An area can contain:

  • An interactive machine, any number of non-interactive machines, and one or two stockpiles.
  • An interactive machine and any number of non-interactive machines.
  • Any number of non-interactive machines and one or two stockpiles.
  • Any number of non-interactive machines.
  • One or two stockpiles.
  • Nothing (empty).

Each type of map specifies the chance that each room or hall will pick a certain type of composition (weighted probability). I’ll use a hall as an example:

The interactive machine, if any, will be placed first.

cogmind_hall_placement_interactive

Interactive machines are initially placed along the edge of an inner rectangle defined by maintaining sufficient machine-wall padding on each side.

It then has a chance to be pushed back against the wall, as long as doing so won’t obstruct any doors or pathways.

The stockpiles, if any, are then placed using the same rules (along an inner rectangle, and possibly pushed against the wall).

Non-interactive machines, if the composition requires any, are used as a final stage “filler.” The largest possible array of a randomized type of machine is placed randomly within the hall’s inner rectangle. Any location in that array which overlaps another object or its padding area will remain empty. In this case the generator chose to place an array of Processing Tanks.

cogmind_hall_placement_noninteractive

A two-dimensional array indicating potential placement of non-interactive machines.

In the above example, placing the bottom-left tank would be too close to the scanalyzer, so it is removed from the array.

cogmind_hall_placement

The final hall.

Non-interactive machines usually appear in repetitive clusters, though sometimes one or more within the group may be replaced with a different machine that is no larger than the others.

Because their frequency affects gameplay balance, there are a limited number of interactive machines and stockpiles that can be placed on a given map--as limits are reached those objects are skipped in the placement phase. Technically this also means that not all of them might be placed if there aren’t enough rooms/halls, though properly designed map parameters should have the right amount of space to fit them all.

Note that most machines are allowed to be rotated in any direction, making it easier to fit them into more areas and increasing the chance of placing everything the map requires.

During the furnishings placement stage, halls are parsed in largest to smallest order--the larger they are the more we need to put something in them, while rooms are parsed in a completely random order for now. Later placement stages put terminals in high-traffic junctions, and individual (non-stockpile) items anywhere on the map, preferring more secluded areas for higher-rated items.

Some map excerpts showing machine placement variety:

cogmind_machine_placement_matter_filter

This Matter Filter fits nicely into this room.

 

cogmind_machine_placement_nuclear_terminal

This terminal presumably controls the neighboring nuclear reactors, as well as providing a point from which to hack the local system.

 

cogmind_machine_placement_electrolysis

Hm, what could they want with all those electrolysis chambers?

 

cogmind_machine_placement_matter_pump

Matter Pumps and an Integration Channel in a side room. Plus someone left a pile of Assault Rifles here for the taking.

The next post will take a closer look at non-interactive machines, including the system used to decide what machines belong on each map. Also some fun stuff like blowing them up ;)

This entry was posted in Design and tagged , , , , , , , , . Bookmark the permalink. Trackbacks are closed, but you can post a comment.

Post a Comment

Your email is never published nor shared. Only the anti-spam entry is required. See here for the privacy policy.

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>