Building the Perfect Avatar for Your Platformer

Adis Kovacevic
The Startup
Published in
8 min readOct 15, 2020

--

When creating a new platformer, or a game based around the movement and actions of a character, the best place to start is the character controls. The way the character controls is the basis for all other aspects of a platformer. It determines everything from the game feel to the level design. Setting these controls and fine-tuning them before creating the levels can save you a ton of rework. Imagine creating dozens of levels only to tweak the character’s jump ability and find he can no longer make half the gaps built into the levels. Let’s dive right in and begin with how to structure the characters abilities and physical controls.

Character state machine

When playing a game, the actions your character performs is controlled by two factors. What buttons you, as the player, are pushing and what state your character is in. For example, you might be pushing the “Jump” button, but your player is already in the air, thus the character just ignores this action. On the surface, these rules seem simple, but it can be a complex tangle of code to map the correct actions for the states a character could be in. With every added scenario and case, the controls can be very complex to code and update when needed, leading to undesired and buggy character behavior. A better approach is to use what is known as a state machine. The character would change his state and have the state determine what each button does.

Simple Character State Machine

Above is an example of a character state machine. The blocks represent the states the character can be in and the arrows represent actions, such as button presses, that move the character from one state to another. Notice how pushing the Jump button in the ‘Grounded/Neutral’ state yields a change into the ‘Jumping’ state. While in the ‘Jumping’ state, there is no mapping for the Jump action anymore, naturally disabling that action and preventing a second jump from occurring. A jump is not allowed until the character returns to the ‘Grounded/Neutral’ state. Also note how when in the ‘Grounded/Neutral’ state, the character has an Attack button, but not in the ‘Jumping’ state. The Implementation for the actions a character can perform while in a state are neat and easy to understand. As a developer, you do not have to worry about all possibilities and checking every situation before allowing a button press. New states can be added with little to no disruption in the existing behavior. Take the state machine diagram below as another example.

Character State Machine

Let’s break down this diagram. In the ‘Grounded/Neutral’ state, your character has the following actions: Jump, Attack, Left/Right, and Down. If the player decides to push the Attack button while in the ‘Grounded/Neutral’ state, the state machine will switch the player to the ‘Ground Attack’ state, playing the attack animation, activating a hitbox, etc. While in this state, the player cannot perform any actions at all. Indeed, all the player can do at this point is watch the attack animation play and wait for the move to end. The ‘Ground Attack’ state has a timer that will move the state machine back to the previous state, putting the character back into the ‘Grounded/Neutral’ state. This is indicated by the Time transition arrow. This naturally prevents a move from being used while another move is already being used and is much easier to design and program. The state machine also changes the behavior of the button presses depending on the state the character is in. For example, While in the ‘Jumping’ state, if the player was to push the attack button, the character would perform an ‘Aerial Attack’ instead of a ‘Ground Attack’. Without a state machine, this would require several checks to accomplish. You would have to check whether or not the character is grounded, whether or not he is already performing a different attack, running, dashing, etc. The checks only get more extensive as you build out the options and flesh out the game.

Movement

The main key to movement is to make the player feel like they are in control. The movement should be responsive, smooth, and consistent. Be sure to not overdue sliding and momentum effects at this stage. It’s better to start with tight controls and loosen them to achieve the right feel. Set max speeds and never allow the character to move faster than this speed limit. The character should reach this max speed very quickly. The max speed in the x direction can be independent of the max speed in the y direction. Pick values that feel right. They should give the character a good balance between weight and speed. When adding gravity (falling speed in the y direction) make sure to cap this speed as well; Otherwise your character will quickly resemble a comet falling from the sky.

Jumping

Jumping is one of the key maneuvers of any platformer. It should be heavily controlled and consistent. Remember that the Y component (controlled by the jump) and X component (players current running speed) should be independent of each other. Getting a running start before jumping will lead to a nice arch-like jump because the x velocity will be left alone for the duration of the jump.

Holding the jump button should yield a higher jump. While in the air, if the player releases the jump button, the upward momentum should be stopped and the player should begin to fall. This allows the player to feel in control of the height of the jumps. Holding the button down for the entirety of the jump will result in a max height jump. Do not use the the physics engine for the jump. While it is easier, it is far better to use a predetermined Jump Height and allow the duration of the button hold to be a percentage of the Jump. Physics engines tend to add a number of inconsistencies to the mechanic making the jump more frustrating for the player.

Ledge Forgiveness

Special care needs to be taken when considering ledges and pitfalls in the game. Whether it be lag, or the player’s slow reaction time, nothing is more frustrating than reaching the edge of a platform, pressing the Jump button, and watching your player fall into the abyss. This occurs because the player’s character has left the platform before the jump button is pressed, putting him into a hopeless falling stare. This split second timing is hard to consistently get right and leave the player feeling as if the controls are ignoring inputs. A solution to this so to allow players to jump some distance/time after leaving the ledge. Even though in reality a jump should not be possible, the added ‘fudge’ can help players with the timing.

This effect can be done in numerous ways. The simplest of which is to allow the player to jump some time after having already left the grounded state. For example 3–5 frames after the character is no longer on the ground, allow the jump to occur. Another technique is to extend the hitbox of the ledge beyond the visible edge. The player will think the ledge is ending a couple pixels before it actually is. And finally, another approach is to create another hitbox that trails the character some distance and uses its coordinates to determine if the player is or is not grounded.

Effective Combat System

Melee/hand-to-hand

Most platformers have some form of enemies or ‘baddies’ in the game. Your character has some way to deal with them as well. For this section, let’s imagine you are designing a platformer with a combat system. How do you register a hit? The weapons or attack surface should have a hitbox, usually shown in red, that is independent of the player’s hitbox. For clarity sakes, I will refer to the player’s hitbox as the hurtbox from now on, shown in green. Named after the fact that the player will take damage or ‘get hurt’ if hit in the hurtbox. This design requires careful collision detection with the enemy’s hitbox colliding with the player’s hurtbox. For weapons, it helps to exaggerate the motion and show a wider graphical effect than the actual hitbox for the weapon. It’s important to telegraph the move well, as it gives the player a chance to dodge or evade the move.

One thing to consider is how long to keep the weapons hitbox active. For example, if it’s just a hitbox that follows the player’s sword, even bumping into the enemies will kill/damage them. This leads to undesirable effects, like idle characters having a form of attack or defense against enemies and Other Players. The best way to avoid this is to remove or deactivate the hitbox when the player is not in the attacking state. The attacking state should activate the hitbox for the duration of the attack and remove/deactivate it after the attack sequence is complete. This not only saves on resources, it prevents unnecessary hitboxes from existing in the game and leading to bugs and glitches.

Prevent Move Spamming

A fast paced game with a deadly and quick attack move often leads to the move being spammed or used continuously. A cool down on the move would solve the problem, however it would also remove the moves effectiveness, especially against multiple targets. Cool downs are best left for more ‘special’ attacks, where the satisfaction is in timing the use of the move. Instead, consider using a penalty delay for missing with that move. A move that does not strike an opponent causes the character to remain without the move for a set period of time. A successful contact however allows the move to instantly be used again. For example, throwing a punch and missing causes the character to fall out of balance and regroup before trying again. Hitting an opponent allows him to instantly use that move again or combo into another attack.

Projectiles

Limit Ammo

Ammo is a great way to minimize the use of a move. Allowing only a certain amount of ammo prevents the player from spamming the move and taking aim more carefully. The amount of ammo should be related to how destructive the projectile is.

Wrap up

At this point, you should be ready to create a character that’s easy to prototype and change with smooth motion, great jumps, and an effective combat system. Only thing left to do is play test and create great dynamic levels to put him in! Great level design itself is a vast topic and deserving of its own articles.

--

--