Oct 10 2018
Jumpy Zergi production Log #3
It has been a while since the last post, but rest assured, the Zergi is still jumping. This time I’m going to show you some of the features we have been working on: color animations, audio controlled animations and the now completed practice mode.
We created effects that allow us to fade colors of blocks and the background between different sections of the levels. Rather than blending the Color as a whole using Color.Lerp(), we built our own function which can blend hue, saturation and value independently from each other. The reason for this was, that we needed to control the colors value or brightness to create flashing effects (for example to the beat of the music), but needed to change the hue between major sections of the level and the saturation for the block color. We also added a shock-wave effect with a little bit of camera shake on top, for dramatic effect of course.
The main challenge was interpolating between different hue values. While saturation and brightness behave linearly, hue does not. This means that blending from pink to orange in a linear way would cycle through purple, blue, teal, green and yellow before finally getting to orange.
The first solution offsets the target hue value by 100%, whenever the difference is greater than +/- 50%, which means interpolating happens along the shortest route. In our previous example, this means we will now fade from pink to red to orange.
The second solution lowers the saturation, depending on the hue difference of the current and target color as well as interpolation time. This stops “in-between” hues from flashing while animating, creating a more natural interpolation effect.
Audio controlled animations
To better merge visuals and music, some level elements are influenced by different frequency sections of the audio track. An example of this is most commonly seen in media player apps, in the form of a bar diagram. We currently use it to animate the size of some of our 2d elements like decorations and triggers.
While we could simply sample the loudness of each frame, we decided to break the samples down into several frequency sections, which can then each be used in the game individually. This gives us the opportunity to sample higher tunes or low bass only and generally use the section which looks the best. There are two things we needed to keep in mind. The first is that lower frequencies are much higher in amplitude (or strength) than higher frequencies. This reduction in “power” follows a logarithmic curve, when it comes to the human perception of audio frequencies. For our purpose, this means that in order to get equally meaningful frequency sections of the track, the selection needs to be wider, the higher its containing frequencies are. The selection of frequencies is then averaged, which creates a numeric (float) value for 8 different frequency sections of the track. The second thing to keep in mind, is that the audio sources volume influences that value as well, so we need to multiply it by a factor of 1/volume (and prevent division by 0 while doing that).
If you would like to know more, here is a great series of videos, which goes further into detail about audio frequencies and how to use them in Unity3D.
Since the game is quite difficult by design, practicing the level by doing it over and over again from the start can get quite tedious and frustrating. The practice mode is designed to remedy that, giving players the ability to use checkpoints where they will respawn after dying. Checkpoints can be set automatically or manually by a button or hotkey. Checkpoints can also be removed, so the previous checkpoint becomes active again.
For us, this meant that all the different variables needed to be saved and restored in each individual checkpoint object. Some examples are player position and speed, gravity and the different color animation states. Another important goal for us was, to not use generic practice music, but instead to keep the original level soundtrack running, even in practice mode. In order to sync the music perfectly to the level after every checkpoint, we saved and set the audio clips sample count for every checkpoint.
Practice mode has its own individual progress. In order to complete a level, the player has to beat it in normal mode, without checkpoints.
Last but not least, if you are into Crypto currencies, we have inside information about the next rising star among them: Zergi Coins! They can be used to buy your favorite Zergi different outfits and are accepted in all Jumpy Zergi approved shops.
This is all for now! The next post will show off some of the games user interface graphics, as well as our new game controller & keyboard detection and support features.
May 21 2018
Jumpy Zergi production Log #2
In our second Jumpy Zergi post, we will talk about the level design process of the game. As we mentioned in our previous Blog Post, Jumpy Zergi is a challenging auto-scrolling 2.5D platformer, in which both the level and inputs from the player are synced to the soundtrack. We will focus on the challenges and difficulties we had to face while in the creation process and in which ways we overcame them.
From the very start of development, it became clear that building a level, that syncs up well with music, is a lot more challenging than first anticipated. We also noticed very early on, that the level would feel too repetitive, without some changes in gameplay. This is why we implemented different speed modifiers and gravity switches, although these features were at first not intended. The first two out of nine sections were built quite early in the game so we could test and balance all the different features. After all the gameplay features have been completed, we continued with the design of the level layout under the following guidelines:
- Interactions and environment should sync up well with the soundtrack
- Balanced difficulty
- Avoid repetition
- Prevent the feeling of unfairness
- Optional alternate and more difficult paths for collectibles
Syncing to soundtrack
Syncing the level to the soundtrack was the first priority when creating it, as this is the most important factor for whether playing the game would be satisfying. When we first started to build a new section, we only used the absolute minimum amount of blocks or platforms on key positions, until we got the syncing right. Only then came balance and design. Even though there is only one input, jump, there are actually more things the level can sync to: jumping, landing, triggers and passing of obstacles or passages at the right time, which is either a distinctive note or beat. We placed small editor guide objects for each of those key moments via a script, tapping along to the music, while the script takes care of positioning the guides.
Also to be considered were the different distances when either jumping or falling, at all the different speeds we have in the level. We kept everything in grid units, which not only makes building the level less complicated, it also looks more appealing and less chaotic that way.
Most sections were a bit too hard when they were first created and later sections were quite a bit harder than earlier ones as well. It was somewhat intended to have an easier start and end with more difficulty in between, but it drifted apart too much. This became especially apparent, when we had our first external testers have a go at the Jumpy Zergi level.
We also made sure, that there are several “break”-parts in the level, were no input is required for a short time. Another important design philosophy was that the level needs to be readable. This means that the elements ahead should be visible before the player needs to act and not pop into view right before the player needs to react to them.
Additionally, we also prevent too narrow timings (precise inputs at exactly the right time) and platforms that are too easy to miss. Instead we increase difficulty by the amount of inputs and the speed of movement.
To keep the level more interesting, each section has been designed with a certain style, one section might consist of floating platforms, another of pillars. As I mentioned earlier, this wasn’t quite enough so we introduced up-side-down gravity and three different speed settings, which are triggered at the start of sections. Additionally, there are also visual effect triggers which can change the color of the glowing outline or the blocks themselves.
Prevent feeling of unfairness
The thing about fairness in games is, things that are exactly as they look like generally feel unfair. Failure or deaths would often seem without reason, which can lead to frustration. This is why in many games, as well as in Jumpy Zergi, there are several things in place to help the player out a little.
The most major adjustments are colliders and hitboxes. Zergi’s collider is actually a bit wider than the visual model, which allows the player to land on platforms easier, if he jumped too early. In contrary, the triggers which check for collisions with things that would kill the player are actually smaller than what they appear to be, which causes very slight spike touches to simply not register.
Another feature is an early jump timer. Every time a player jumps when still in the air, a small timer keeps querying the grounded state for a few tenths of a second. Should the character land on the floor or on a block in that time, a jump input will occur automatically. This type of feature can be found in almost any game that has jumping in it, without anyone noticing. People will notice if it is missing though, followed by the familiar thought “I definitely jumped, why didn’t the character jump?”.
The same feature but for jumping late is also implemented in many different games. Instead of using one raycaster¹ to detect the grounded status, there are two with one at the front and one at the back of the character. This allows for late jumps to still register and prevents the same frustrations as with jumping too early. Also note, while the Zergi character rotates when jumping, this does actually only effect the visual model. All the game components only move with the controls, but not with the characters animations.
¹ a raycaster sends or casts a ray in a direction (in our case down) until it hits a collider, at which point it returns several data about the collision like name and hit coordinates.
To give the level a little more replayability and make the game more interesting, alternative and harder routes which are sometimes hidden, have been built into certain spots in the level. These paths will contain collectibles (probably coins), which have not yet been implemented. Since they are only a secondary feature, they were mostly added to a section later, when the section was already completed.
Short update on current progress:
The level design for the first level is now completed, as well as the testing and balancing of it. A bunch of new features have been implemented, like block animations, color animations, audio controls and some UI options. Next will be the finalization of major features, a proper menu and the practice mode. It also became clear, that we will need a more beginner friendly second level, which will then become the first.
As always, keep an eye on the next Jumpy Zergi post, where we will show you some features of our game and how we created them.
Apr 07 2018
Jumpy Zergi production Log #1
A project which started off on an uneventful weekend is now being developed whenever there is some free time. Jumpy Zergi is a free little game, with the character based on Carbot Animations version of a Zergling, or as we like to call it, Zergi. The game is a 2D platformer with 3D graphics (or a 2.5d game), in which movement is automatic and the only input is jumping. The game is synchronized with the music and requires precise input timings to complete the level. Jumps need to be timed correctly to avoid spikes and land on platforms. The game is inspired by titles like The Impossible Game and Geometry Dash.
Currently planned game features:
- Simple and precise controls
- Catchy music and an environment that goes along with the beat
- Simple but shiny and dynamic 3D graphics and 2D level design
- Hard and challenging
- Spikes, cubes, platforms, speed and gravity switches
- Be a Zergi!
It was clear in the beginning, that the game should be simple in both gameplay and graphics, in order to release a polished product in free time only. The creation of a well polished game with minimalistic content, which can be added onto later is the final goal of this project. A 2D platformer with only one input seemed like a good idea. As usual, the project turned out to be more work than first anticipated, partly due to always wanting to improve the game.
The main objectives for Jumpy Zergi are:
- Simple enough to be created casually, but with professional polishing
- Simple but challenging gameplay, without being unfair
- Playing a level must feel natural, no clunky controls, every necessary input should go well with the music
- The entire level should be dynamic and go with the music as well
A lot of the time goes into prototyping, testing and tweaking, as well as building the level. The actual asset creation goes by rather quickly. Everything was designed around a grid, to make gameplay consistent and level design more streamlined. Once the objectives were defined, I immediately started prototyping, by implementing features in a very basic form first and with very quickly created graphic elements. The 3D model of the Zergi and its rig already existed from previous projects, however it was not animated yet.
The game continued to look likes this for quite some time. At this point, a lot of work went into improving and tweaking the controls, adjusting hit boxes and character grounding registration. For example, the character should be able to reach a block or platform which is 2 units higher than its current position, but should not be able to hit something which is 3 units higher. The jumping mechanic is also a bit more generous by letting you jump when more than half of the character is already over the edge and in the air.
Apart from jumping over obstacles or on platforms, the game also features gravity and speed changing objects. Once they are activated, the player has to control his Zergi upside down or at a different speed than before. Those features have not been initially planned however. The level is going to be approximately 1 minute and 30 seconds long. When level blocking was in progress, it became apparent that simply jumping along for that time became monotone. With the addition of changing the speed or the down-axis the game becomes more interesting and also more challenging, without breaking the one input rule.
Progress so far:
Most of the game mechanics and elements like blocks and spikes of varying sizes, as well as the character itself are already finished. Game elements animate in and out of the scene and have a glow shader attached to them, which will later be animated. The reflection is entirely faked by using a transparent gradient and duplicated assets which are negatively scaled and placed on the opposite on the vertical axis. Speed an gravity triggers already work and have their position in the level defined. About 30% of the level has been built, while the rest of it has been blocked out with markers, to make syncing with the soundtrack easier.
Currently, the level is being built, which involves more testing and tweaking than actual building. When the level is finished and balanced properly we will then take on additional decorations, animations and polishing for the main level. Most of the user interface is also still missing, as well as the main menu. A practice mode will also be added, which will allow the player to place checkpoints on the map to learn the level before trying it in one go. If there is enough time, collectibles and achievements may also be implemented into the game. Depending on feedback, the game might be updated with a second level in the future.
Keep an eye on the next Jumpy Zergi production log, which will focus on level design and how we balance the level to keep it interesting and challenging.