Background
Feline Frenzy is a game I made over the spring/summer as a hobby project. It is a local 2-player fighting game (so something like Super Smash Bros) where players pilot cat characters and battle versus each other.
I ended up using Unity as the game engine backing my game. I made this choice because I was already fluent with Java, and C# (which Unity uses as its scripting language) is very similar. I also saw that Unity is the most popular game engine used by game developers overall, which also factored into my choice.
The Problem of Networking
Looking back, my initial expectations for the scope of the game were too high. At first, I wanted my game to be networked, and I also wanted more character archetypes than just cats. However, I soon discovered that implementing networked code was much more difficult than I expected.
First, I underestimated the difficulty of accounting for latency in a fast-paced fighting game. Without properly accounting for potential high latency between the client and server, the game will be very laggy (even using a lossy protocol like UDP). Typically, in a physics-based game, the solution is to “predict” the movement of players on the server/other clients' end, and make updates to the game based on these extrapolations. For example, if we know the kinematic properties of a player at some time ago, we can calculate the current position of the player using the right physics formulas.
You can also predict collisions and other interactions using this method. However, doing this properly is extremely difficult, to say the least. Integrating game physics with predictions is one of the most challenging parts of networked games, and there is no “standard” solution for any of this. Different games will potentially require different methods to solve the networking problem.
Furthermore, doing this also introduces a new problem with delayed updates: when a client predicts the state of another player, but the next update does not match the prediction. This will force the client to suddenly pop the remote player into the correct position, which can look very jarring on screen. If not handled well, these delayed prediction corrections can make the game into a jerky, unplayable mess.
Once again, this is not an easy thing to solve. This was the point where I decided the drastically lower the scope of my game by making it local multiplayer only.
Finishing the Game
Everything progressed smoothly after that. Within two months, I had a playable draft of the game (which can be downloaded below). There are still several things I need to iron out, but overall I'm satisfied with what came out of the project.
I had a blast creating the game, but I'm aware of the limitations that come from using a feature-rich engine like Unity. I wasn't able to get deeper insights into the systems behind game engines; for example, collision detection or event systems. This is unfortunate, since gaining a richer understanding of these systems was why I started this project in the first place.
Next time I make a game, I'm planning on creating the engine completely from scratch. To be honest, I'm probably drastically underestimating the work needed to create a game engine, just as I did with the whole networking thing. We'll see. But, it will certainly be a more interesting experience than using a pre-existing engine, so I can't wait to try. In the meantime, you can try out the game below. I'll still be making updates to the game from time to time.