[This post was first published on Patreon on February 9th, 2024, for subscribers only]
This is the first time I talk with you about the development of Jailbroken. This is the fourth year I have been working on it and there is still a lot of things to do, mostly content (scenarios, enemies, sounds, etc.). I have tried to make a stable foundation atop which to build all the floors of the game in a fast and safe way. In the beginning, I spent so much time making hundreds of decisions about design, art, story, scope, etc. and was forced to create many tools that I thought Unity was already providing but was not. I even needed to modify the source code of the rendering pipeline in order to achieve the visual quality I wanted for the game. But that is over now, this year I want to focus on building the floors and see what I can do with the toolbox I have.
I want to share with you a brief summary of what I worked on for the last 2 months. Most of it has to do with the new enemy character prototype, code-named “RollingCrabBot”, which was the first character using melee attacks.
AI system refactoring
Until now, the AI was designed for each character to use one type of attack (shooting), all existing characters used ranged attacks and everything was fine. Then the RollingCrabBot made use of both, melee and ranged attacks, and it was necessary to find a way to switch among them as the situation requires. In Jailbroken, each character is implemented as a puppet that receives commands from a “controller”, which may be either a player or an AI script. The AI controller was almost empty, acting as a container of AI behaviours; each AI behaviour was in charge of different sets of commands and decisions, and there could be more than one included and executing at the same time in a controller (one for walking, other for shooting, etc.). But now that the character could attack in two very different ways, it was necessary that “something” above all AI behaviours made the decision of which of them should execute while other sleeps (the character is not going to use melee attacks while shooting, only one may be active). So these kind of decisions are now made by the controller which also owns the entire Flow-graph and all the variables that are written and read by each AI behaviour.
Melee attacks implementation
Melee attacks are very different from any ranged attack due to 2 reasons: obviously they do not throw projectiles and the thing that hurts other characters normally belong to the body of the attacker (a kick, a punch, even a sword can be considered as part of the arm). Each melee attack movement has its own sprite animation and the damage is calculated using “overlapping areas” that activate in a given keyframe of the animation. Melee attacks may be concatenated (think of every hack&slash game).
RollingCrabBot animations
The RollingCrabBot is compound of several animations that play simultaneously. The eyes, the body, the left arm, the right arm and the wheels are all animated separately. New melee attack animations were created (swinging the saw and cutting a grabbed character) and now the eyes and the head aim at the target (normally the player’s character). A back and forth animation was added to both arms.
Solving the problem of flipping the character horizontally
It is worth to note first that the sprites of the RollingCrabBot are not just “flipped” when it turns to the left, as you can see, the arm with the saw is still the left arm when the character turns. Additional animations were drawn to achieve this little detail. In the end, the animator contains two “clones” of all the animation states, one for the right side and other for the left side. After many experiments, this was the best solution I found, as simple as it sounds. It was the cleaner way to move the body parts to the proper position, change the sort order of the sprites, change some colors, etc. As you can see in the picture below, the position of the left arm is not exactly the same when flipping; the reason is just aesthetic, I realized that the saw was occluding the head when looking to the left and that looked bad, so I decided to move the saw down.
Camera shaking and Time scale FXs refactoring
Now both effects can be played from any point of the codebase. I added both to the melee attack movement of the RollingCrabBot, playing them when it hits the player’s character, because it makes it feel more forceful (the camera shakes) and lets the player be aware of that damage (the time freezes for an instant). Time is also frozen when the player’s character is grabbed by the pincer of the RollingCrabBot to make it more obvious.
Many AI adjustments to improve the combat experience
I have intensively tested the combat AI, found some complex corner cases and fixed them. I also added new parameters to improve the experience; for example, now the required distance to chase the player’s character, or to flee from it, changes depending on whether it is using either melee attacks or ranged attacks.
Pool objects reusability
I implemented a special mechanism to mark objects in a pool as “deleted” without destroying them, so when new objects are added to the pool it just removes that mark instead of instantiating them. This is useful when spawning and killing characters that use ranged weapons, which need to add new bullet instances to a shared pool, and would either destroy those instances or leave them unused when the character dies.
Creation of a UI indicator for the pincer launcher of the RollingCrabBot
When the RollingCrabBot aims at the player’s character, it waits for a while before launching the pincer. The fact that the character is being targeted has to be obvious to the player so he can make a quick decision, either fleeing or dodging the incoming attack. I added an animated indicator that tells the player that the enemy has the intention of grabbing his character and how much time is left before it shoots.
Character detection improvement
So far, the calculation of whether a character can see another consisted in casting a ray towards a single point in space. Now the system uses areas, a set of points that define the silhouette of the character. It is still a rough approximation (I do not want to ruin the performance), but now at least if only the head of a character is visible by another, it is detected.