Lots of games have “minimaps” allowing you to view a greater area than normally visible in the game screen, although (except in maybe a few rare instances) these usually aren’t games with displays limited to a strict terminal grid like we have with Cogmind. After all, you can only “zoom” so much given the restrictions of such a grid.
That said, it has certainly been requested multiple times before, so I first explored an alternative possibility last year, what I’ve been calling an “overmap,” just to kinda work through what an implementation might entail, and what benefits it could provide us with.
At the time it didn’t get very far since it was a spur-of-the-moment type of little side project and I got too busy with other features later, though the rudimentary code and interface have actually been in the game all this time and some weeks ago I picked it back up again to play with the idea some more.
Method
So what’s the best option here--how much more information can we really show using an alternative display method that obeys the grid?
Fortunately for us Cogmind does technically have a narrower grid than that used by the map: the grid on which text is displayed, and which represents the actual base terminal grid underlying the program. Map cells each occupy the same amount of space as two of these text cells combined. Purely by taking advantage of that fact, we could use text cells to represent map cells in order to narrow the map into half as much space horizontally.
Then we can get even more creative and use a CP437 character, the half block, placed in every single overmap “text” cell to divide it in half yet again, this time vertically. Then the foreground color of a cell, that coloring the block itself, is used to represent one map cell and background color represents another. Altogether this allows us to compress four map cells into a quarter of the space!
Comparing text and map cells in Cogmind. Notice how the square ‘#’ cell (an ASCII mode wall) occupies the same amount of space as two letters (“nd”) below it.
Representing four map cells in two text cells using purely foreground and background colors, also showing how the wider room looks when converted to the colored block method.
Using this method, a 200×200 map like Factory could be displayed in a 100×100 area (one quarter of its normal size in pixel terms as well), 35% of which would fit in the usual map display area, and 48% of which could appear if we expand the “overmap” to fill the entire Cogmind window! In other words, using this method we can squeeze an entire Factory map into approximately two screens worth of visual data.
A quick demo of opening a Factory map in its basic overmap form.
Some Pros and Cons
As you can see it loses a lot of detail, but I mean it’s essentially just a “huge minimap” so that’s inevitable :P. In that sense I’ve always been skeptical of how useful it really is considering you can already 1) see such a large area at once on Cogmind maps due to the relatively small grid (by default containing more cells at once than almost any other roguelike) and 2) easily pan around the map at full detail and get all the normal features and benefits of doing so.
I can see it coming in handy to more quickly skip the map view focus to a specific distant point on the map, at least via mouse (this aspect would perhaps be somewhat less useful for keyboard users in that regard?).
Certainly more worrisome from a development perspective is that there wouldn’t be a whole lot of interaction possibilities due to the fact that half-cells cannot normally be distinguished and interacted with separately in Cogmind’s engine, although technically I guess it might be feasible to get the engine to make an exception here (basically have the overmap ask it for extra info when necessary--this could lead to a fair number of unforeseen complications or restrictions though, hard to tell without further testing). But obviously players want polished features in their roguelikes, so it’s not all that desirable to release a feature that either can’t be polished due to limitations, or isn’t worth putting in a huge amount of effort to polish for limited returns. Features like this are usually best avoided because they’re more likely to lead to unhappy players. These are some of the primary concerns that have been keeping me from doing much with the overmap all this time.
That aside, what other benefits could we potentially get out of something like this? Naturally based on its greater range of visibility we can assume many of its features would be associated with the idea “exploration.” Cogmind’s main map view already has a good bit of this in the form of intel and labels for off-screen objects, but perhaps a dedicated display would lend itself to additional uses instead of simply highlighting known stairs, for example.
One interesting idea I had while working on the foundation for this feature was to have an optional highlight for areas that haven’t been fully explored yet. Combined with player “map sense” this could perhaps help realize that an exit may have been passed somewhere, or remind that a particular door wasn’t opened, or even for tracking down that elusive Garrison Access in -8/Materials ;)
A partially-explored Factory map with edge highlighting.
Another common request related to this sort of feature would be the ability to add annotations. I’m not really sure what people would use it for, but I’ve added some random samples here as an example of what that might look like :)
Sample optional map notes superimposed on the overmap to describe certain locations.
Aside from gameplay use, I imagine some players might also be interested in using this feature to annotate how certain battles/adventures across a map progressed in order to share with others (or just for their own records). Some players do this already, but using either screenshots or Cogmind’s full map export-to-PNG feature:
Sample map export image from a run shared by Pimski. Exporting a map to an image creates a large PNG showing all areas that have been explored so far.
It’s also possible that we’ll one day get on-map annotations regardless of the overmap, and those could transfer between the two automatically.
Despite my reservations regarding the overmap feature, I did add it to the feature voting list for patrons where it’s been garnering a surprising number of votes, at one point in the lead though more recently falling to second place as item searching and filtering somewhat overtook it.
Anyone who’s followed my development work over the years will know that I’m big on providing all sorts of quality of life features, optional functionality, configurable settings, and so on. This is also why even from the earliest stages (pre-7DRL!), and ever since, I’ve given the utmost priority to Cogmind’s interface.
How players interact with a game, both in terms of input and feedback, is vital to the experience, so even the greatest mechanics and content can be held back by insufficient attention to UX. Although it’s a lot of work to always be putting the interface first (while still trying to maintain progress and design within the necessary constraints), and I sometimes have to pick and choose what I can implement as a result, I think it’s been worth it in the long term. Not everything I’d like to do is really possible, but I try my best.
Having recently covered the new ambient audio system, today I’ll be introducing Cogmind’s audio-related accessibility features, features that other roguelike developers could potentially learn from and apply to help their players as well.
In particular I’ll be talking about Cogmind’s “visible SFX” system, allowing you to see the sources of sound effects, and the audio log for listing in text form both ambient and non-ambient sounds currently heard from Cogmind’s position. As we’ll see, the cool thing about both of these features is that they’re not just for people who must have them by necessity for accessibility reasons, but can also help other players in certain situations! Like anyone playing with the volume low, or even muted, or in an otherwise loud environment--everyone can benefit :D
Visible SFX
Originally a “what if” kinda feature that was mostly intended as a fun experiment, I immediately started liking the implications of being able to see the origin of sound effects outside your field of vision. This means being more aware of battles happening nearby, pinpointing enemies attacking from outside your visual range, locating undiscovered doors currently in use, knowing exactly where nearby garrison reinforcements are coming from… all kinds of useful applications. It’s essentially a free type of sensor, but one that only works when the surroundings are changing and therefore often lends itself more to reactive than proactive tactics.
Visible SFX demo, “seeing” a battle playing out around the corner.
More or less the same situation as above, but playing out on a black background so it’s a bit clearer.
The animation is generally just a single flashed dot at the origin and a quickly fading box around it, although for sounds with especially longer ranges (usually explosions) and therefore presumably louder, the animation is both brighter and has a larger fade radius.
Visible SFX animations are also color-coded by sound type to make the indicators more useful, even more so when lots of things are happening at once:
Red: Combat-related
Orange: Door open/close
Yellow: Trap trigger, carrier deployment, or garrison dispatch
Blue: Emergency door open/close or phase wall destroyed
Green: Machine destroyed
Brown: Walls destroyed or cave-in
Successive red flashes mean there’s fighting going on, naturally one of the more common situations, and if you didn’t instigate it, then depending on your build and condition it might be wise to either avoid the area or hurry over to lend your firepower to whichever side is on good terms with you (hopefully one of them is? :P). Either way, the system offers more options for informed decision-making rather than flying blind.
Together with the extra positional information you otherwise wouldn’t have simply by listening to the sounds, this feature also has the added advantage of better accessibility for hearing-impaired players, or anyone else playing without sound.
Although visible SFX are active by default, it’s possible to turn off in the advanced configuration file in case the extra visual flair bothers someone.
(Visible SFX were added to Cogmind three years ago back in Beta 1, though I haven’t mentioned them on the blog before.)
Audio Log
Something I was excited to finally add to Cogmind, since I’ve wanted to do it for a very long time now, is the audio log. The audio log is meant primarily as an accessibility feature akin to closed captions, allowing anyone who keeps their volume low or muted to be able to retain access to important audio knowledge (alongside the visual SFX feature, although that one is much more of a perk for everyone). This optional feature is disabled by default, but after testing it out I think this’ll be a pretty popular one even among those who don’t require it.
Features
Now, I say “closed captions,” but it’s definitely not a list of “pew-pew” and “kaboom” or anything like that, instead listing the name of the effect’s source in a small window embedded in the top-right corner of the map view. Ambient sounds are listed first, followed by a separator, then any non-ambient sound effects (the latter category referring to one-time sounds like gunfire and explosions).
Walking around a Materials map as the audio log updates to reflect machines that are being heard from each point.
The number to the left of each sound type indicates its current volume, which players can use as a proxy for distance.
Like visible SFX, the audio log also color-codes its contents to provide extra info where applicable:
Gray: Fluff machines, those serving to reflect the theme of the area and be destructible obstacles rather than serving an otherwise significant mechanical function.
Orange: Explosive machines. Beware.
Blue: Special-purpose machines with a unique function. Destroying these always has some effect.
Watching the audio log while passing turns and occasionally moving around as a war is playing out nearby. This demo also makes it clearer that sounds are ordered by near-to-far rather than the order in which they were heard.
Non-ambient sounds are color-coded by category as well:
Yellow: Attacks and gunfire.
Orange: Explosions.
Red: Robot destruction. Very specific compared to other categories, but also very important so it gets its own color.
Green: A wide variety of events including traps, drones, turrets, scans, phase doors, door hacking--basically everything that doesn’t fit in any of the other three categories.
When combined with the visible SFX system the non-ambient data is even more powerful: “see” this great fight heard outside the room as it’s described by the audio log and blips on the map:
Funny how it ends ;)
Not quite every sound appears in the log. In choosing what sounds to report in the audio log, in most cases it was geared towards information that is strategically helpful to know when out of view, rather than providing an exhaustive list. Limiting it to what really matters helps keep the log cleaner.
Although door interaction is fairly important, it is not reflected in the audio log since even if out of view they are clearly displayed via the visible SFX system, and their frequency is often rather high so it might threaten to drown out more meaningful sounds. An exception was made for phase wall interactions, since those are strategically important but do not reveal their precise location as a visible SFX source.
Other sounds that have clear visual alternatives are also generally excluded to avoid padding the audio log with unnecessary “noise.” Examples include dispatch alerts, and the EMP charging and discharging in Waste (which come with their own graphics and messages).
So while the audio log technically doesn’t paint a 100% complete picture of Cogmind’s soundscape, it provides one aimed at an optimized play experience, not unlike the optimizations found in many other parts of the interface.
Challenges
It was a surprising amount of work to finish the audio log, taking an entire week to complete as I discovered quite a few roadblocks along the way. Definitely worth it and I’m glad it’s now implemented, but I expected it to take just a day or two xD
There were lots of questions to answer about this feature…
Right from the initial mockup stage we of course needed to know what kind of information would be conveyed. At first I was thinking distance alongside the name of the sound’s origin (e.g. the machine--at this point I was only thinking about ambient loops), but then realized that precise distance is conveying more specific information than you get by simply hearing a machine. Overall I wanted to try to avoid making the audio log seem like a necessary feature for everyone to have active at all times, meaning the info provided should to be comparable to hearing a sound. So of course it should report the volume as a number (percentage), duh.
Excerpt from my original audio log mockups. You can see there were yet more changes made after these ideas.
Then I was considering how an ambient sound list would treat multiple sources of the same type, like a group of Nuclear Reactors. The answer is to just do like the actual ambient audio system and only list the type once at its loudest current volume, again maintaining parity between the audio log and what is heard, but I clearly kept getting sidetracked thinking about all the new info made possible by this new format! The point is that throughout the process one of the roadblocks was myself--I repeatedly had to reign in these wild design thoughts :P
Naming the ambient sounds for the audio log wasn’t hard since I already had a list of the sources and their respective names, and none of them are reused across different sources. Non-ambient sounds, however, were much more problematic since there was no precedent for this in the architecture (which of course hadn’t taken it into account from the start), but including them is quite important for accessibility. After all, once you’re familiar with the sounds certain weapons make, for example, the fact that you can hear them around the corner technically lets you guess what types of enemies (or allies) are fighting nearby, even without sensor data. This same information needs to be reflected in the audio log.
I experimented with a number of different approaches for the names of one-time sound effects, but after a complete survey of the parts involved (in particular weapons) determined that it made the most sense to use a single name associated with the audio sample and add no further differentiation. This means that weapon sounds do not necessarily list the specific weapon name, but instead the base name for the sound. For example there are a number of railgun variants that use the same sound, and the audio log will not differentiate between them, simply listing each as a “Railgun.” Any weapons with unique sounds are indicated by their specific name where applicable, though. This, too, seems obvious in hindsight, again maintaining parity with what is heard, but it wasn’t clear to me at first…
Other naming issues or ideas considered along the way:
I originally thought the audio log would have to take into account player knowledge, i.e. unknown parts or unidentified prototypes, but in the end it doesn’t really make sense to obscure that information since players who generally play with the sound on learn to quickly recognize different SFX and retain that metaknowledge regardless of what the game would list in the log anyway. So we can ignore this limitation (which would otherwise be a hugely complex possibility to account for). Bullet dodged.
At one point I also thought about using descriptive names that didn’t exactly match weapon names, e.g. “Weak Laser” for Small Lasers or Backup Lasers, since both use same sound effect, but this approach doesn’t scale well at all and would just end up being unnecessarily confusing, forcing players to learn a whole new set of words just for this feature.
Then I also thought about using a special type of marker, prefixing the sound name with a tilde (~) in certain cases to represent that the sound belongs to a category of multiple variants and it could be any of them, but that seemed like unnecessary extra info so I simply removed all of those from the data.
Under the final naming system explosion sounds were an issue since many of the same samples are shared across different types of sources such as launchers, machines, and traps, so for those I opted to go with a more generic “Explosion (XX)”, where the XX refers to the common abbreviation for the relevant damage type.
Multiprojectile weapons presented one of the biggest problems, one for which I sadly only found a partial solution. Each projectile actually plays its own sound because of how the projectile mechanics are tied to the particle system, and because the audio log is directly tied into the sound system, which doesn’t know about game mechanics or what’s really happening, thus a single weapon can cause more than one (or even numerous!) entries to appear at once.
The best solution I could come up with for limiting the extra entries involved adding a variable set manually for each sound effect that essentially blocks a predetermined number of subsequent matching audio log messages after the first. Hacky, yes, but it mostly works…
For example an EM Shotgun fires two projectiles, each playing the same sound*, but because the sound effect has a ‘1’ assigned to that variable, on playing the sound the first time the audio system records that it should simply block the next attempt from being logged. (*Note that even though it’s the same sound, weapons tend to randomly modify their pitch for each firing/projectile, and multiprojectile weapons in particular may also add a random but slight amount of staggering to their projectile firing times.)
Unfortunately it’s not a perfect solution because the value must be set at the SFX level, but in rare cases some weapons use the same sound effect but each fire a different number of projectiles, so there are a small handful weapons for which the log might desync on certain turns, though in most cases these are not weapons enemies use anyway (only Cogmind does), so it should rarely if ever come into play.
Technically I suppose we could just always report every single projectile as a separate audio entry, but for some weapons that could get excessive, and it also just makes the log harder to read by polluting it with extra lines, so maybe I could change it later, but for now we’ll stick with this method.
Aside: I did actually test the per-projectile approach, using the standard roguelike message log behavior for duplicate entries, but that didn’t pan out. The idea was to merge duplicate entries with a multiplier, like “50 / Flak Gun (x6)” and so on, simply allowing multiple projectiles to stack when they are of the same type and volume. One problem here is that weapon sound effects are often heard at maximum volume across a decent range, leading to lots of overlap in the log and making it difficult to discern just how many different weapons are being heard (or at least require the player to do some math when there are lots of things happening at once). The potential gains here (being precise and consistent in every case) didn’t outweigh the costs (confusing!), and considering how rare it is for enemies to have a weapon that might cause temporary audio log desyncing, I prefer that the log show weapons on a per-weapon basis rather than per-projectile. Obviously most games don’t have to worry about this kind of thing at all--it’s kind of a weird situation likely unique to the way Cogmind’s projectile, logic, and audio systems interact :P
Altogether it was a lot of work to go back through every sound and projectile, cross-referencing all their uses in order to assign names and other values for audio log purposes, but eventually that was done and… oh wait, there was still more to do xD
Aside from the content, the new audio log’s existence itself caused some issues. For one its design places it against the right edge of the map, which would obscure any intel markers appearing along that edge segment.
To resolve that I spent a while updating the intel marker placement system to get them to avoid the window itself:
The audio log displacing various intel markers that would appear along the right edge.
Labels for offscreen exits needed a similar treatment, although there are always far fewer of those, so I opted to instead just shift them downward rather than pushing them to the left of the audio log window:
The audio log displacing various offscreen exit labels by pushing them downward if they would otherwise appear behind the window.
In hindsight maybe it’d be better to just treat the audio log like most other on-map windows that can appear and displace it from every edge by 1 column/row, although I felt like the right side should be snug against the edge since this particular window doesn’t have its own border. So maybe it needs its own border??? As a result of writing this article to here I had to mock it up :P
Mockup for an alternative audio log concept, with a border and increased padding.
This option occupies more space (and has to leave even more space for markers), but I guess the consistency could be worth it? It also serves to better separate the log from the map behind it so that it’s more clearly it’s own thing, which is kinda nice. Cogmind’s special mode UI windows that appear at the bottom-left of the map already do this, as do the achievement icons that appear in the bottom right when those are earned…
That said, I saw the audio log as more of a right-adjusted counterpart to the full combat log appearing at the top-left of the map, also without any border. Designwise that one is slightly different, however, because as left-adjusted lines (and potentially long ones at that) it felt fine to have them cover only as much of the map as they needed to on a per-line basis, whereas the audio log on the right works better when the width of the area covered is uniform.
Anyway, I’ll have to think about that one. (Edit: On discussing this with patrons, one good point brought up by Tone is that an explicitly bordered window that frequently changes its height could end up being more distracting, which makes a lot of sense and is good reason to leave it as is, without the border, like its similarly “shapeshifting” borderless counterpart, the full combat log.)
There you have it, just a sampling of the problems encountered in building the audio log--there were lots of other little ones, mostly specific to how Cogmind’s architecture works, its limitations, or trying to get information from one place to another, and, again, overall it took a full week to finish this “little” feature for which a lot of the foundation had already been established!
Options
The audio log itself is optional, off by default but accessible from the options menu. As usual, I’ve also made some of its behaviors tweakable where that may be desirable:
Normally ambient sounds are always listed, while non-ambient sounds are only shown when the origin is outside Cogmind’s FOV. Although this goes against the idea of a truly complete “closed captioning” system, this is actually a more reasonable approach to default to since you can clearly see visible attacks and other sources of audio anyway, and this behavior also keeps the audio log focused on sources currently out of view without letting it become too cluttered with duplicate information. But of course the option is always there to include every sound effect if someone wants/needs to expand the rules. Regardless of this setting, non-ambient sounds originating from Cogmind’s own position (mainly attacks) aren’t reported to the audio log, since those should be obvious and would just clog up the log with too much info.
Ambient sources ended up being listed regardless of whether they’re in view because even though it might’ve similarly made sense to only list those that are outside FOV, it turns out this was completely impossible without rewriting much of the ambient audio system xD. No matter, it’s fun (and sometimes convenient) to see those listed, anyway, and they’re definitely not excessive like non-ambient sounds can be!
Fluff machines (reminder: those that do not explode and have no special mechanical purpose) are normally included in the audio log, but there is also a setting to exclude them to avoid the extra noise. I imagine most players would want to leave them on for a number of reasons, though preferences could depend on what other settings are being used.
The maximum length of the log is adjustable, too (down to the bottom of the map view, which is actually the default), as is the length of time for which non-ambient sound effects remain visible before disappearing from the log.
General Audio Settings
As a major accessibility feature the audio log toggle has been given a place in the Audio section of Cogmind’s primary options menu, alongside several other options some might find useful.
Cogmind’s latest options menu layout and contents.
Of course there’s a master volume control, but as part of that each of four separate channel categories can also be adjusted individually to change their relative volume. “Interface” includes all the UI feedback, the beeps and clicks and alerts, etc.; “Game”covers mechanics, combat, and other events; “Props” are all the environment objects like machines (basically any ambient loops that aren’t the mapwide audio); and “Locale” refers to the mapwide ambient audio track for the current map.
Over the years I’ve also added a couple other special audio options by request, though these only appear in the advanced configuration file:
muteTextSfx: Some players are sensitive to the text typing sound, which is pretty ubiquitous in Cogmind because there’s text being printed to the log all the time as things are happening, but it usually isn’t a vital part of the interface feedback, so I added a way to disable that particular effect.
muteGlobalAlertSfx: At least one player didn’t like hearing global alerts, generally referring to enemy squad dispatches as a result of your presence or actions, or otherwise potential danger coming your way, so I added a separate way to disable those. Alert situations are also accompanied by a more specific white log message and an additional flashing message at the top of the map view, anyway, so it’s usually not too hard to miss. Personally I tended to miss anything except an alarm playing, but the idea of options is that not everyone has the same observational habits or abilities so making things customizable is usually advantageous where possible.
As with many of Cogmind’s huge range of quality of life features, it took a while to reach the current state--naturally not every issue will be foreseen and implemented right away, and it can take years to properly add all this stuff to a game (especially as a solo dev), but in the long run listening to feedback from players and doing what I can to offer improvements to the experience has been an important part of the process.
SFX, Stereo, Action!
You can see both the visible SFX and audio log in action in my first Beta 10 prerelease stream in which I introduced the log alongside the new soundscape:
I first introduced Cogmind’s ambient sound system back in 2014 during the pre-alpha days, as it was initially developed for Cogmind’s predecessor (X@COM) in the years before that, and sound would continue to play an important role going forward. It wasn’t an especially long post like the ones I tend to write these days, but it did touch on the basics of propagation, sound dampening, and falloff models.
Since then I’ve also written a number of articles about sound effects and audio in general, but now it’s finally time to address the relative lack of ambient audio in Cogmind! I’d been putting this feature off for a long while and it sat at the end of the pre-1.0 roadmap for years, at first because it made more sense to work on all that content after everything else was complete, but then later due to my concussion leading to hearing issues, which only after a couple years finally reached a point where they wouldn’t be a significant roadblock.
Here we go!
Technical Overview
For relevant background to help better understand this article, here’s a quick review of the ambient audio system’s features…
There’s a whole lot of sound-related values defined in Cogmind’s data files. Above is an excerpt combining various sections, both ambient and non-ambient from a range of categories, to give a sampling of the variety (the full file contains 1122 entries :P).
Each sound is defined along with a “minimum” radius representing the distance before its “falloff” begins (i.e. the volume begins decreasing due to distance), and a maximum radius indicating the furthest distance out to which the sound travels as it’s fading. A given sound can use one of four different falloff models depending on its needs, either linear, logarithmic, reverse logarithmic, or inverse.
Demonstrating the relative volume of audio emitted from a given source (the machine at the center) using different falloff models, alongside rough approximations of the graph representing each.
The above examples all have a minimum radius of 2 (and max of 15), so the different results come purely from changes to the falloff, but by adjusting the other values a huge range of options become possible. For comparison, here’s a logarithmic falloff with a longer plateau (radius 8~15):
This falloff sample has a longer plateau than I generally use, but it can come in handy for some purposes.
On every player move, or with any action that might have affected the amount of sound reaching the player’s location (terrain destruction, machine toggling, etc), the audio sources potentially within earshot of the player pathfind to the player to determine how far away they are for volume determination purposes. The final new sound profile for the player’s current location is compared to the any sounds that were playing from the previous state, and the old state fades into the new state, which might involve simply slowly adjusting the volume of the same set of sounds, adding new sounds, or gradually removing those that are no longer in range.
Visualizing the sound paths from each nearby audible machine, paths which are used to determine the final volume at the player’s location.
Using a system like this is both quick and makes it pretty easy to account for dampening effects of the path successfully passing through materials, like the doors in Cogmind which block 50% of the volume. You can see the effect of doors in the falloff samples from earlier (it’s most noticeable in the reverse log demo), but here’s another still shot using the sound path visualizer in which you can see the volume dropping quickly when passing through doors.
Doors to two rooms lowering the volume of the machines heard within.
So that’s the underlying architecture we’re working with here, let’s move on to where the soundscape actually takes shape.
Audio Style
Naturally a lot of games tend to use music to fill the role of “continuous audio,” which when done well is instrumental in conveying the desired mood, and possibly atmosphere as well.
It can also be great to just enjoy out of game. I personally love VGM, having listened to it for the past 30 years (I guess since before listening to VGM was a thing many people really did :P), and in the early years recorded the music from console games on my TV to create OSTs and mix tapes. Later on importing OST and arrangement CDs from Japan became a thing, so I did a lot of that, too, and still listen to the original rips I made to this day…
So yeah getting a Cogmind OST by a proper composer would be pretty damn awesome, but at the same time developers need to choose for their game the type of audio that will best achieve the vision for its world.
The audio style discussion has played in some form or another, in some place or another, pretty much every year of Cogmind development so far as different players ask about it, or I bring it up myself when planning for the future. It was once even the topic of a post here on the blog, back in 2017. Over the years I’ve certainly been collecting a list of interested composers, or others that I’ve become interested in, and analyzing whether or not I think they’d be appropriate for this particular job if it came to that. Many have also approached me asking about Cogmind, including a number of players.
For now though, music is probably not right for Cogmind. With an emphasis on immersive atmosphere, and a semi-realistic dark sci-fi one at that, I think environment-driven ambient audio would better fit the role. Even if it doesn’t work out the way I envision it (spoiler: it does), considering that the architecture for an environment-based ambient audio system already exists and the only further need is to add the content, and doing so involves fewer challenges and commitments than working with a third party composer, it makes sense to start with this approach and experience the results to hear for ourselves. Let the machines and other objects of the world dynamically create the soundscape, and if that works then we’re all set.
Then there’s the additional benefit of this approach: it’s heavily focused on sound effects and loops, which I’m familiar with after working with them for many years, and is also something I can manage on my own, which in my book is always a plus over bringing in outside help. It means that iterating is faster, and I have more direct control over making sure each step along the way is successfully integrating with my vision. Also of course when I inevitably need more content I’m always available to add it :P
That’s what the rest of this article is about--the process behind pulling that soundscape together.
Machine Loops
The main focus of the ambient audio is Cogmind’s machines, of which there are over a hundred.
Technically before reaching this part of the development process, in previous years I’d already added loops for 17 special machines and other various sources especially meaningful to the plot or mechanics. At the time I didn’t want to wait on those since in some cases they’re quite important, so it made sense to emphasize their impact with audio as soon as possible. “Fluff” machines could wait, but not things like machines capable of significantly changing the entire run :P
Categorization
With such a large number of machines, providing sound for all of them is a rather daunting task, so we do what we do with all daunting tasks: break it down! I first roughly identified the different categories of machines in Cogmind from an audio perspective. (Technically Cogmind machines were already divided into themes for map placement purposes, but those categories do not always align perfectly with what kinds of audio you might get from them, hence the need for alternative audio-specific categories.)
Here’s the breakdown as reflected in the ambient loop directory structure, including the number of loops in each as of this writing (there will no doubt be a few more added in the near term, but most everything has audio at this point):
The current tally of Cogmind’s ambient loop files. Ambient audio is sourced from “props,” which are anything in the environment that is not a cell, item, or entity (robot)--generally machines for the most part.
“Interactive” refers essentially to terminal types, all of which were originally using the same placeholder loop, but now every faction has one or more unique sounds for their terminals. They look and operate differently, so it only makes sense to differentiate their sounds, too :D
“Prefab” includes machines I draw directly into hardcoded map sections via REXPaint, those with a unique name and possibly function as well. (Read more about prefab development here.)
The “Theme” directory contains all the machines that are procedurally inserted into maps. A majority of these are fluff, though in particular the “Special” subcategory includes all the explosive machines and a few with unique functions. Among the Theme machines I did that group first to ensure they got first pick from the audio resources I was working with, since they’re more important.
Creation
In terms of actually creating the sounds, I’ve already covered that before in the sound design how-to article I wrote in the early years of the project. Reminder: I don’t do this from scratch, instead using existing samples and editing them as necessary.
I spent a couple weeks going through lots of samples looking for what sounded like my vision for each machine in question. Obviously since it’s sci-fi there’s often a lot of leeway for interpretation, but still important to be consistent. Working with a single category/subcategory at once, I’d use Audacity for looping all the tracks, adjusting or mixing some of them for better effect.
Editing Cogmind’s machine loops in Audacity.
As each category’s loops were completed, I’d fire up Cogmind’s sandbox mode to hear them in game and adjust sound propagation values as appropriate. The sandbox contains one of every themed machine, making it more convenient to do this than actually finding them in game.
Cogmind’s development sandbox, which has grown incredibly messy over the years since it has continued automatically expanding itself based on game content, but I don’t really use it much anymore--it was instrumental in early development but barely gets loaded up these days.
However, the machines in the sandbox are also quite close together, which would interfere with the task of making machine-specific adjustments (although the proximity does come in handy when testing out overlapping audio from different machines!). So right away I needed some new debug features to make this job easier.
Enter audio toggling. It was suddenly important and very useful to be able to toggle all ambient sources across an entire map, as well as toggle them individually by source. This functionality would also be of help once we get to the stage of testing ambient audio in regular map environments.
Toggling ambient audio sources in the sandbox.
Now I could more easily hear any given machine in isolation, and test how its audio propagation settings worked for its particular sound. I started everything with reasonable default propagation values, and adjusted from there. These values are set in the external data file shown earlier, a file which requires a game restart in order to load any changes. So while at first I was determining final values by listening to each machine and making educated guesses about what it should be changed to before restarting, this approach is slow and incompatible with the sheer amount of content being worked with here.
Time for another new debugging feature!
Rapid iteration is important, so I added a way to dynamically adjust a given audio source’s min/max radius and falloff using the debugging console, making it possible to immediately experience the results of any change and easily experiment with different possibilities.
This continued for more than 100 machines until everything seemed to have suitable values…
Polishing
Of course with all this audio content going into the game at once, it’s about more than just editing loops for individual sources--we’d also need to take a look at the atmosphere as a whole and ensure it’s properly balanced, and I’d need new tools to facilitate that process as well.
First of all, as I walked around real maps it became apparent that the default linear falloff model I’d been using for most machines didn’t actually work that well when applied to all machines across the floor. I’d started with that type because it happens to be what was used all these years for the special prefab machines added before this new undertaking, and it works there because those tend to have longer audio ranges and I wanted them to be pretty clearly identifiable shortly after they come into earshot. Not so with all the generic machines scattered about. (When applied to them, a linear falloff makes the ambiance feel more confusing with a greater number and variety of sounds quickly fading in and out as you move around.)
To experiment with a new default falloff model, I added a console command to simultaneously switch all machines to a different model, eventually settling on logarithmic as the default:
Testing a couple of different falloff models under the ambient audio visualizer.
Another factor to explore was the extent of silent gaps between areas of machinery on various maps. Technically we could fill an entire map with machine audio if the ranges are long enough, although this would also mean more overlapping and general cacophony. Still, to test the size of gaps and see how changing average audio ranges might affect the experience, I also added the ability to simultaneously adjust the range of all sources:
Adjusting machine ambient ranges across an entire map at once.
When the majority of machines had ambient audio, I did a dev stream to demo the intermediate results while talking about the process and exploring what maps sounded like at that stage. Still very WIP at that point, but it was exciting to finally hear the soundscape taking shape!
One thing clear from walking around was the lack of normalization--some machines are clearly too loud relative to others (some also seemed too quiet, but we’ll get to that later in the section on mapwide ambience). So the next thing I worked on after the stream was addressing that issue, starting with yet another console-based convenience feature: the ability to reduce the base volume of individual machines on the fly, in game. Commence rapid iteration!
(Normally I’d show you a gif of realtime volume adjustment here, but the ambient visualization system only reflects relative volume numbers rather than absolute volume, so it wouldn’t be much use since nothing appears to change when this setting is modified :P)
After confirming this would give satisfactory results, I made it a part of the architecture, i.e. machine audio samples could have their base volume reduced via settings in the game data. This means it would be possible to avoid resampling all the associated audio tracks, which would be pretty time-consuming by comparison. In all, I lowered about half of the machines’ volume by 50~75% through this method in the week after that stream.
Mapwide Ambience
A soundscape composed primarily of the humming, whirring, buzzing and clanking of machines is great, though there are always going to be some gaps, places where machine audio doesn’t reach. The idea is to fill those with a general ambient track, preferably a different one for each unique map type.
To demonstrate the gaps relative to the areas from which machines are heard, in these images I’ve used a separate color (blue) to highlight gaps, or any location reached by absolutely no sourced ambient audio:
Audio gaps (blue) compared to sounds emitted by machines (orange), in part of a Factory map.
Audio gaps vs. machine audio in a sample Garrison map.
Audio gaps vs. machine audio in a sample small Materials map.
Although sometimes silence is a good thing (and put to use for that reason), it’s not great in areas that are otherwise brimming with machine activity, since repeatedly passing between louder and completely silent areas can be unnecessarily jarring and weird.
So we’ve gotta fill those gaps with something. Enter mapwide ambience.
We’ve actually had a couple of mapwide ambient tracks in the game for years now, originally labeled placeholders and essentially added to test out the system and also let players know this is a likely feature to be expanded upon. The one with which players will be most familiar is in the cave areas, a spooky organic drone that many commented on as being quite fitting for the area, and still others said they’d never even noticed xD (because technically I set the sample to quite a low base volume, and whether or not certain players could hear it might depend on their audio setup).
To fill gaps on other maps I wanted to expand on this idea, for the most part just using very low-key synth drones to act as a bridge between areas with sourced audio and set the overall tone with your average sci-fi background fare. Overall the tracks I’m using are relatively dark and mysterious, fitting with Cogmind’s general atmosphere.
Now instead of 2 mapwide tracks we have 26 :)
I might go on to add additional random faint sound effects as necessary to serve as “accents” for the generic loops to liven the audio up just a bit, although I haven’t done that at this phase yet, and even if it were to happen it probably wouldn’t be until after Beta 10 releases with all the new audio, in order to leave time for broader feedback.
One issue that popped up with the mapwide tracks is that their desired volume level in otherwise silent areas could easily drown out some fainter or deeper machine sound effects when applied at the same level across the entire map. The answer seemed pretty obvious: Just lower the mapwide ambient volume when around other machines. Cogmind dynamically reduces the ambient volume by 50% of the loudest foreground loop’s volume. For example if the player is passing near a machine they’re hearing at 80% of its max volume, then the mapwide ambient audio is set to 60% volume (100-(80/2)). This seems to work quite well!
Visualizing only the volume level of the mapwide ambient track as it varies across a section of Factory map (as usual darker represents quieter).
Results
As of this writing and the latest prerelease build I released for patrons, Cogmind gained an additional 117 sourced ambient sounds over the previous release and the soundscape is really coming together. It adds to the atmosphere without generally being too overwhelming despite the number of possible sources. There’s usually no more than 2-3 different types within earshot of each other anyway, if that.
Visualizing the variety of machine audio across a Factory floor, where each unique sound is associated with a random color.
These plus the 24 new mapwide tracks did, of course, expand Cogmind’s disk size--a clean install now weighs in at 43.5 MB, a 45% increase over Beta 9.6. The audio samples went from comprising 46% of install size to 63%. Overall still pretty lightweight considering the massive number of samples included (by indie game standards), but Cogmind is certainly getting a bit hefty since its 3 MB 7DRL days :P
To see the latest WIP version of Cogmind’s soundscape in action, check out my first Beta 10 prerelease stream where we’ll explore the audio while fooling around and kicking butt:
In the next article we’re going to take this whole thing to the next level by adding a closed caption-like feature in the form of an audio log, so you can get the full tactical advantages of this audio system even with the sound off! (Actually you can already see it in action in the stream recording above, but I’m going to go into detail about its design and the challenges I encountered in building it.) We’ll also cover some other audio accessibility features for roguelikes…
I sometimes get questions about what I use to develop Cogmind and although I compiled a list on r/RoguelikeDev years back, it’s undergone a few changes since then, so it’s about time to put an updated version here on the blog for anyone who’s interested. Maybe you’ll find something useful you weren’t aware of before :)
Text Editing
Notepad++
No doubt the star of the show, Notepad++ is such a fast and versatile editor. I love how responsive it is. I’m actually still using a custom version built in 2012, from back before NP++ included support for extensive user-defined syntax highlighting. These features were eventually added to NP++ itself (I think contributed by the devs who developed the version I’m using now, actually), though I’m happy with what I’ve got now so I just keep using it.
I use Notepad++ for editing game data and scripts, for which I created custom syntax rules and set a ton of Cogmind-related keywords to make the job of content creation easier.
Editing Cogmind data files in Notepad++, with custom syntax highlighting and keywords (open for full size).
Every day I pretty much always have Notepad++ open with Cogmind’s most commonly edited data files already loaded, mirroring most to top and bottom panes so I can take advantage of horizontal scrolling and keep column headers visible, or of course simply be able to edit two separate locations in the same file (or reference one position while editing another)
I also frequently use the macro system to facilitate editing (which is again so much faster and more responsive than those I’ve found in other programs), and will sometimes even drop text from other programs into NP++ to record and run a macro on it before copying back the results :P
Simultaneous multi-line editing is also great, especially for my needs given the typical layout of Cogmind’s data files.
Random example of using multiline editing in Notepad++.
Yay for Notepad++!
TED Notepad
I found this gem while looking for a Windows Notepad alternative, and it really delivers. I write all my notes (e.g. todo lists, game design docs) in simple .txt files, and TED Notepad is a great lightweight editor with a wide variety of text processing features that can come in handy sometimes, too.
Some of TED Notepad’s text processing options.
As much as I like Notepad++, I don’t want to use it for this since I prefer having an editor with somewhat different settings and behaviors more suitable for my typical note-taking needs. I use a different font and colors for editing notes, and it’s nice to have separate small windows for each file I’m working with, windows that I can also close with a simple press of Escape.
Sample notes from Cogmind’s terminal hacking overhaul in early alpha (open for full size). I’ve shared a fair number of screenshots of my notes on the blog before, so this style will be familiar to regular readers :)
Programming
Visual Studio
Cogmind is written in C++ and my primary IDE is Visual Studio, which needs no introduction.
I started using VS back in 2006 after migrating over from Bloodshed Dev-C++ at the suggestion of my brother. (Ancient history: Years before that I just wrote C code in Windows Notepad and used a command line compiler… What a long road it’s been :P)
Cogmind was first developed in Visual Studio 2010, and although there have been five new major versions since then, I’m still using 2010 since it works fine and I’ve got it all set up the way I like it (I have a number of extensions), so don’t see a need to switch versions.
Sample source code from the UI in Cogmind’s most recent special event/mode, in VS2010 using my color scheme. Like the notes shots, you’re probably familiar with seeing these from time to time on the blog :P
Overall I really like the Visual Studio debugger and have become familiar with many of its other features over the years. Some of my favorite/most-used hotkeys:
Shift-Alt-Arrows: Expand cursor across multiple rows for multiline editing, or to select an arbitrary block of text for copy-paste; like in Notepad++, editing multiple rows at once is a great feature that comes in handy when coding certain things
Shift-Alt-s: Split the current file in two views, to access two different places at once
Ctrl-Shift-Up/Down: Move cursor between top/bottom file views
Ctrl-Tab: Switch back and forth between the most recent two edited open files (or press faster to go back further in the editing chain)
Ctrl-]: Move cursor to matching parenthesis/bracket
Ctrl-k, Ctrl-k: Set/clear a bookmark at the current line
Ctrl-k, Ctrl-n: Move cursor to the next bookmarked line
Ctrl--: Move cursor to its previous significant location (and Shift-Ctrl-- to move forward again if somewhere back in the cursor history)
There’s also the more obvious/common Ctrl-Shift-B to build, F5 to build/run, Shift-F5 to stop debugging, and F9 to set or clear a breakpoint.
I think I changed one of these from its default binding, but at least this list lets you know it’s a feature!
I don’t use the mouse much while coding, if I can help it :P
Very Sleepy
Very Sleepy is a great and free CPU profiler for Windows which has helped me improve Cogmind a good number of times whenever something starts to slow it down and I need to find just what it is, or look for general areas that can be improved.
I’ve shared info about this on the blog before, most recently in my article on Turn Time Systems last year, and probably most importantly in this progress update where I talked about multithreading Cogmind’s most time-consuming asset loading routines to cut the game startup time by one-third. I’ve also used it to help optimize pathfinding on multiple occasions. Roguelikes tend to do a lot of pathfinding!
Identifying high-level optimization targets in Cogmind’s startup process using data from Very Sleepy profiling.
Very Sleepy is super easy to use: Just point it at a running .exe and start. Collect data. Win. Amazing stuff.
Trivia: REXPaint‘s default GUI skin theme is named “Sleepy,” after Very Sleepy, since around the time I released the first public version in 2013 I wanted to use something other than the default theme I’d originally built for it when working on X@COM, and had just discovered Very Sleepy at the time and its website used a similar blue-ish color scheme that I liked (which is apparently now different these days!).
Design
yEd
During pre-alpha development I wanted a convenient way to design Cogmind’s world map via computer. Sketching on paper is fine for one-off tasks, but of course in this case I knew I’d be updating it in the future and wanted to be able to dynamically add areas, group them, show relationships… so flowcharting software seemed like a natural fit.
Cogmind’s world map as seen in my yEd graph, albeit with branches distorted (and some locations completely removed for the screenshot :P) to avoid leaking spoilers. It started out simpler and has been expanding for years as I continue to add new maps.
In my search I found yEd Graph Editor, a free solution which also happens to be quite powerful. I only use a tiny fraction of its capabilities, but at the low end it’s really user-friendly, quick to get started with, and easily produces nice-looking graphs.
Aside from the original purpose, to create the world layout, I’ve since used it for a number of others things like making flowcharts for demonstrations. For example this one from my article on level design:
The yEd graph created to demonstrate the primary long-term strategic decisions related to the Exiles, a new world map location added last year.
I’ve also sometimes used it for figuring out program architecture if there are a lot of moving parts.
In going back through my yEd files for this post looking for examples of others kinds of things I’ve used it for over the years, I found this visual breakdown of Cogmind’s early development timeline, including game content relationships:
Haha, wow time does fly… This graph accompanied my announcement regarding Cogmind’s upcoming “alpha release state” in 2015, written a couple months before the first release.
Anyway, if you need software for something like this, I highly recommend yEd.
Excel
Spreadsheets are extremely important when designing a large game, helping organize lots of raw data and balance mechanics. I didn’t originally want to use Microsoft Excel, since MS Word is a pretty terrible word processor and Excel must be of similar quality, right? Wrong.
For the first year I was using OpenOffice Calc for spreadsheets, but during that time it felt like the software was fighting against me anytime I wanted to do something, and there were weird design decisions all over the place. So when at one point for some reason at the time I had to use Excel, I discovered just how easy it was to do so many things I wanted to do, even without any experience! Things Just Worked. So I switched my design spreadsheets over (which was kinda painful since some things didn’t translate well, but I didn’t need all of the files by then, so I just converted and fixed the important ones).
I’m actually still using an old 2007 version of Excel I had, too, but it’s fine :)
Various design-related Cogmind spreadsheets (open for full size).
Player scoresheet data as output to a .csv file for analysis in Excel.
Ever since starting this commercial project I’ve also been using a massive Excel spreadsheet to record my daily work progress.
Recording and categorizing hours of work each day, and noting where that time was spent. It’s also then easy to produce and maintain a variety of graphs based on this data. This data set, now north of 2,500 rows, is what I’ve been using to share occasional progress graphs over the years, like I do in some of my annual reviews, for example.
Spreadsheets are of course also useful for storing and analyzing financial data and any other database-like info that you need when running a business.
Excel makes it quite easy to do all this, and of course it’s a huge piece of software with a lot of features and there’s a large variety of things you might want to do and aren’t sure how, but at least it’s easy to find answers online since it’s so widely used.
Art
REXPaint
My most commonly used art-related tool is REXPaint, the ASCII/ANSI editor I first released publicly shortly before starting Cogmind development proper, and have updated many times since (with no doubt more versions to come!). It’s incredibly valuable for UI mockups and mapping, and of course makes it possible to more easily produce Cogmind’s iconic item and achievement art.
Part of one of Cogmind’s many item art “spritesheets,” as it appears in REXPaint.
A sample of the variety of my internal design work done in REXPaint (most of it for Cogmind) (open for full size).
Lots of devs and artists use REXPaint--you can see some samples of their work in the gallery.
For anything that doesn’t fall under the grid-based umbrella that REXPaint is built to work with, I use a lot of Photoshop. That includes screenshot work, logos, and other raster images for marketing purposes. Also of course a lot of the diagrams and other images shared on this blog :)
It’s an amazingly powerful tool, one that I started using over 20 years ago since that’s what my parents have always used :P. I’ve tested out a lot of other programs over the years, but always come back to Photoshop.
Although it’s probably not the best tool for the job, I’m most familiar with it so I even use it for pixelwise work including tilesets and bitmap fonts, as explained in my font series.
Examining bitmap font layers in Photoshop.
Because traditional roguelike screenshots are almost always best created as pixel-perfect PNGs, good PNG support is clearly an important thing to have in your software of choice. For that I use SuperPNG, a Photoshop plugin with more control over PNG output and better results than what you’d get with Photoshop’s native plugin.
Sound
Audacity
Ever since my first game that actually had sound effects, I’ve been using Audacity to manipulate and otherwise work with them. It’s a pretty powerful package for the low price of free. Getting just the right sounds often involves mixing, adjustments, conversion etc., and Audacity handles whatever I throw at it, so I’m satisfied :)
Mixing samples in Audacity to create a final explosion sound effect.
Reaper is a powerful digital audio workstation, for people who really know what they’re doing. I am not one of said people, but I did really need something that could handle high-quality bulk conversion of audio assets, something Audicity couldn’t really do very well at all (maybe it’s gotten better in more recent versions? I dunno), and this was the best thing I could find for the job.
Winamp
Shout out to this vital tool! Okay so Winamp is technically a music player, one that I’ve been using for a couple decades and still use every day, but 1) listening to music while developing is really what keeps me going and focused, and 2) I do also use it for quick local browsing of large numbers of sound samples when doing audio work.
Winamp development died out years ago, then surprisingly a couple years ago a new version appeared and there is presumably more work going into a successor, but anyway, I’m using that new version, which has improved support for Windows 10.
Media
LICEcap & gifsicle
A side effect of Cogmind’s design focus on avoiding unnecessary visual distractions means that most static screenshots tend to look pretty boring, at least compared to what the game can look like in motion.
Characters look even cooler when they’re moving around, eh? :P
A quick survey of all the Cogmind media I’ve shared on Twitter over the past seven years shows that 35% of it was GIFs (the remaining two-thirds being PNGs).
In my search for an easy way to record GIFs I found LICEcap, an incredibly simple but effective program for recording directly from your desktop. I tried many others, but most either didn’t work for me, or at least not very well. LICEcap consistently produces very nice results, and that’s what I’ve used for all my Cogmind GIFs.
For even better results, I also run the LICEcap output through gifsicle, which optimizes GIFs into much smaller files that appear identical to the original--you can save a lot of space (and therefore loading time) with traditional roguelikes due to their typical minimalist visual style. For example GIFs can be optimized by removing data for pixels that don’t change between frames, and seeing as a large portion of roguelike interfaces and map views are static at any given time, even long GIFs can end up with a surprisingly low disk size.
gifsicle is a command line program, so if you want to try this approach without reading through the manual:
Put both gifsicle.exe and gifsicle-shrinkall.bat in the same directory along with any GIFs you want to shrink, and run the .bat file
Enjoy your smaller GIFs :D
The batch file just contains the line “for %%f in (*.gif) do gifsicle --batch -O3 -k256 %%~nf.gif”, which instructs gifsicle.exe to shrink all the .gif files it finds in the same directory.
gifsicle can help you with lots of other GIF-related modifications, though this is the only one I run for literally every recorded animation.
OBS Studio
As something interesting to try I began occasionally streaming Cogmind weekly seed play, the first ever apparently taking place in November 2015, though I didn’t actually start saving them until December 2017, so the first couple awkward years of my streams are no longer accessible (maybe that’s a good thing :P).
It was a sudden decision to begin doing that, after seeing other devs doing the same and players expressing interest, and at the time OBS seemed to be the most popular way to stream, so I used that.
Streaming gradually became something I do alongside development, mainly of various Cogmind runs, as a way to both interact with the community and keep tabs on the player side of the experience. Certainly a much broader range of feedback comes from players, including indirectly just from watching what players share and talk about, though that’s no substitute for playing it myself to get the full moment-to-moment experience and possibly lead to fixes, tweaks, or new ideas.
Later on OBS gave way to the newer OBS Studio, so I switched to that. It might take a little while to get everything set up nicely, but once everything’s up and running there’s no real need to mess with it. Overall a decent piece of software.
(Trailer Production)
One thing I found OBS unsuitable for in my case was recording game footage for the trailer, but there were plenty of alternatives to try out there.
Similar to how I use two separate text editors, I like having a separate editor for all my web dev work so that the environment (e.g. fonts/theme/hotkeys/other options) can be set up differently, plus using different softare helps me get into a different mentality, and my web dev stuff is also pretty simple anyway, so no need for something like Visual Studio with all its bells and whistles.
I’ve gone through several different editors over the years, and have currently settled on Visual Studio Code.
Visual Studio Code showing an excerpt of Cogmind’s website FAQ source.
I haven’t used VS Code a whole lot since I only switched to it within the past year and have been doing less web dev in that time, but it seems pretty nice, and it’s amazing to see MS build something that even many Linux developers have fallen in love with! (it’s cross-platform)
I use it mainly for editing HTML and CSS files.
FileZilla
If you’ve got a website and regularly deal with lots of files, you’re almost certainly going to want an FTP client to expedite the process. Duh. For this I use FileZilla, a pretty popular solution that gets the job done for me.
Backup
FBackup
Backups are vital. It’s sad how many times over the years we hear stories about devs (including in the roguelike community…) who’ve lost their entire project simply because a drive died and they only had one copy. Sometimes it’s months or even years of work!
I have an external hard drive for on-site backups, and use FBackup to mirror all my personal data (including of course Cogmind). It’s fairly easy to set up and use, and I used to run it all the time, but now I admit I don’t do it as often since I pay for an even better solution:
Crashplan
For a while I was trying to store backups of my data on a remove server of my own, but it was just too cumbersome and error-prone, so I went searching for a better solution.
Crashplan is one of the best, a service I use to maintain incremental backups of most of my data, pretty much in real time. I feel a lot safer having everything stored off site.
I haven’t ever needed Crashplan to recover Cogmind data before, but it’s helped me out a few other times and the recovery is quick and easy. Theoretically I guess I could also use it roll the Cogmind source back to any arbitrary point, too, though I doubt I’d ever need it to do that :P
By now you might notice there’s a major component missing from this (and/or the Programming) section of my list: version/source control. So technically I do have a GitHub account and that’s where Cogmind’s scoresheet definition lives so that that the new online scoresheet system (not built by me) can reference it, as can others looking to access the data (although I hear that will be available via an API in the future).
But other than that, I don’t use third-party source control solutions. Yes I do keep organized backups of Cogmind’s internal versions, but mainly just for the relatively rare need to reference them, and I don’t use any special software to manage this process.
Miscellaneous
There’s one other tool I like that doesn’t really fit well elsewhere, but can be quite useful: Bulk Rename Utility. If you ever have to rename a large number of files in a smart manner, BRU is for you.
Also the UI is great ;)
Behold, Bulk Rename Utility with all its glorious fields, buttons, and drop-down menus!
It can honestly take a bit to get used to the UI, but it is very very powerful. It helps that you can see a realtime preview of all the changes you’re going to make once you execute, so you don’t have to apply any actual file renaming until you’re sure you’ll get the results you want.
Abandoned Tools
Aside from some examples mentioned above (OpenOffice Calc…), there’s other software that I was using at one point during Cogmind development but later abandoned. Might as well give them some cursory coverage here, too, for the record.
SilverNote
Cogmind’s original alpha design doc was written entirely in SilverNote. At the beginning of the project I was looking for a solution with strong support for list-based note taking, since that’s almost always how I write my notes (lists with sublists with sublists and so on), and SilverNote seemed to fit the bill.
It turns out SilverNote is a pretty bad piece of software, and the dev didn’t seem interested in fixing its bugs and other issues (the original website doesn’t even exist anymore, and it’s now apparently freeware).
By the time I’d made that determination I already had a bunch of notes stored in its proprietary format, so I decided to just power through and continue using it up to the alpha launch, since it was just the main design doc anyway.
Most of the content and features described therein was already implemented as of Alpha 1, so not long after the launch I just had SilverNote use its “export to HTML” feature to convert the old notes to a more accessible format in case I needed to reference them later, and stopped using SilverNote entirely.
Instead I began happily using .txt files again :P
An excerpt from Cogmind’s original alpha design doc. Each ‘+’ hides subsections, many of which have lists many levels deep where necessary. (SilverNote only crashed about ten times while I was trying to open the notes and get them prepared for this screenshot xD)
You can see a full summary of the above doc here, with more examples of what it contains, although when fully expanded the doc is 56 pages long (plus contains things I wouldn’t want to get questions about and have to explain :P), so this summary, too, is mostly top-level notes. Still, you can see some of the categories and contents if interested.
Note that Cogmind’s alpha design doc is missing more fundamental things you generally find in a design doc, because remember Cogmind Alpha was basically the second go at this, building on what was already done for the 7DRL the year before starting this as a commercial project. The 7DRL itself already had its own design doc covering a lot of the basics, and those features were already complete and carried over to the commercial version (I didn’t even rewrite the 7DRL code, just used it directly).
Sublime Text
Sublime Text was the hot new text editor when I happened to be looking for something to do my web dev with, so used it for a while and it was just okay. Then they switched to a pay model (it was originally free) and I didn’t really like it that much, so I went to look for something else.
I mean there are a lot of text editors out there and I’ve only used a handful of them :)
Atom
I replaced Sublime Text with Atom, another editor growing in popularity.
Oh my god this program. is. so. slow.
I compare everything to Notepad++, so maybe I’m biased because NP++ is insanely responsive almost regardless of what I throw at it, but Atom just felt like coding through molasses.
Nonetheless, I actually continued using it for a couple years or so because after finally getting it configured I was too busy with real work to go searching for yet another program, and I try to do as little web dev as possible anyway so it was only so painful :P
(Note: Maybe it’s gotten faster now, I dunno, but it was definitely anything but fast before.)
Conclusion
There you have it--my Cogmind dev tools!
I think I’ve covered everything here, but if I missed/overlooked a category or some aspect you’re interested in, feel free to ask.
And a final question: If anyone’s interested in an overview of the history and structure of the engine powering Cogmind (Rogue Engine X, first built in 2011), let me know and I could do that as the next post. Seems like a natural followup to something like this.
Creatures/entities that occupy more than one space in the grid-based world of a roguelike still aren’t all that common, although in the development community this is an increasingly popular topic. Many of these discussions revolve around how to solve various technical and design issues associated with this type of entity, and while I’ve provided input in a number of these conversations over the years, it’s really about time to collect some of these experiences, observations and advice into a single article for better reference :)
I gave “multi-tile robots” cursory coverage back when I was first spinning up Cogmind as a commercial project in 2013, but all I really did there was give a basic description rather than look into the nuts and bolts underpinning this feature.
I’ve been working with multitile creatures since 2011 when I first added them to X@COM. As I wrote about there, it was quite a headache because I didn’t include them from the very beginning, but it was both necessary to do considering the primary source material (X-Com) and also definitely adds a lot of character to these creatures, so very much worthwhile.
The famous example of a big ‘D’ dragon occupying only one space, the same tactical unit as a tiny adventurer, is great in its own way (elegant!), but there’s something to be said for the psychological impact and mechanical implications of an actually physically larger creature.
An adventurer faces off against… count them… five dragons in this room :P
I guess there’s also the realism argument--although complete realism isn’t usually a good goal in games, it’s always nice when you can both embrace it and get some benefits in return.
“Holy… look at that thing! We probably can’t take it on at this point, but if we escape down this narrow corridor it probably won’t be able to follow us… We’ll find another way around.”
Types and Examples
Technically the concept of “multitile” creatures can be subdivided into a number of different categories, not all of which I’ll be covering in detail here.
For example a number of roguelikes have stationary multitile creatures, like Ivy Creepers in Ragnarok.
Ivy Creeper wiki data from Ragnarok. (It’d be nice to get a shot of them in action, but they’re rare in that game, and unlike with other games the internet lacks a good variety of screenshots of this very old roguelike!)
Although stationary, sometimes creatures in this category can also grow outward, like the various Ivies in HyperRogue.
Overall these are fairly easy for developers to work with, it’s just a case of whether you want/need something like this in game.
There are also snake-styled multitile creatures which can move, but where the body essentially follows whatever path the head has taken, so also not all that hard to manage.
A Long Worm in NetHack, where only the head (‘w’) can attack, but attacking it in the body (‘~’) may cause it to divide into two worms.
HyperRogue also has several snake-like multitile creatures, including Sandworms.
The genre also includes amorphous area-based creatures like DCSS Krakens, which consist of a single body tile and send out tentacles which essentially behave as individual creatures (although their range from the body is restricted, and damaging them also damages the Kraken).
For the purposes of this article, to keep the scope in check (and more importantly to cover the especially challenging areas where questions usually arise) I’m really only interested in the most generic type of multitile creatures, those where the entire creature is a “connected solid blob” that is present on the map and moves as a unit like other single-tile creatures.
Probably the most extreme example of this category would be Dumuzid, a 7DRL explicitly designed around the concept of size, so it’s not surprising that you can end up with a massive sprawling body that moves as one.
Defeating enemies to expand your own body in Dumuzid, often eventually finding it difficult to fit through various areas, or the right angle to attack an enemy. This is just the start--your body can get quite expansive, and you might need to intentionally shave it down sometimes as well. It’s even possible to lose by getting stuck!
Some more typical examples, all coincidentally reflecting the theme that multitile creatures are often used for especially challenging or awe-inspiring enemies like bosses:
Lost Flame has quite a few types of multitile enemies (and not just bosses, either!) which meld well with the game’s heavy focus on telegraphed attacks and tactical positioning.
For X@COM I went all in on the multitile units, branching out from the original requirements for X-Com. It’s fun to drive a tank through walls and watch the building collapse :). It’s also fun--but scarier--to watch huge enemies rampage through buildings, knocking down walls and crushing furniture! X-Com itself only had units up to 2×2, but when putting in place mechanics like this, may as well make the size arbitrary! Back then while recording a video demonstrating sound testing there was a 5×5 Colossus at the end, which you can see below starting from 3:50:
Having inherited its architecture and even some mechanics from X@COM, Cogmind also includes a number of multitile entities for their shock and awe factor. Although there are slightly more obstacles to overcome when moving from a more open surface environment vs. the subterranean environments more typical among roguelikes, for me it’s worth the trouble.
A Cogmind Behemoth in the wild. (Uh oh, all hell is about to break loose and those machines are explosive…)
IVAN reportedly also has 2×2 monsters that can usually destroy walls in order to move around (or are simply stationary), but I couldn’t find any good resources or images on those.
I’ll be sharing more examples from Cogmind and other roguelikes below where applicable to the topics we’ll be covering.
Note that as discussed here multitile creatures refer to those of an actual larger size when it comes to mechanics and the number of grid spaces they occupy, not just cosmetic size, which a number of games do as a simple way around implementation issues, but as a result also don’t fully realize their potential.
Appearance
There are a number of different ways to depict multitile creatures on the map, some of which might need to get creative if limited to ASCII and/or traditional grids with an otherwise uniform cell size.
For Cogmind’s ASCII mode I chose to repeat the single character across the area currently occupied by the entity. The usual opposition to this concept claims that it becomes impossible to distinguish whether it is a group of entities or a single large entity, but in practice that’s not really much of an issue since based on the game content it’s otherwise extremely rare to have individuals matching that letter both adjacent to each other in a uniform shape and also moving in perfect formation. Not to mention when examining such an entity all the spaces are highlighted together, and labeling (or for example in other roguelikes listing what is currently visible) only does so once for the entire thing, rather than for every constituent cell. So this isn’t really something to worry about unless there is something else specific to the given game’s content or mechanics that might lead to confusion.
Highlighting and labeling a large robot in Cogmind’s ASCII mode.
Incursion offers another potential approach for ASCII-based roguelikes, linking the creature’s character to its surrounding occupied cells with a separate representative character, in this case using ‘+’:
A Huge Viper in Incursion--the ‘R’ surrounded by ‘+’.
Under a very strict grid-based system like that often used in ASCII games, it’s technically still possible to draw multitile creatures using a sprite that extends over more than one cell. Cogmind’s engine in particular doesn’t even support drawing anything that doesn’t match the grid size, so the only way to draw a multitile object is to do it piecemeal, one cell at a time. For example, the 2×2 Behemoth consists of four separate cells, appearing as such in the sprite sheet:
Cogmind sprite sheet excerpt--Behemoth cells. The first is the top-left, followed by top-right, bottom-left, and bottom-right. The same system is extrapolated for even larger entities.
Many roguelikes using modern engines don’t necessarily care about this sort of thing, and are instead able to simply draw any sprite, large or small, at any position. Zorbus offers a good example of multiple different methods for drawing large creatures when there aren’t any architectural restrictions.
Various dragon representations in Zorbus. While most of these are purely stylistic differences, important to note is the ASCII version demonstrating yet another approach: Just make the letter bigger :P
Partial Visibility
A number of roguelikes (including Zorbus above) might display multitile creatures simply using large characters, highlighting another consideration when working with multitile creatures: partial visibility. Field of view in roguelikes is almost always handled on a cellwise basis, so what does the player see if only one or more pieces of a multitile creature are visible?
In terms of ASCII and Cogmind’s default approach of repeating the same character throughout every occupied cell, seeing only part of a creature doesn’t make much of a difference since every cell contains the same representation. Perhaps the main concern here would be that a player might not be able to immediately distinguish whether a single ‘B’, for example, is a corner piece of a large Behemoth or a single-tile Brawler-class robot. This is where it helps to have those automated labels demonstrated earlier--the question is answered immediately on spotting them!
A partially visible Behemoth has its top-left corner labeled on sight.
To demonstrate another scenario, we can use a graphical Cogmind mod recently released by Ape, which converts the default multicharacter style to instead use large characters like so:
A large-character multitile Behemoth as it appears in Ape’s graphical Cogmind mod. So imposing! I love it. (This particular ASCII mod also uses the tileset specifically for walls.)
So what happens when this only the corner of this particular Behemoth is visible?
A partially visible Behemoth assuming large characters are used for multitile entities.
Again the autolabeling will help here anyway, but the top-left corner of a large ‘B’ character actually looks like an off-center ‘c’! And of course each other corner, or side, will have its own unique appearance. Partial visibility doesn’t work so well with this approach as far as quick visual parsing goes (usually one of the advantages of using ASCII in the first place).
Based on this info, with multitile creatures we might want to break the mold of displaying only the cells that a player can currently see, and instead allow the player to know and see the full extent of any multitile creature they can at least see part of. This could apply to both ASCII and tilesets. Either show the entire creature normally if any of its parts are visible, or show it all but consider fading those cells not currently in FOV, since it can still be important to know when certain subsections are technically out of view.
Examples of what it would be like to show the full large-character Behemoth even though only its corner is visible (A), or perhaps fade those sections which aren’t themselves in view at the moment (B).
For cogmind in particular I decided against showing parts outside FOV (which is an option even if separate characters are used for each part!) because it would complicate a lot of the UI features in my case. I imagine it would work fine for a lot of other roguelikes, though.
Architecture
Handling relative position data for entities is fairly straightforward when each one can only occupy one cell at a time, but what do you do for those with a larger footprint? Some people get hung up on this question. The answer for a given roguelike could depend on other needs and architectural concerns, but here I’ll share what’s worked well for me.
This is rooted in the format for general map data, so here’s a diagram of how Cogmind map objects are structured:
Diagramming the relationship between common object types on a Cogmind map.
This diagram includes some superfluous info because I pulled it from a broader discussion, but the concept to pay attention to here is that 1) an entire map/floor is represented by a two-dimensional matrix of Cell objects, and 2) within each of those cells is an Entity object. “Entity” refers to an actor/creature/character/mob/whateveryoucallit, where the Cell stores its occupant’s handle (sorta like a pointer) or simply null if no Entity is currently present at that location.
Although I do also have a list of all the Entities in existence (technically managed as a separate list for each faction), and that format clearly comes in handy for some types of operations that need to iterate over all Entities, I find it very useful to have an actual 2D space across which to perform spacial searches and apply effects etc. For performance reasons this is especially important in Cogmind where there are hundreds of Entities at once.
So what does this mean for multitile Entities? Well… just put their unique handle in every Cell they occupy :)
It’s not like the Entity object itself is actually copied anywhere--it’s just a little handle, so there’s no serious waste of space, but definitely a serious bonus to convenience. Processes checking who’s occupying any one (or more) of those Cells will be pointed to the same Entity. Whenever the Entity changes position, it just moves its handles from all of the original space(s) it occupied to the new ones.
Each Entity itself also stores a list of all the map coordinates it currently occupies. While it’s true that for most/single-celled Entities this list only contains one coordinate, implementing the system like this makes it easily scalable. At the same time, although for most roguelikes you could generally extrapolate these additional coordinates if you know their reference position and size, that’s pretty slow to be doing all the time!
In my case I chose the Entity’s top-left corner as their “reference position,” the first to appear in its list, where any additional coordinates are added in row-first order (notice how the indices here will conveniently mirror offsets in the sprite sheet shown earlier ;)). The idea of a reference position will come in handy later.
(Although most devs there don’t make mention of multitile entities, regarding map object architecture you might find other inspiration in the previousrelevant FAQs over on r/RoguelikeDev.)
Shape
Before we go any further it’s important to talk about shape as it relates to multitile creatures.
By far the most common multitile creature in a roguelike, if there are any at all, is the so-called “2×2”, occupying a total of four cells. As a square this is fairly easy to deal with because it doesn’t have any convex or concave elements to complicate movement or interactions.
Non-square shapes (even just rectangles!) are problematic since then you likely have to deal with the logic and consequences of rotation, among other issues. With multitile creatures already introducing enough of their own complications, most roguelikes don’t venture into other shapes. (Something like Dumuzid is of course an exception here, since its a small game where the central theme happens to be size manipulation. Interestingly, it does not allow rotation, either.) Rotation suggests an explicit facing, anyway, and most roguelikes don’t have facing mechanics, so multitile creatures that imply multiple orientations are often avoided.
Pathfinding
Whenever the topic of multitile creatures pops up in the roguelikedev community, there’s a good chance it’s someone asking about pathfinding. In a game where every actor occupies exactly one space, moving them across a grid seems a lot more straightforward than managing those which need extra space to move around.
For the purposes of pathfinding for multitile creatures we’re going to be ignoring these less common scenarios and, again, creatures outside this article’s scope:
non-square shapes (and by extension any rotation involved with those--CDDA has rotating multitile vehicles of various shapes if you want to look into that, for example here)
snakes (longer are especially challenging, since they can block themselves!)
amorphous creatures
Still, if you’re working with any of the above, it’s mainly a case of picking a primary reference part (of the creature in question) on which the pathfinding is based, and extrapolate positions for other connected parts as it’s moving, which is actually akin to what we’ll be doing here in a moment for regular square multitile creatures.
Method 1: Static Approach
One method I haven’t used before but have seen others use is to explicitly map out the spaces available to large creatures, and use that map for pathfinding. Taking the most common 2×2 creature as an example, you can make a copy of your map and block any otherwise open spaces that have a wall or other impassable obstacle to their south, east, or southeast.
A basic sample map next to its precalculated movement map highlighting all the spaces our ‘D’ragon can access and occupy (green background). This representation assumes the creature’s reference position for pathfinding purposes is the top-left corner of its square.
So as per the above screenshots, pathfinding algorithms would rely on two separate maps, one used for standard-sized actors, and another for 2×2 creatures:
Comparison of movement/pathfinding area available to 1×1 entities (left) vs. 2×2 entities (right).
Our dragon is on the move! See how its top-left corner always stays in the green areas, although the rest of its body might extend into the black.
However, this approach works better for static maps, since changes to the map due to terrain destruction or other factors would require recalculating the pathfinding map(s) (or at least parts of it). I love rampant terrain destruction in my roguelikes, so this approach won’t really work so well in my case. As you’ll see below, an alternative dynamic approach can also take into account more factors, anyway, creature size being just one of them.
Method 2: Dynamic Approach
The dynamic approach starts getting more deeply into how you build your pathfinding system architecture. Amit’s got great resources on A* pathfinding over at Red Blob if you want to read up on that common algorithm for more background. I’m not going over basic A* here, instead looking at how to best apply it so that it can specifically account for creatures of arbitrary size.
For all but the simplest roguelike worlds you’ll often want to have creatures actually examine each potential cell along a path and weigh it in terms of various relevant factors, for example terrain movement costs (which can differ by creature type and terrain?), or the creature’s own capabilities (able to swim? fly? open doors? some other form of environmental interaction?). One nice way to compartmentalize this feature: Callbacks.
In simple terms, when a creature wants to find a path from point A to point B and calls the game’s pathfinding function, it also provides a callback function that essentially contains instructions for how to value cells along prospective paths. A* pathfinding operates by assigning “cost” values to cells until it finds the sequence of moves that can arrive at the intended target for the lowest total cost. So the callback’s job is to just return the cost for a given cell in order to facilitate those calculations.
Cogmind’s pathfinding callback object.
As shown above, Cogmind’s primary movement pathfinding callback that’s sent to the algorithm is actually an object holding multiple methods, originally virtually defined by the base class associated with the pathfinder itself (Cartographer2D). I found it more efficient to split out into multiple methods some of the checks that a callback might need to handle, e.g. isValid() is used to tell whether the goal is a valid movement position, which is probably important to know before bothering to start :P. (Cartographer2d also supports pathfinding via cell-enabled teleportation, but Cogmind itself doesn’t feature that kind of teleportation so the callback object doesn’t define the necessary method.)
Where does this accommodate multitile creatures? First of all, remember that the reference part of the creature is what’s being used to calculate their path--the beginning of the path matches their top-left corner, and the end of the path will be the final location of their top-left corner.
A sample path for our multitile dragon, based on its reference part.
The isValid() function* just needs to be sure to check not only whether the reference position at each cell along the path is valid, but that all other relative parts of the same creature are also valid (*and by extension getMoveCost(), which is what checks isValid() before calculating and returning the cost for a cell).
For reference, here’s the actual source for those methods as used in Cogmind, with some of the very game-specific code left in for demonstration purposes (some of it was temporarily removed to skim down the size and avoid overcomplicating the example). Note how isValid() checks the validity of all constituent parts for large square creatures (of arbitrary size) assuming it’s standing at a given coordinate location.
This dynamic approach doesn’t require precalculating or maintaining any other pathfinding maps, can take into account any number of other factors (regardless of whether they’re changing all the time!), and is clearly just what we need for allowing multitile creatures to move around while also considering whatever else they need to consider.
In summary you get a lot of flexibility by using callbacks for pathfinding. We can add whatever absolute checks we want to isValidCell() and they’ll be applied to any cell the creature might think about occupying, or add checks to getMoveCost() for moves that are allowed but might have a different cost than moving into/through a normal cell. Cogmind doesn’t make especially heavy use of these features, though as you can see there are conditions determining whether or not an entity can use different types of hidden doors, and the cost of pathing through a known trap or area prone to cave-ins is higher (making it less likely).
Aside: The popular roguelike library libtcod (which I recommend in my How to Make a Roguelike talk/article) includes support for pathfinding callbacks! In fact, using libtcod in my early roguelikedev days is actually where I learned about them in the first place :)
Design
Having gotten the primary technical concerns out of the way, there’s also the design side of the equation when it comes to multitile creatures. Surely you can’t just drop them into a world made for your typical 1×1 cell-sized creatures and expect everything to be okay :P
Environment-based Factors
Naturally more open maps are better suited for these large creatures, since terrain is the biggest obstacle to their movement. Although roguelike maps tend to have a lot of tight spaces, even subterranean maps can also be made more hospitable for large creatures if there are at least some open areas for them to comfortably occupy.
For example Cogmind’s most common 2×2 unit, Behemoths, aren’t located in random rooms, but instead specifically placed in areas where multiple rooms and corridors have converged to create a larger space.
According to the mapgen rules, in Cogmind multitile entities (in this case somewhat scary and destructive mobile weapons platforms) might be defending any of these areas.
This ensures they’ll have some room to maneuver and engage threats without being overly restricted, and while it’s true they’ll not always be able to stray too far out of the area they’re defending, they still present interesting challenges when compounded with other factors to complicate situations, like a player fighting a running battle through such an area, or encountering other enemies at the same time and finding it difficult to disengage.
Other challenges arise when there’s no easy way to circumvent a large creature and a confrontation is almost guaranteed sooner or later. This also starts to suggests the idea of “multitile creature as boss or miniboss,” where their extra visual weight signals that they’re not to be trifled with (hopefully with stats and abilities to back up this assumption!).
Since multitile creatures can be problematic for map layouts, it makes sense to limit their overall number in the first place, plus having fewer of them enhances their wow factor anyway. Again: boss material.
On that note, another way around some of these issues is to design special areas explicitly for multitile creatures, like their home/den/native habitat. “Waste” is an example of one such place found in Cogmind, where chutes from Factory zones send scrap for disposal, and mobile Compactors mill about crushing everything.
Compactors are each 2×2 multitile entities, and all corridors in randomized Waste layouts are exactly four cells wide, just barely allowing two Compactors to pass each other. This of course presents a problem for players who have attracted the attention of more than one Compactor, since they can form an oncoming wall of death, so maneuvering to prevent or undo such a situation and slip by can be a useful skill if without the firepower or other means to actually take these chunky bots down.
Sample “Waste” map layout with multitile Compactor occupants.
Since we were talking about multitile creature representations earlier, here’s an alternative look at the same scene:
Sample Waste map revealed in ASCII mode.
Garrisons are another example of a Cogmind map type in which multitile entities have influenced the design, where there is often a 2×2 Behemoth guarding the central room and double-width corridors extending outward to all four access points.
Sample Garrison layouts with central open room (potential Behemoth defender!) and wide corridor spokes.
There are still small access tunnels mostly hidden behind walls that might be useful in avoiding a confrontation with the Behemoth in a Garrison, but overall it’s quite a game of cat and mouse if you’re not ready to engage them head on, since due to the layout and Garrison mechanics it’s likely you’ll have to pass through the central room more than once from different angles before being able to actually leave.
Creature-based Factors
Aside from external factors like map design, we can also examine this issue from the other side: What about giving multitile creatures more control over how they can maneuver through, or manipulate, the spaces around them? This is where various mechanics and creature-specific abilities come into play.
Seemingly the most common approach here, and the one that makes the most sense (because, I mean, they’re big creatures, yeah?) is to simply let them crush obstacles and smash their way through terrain! Whether or not this will work for you can of course depend on the environment and other circumstances, but it serves as yet another source of wow factor when some creature practically ignores walls that block normal-sized foes and just comes right through them.
The multitile creature demo in the X@COM video I shared earlier happens to show it smashing through walls, although much of it is out of view while doing so. In that game the system is generalized such that different materials require a different amount of force to knock down/through, so while a soldier can relatively easily jump through a glass window, or a bigger alien can possibly stomp through a fence, it takes a tank or huge alien to smash through walls of brick or stone.
A tank driving through a house in X@COM. You can also see it pushed back (and later to the left) due to displacement from falling debris from the second floor after it loses the support of some walls below it.
While pathfinding, A* callbacks can help determine 1) whether a given unit is even able to take a “shortcut” through a given material and 2) whether the potential cost(s) of doing so are not greater than going around it (if possible).
X@COM pathfinding range comparison between a soldier (center blue triangle) and the multitile tank next to it. Notice how the soldier’s range doesn’t include obstacles, and isn’t able to quickly make past the tall hedge to the north, whereas the tank has the option to just crash right through so it can reach almost all visible locations in a single turn. (Aside: The soldier’s potential path area includes a brighter green portion, which is actually up on the second floor of the house they’re in, via the ‘<‘ stairs around the corner just inside from the garage. The tank can’t use the stairs, so its path is restricted to the ground level here :P)
[SPOILER ALERT: If you’re a spoiler-averse Cogmind player, you might want to just skip this paragraph.] Although not nearly as detailed, Cogmind has a similar mechanic specific to a certain entity. It’s a fairly rare encounter, but players might at some point discover an experimental “Superbehemoth” capable of disintegrating terrain around it, effectively tunneling through it if necessary to get somewhere.
As mentioned earlier, I’ve heard that IVAN also has 2×2 multitile creatures that can destroy terrain in order to move, thereby sidestepping one of the tougher challenges with this type of creature.
Very much in the theme of ASCII and turn-based grids and all the things that speak to a “limitations breed creativity” mindset, in trying to integrate multitile creatures into a roguelike you can always experiment with other forms of movement and enabling mechanics, too.
Maybe a multitile creature can temporarily reshape itself to squeeze through narrow areas and unexpectedly pop out on the other side? Maybe they can teleport or use some kind of network of gateways? I still haven’t actually done it, but one of the ideas I think would be fun to implement is a giant robot that can dispatch a bunch of tiny engineering drones to excavate pathways on the fly when it needs to, and they rebuild walls and terrain behind it after it’s passed.
Another approach here is to allow multitile creatures more flexibility in how they can attack, essentially projecting their sphere of influence beyond their movement range. Early in Cogmind development this was actually one of the first ways I made Behemoths more formidable than they started out, since they are otherwise huge lumbering bots that could be evaded by keeping obstacles between yourself and them. Well they already have powerful enough weapons, so I just made their AI much more aggressive, willing to fire their cannons through machines and terrain to get at targets.
Behemoth says we aren’t going to get away so lucky. Double bonus when the machines they’re shooting through are explosive :)
So if the mechanics/environment/theme are suitable, consider giving multitile creatures the ability to attack and destroy terrain, or even just attacks that can penetrate terrain and other objects.
Or maybe they send out other attackers to engage targets? This could force the player to come to them in order to the deal with the source of the ranged threat, not unlike the stationary dispatchers of POYLBOT-7.
Miscellaneous Issues
You’ll no doubt discover more complications stemming from the introduction of multitile creatures, some of them specific to your mechanics and needs.
Origin vs. Target
One of the more common ones you don’t normally need to think about in a roguelike is the specific origin or target of an attack, in cell terms, considering that creatures might occupy more than one grid position. Perhaps if you have an odd-dimensioned multitile creature (e.g. 3×3) you might want to use its center point for this purpose. Or if you have special mechanics and a facing component there is/are actually a designated point on the creature where its attack(s) originate.
MechRL, a 7DRL from 2020, has you building your mech from visible parts that could easily use their respective locations to serve as the origins of attacks.
In my case, for the origin I always select the point on the attacker that is closest to the defender, and have it target the nearest point on the defender. That’s for AI-controlled units, anyway--the player has more freedom to select any cell occupied by the target, making it somewhat easier to acquire a clear line of fire on partially obscured targets. It would be better to allow the AI to target any visible cell as well, but I felt it wasn’t really needed, or worth adding that complexity, for my purposes.
AOE
If you’ve got area-based effects like explosions, as many roguelikes do, that’ll be something else to consider. Should multitile creatures take extra damage/effects separately for every one of their tiles within the radius?
Having larger entities take more AOE damage like this is an option if you think it balances well given your mechanics, and players may even sometimes assume it in tactical games with a heavy emphasis on grid-based play (in my experience it’s not an entirely uncommon question among players).
Personally I think it makes balance much more difficult to achieve when it comes to Cogmind mechanics, so I prevented that from being a thing--regardless of size, a single unit can only be affected once by a given AOE attack.
Sorry big explosion, you can only hit that Behemoth once.
I simply keep a record of all the entities already impacted by each active AOE effect, in order to prevent further segments from applying the same effect. As per the map object architecture I shared earlier, each Cell occupied by a multitile Entity stores a handle pointing to the same Entity, so marking the first one affected by an expanding radius naturally makes all the others “immune” to the same event.
In the original X-Com (and therefore X@COM), explosions separately impacted every segment of a large target within their radius, like this 2×2 Cyberdisc. They have high resistance against explosives to compensate and won’t generally die if only a small part of them is hit.
I ended up needing to take the same precautions for Cogmind’s penetrating weapons as well (capable of piercing a target and going on to affect additional targets behind it)--I didn’t realize until 2017 that these weapons were disproportionately effective against larger targets, since they could pierce one section and then hit one or more additional sections, affecting each separately. Now this does make logical sense, sure, but balance-wise it’s not so compatible.
In theory this shot could penetrate two separate pieces of the Behemoth (but only affect the first) before hitting its target (which might also itself be penetrated :P).
Terrain
You might also need to consider how multitile creatures interact with various types of terrain. Like what happens if they simultaneously occupy locations with different or even incompatible effects? How are variable terrain-based movement costs applied?
For this and other reasons, it’s a good idea to add this kind of creature early in development so that you can take them into consideration throughout the process. Introducing them later could be quite problematic since you have to uncover and resolve all these issues retroactively rather than building each consideration into the system bit by bit as you encounter it.
Cogmind doesn’t include many terrain-based factors, although one example I can provide here is traps. Chute traps, which suck units down into the ground into another area (the aforementioned Waste!), only occupy a single space, so they essentially ignore larger entities that “wouldn’t fit” :). Most other traps however, like those of an explosive nature, are triggered normally for every cell the entity steps on, meaning it’s possible to set off more than one in the same turn.
3D
Few roguelikes take advantage of 3D grid space, but while we’re on the topic we might as well cover some points regarding adding a third dimension to our multitile creatures.
Earlier I talked about square shapes being by far the easiest to work with when it comes to multitile creatures, though the z-height of such a creature doesn’t necessary need to match the other two dimensions. A 3×3 creature with a height of 2 isn’t going to operate significantly differently from one of height 3. We are, however, assuming that height is uniform across its area. You can easily have 3x3x3 cube-shaped creatures, flatter 3x3x2 creatures, or even tall and narrow 1x1x2 creatures.
In most cases you’ll be able to simply extrapolate everything we’ve already done for multitile creatures into the third dimension--like our pathfinding callback needs to check not just two dimensions, but three. I did this for X@COM, where I added 3D creatures and used the top-left corner of their lowest/base level as their reference point.
A multitile Colossus in its 5x5x3 glory, showing the three z-levels it occupies next to a house, and with its reference point highlighted.
And although a full discussion of how to represent a 3D space in a top-down 2D map is beyond the scope of this article, it’s worth pointing out that with creatures like this it can be beneficial to allow a way to see them from the side as well. I first talked about side views back in 2011 when I implemented this feature for X@COM, and later shared how this can be applied to viewing 3D multitile units from the side as well.
Here you can see the Colossus being viewed from the side as well, in a popup window that appears across the top there to display the line of sight from a different angle. That’s a lot of @ :)
This makes is easier to visualize targeting their different z-levels in case there are obstacles blocking line of fire at a given height.
More?
I’ve covered a lot of the main multitile creature topics here, but it’s a big one (haha) so feel free to ask about related issues or anything here you’d like clarification on!
Update 240903: I have since further expanded Cogmind’s feature set with yet more new behaviors to support multitile creatures, including wall smashing, pushing, crushing, and multiple improvements to large ally movement and navigation. Details in this article.
Anonymous on Hacking, the InterfaceCY-PHR sounds like such a troll of a bot, and it probably be very annoying (in a good way) as well as dangerous
Kyzrati on Hacking, the InterfaceGood point, and a good reminder from this now-ancient article :) Obviously never took that direction in the regular game, but yep ...
y0un65t3r on Hacking, the InterfaceSome of these unused hacking risks would make epic CY-PHR mechanics!
Kyzrati on A Simple Approach to Player-Designed RobotsYeah it's turned out quite well! (and we've been having a lot of fun with these things even outside the game, as you can see...
Kyzrati on Fog of WarYeah it's a pretty old post at this point, and I remember that was a fun article but they must've changed their link structure, or...