Project Battlefield: Part 1
An action platforming fighting game heavily inspired by Super Smash Bros.
|June – Sep. 2016
Game physics, several character control code iterations
|Oct. 2016 – Present
Opened to VGDC UCI club members as a Quarter-long learning project.
Skip to Part 2
Growing up, I owned a Nintendo 64. Whenever friends came over we’d pop in a cart and spend hours cackling when we got a blue shell in Mario Kart or fuming in silence while handing over all of our stars in Mario Party.
I bet the guy who designed the Blue Shell is the same guy who designed Chance Time, and I bet he has no friends.
While we got competitive about everything under the sun, it was all fun and games until we popped Super Smash Bros. into the N64. Then we meant business.
Things only escalated when Super Smash Bros. Melee came out for the GameCube, and boy did they escalate. Final Destination, no items.
VGDC Smash Retrospective
Back in Jan. 2015, an alumus pitched a Super Smash Bros.-style game to VGDC UCI featuring characters from the club’s extensive catalog of past games.
Originally, the team wanted to create a new sort of platforming game for mobile devices. Being very sold on the idea of a Super Smash game, I built a prototype in Unity and presented it to the team. Convinced of its feasibility, the designers decided to go ahead with the fighting game. We even recruited some 3D art students to create assets! The set-up was perfect.
Unfortunately, the team didn’t quite gel. Complications between artists and absent team members made it difficult to stay motivated. Our other programmer diligently continued work on his own, adding special effects and various mechanics, but couldn’t keep things going on his own.
I wasn’t very familiar with Unity physics at the time, and, as my classes ramped up, I didn’t have the time or attention to fully learn its intricacies.
Before long, the team dissolved and we abandoned the project.
Completing Shovelball in May 2016 convinced me I could make the kind of action-platforming game I wanted to in Unity.
When I first sat down to program, I intended to create a cleaner, more robust version of Shovelball. I wanted a system complex enough to incorporate special moves and delays in order to balance asymmetric characters against one another.
This led me to look deeper into Unity’s physics system.
Unity’s physics runs on an update loop separate from its logical loop. Because my game’s mechanics would be tightly coupled to the physics, I placed only input handling in the logical loop and everything else in the physics loop.
The main advantage of the physics loop is a strict update frequency. For this game, I set the physics loop to perform 60 updates per second.
I also re-incorporated my acceleration system from past projects, because I felt they produced the best tunable game-feel for character control and game physics.
So far, these are all things I learned while working on Spooder-mans and Shovelball.
And then I went deeper.
Unity provides us with interrupt-style functions called OnTriggerEnter, OnTriggerExit, OnCollisionEnter, and OnCollisionExit. The first two activate on trigger-type Colliders, the last two activate on objects with Rigidbodies.
As it turns out, when a collider slides over the top of two perfectly aligned colliders, whether a collision triggers or not is random.
It’s not hard to see how this can be a problem in a platforming game. Say you have two disconnected platforms that are level every so often, and you’d like to allow some leeway for the player to get on top of the other.
Some may suggest using a capsule collider, but then you have this ugly effect of characters sliding off the edges of perfectly square platforms. In a game about precise controls and quick reaction times, whether someone is grounded or not should be clear as day.
The same problem happens when colliders are stacked, allowing characters to randomly stand against walls.
As an intermediate solution, I used several raycasts to prop the character up on “stilts”, where collisions with the ground and walls aren’t handled using Unity’s built-in functions, but my own.
While working on the game, I watched a lot of Kirby: Planet Robobot playthroughs. I really liked the feel of the game; even just from watching the videos. Hal Laboratories’ Shinya Kumazaki’s Kirby games feature an action-oriented Kirby rather than the more sensitive Kirby of Dreamland 2 and Crystal Shards. Well, as sensitive as an indiscriminate swallowing monster can be.
After having built some systems, I wanted a way to put them through their paces. So, I decided to implement a Kirby-like game with a large number of character states and interactions. And when you need to keep track of character states, you need a state machine.
Unity’s Animator is a state machine. The AnimatorController lets scripts talk to the Animator. States can dictate things like whether a character can jump, or if it’s taking damage. Simple enough.
Problem: My character could switch out powers whenever it wanted, so my Animator needed to capture all possible combinations of Animations. Unity only allows you to extend a single AnimatorController with different sets of Animations. No modifying states. No modifying transitions.
My character script would know which power to use, which AnimatorController to instantiate, and which transitions to call. Animations would keep track of attacks, adjust hitboxes, and call functions when they finished.
I used this design before in Shovelball and Spooder-mans. Could it handle something as complex as Kirby?
This was the Animator with movement and basic attacks:
And this was the Animator with all regular attacks (no multi-part attacks):
With 20+ copy powers, unique animations, and physics effects for each, there wasn’t an easy way for a single Animator to handle them all.
Was there a better way to do it? Maybe with sub-states. But navigating the UI was a pain. I had to click countless tiny arrows to set every transition’s conditions and behavior. If I had multiple transitions between the two states, separating them all out was painful.
My character script set each transition’s flag. The new state played its animation and triggered another flag. My character script processed the new flag, unset it, then set more flags.
Every time I wanted to make a change, I’d have to remove flag handlers, add flag handlers, add flags to the Animator, remove flags from the Animator, ensure Animations didn’t use old flags, add flags to Animations, add states, remove states, remove transitions, add transitions, set transition values, and…
Every tweak took an extremely long time. And when being creative, fast iteration is a must.
Finally, I produced a rather clunky Kirby clone:
I felt that the project needed some major restructuring to move forward.
Continued in Part 2
The game images are from Mario Party and Super Smash Bros. Melee by Nintendo.
Leonardo di Caprio’s face is from the film Inception.