The GMTK Game Jam 2022 was my first Game Jam that I have ever attended. Before the pandemic, ever since my introduction to the world of Game Development, I have always wanted to join a jam. But back then, with my lack of skills as well as experience, I was quite fearful to get started. I also did not have much friends or connections that would allow me to comfortably experience my first Game Jam.
It all changed in 2021 when I finally decided to pursue a career in Game Development and to finally embrace my creative side. I have been extremely blessed working with the studio I am currently in. I met wonderful people—artists, programmers and designers alike. In the heat of the moment, we decided to join a game jam for which a lot of us have never tried but have always wanted to.
This game is designed in Unity Engine ver 2021.3.4. Final build version of the project is available in my Github repository as Project Gooseberries.
Designing My First Platformer
I have always wanted to design a platformer. I always treat it as an initiation genre for those who wanted to be a Game Designer. For some reason, I carried this notion that everyone started with a platformer (maybe it was due to the Mario World games). But I myself have never attempted to create a platformer, and I really wanted to. It is also a genre that I believe to be the most versatile among the many different game genre out there. I chose to proceed with a platformer, believing that it could probably fit into any theme the jam would give us.
Initially I wanted to keep the platformer simple. But obviously because it’s a Game Jam the unique mechanic of the game needed to be highlighted in a way. So I opted for a type of game that disallow the player to input movement. I was inspired by Kirby Canvas Curse which was one of the few games that I really loved playing from the Nintendo DS back when it first came out. I wanted to design a platformer that revolved around Tetris tiles, such that the player needed to build their own platform for the players to move.
That was how it started at least, but after much discussions with the other designers in the team, we ended up with another kind of game entirely. The ideation period was quite an eye-opener for me. It made me realise that (obviously) people tried different games and they a set of favorite genre that they wanted to make. We settled on the idea of doing a platformer, but the twist being introduced vary quite considerably. We had Rhythm Game and Stealth-Action Hybrid being mentioned. Some of the game requires a very ambitious mechanic to be implemented (which I personally am not confident of doing within the span of 48 hours). In the end, we opted to go forward with a platformer for which the player can control 2 characters with a limited movement. This was mainly inspired by the game Brothers: A Tale of Two Sons.
Character and World Design
I didn’t manage to touch a lot on the Character design, especially on the final product and the direction of the game. Generally the game’s theme is inspired closely to the anime Goblin Slayer. And I was pretty satisfied with the final design of the characters because it ended up quite funny and enjoyable as a game (animation and interaction wise).
Generally what kicked off the environmental theme of the game was the many discussions and the small script that I had written to help myself visualise the tutorial of the game.
Check out my Manuscript for the Tutorial Script!
We end up with the general concept of setting the world in a mystical forest that was mostly conceptualise by our artist. It was quite far from what I have in mind at first (because my initial script was based off Morbidia), but the final product by itself was amazing. I could foresee having a world build around such and its beauty became one the highlight of our game.
A Roll of the Dice — GameJam Theme
The theme of the Jam was announced at 2AM Saturday in the morning in Singapore and that was already quite a lot of pain for us. A lot of us was tired from a day’s work in the Friday and we needed to stay awake until 2AM to see the theme of the Jam. At that time we were pretty exhausted and we could not think clearly. The announcement of the theme took us quite aback as well because A Roll of the Dice is a theme for which a specific genre triumphed with—Turn-Based Strategy.
A lot of us was considering of shifting our entire idea and generate an entirely new idea. I think it was mostly because, there is such a better genre that we can adopt in order to maximise the theme of the Jam. We discussed, and it was a rather difficult discussion. In the end we decided to stick with what was already planned, and just add on a few mechanics to fit the theme of the game.
The adjustment of the game was a team’s decision. But I personally felt that I am taking the most responsibility on the decision. I too personally felt that it was not the best idea that we could come up with considering the theme. But I believe it is probably the best idea we can work with considering the amount of effort we had put in for the Jam.
The aspect of rolling the dice in this game revolved on the decision of difficulty a player can have after every checkpoint. The player are to collect Dice Faces throughout the level, for which these dice faces determine the rolls they can land on when they complete the level. The rolls will then determine the amount of enemy and points they can spend to upgrade their character.
The concept of rolling the dice in the game happens both literally and figuratively. The literal rolling of the dice happens in the checkpoint to decide the difficulty of a level. Whereas the figurative rolling of the dice happens in the decision of the player throughout the level when they choose which dice faces they wanted to collect.
So why is it figurative? You see the thing is, if the player decides to collect all high-numbered dice faces, they will be awarded with the chance to roll a high number of upgrade point but risk the idea of encountering higher number of enemies. The reverse is also true—they can face less enemy but have less upgrade point. So the decision is up to the player to choose how they want to proceed with the level based on the types of dice face they want to collect.
Well, that was the psychology behind the game but I believe it was not presented in the best way due to time constraints and also due the overly ambitious level design which I am a fault of. Regardless of what the result was, I am quite proud of it because of the depth and potential the game possess. In the case I decide to continue improving the game, it could become a game that I can truly take pride in. And I guess that is the most important thing I can receive from my first Game Jam.
Parallax Effect
Here comes the more technical side of thing. One of the few things we have decided on when we decided to make a 2D Platformer was that the environment needed to be displayed in Parallax. A lot of us have seen its beauty and we have seen a lot of it being used in the games that we have played before. It adds a lot of dynamic to the background as well and adds on to the aesthetics factor of the game. Most importantly it adds on life to the already beautiful concept of our environment.
The problem was, I think none of us really had the experience to do a Parallax before. Thankfully, we received an amazing help from a video by AdamCYounis. For those who would like to implement a parallax effect to your game, I would suggest giving his video a view. It gives me a very detailed concept when it comes to the logic involved in a Parallax Effect.
Issue 1 — Cut Off on the Y-Axis
Of course it was not smooth sailing. The concept of the Parallax Effect is there but for our game we needed to take into account the y-axis as well. There was a lot of considerations when it come to this. When it comes to the x-axis, the parallax effect is very much smooth sailing because the sprite can be looped horizontally without much issue. On the other hand, it is not possible to loop the y-axis. So when there is a movement in the y-axis, the sprite will get cut off below and that was one of the first issue I encountered.
The first thing I tried was to freeze the y-axis, and it went horribly wrong. When the character jumped and the camera shifted in the y-axis, the background remained and what we will get is a background will rise with the player when they jump. We don’t want that because it looked like the entire world have moved with the player.
Extending the art vertically works pretty well, obviously it is an extra work on the artist and extra space in the memory. So in order to accommodate this, it is important to define how much height the character can traverse. This is to set a clamp and scope for the artist to how much height they needed to provide.
Issue 2 — Integration with Cinemachine
To accommodate the game camera, I opted to use Cinemachine to make sure that the camera movement felt smoother with the player’s movement. It worked pretty great. But the Parallax Script had reference to the original camera and the calculation became delayed. It made the entire environment to move very jittery and not fit for a game. It felt like there’s a frame drop.
So I went on to play around with the reference camera and thankfully it did not take a lot of time to fix. But it is a good thing to take note that there is a frame delay for the Cinemachine Virtual Camera to process the movement in the Main Camera. Since my parallax calculation used the main camera it causes a delayed calculation which resulted in the jitter in the background. This was solved by changing the reference from the Main Camera to the Cinemachine Virtual Camera. There is probably a cleaner way to fix this by modifying Unity’s Script Execution Order but given the 48 hours time frame I did not experiment on this to fix the issue.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ParallaxCamera : MonoBehaviour
{
//public Camera cam;
public Cinemachine.CinemachineVirtualCamera cam;
public Camera tempCam;
public Transform player;
Vector2 startPosition;
float startXPosition;
float startYPosition;
float startZPosition;
public bool ignoreY;
Vector2 distBetweenCamAndObject => (Vector2)cam.transform.position - startPosition;
float distanceFromPlayer => transform.position.z - player.position.z;
float clippingPlane => (cam.transform.position.z + (distanceFromPlayer > 0 ? cam.m_Lens.FarClipPlane : cam.m_Lens.NearClipPlane));
float parallaxFactor => Mathf.Abs(distanceFromPlayer) / clippingPlane;
private void Start()
{
Initialise_StartingPosition();
}
private void Update()
{
transform.position = new Vector3(ParallaxEffect().x, ParallaxEffect().y, startZPosition);
if (ignoreY)
transform.position = new Vector3(ParallaxEffect().x, startYPosition, startZPosition);
else
transform.position = new Vector3(ParallaxEffect().x, ParallaxEffect().y, startZPosition);
}
#region Local Functions
void Initialise_StartingPosition()
{
startPosition = transform.position;
startXPosition = transform.position.x;
startYPosition = transform.position.y;
startZPosition = transform.position.z;
}
Vector2 ParallaxEffect()
{
float horizontalParallax = startPosition.x + (distBetweenCamAndObject.x * parallaxFactor);
float verticalParallax;
if (ignoreY)
{
verticalParallax = startPosition.y ;
}
else
{
verticalParallax = startPosition.y + (distBetweenCamAndObject.y * parallaxFactor);
}
return new Vector2(horizontalParallax, verticalParallax);
}
#endregion
}
Tileset vs Sprite
The final and most important key learning point I wanted to make in this Post-Mortem is the difference between using a Tileset and Sprite when it comes to level building.
From the beginning, our team have decided to go for Tileset without considering much on Sprite usage for Level building. For the most part, it was a wise decision only until the later part of the game design.
Tilesets are known to be incredibly modular when it comes to Level Design. The designer can easily assemble and modify the level using the Tilemap. It makes prototyping much faster and easier compared to using sprites. However, this is only true if we have an established rules to the rest of the sprites (characters and other interactable). This was something we did not take account of and it causes very weird interaction with the tile.
Issue 1 — Weird and Unaccountable Physics
This issue arises because we designed the Character Sprite based on the Tileset. Our Characters are generally 2 sprites high, and we wanted to design the game such that the character can jump up to 2 sprites high. That would mean that the Character can jump as high as their height and that looks very weird. We noticed this problem and wanted to change it, but it was not entirely possible because we have already set the tiles to be of such height. Reducing the pixel per unit in the sprite sheet causes the grid to show padding instead and that would not work.
This is a very big problem with regards to floating tiles. Tiles that are meant to be an actual platform. It is an issue more apparent to platforms rather than the base of the level itself. Let’s say that I wanted to build a platform 1.5 units high from the ground, I cannot do that. Because the grid layout does not allow me to do so. And it gets very annoying at times because it would make my character jump an extra unit higher when it was not intended. It causes it to become very unnatural.
I am sure that this problem arises due to my lack of experience with Tilesets. I am sure there are workarounds but the time constraints makes it impossible for me to thoroughly study the nature of tilesets. Perhaps I can study this further in my free time or for future projects.
Issue 2 — Globally Harder to Modify
Another problem was baking the collider into the tileset. I understand that you can adjust it by drawing the Physics into each tiles and that versatility at least gives me some control to the tile. But at the end of the day, the tiles itself will be repeated and so does its baked physics. When there are times where I want to specifically adjust a certain tile, it feels very hard to do so.
The problem becomes more apparent when my artist provided me with a sprite to handle all moving platforms. The easiness to set it up and the flexibility it offers made me question the decision of using tileset in the first place. I can scale the sprites as much as I want while preserving its integrity. I can also place it anywhere within the 2D space of the level and that gives me a lot flexibility that I appreciate. And something that I don’t have with tileset and the grid layout.
Given another chance and enough time, I would love to build a platformers using entirely sprites. I believe it gave so much control to the designer and preserve the integrity of the artwork that I am sure the artist can appreciate. Also given the repertoire of games that has been built using sprites, going forward I believe that Sprites is the way to go to build a more refined platformer.
To End
In conclusion, these are the few things that I learned from my first Game Jam. There are a lot of things that I get to learn when it comes to generally 2D Sprite Manipulation in Level Design. I most definitely could improve in the theory behind the Level Design itself because it is something that I did not get much time to work on. I would definitely want to work on these in my next opportunities. As for World Building itself, it is something that I wished I can focus on in a Gamejam but obviously only with the appropriate team. I feel that it is something I can do only if I don’t have to do any Programming as an extra task.
Leave a comment