Specialization
Overview
Summary:
Ori and the Blind Forest has long been one of my all time favorite games, and that’s largely because of its movement. So when the time came for specialization at The Game Assembly, I knew I had to recreate arguably the best 2D movement of all time. Here it is: my interpretation of Ori’s movement.
Details:
Project span: 8 weeks (half time)
Engine: BOB Engine (Custom engine made during second school year)
Movement Abilities: Bash, Glide, Wall climb/run, Double jump and Ground pound
Final comparisons:
Here’s my final comparison with Ori. Overall, I’m very proud of the result, and aside from a few minor points, I feel it’s pretty much one to one. Below, I dive deeper into the challenges I faced and the thought processes that guided me throughout this project.
Bash
Jump
Aircontrol & glide
Ground pound
Walljump/climb
Setup – the planning
For this project I chose to use our custom engine, built during our time at The Game Assembly. Getting started was simple, I switched to an orthographic camera and ignored the z axis for movement, which worked surprisingly well.
With the engine decided I moved on to deciding which abilities to implement from Ori. I chose the following: Bash, wall jump, wall run, wall climb, double jump, glide, and ground pound. Bash was my top priority becuase it’s the move that originally made me fall in love with Ori’s movement. I also added bounce pads, teleporters, and both static and moving bashable objects to make the experience more complete and to better showcase the movement mechanics.
Getting started – MVP Movement
Setting up the basic run and jump movement was fairly straightforward, thanks to my experience working on movement in our sixth game project, which used Mario 64 as a reference. Even though I already had a working state machine and PhysX library, I wanted to clean up my structure and tailor it specifically for this project. The final states I implemented were: Idle, Run, Jump, Double Jump, Falling, Landing, Ground Pound, Bouncing, Bash, Glide, Wall, and Wall Run.
Visualization of my statemachine
Although Ori’s movement feels floaty, I chose to stick with a character controller rather than a rigidbody with PhysX. This gave me full control over movement, even for abilities that rely on forces.
Once the basics and structure were in place, my next goal was to create an MVP (Minimal viable product) for all the movement. I just wanted a functional version to get a clearer picture of how everything came together. Next, I’ll dive deeper into each of the abilities.
Jump and double jump
While implementing the jumps, I wanted them to be force based, just like in Ori. I also experimented with adding an impulse for the base jump to achieve a minimum height when simply tapping the button. This made the jumps easier to control and helped align them with the movement metrics later.
MVP state of jump and double jump
MVP state of air control and glide
Air control and Glide
For air control, I wanted the character to retain a sense of weight from the forces applied while in the air. At this stage, the force was still fairly high, but it was enough to experiment with and fine tune the feel. When it came to the glide, I simply reset the vertical velocity and reduced gravity, giving the character that signature floaty motion while maintaining control.
Ground pound
The ground pound wasn’t anything particularly special, just a downward force combined with increased gravity. I also added timers to linger briefly in the air and on the ground before returning to the idle state. I didn’t make many changes to this ability later on.
MVP state of ground pound
MVP state of all the wall states
Wall Climb/Run/Jump
For wall interactions, I used the PhysX hit normal when detecting collisions to determine if the player was touching a wall. I set up a Wall state to handle everything while the player is in contact with the wall, and a Wall Run state that lets the player cling to the wall while holding the climb/glide button, allowing movement up and down. At first, this was quite buggy, but through iteration and feedback from teachers, I refined it during the polish phase. Most of the issues came from the Wall state, if the player stopped even for a microsecond while touching the wall, they would fall. It felt more like you had to fight the wall to climb it rather than move naturally.
Bash
Here comes the golden child: the Bash. My first thought, like with the other abilities, was that it had to be force based. I also wanted to control the duration, so I used a timer for that. By combining these and launching in the direction of the controller’s joystick, I got the result below. It was far from polished, but it captured the vision. This ended up being the ability I changed the most over time, with a lot of playtesting to find the right feel.
MVP state of bash
Metrics
Once I had all the movement abilities in an MVP state, I wanted to match them as closely as possible to Ori’s metrics. The first step was setting up Dear ImGui for all the movement variables. Nothing fancy, but it allowed me to adjust values in real time during play, which made my time much more efficient.
Next, I looked for a spot in Ori with fairly even ground and distinct background elements. This made it easier to match metrics, for instance, counting how many Oris fit in a single jump.
Most metrics were achievable with my MVP implementations except for the Bash. No matter how I adjusted the values, it never felt quite right. I decided to take a break and revisit it during the polish phase, knowing I would need to rethink the implementation to get it just right.
The final ImGui variables and layout
The level – Ginso tree inspiration
The level in unreal, front 2d view
I knew I had to showcase my movement somehow. Instead of a traditional player gym, I decided to recreate part of an Ori level. Although I had no experience in level design, I thought it would be more fun and a better way to highlight my project. I chose the Ginso Tree area with a few limitations: no enemies, no spikes, and of course, no water chasing you. Essentially, it’s a vertical level that uses most of the game’s abilities to progress.
I realized later that the Ground Pound had almost no purpose here, since there was no combat or breakable terrain, and it isn’t introduced until after Ginso Tree in the original game. I had considered this during development, but unfortunately didn’t have time to address it. Gliding faced a similar limitation, though it remained useful in some Bash sections, giving extra time to plan and helping reach lateral Bash targets.
Polish, polish, polish
During the polish phase, my main focus was the Bash, the most crucial ability. I knew that if I got it right, the rest of the movement would start to fall into place. That said, there were still other elements that needed refining, such as the wall states and the overall amount of air control, though the latter was a smaller task.
At this stage, the Bash only used a force, and I found it really difficult to find the right values. After extensive playtesting and feedback from classmates, and teachers I realized just how insanely fast the Bash felt in Ori the moment the button was released. To address this, I added an impulse, similar to the normal jump. This was key to achieving the right feeling, a very high impulse that almost feels like teleporting. After the impulse, I applied a force that gradually decelerated, and added a small timer to give even more control over the player after bashing.
Bash
I also discovered how buggy my wall states were. Sometimes it felt like the player lost contact with the wall, making jumps difficult. The problem was that the moment the player lost contact for even a single frame, they immediately entered the falling state, which interrupted jumps entirely. I fixed this by adding a small timer, a sort of “coyote time” for wall cling.
Walljump/climb
Finally, I focused on adjusting the air force. At first, I thought a higher force would make the movement feel more like Ori, but through testing I discovered that a lower force combined with a higher maximum speed was the key to achieving the right feel.
At the end of the polish phase, here are the rest of my comparisons with Ori.
Jump
Air control & glide
Ground pound
Conclusion – the result
Reflecting on the process, I’m really proud of what I accomplished during this, a recreation of my favorite 2D movement of all time. That said, there’s always room for improvement. The most obvious area is my horizontal movement. With just a bit more time, I would have liked to increase the max speed and tweak the force slightly. As you can see in my comparison, it differs quite a bit. It’s not a difficult fix, but it would have made the movement feel even closer to the original.
Additionally, while talking with one of my teachers, I learned about curve functions. I had never used them for movement before, but they immediately intrigued me. I think they could have helped a lot with the Bash, as well as the jumps and Ground Pound. Instead of manually accelerating and decelerating forces, I could have relied on these curves to achieve smoother, more precise motion.
In conclusion, this project has taught me a great deal, mainly how to integrate forces into movement to make it floaty yet responsive, while also diving deeper into PhysX and exploring level and game design. This has been a dream of mine for a long time, and I’m thrilled to have made it a reality. Thank you for taking the time to read through my dream project.