Just read a pretty insightful bit about what “Super Mario Bros” (the original NES title) did right. Like most wanna-be game-developers, I’ve spent quite a few years speculating about game-design; trying to shake out some set of principles that could describe why some games are good, and others are not. When we started working on frogatto, it was no surprise to me that there were quite a few crucial design points about platformers which I had never considered beforehand. As we worked on the game, we’ve noticed that a number of aspects just weren’t fun, and we’ve gradually tried to suss out … why?
This blog post nailed one of the precise design problems we’ve run into which I’ve been trying to address since 1.0; when we originally added the forest, cave and dungeon sections, we simply didn’t have enough unique gameplay to float them. We were short on both unique enemies and puzzles, and although the first part of the game advertised some enormous promise, the second 3/4 did not. But it wasn’t simply a matter of adding more monsters; they had to add that nebulous quantity of “fun”. I actually burned quite a bit of time figuring out what the hell ‘fun’ even means when you’re designing videogame enemies; there are at least 10 partly or un-animated monster designs that have been prototyped, but which we’ve wholly axed between then and now because they just weren’t fun.
I think one of the big things it started with, which is an excellent foil for exposing the mental traps that underlie almost all of the other problems was an idea that monster viability should be independent of the level around it. It was in fact a bad idea. Do not try to design creatures which can work in any possible level layout; it’s possible, but it’s enormously complex and time consuming, and it doesn’t add a lot of benefit. There are a number of reasons people fall into this trap:
If you’re also a general engine project like we have been at some points in the past, the philosophy of generality bleeds over. When you’re designing a general engine or a general game editor, you can fall into a trap of wanting to insulate against all possible “bad surprises” for your users. If a user places something, they shouldn’t have to know anything about it; it should Just Work; it should negotiate all possible mismatches/design-incompatibilities/whatever to just magically figure out its setting, adapt, and function the way the user imagines it should. This is how, for example, vector art behaves in an otherwise internally raster-based program like photoshop; it’s a square peg going into a round hole, and the glue to make it “just work” is considerable.
For one example, consider making a flying enemy with basic behavior that makes it fly from one X position, to another X position. In a generous, open space with no terrain in the way, writing this is trivial; you give it constant acceleration, and make it reverse direction once its position exceeds a certain value. Easy. It seems reasonable, from a level-designer’s standpoint, that it should always work regardless of the layout; all it’s doing is just pathfinding from point A to point B, right? So if you put it in a twisting corridor, it’ll naturally duck under the outcrops, and rise over ridges to find a path back and forth. Except actually it won’t, because in the implementation I just described, there is no pathfinding. There’s no AI; there’s just one, single line of code with two conditionals in it.
The pitfall, there, is assuming you’re catering to that imaginary user with entirely reasonable, but difficult-to-fulfill expectations. You’re not; you’re writing a game which has an almost certain probability of being edited by only one person, and in the absurdly unlikely event your game DOES become popular with a modding community, you should assume that modders will have a high correlation between cleverness and productiveness (those who are baffled when a monster doesn’t work right in certain circumstances will have a lot of difficulty getting a great deal of other things done, and aren’t likely to get anything done), you should remember that it can always be improved later, and more than anything, you should remember that there won’t be a modding community in the first place if you don’t ship a game they can become fans of.
Apart from bending over backwards to please a hypothetical user, the other idea that can lead to overbearing generality is an idea that you, yourself will benefit from being able to use that same creature everywhere. There is truth to this – one really good, really clever enemy can get some great mileage … but it depends on whether it changes gameplay from the player’s perspective. Most specifically; is the player being forced to make different decisions than usual in order to deal with this threat? At it’s most basic level, a game is a series of interesting decisions*; if you do a boatload of work on an enemy to make it work in different situations, but the basic decisions the player faces are still the same, you’ve wasted your time. The basic gameplay is still the same; you’re just jumping through hoops to provide it. At worst is when you do something enormously difficult to implement, and (perhaps due to the enemy generally being offscreen), it’s entirely invisible to the player whether you did or didn’t do it.
Perhaps most tragic is when someone has a personal vendetta against something that disappointed them in their youth; say, using a Doom level editor and finding that some creature just glitched out in some situation that never happens in the real game, but happens in the particular edit you were trying to make. As a starry-eyed kid, you think “These guys were so lazy to have not fixed this obvious flaw. By golly, when I grow up, I’m gonna do this right when I make a game!” This sort of thing typically is called a sacred cow – it’s a rule you follow and never question, but it’s a rule that you made when you were a pretty naive kid, and you didn’t base it any thought about game design; you based it on strong feelings of disappointment – even if it worked flawlessly the way it was meant to be used, and provided wonderful entertainment for you the other 99% of the time. The danger of the ‘sacred cow’ is it’s namesake – is your refusal to remove something that is very costly to you. You’re now an adult; it’s time to put away childish things.
Sacred cows can bleed out into being more general gameplay mechanics; one which we held onto for quite a while was that all creatures in the game occupied strict rectangles of solidity. Unless a creature was somehow literally ethereal (like a ghost), we intended to make sure that all creatures followed physical rules; they can’t cheat and go through walls, and if multiple instance of them are in too tight a space, they can get congested and form a traffic jam. We abandoned this ages ago (shortly after 1.0), but earlier on, this caused some enormous mental blocks. The greatest tragedy behind this was we couldn’t provide any concrete reason why ‘realistic behavior’ made the game better; we simply had a personal vendetta against the idea (perhaps it felt like cheating on the computer’s part when we first encountered it in a game?) and we were determined to avenge that slight. What a waste.
It’s basically cost/benefit analysis, with one key idea: always remember your goal is to ship this game. Not to make some modder’s paradise. Not to make the perfect system. Not to write the next GameMaker or Unity. If you’re too naive to settle for the extraordinarily impressive feat of just shipping a game, I can’t help you. But if you’re mature enough to have already settled, the mantra can’t be repeated enough, because it’s so easy to slip back into these traps.
The way this hurt frogatto ironically wasn’t because we spent a lot of time writing something astronomically complex, but it hurt us because I wrote-off a whole panoply of monster ideas as not worth pursuing because they were insufficiently general. I saw a few cases where a given design would be hopelessly, hilariously inept, and decided that if there was anything in the game that could ‘bluescreen’ a given creature, the whole design of the creature was flawed and shouldn’t be considered, period. It seems to me that almost all cases where I have some sort of writer’s block or difficulty brainstorming are because there’s some internal “governor”; some ruleset in my head which I’m not fully aware of, discarding ideas before they’re fully formed. When this is in effect, I try to brainstorm about something and it just seems like “there aren’t any good ideas to be tried”; as though the problem lies in an exhausted possibility space rather than my dismissive perception of it.
So here’s a list of things that blog post touched on which are good design points for platformers – I think the mental self-analysis above is more important for deriving these from first principles, but these are worth hashing out a list of if you’d like cliffs notes:
- monsters need only work in one well-suited level layout geared towards them; it’s entirely okay for them to glitch out or just be helpless in others. Just don’t use them there.
- allow monsters to cheat and do things like pass-through-walls (c.f. our bats) if their physical limitations stand in the way of a fun enemy design.
- monsters need to vary on multiple dimensions of behavior; it’s fine to pick a few easy-to-do behaviors like giving them more HP/Speed/Damage, but each of these can only be used once. In fact because these particular easy-to-abuse ones are incredibly common and familiar to gamers, these have very little mileage, and you should really only do one “same but better” variant. Two is pushing it.
- aim for interesting effects that can be achieved with implementation simplicity, and if possible adjust the level to keep their implementation simple.
- simple behaviors can get much better mileage with slight twists. Tweaking a shooter who’s a sitting duck on flat ground to be able to shoot down from an inaccessible, high position the player can’t retaliate towards, can grossly extend the life of your current content.
- You can make the game feel deeper; i.e. you can fake complexity, by combining similar twists with different environments; a basic idea like an enemy that jumps should be put to use on two different enemies in sufficiently different levels that the threat posed is completely different. If you make this second monster look completely different, and have different timing/etc, it will feel much more different than its implementation actually is. Ideally it may feel entirely different even though internally it’s mostly the same.
- enemies can and should be combined to make much more challenging puzzles; one enemy can provide a necessary means to defeat another enemy (tricking two enemies into shooting each other, or one enemy providing ammo to defeat the other). Another twist is that if you place enemies together, don’t just haphazardly combine them, but put enemies whose particular abilities don’t contest each other. Putting a shooter who can fire shots down at an area with a walker (making you dodge whilst you deal with the walker) is much more interesting than just two different walkers.
- make enemies which require entirely different actions to defeat. If you’re a shooter, make some enemies that are entirely immune to being shot at with any weapon whatsoever, and which instead need to be dealt with with some different gameplay verb entirely (perhaps the player has to perform some physical move in the game to them (jumping on them, or kicking another enemy at them), perhaps they have to be led into traps or pitfalls. Perhaps they have to be led to mutually destroy each other by causing them to aggress against another monster rather than the player (caused maybe by one accidentally shooting another in the back).
I expect I’ll probably need to write a follow-up to this. As it stands in the game right now, I’ve been working hard to differentiate monster designs, but there are definitely a couple early enemies (which is a bad first impression) that are painfully similar; the closest are the ants, and the beetles (both the regular and water-beetle variety). I had an idea that the former could die from being jumped on and other could bounce, but I feel like something more interesting could done (new animations like flight are on the table as an option). Fumpers and rabbits are close enough to squeak by, although I should be careful to avoid making future designs that work too much like them. Some mechanics that are dying to be exploited are mutually-destructive enemies (moth-bombers being our only example), and enemies that strictly require powerups to kill (shooting the wings off high fliers being an only current example).
Tangentially related, but there’s also another worthwhile post which is targeted at RPG design but actually applies just as well to platformers.
* (credit to Sid Meier)