After releasing BullShoppe and stepping back from The Grind, I wanted to explore some more small-scale game ideas. This time I was interested in making a competitive “party-style” game that could be played with friends either locally or online.

I landed on the premise of “Super Smash Bros. meets dodgeball” early on. Since it’s a simple sport to jump into in real life, I figured that would carry over easy enough. Since the initial pitch (ha) of the game saw the ball as a round-based, “one-hit-kill” mechanic, I decided to call it “Bomb Ball”.

# The first prototype in Unreal Engine

My first attempt at creating Bomb Ball was in Unreal Engine. I had initially created the ball as a physics object that would bounce around the level. I had developed enough of the idea within a couple of days and was able to play test it almost immediately.

The reception I got was really positive, despite the janky physics and crummy netcode. During the play tests it became clear that a few more mechanics were needed beyond just throwing the ball and moving around. So a “dodge” and “catch” mechanics were added.

# Doing custom netcode in Unreal is not fun

Though I had a good deal of experience working with Unreal’s networking model before, this project really pushed me to learn it at a much deeper level. Unfortunately I began to find the number of abstractions and code indirections infuriating and wanted to try building a custom solution.

Notice how the ball keeps hitting the players but nothing happens? Or how the ball and players seem to jerk around? That's the netcode.
Notice how the ball keeps hitting the players but nothing happens? Or how the ball and players seem to jerk around? That’s the netcode.

# Fake physics wherever you can

Using physics objects as a core mechanic in a game, especially a networked game, is a god damn nightmare. Don’t do it.

The ball was originally using Unreal’s physics dynamics and as a result would bounce “realistically”, even out of the stage. What I wanted was ultimately not realistic, I kept having to find different ways to artifically constrain the ball’s movement. This meant I was actively fighting against the engine.

Instead the “ball” ended up being represented with a capsule whose movement was far more linear and relied on simple vector math and raycasts. This allowed the ball to move in a more predictable (almost deterministic) way and would be critical in helping the game feel the way I wanted.

# Play testing sooner rather than later

At this point, I had worked on a few games and had finally learned the importance of play testing early and often. The feeling of hearing your friends or family erupt in laughter as they play your game is one of the most rewarding experiences I can think of.

While play testing in isolation, I kept losing track of where the ball ended up after it was thrown1. This was solved easily enough by having a smoke trail that lingered behind the ball, allowing a player to track it’s total movement.

When play testing with others, a more critical issue was discovered. It was unclear was “hot” and could knock out a player. Players kept thinking the ball was safe to grab, only to get knocked out when they touched it. This was lost on me as I had spent so much time with the game that I could recognize the ball’s state based on its speed.

Making the ball glow was a great visual indicator that solved this while also adding to the overall game feel.

This custom material allowed me to control the ball's appearance via parameters to gain that "hot" effect.
This custom material allowed me to control the ball’s appearance via parameters to gain that “hot” effect.
The ball material was later simplified when it was ported to Godot.
The ball material was later simplified when it was ported to Godot.

# Moving to Unity

As an experiment, I decided to try and experiment with porting the project to Unity to see what the same experience would be like. Some things were definitely easier, working in C# is far more straight forward when compared to Unreal’s flavor of C++.

After around 7 hours, I had fully ported the project over to Unity and had it running. I was able to get the ball moving around the level and players could throw it at each other. I will say that testing networked games in Unity is an absolute travesty2, but otherwise the experience was a mostly pleasant one for the time being.

# Getting the “juice” just right

Part of what makes the Smash Bros series so good is their mastery of what every action, effect, and detail needs to feel like. Given how much focus is on the ball, I knew it would be critical to get the effects on the ball just right.

This smoke effect is one of my favorite things I've ever created...
This smoke effect is one of my favorite things I’ve ever created…

I would continue to iterate on these effects as the project carried on. Before long I decided to put some more efforts into the character designs.

# Keeping the characters simple and expressive

It was important that the characters be expressive and easily distinguishable from one another, even admidst the chaos. My prototype characters did a good job of this by relying on a dominant color associated with each player.

I’m a fan of Mr Lovenstein and his comics. His characters are often basic, stocky, made up of a single primary color, and extremely expressive. Dan offered to help me with character design and made a few sketches of body types based on my fondness of Mr Lovenstein’s style.

For the faces, I had tried modeling them different ways but was never happy with the result. Instead I opted for a custom shader that would shift the UVs of a face texture across a secondary mesh in front of the character’s head. This allowed me to have a single texture for all the faces and control the expressions via parameters in the shader.

Re-designed Character in Lobby
The re-designed base character in the game lobby before a match. This is where outfits would be selected and each player can "ready up".

Beyond readability, the character designs needed to be simple as I planned to support multiple outfits and costumes as unlockables. The way it should be, as rewards for playing and not swiping a credit card3.

# Migrating from Unity to Godot

After using Unity for a while, I found I was getting really frustrated with how their new input system worked — particularly around multiple controllers during local multiplayer.

Godot 4 had been announced and I knew from some previous investigation that several systems (like input) were getting overhauled. I decided to give it a try and see if it would be a better fit for the project.

It was clear that Godot 4 was still a ways off from being stable. I was experiencing constant crashes and bugs that were making development a nightmare. But there were a number of aspects that felt significantly easier than what I was encountering in Unity.

I decided to port to Godot 3 for the time being and then upgrade the project to Godot 4 when it was more stable. This made the most sense as there were likely to be others wanting to follow a similar upgrade path. This means there were more likely to be tools and resources available to help with the transition.

The sound design was handled by Dan Taylor.

After around 3 hours of work, I had completely ported the project over from Unity to Godot 3. At this point I started experimenting with more effects environmental interactions, like shaking objects when the ball hits them or having parts of the level be breakable.

It was at this time that I also began exploring different types of game modes and power-ups that could be added to the game in hopes of making it more interesting and replayable.

# You gotta be f***ing kidding me…

Around 5 months into development, one of my friends sent me a link to a new game that Ubisoft had just released. It was called OddBallers and it was extremely similar to what I had been creating and planning.

This sucked the wind out of my sails pretty quickly. I had been working on this project for a few months and was really excited about it. But seeing OddBallers have a tiny boom of popularity before fizzling out made me realize that my idea would likely suffer the same fate unless I could find a way to differentiate the formula.

I decided to put the project on hold and focus on other things until I could figure out how to make Bomb Ball stand out.


  1. This problem was only made worse when the ball would fly out of bounds. ↩︎

  2. I should say “was” as I believe this has been improved in recent versions. If you wanted to test a networked game in Unity during this time, you had to create a symlinked mirror project and run two instances of the game at the same time. ↩︎

  3. Or… tapping it against a chip reader…? ↩︎