What should a good platformer feel like? If you wanted to you could stop and think about it for a minute, but fortunately you don’t have to because I am here today to argue that it should feel mostly like this:
Super Mario Bros was not the first platform game ever released, but it is probably the most important. It is the bedrock on which the contemporary ‘platformer’ genre is founded; it is the thing that made Shigeru Miyamoto a household name, and the key component in Nintendo’s magical money-printing machine. But enough navel-gazing: What exactly is so special about Super Mario Bros? What makes it work?
You may be familiar with Tim Rogers. He is a game designer and possible crazy person who writes multi-thousand word essays on Kotaku as well as the excellent Action Button Dot Net. And, in one of his Kotaku pieces, he succinctly explains (which is rare for him) the secret to Mario’s success:
If you asked a space alien from the future to play Super Mario Bros., and then play any of the other side-scrolling platform games of that era, and then report back to you with one sentence on what he perceived as the major difference between the two, he would speak gibberish into his auto-translator, and it would output a little piece of ticker-tape with the words “STICKY FRICTION” printed on it. It is the inertia of Mario’s run that endeared him to us. It didn’t have anything to do with brand strength or graphic design. Those things were secondary. It was all about the inertia, the acceleration, the to-a-halt-screeching when you change direction. You can feel the weight of the character. People never put these feelings into words when talking about games, though they really, really are everything.
Friction, for our purposes, is more than a Newtonian coefficient or counter-force; it’s an aesthetic. It’s the way things move relative to one another and how players interpret that movement to construct their understanding of the game world. When Rogers speaks of inertia, he refers to the way virtual pixels on a screen can gain real mass, movement and livelihood through their dynamics (that is, the manner in which they change). Super Mario Bros does not need high-quality sound effects or 32-bit colour to convey itself to us. It does not need a rumble pack or a motion sensor. We grow to understand it with each of Mario’s steps, leaps and falls.
I thought a lot about this as I first started developing the platformer-ish aspect of my portfolio. Frankly, it scared me a little. I wasn’t quite sure how I wanted the movement to work, but I knew that if the friction didn’t feel right the whole thing would seem cheap and flimsy. And so I started coding. I gave myself a few simple parameters to tweak, then a few more complicated ones. I wondered what would happen if the character could jump or climb stairs and ramps; perhaps if my dude felt good to control in a real Mario level it would also feel good running side-to-side through a less elaborate virtual campus? I followed this rabbit hole down into collision detection systems, the Box2D API, and ultimately a rather complicated software solution. I’ve put it here for you to play around with and, if you like, download and use for your own purposes.
The Rather Complicated Platformer Physics Test Harness
What I have here is a parametrized system for old-school platformer movement, meant to simulate many different sorts of friction from Super Mario Bros to Super Meat Boy. It is both an interface specifying the kinds of parameters you would need to define many different platformer protagonists and an implementation in Flash/ActionScript 3 using the Box2D API (the two are cleanly separated, so if you want to use one but not the other it’s pretty easy to do). It probably won’t be able to do exactly what you need it to, but the idea is to get you 80% of the way there no matter what direction you’re going. This little test harness allows you to change any parameter you like on the fly and test the results in a sample platformer environment:
Download the source files here. (The FLA probably requires Flash CS4 or higher to open.)
What the Parameters Do
The Ground Movement parameters are simple enough, I think; when told to run, the player will accelerate at the desired rate until reaching the desired maximum velocity. When told to stand still (that is, when all movement buttons are released) the player will decelerate at the specified rate towards 0 velocity. The Air Movement parameters mirror the ground ones, but apply while the character is airborne; this allows you to customize the level of air control as well as freefall acceleration/velocity. Friction adds a bit of resistance to the player’s interaction with other surfaces in case you need a little extra stickiness.
The Jumping parameters allow you to set a constant velocity at which the player ascends during a jump as well as the minimum and maximum time she can spend ascending (thus allowing or forbidding the ‘cancellation’ of a jump midway through). JumpHangtime specifies the time at which the player can hover in midair at the apex of the jump, providing for a bit of friction in between the ascending and falling motions. The pre- and post- jump grace periods specify time intervals during which pressing the ‘jump’ button will still result in a jump even if the player hasn’t quite landed on solid ground yet or has just run off the edge of a cliff; this can help you achieve the sense of ‘pixel perfect’ platforming even if, in fact, your player is maybe a pixel or two off.
The Floor/Ceiling parameters are weird, and define the angles at which surfaces become ‘sticky floors’ (the player can release all the movement keys and remain perfectly still, even on an incline) or ‘ceilings’ that cause the player to bump her head and cease jumping (rather than hovering in midair while the physics tells her to ascend but the wall prevents her from doing so). Thus, if you want the player to be able to walk calmly up ridiculously steep inclines you can increase floorAngle, or if you want her to slide off of angled ceilings like they’re coated in Teflon you could set ceilingAngle to 0.
Advantages/Disadvantages of This Approach
There are a lot of different tutorials around the internet showing you how to do old-school platformer mechanics in Flash. The big decision you have to make is what sort of collision detection technique you want to use. Physics engines like Box2D allow you to define crazy shapes in the environment that collide nicely, but introduce a host of other problems you then have to deal with (most relating to the fact that physics in classic platform games are nothing at all like real-life physics, and that human beings are not actually shaped like circles or boxes). Other approaches limit you to square geometry (no ramps!) or rigid tile-based solutions (some ramps, but now you have to implement a whole freaking tile-based thing); the advantage is that you don’t have to compensate for all the wonderful things a full-featured physics engine can do for you (like forcing your character to slide down small inclines rather than standing still because, if you recall your high school kinematics, it turns out that F = ma and there is a thing called ‘gravity’ that points downward). Here is a more specific list of pros and cons:
A Bunch of Pros
- This system lets you experiment with a lot of different kinds of friction very quickly.
- It lets you build environments out of simple geometry like inclined boxes and circles rather than just tiles. You can therefore include things like small ramps at whatever angle you like.
- It allows you to do all the fun stuff physics engines let you do while still having a protagonist who controls somewhat like Mario.
- It fixes a lot of the common problems related to using a physics engine for a classic platformer, such as: Stationary players sliding down ramps on which they should remain still; sticking to the sides of walls in mid-air due to high friction; not ceasing a jump after bumping into a ceiling (or ALWAYS ceasing a jump after bumping into ANYTHING); getting caught on tiny pieces of geometry that should probably just be run right over; running over large pieces of geometry on which you should probably get stuck; et cetera.
- It fixes all of these using strategies that don’t completely bork all the fun stuff physics engines let you do. (For example, a more naive solution might force the player velocity to whatever you think it should be every tick, applying a theoretically-infinite amount of force and thus causing her to easily move boxes that weigh 85 tons and should perhaps remain where they are.)
- The approach I’ve laid out here also divides programming quite sharply from design without the need for some supplementary tool like a tile editor (you can just place everything using Flash), so if you’re on a multi-person team or, like me, you find the idea of tweaking level layouts in a text editor distasteful, this provides a reasonable workflow.
A Few Cons
- Occasionally the player can still end up catching on one piece of geometry that juts out imperceptibly from another, and the various solutions for this problem (one of which I’ve made available in this implementation by letting you round off the corners of the player geometry) can create secondary issues (such as if the player creeps towards the edge of a pit and starts sagging down into it because the corners of her geometry are rounded).
- Due to the nature of comprehensive physics systems like Box2D, the controls may never be quite as tight and predictable as they could be if you were rolling your own specialized system that only does exactly what you need (such as the one used in Super Mario Brothers). Mario games fake the complexity of reality using a few simple rules, while Box2D platformers use somewhat more complicated rules to fake simplicity.
- The division of programming and design I mentioned earlier has a tendency to increase the total amount of work required to build levels (the ActionScript must manually expose variables to Flash, and setting up the Flash Symbols properly can be a headache), so if you’re comfortable writing out tilesets as huge manually-defined arrays you can save a bunch of time that way.
What You Should Use For Your Platformer
In general, a hardcore platform game like Super Meat Boy needs more precision than something like this can easily provide (I believe it uses a tile-based system, like most classic platformers) while a system such as this one is better suited either to less twitchy platformers that benefit from diverse level geometry or to platformers like Trine whose mechanics incorporate physics in some significant way. Choose your poison wisely.
A Note About Component Definitions
This test harness uses something called Component Definitions to lay out where its geometry is and where the player spawns. The idea is that rather than creating the walls and platforms one at a time using AS3 code, I actually plop them right down on the stage and make various AS3 class parameters Inspectable, which allows them to be edited on a per-instance basis in Flash so long as you set the given library object’s Component Definition to its ActionScript class name. This is a cool way of separating design concerns from programming and allowing you to tweak AS3 properties from within Flash. Unfortunately it’s also horribly-documented and more than a little buggy. If you want to, you can read a little about how to do this here.