Updated: Aug 12
Bot Brawl is a fighting game that I am working on in my free time with a colleague. We are still very early on and are using placeholder models and animations from Mixamo for testing purposes. I have no prior experience developing a fighting game, but I am a big fan of the genre. I do not expect it to be an easy task, but I believe it will be an educational experience (and hopefully an enjoyable one too).
The game is being developed in Unity and I will be doing the majority of the programming for the project. It is a 2D fighting game and our plan is to take aspects from various different fighting games which we enjoy. It is leaning more towards being an "anime game" in terms of its gameplay, with fast and strong movement options such as a run and an air dash. Our goal is to create a fully-functional experience with just one character to see if our concept works before continuing further.
Before I get started, I'll explain a few basic terms and ideas of the fighting game genre. If anything is unclear, I would point you towards The Fighting Game Glossary by Infil. It is a fantastic resource for fighting game terminology. I myself am using it almost every day that I work on the game.
In simplest terms, fighting games are about reducing your opponent's health to zero without allowing your health to deplete. In one-on-one fighters, you win a round by reducing your opponent's health to zero. If you win two rounds, you will have won the game. Fighting game characters have access to normal attacks at the press of a button, special moves which are activated by a motion input and a button, and lastly, supers which are only available when you have a certain amount of meter and are also activated by a motion input and a button. You are able to block incoming attacks by holding the opposite direction of your opponent. Overhead attacks, such as air attacks must be blocked while standing (holding back), while low attacks must be blocked while crouching (holding down and back). There are also throws, activated by a single button or multiple buttons at the same time. Throws are a way of damaging a player who is blocking, but they can only be used in point-blank range.
Now onto some of what I have implemented so far. For starters, inputs. My solution for input detection is to get a Vector2 from the player’s thumbstick or keyboard inputs and convert it into a string depending on its values. Then for button inputs, the three attack buttons which are X, Y, & B on an Xbox controller, will become a string of “light”, “medium”, or “heavy”. I considered using an enum for holding the input data, but I decided to go with strings instead because I wanted to be able to easily look for multiple correct inputs for attacks.
This is the “Jab” attack, which you can get by pressing the light button and holding either back or neutral on the thumbstick. There is an attack that is only obtained by holding forward and pressing light, therefore you cannot get jab while holding forward. Other than that, either back or neutral on the stick are acceptable directions for getting a jab. Since this character has only one crouching light attack, it can be activated by holding down and back, down only, or down and forward.
Something that I am thinking about doing is transitioning the string format for directional inputs to one using ints instead. I am considering this change for two reasons. Firstly, using ints instead of strings would be more performant. While it may not be a huge difference in performance, I want to make absolutely sure that the game is able to run at a consistent 60 frames per second. Also, because other games use this notation to describe different attacks and inputs. Numpad Notation uses the nine numbers on a keyboards numpad to describe the nine directional inputs. It may seem confusing at first, but I prefer it in the long run especially when describing the inputs for a combo. For example, it is far quicker for you to say “2L, 2M, 2H, 236H” than “crouch light, crouch medium, crouch heavy, quarter circle forward heavy”. Most fighting games have their own unique notation, although numpad notation is used in most anime style fighters and so I’d prefer to use it to describe my games inputs.
To finish off this devlog, let me talk about some of the fun stuff… normal attacks and combos. Fighting games need to maintain a consistent frame rate (generally 60 fps) because most actions in game are measured in the number of frames they take to perform. Normals are broken up into startup, active, and recovery frames. Startup frames are how long it takes for the move to become active. Active frames are how long the move is active for or for how many frames your opponent can be hit by it. Recovery frames are how long until you can take another action. Setting this functionality up was relatively simple. When a normal attack is inputted by the player, it starts a coroutine which waits for the appropriate number of frames and switches states between startup, active, and recovery. When it is in the active state it enables the moves hitbox and then when it transitions to recovery it disables it.
After being hit by a move, you are put in a state called hit stun. While in hit stun, you cannot take any action including blocking, jumping, or attacking. Different normals have different startup frames and put you in hit stun for a different number of frames. Due to this, only certain moves can be combo’d into one another. A combo occurs when you are hit while still in hit stun from the previous hit. A basic combo is 5L, 5M, 5H. It is very beginner friendly because you are just moving from one button to the next in order of strength level and do not need to worry about changing your directional input throughout the combo.
Hit stop occurs when an attack connects, whether it is blocked or not. It freezes both players animations for a short period of time in order to sell the impact from the hit. Hit stop is beneficially for adding weight to stronger attacks as well as making it easier for the player to react to their hit connecting. Notice the difference in speed from the version without hit stop (left), and the one with hit stop (right).
The slower speed of the hits make it significantly easier to react to the first attack hitting and continue the combo. Plus I think it "feels" much better to watch because the attacks look weightier. I originally set it up without any hit stop, but changed my mind once I tested it and saw how it looked.
Well that is going to be all for my first devlog. In my next post I will be diving deeper into the base classes I created such as NormalAttack, SpecialMove, & CharacterData. I hope you enjoyed and learned something from this.