Building a perfect jump for The Lightbringer

A result of a year of iteration on the feel of jumping in action adventure platformer The Lightbringer by Rock Square Thunder

Probably the most important feature of any platformer game is jumping. We have spent quite a few weeks iterating on the feel of jumping mechanics in The Lightbringer.

We have written our own controllers, tested existing ones from the asset store and the mix of both. At the end we have used Lightbug’s Character Controller Pro as a base and added our own custom functionalities on top of it.

To help other indie developers with their adventures into building awesome games I’d like to share how we achieved our (not so) perfect jump.

We have 3 parameters that determine how far, high and fast our character jumps. These are: JumpReach, JumpTime and JumpHeight

These parameters are set by the designer when balancing the feel. We use those params to calculate 3 other properties:

ForwardSpeed = 0.5f * JumpReach / JumpTime;
Acceleration = 2 * JumpHeight / (JumpTime * JumpTime);
InitialVelocity = Acceleration * JumpTime;

And those properties let us calculate 2 velocities at any given moment:

The one used when the players is jumping up:

CurrentVelocity(float time) => InitialVelocity — Acceleration * Mathf.Abs(time);

And the other one used when the plays is falling down:

CurrentDownVelocity(float time) => Acceleration * time;
Jumping in The Lightbringer

Now we can use this to actually perform jumps.

At the beginning of the jump we set our vertical speed like this:

VerticalMovement = Vector3.up * InitialVelocity;

Now we have begun a process of jumping up. Now in the FixedUpdate we calculate current vertical and horizontal speeds like this:

HorizontalMovement = direction * ForwardSpeed;
VerticalMovement = Vector3.up * CurrentVelocity(Time.time — jumpStartTime));

After half of the time configured in the param “JumpTime” we stop jumping up. Here you have a choice — if you want you can add a brief “hang in the air” time, we use 0.1f in which you don’t move either up or down, only forward.

Then we begin a process of jumping down.

fallStartTime = 0f;
HorizontalMovement = 0f;

And now in the FixedUpdate we calculate current vertical and horizontal speeds like this:

HorizontalMovement = direction * ForwardSpeed;
VerticalMovement = Vector3.down * CurrentDownVelocity(Time.time — fallStartTime);

And we fall down until we detect a collision with the ground.

And that’s it. Using those techniques you can create a really nice jump feel.
Enough jumping for today ;)

If you guys have any question feel free to jump on our Discord:

Latest Jobs

Cryptic Studios

Senior Producer

Anne Arundel Community College

Arnold, MD, USA
Instructor/Assistant Professor, Game Art

Night School Studio

Los Angeles, CA, USA
Level Designer / Scripter, Games Studio
More Jobs   


Explore the
Subscribe to
Follow us

Game Developer Job Board

Game Developer Newsletter


Explore the

Game Developer Job Board

Browse open positions across the game industry or recruit new talent for your studio

Subscribe to

Game Developer Newsletter

Get daily Game Developer top stories every morning straight into your inbox

Follow us


Follow us @gamedevdotcom to stay up-to-date with the latest news & insider information about events & more