Making a difficult game about fitting in - Acerola Jam 0

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hey everyone! Recently, I participated in  my very first solo game jam, Acerola Jam 0. It was the perfect opportunity to take a step  back from my main project and see if I could   create a full game based around a theme in just  two weeks. I wanted to make sure to include all   the little details like music, sound effects,  menus, and an ending so that it feels polished. By publishing a small game, I would finally  be able to get a feel for the later parts of   a game dev cycle and I hope to be able to apply  those learnings to my main project in the future! So today, let me take you through the full   start-to-finish process of  making “A Gnormal Journey”. It all started with the announcement of the  theme: Aberration. The full definition provided   was “a departure from what is normal, usual,  or expected, typically one that is unwelcome.” I thought this theme was really  interesting and for some reason   the first thing that popped into my head was  to make a game about conforming to a society. After a long think, the best idea I could come  up with was actually a local multiplayer game.   You would control a character trying to  blend in with a crowd using the keyboard,   while your friend has to guess which  character you are using the mouse. I guess I was kind of inspired by that one Wii  game where you have to find the odd person out. But there was just one tiny problem with my  idea. After checking the rules, I realised   that the games needed to prioritize single-player  gameplay. Which… made a lot of sense, actually. But since I liked my idea so much,   I decided to stick with it and try to make  both single player and multiplayer modes. As I’m sure you can imagine, this was not really   feasible for a two-week game jam  so I had to scrap multiplayer. But anyway, I didn’t realise that at the  time, so as soon as I got back home from work,   I excitedly set up a new git repository  and created a blank 2D Godot project. I decided the first step would be to  create some placeholder art for the   characters in Photoshop. Well at least  it was meant to be placeholder art,   but I never felt the need to  change them, so they stayed! I kept the design suuper simple because  eventually, there would be large numbers   of them on screen. For the overall aesthetic  of the game, I was really inspired by a game   called The Gnorp Apologue, which has such  charming monochrome pixel art. It’s so   fun watching these little guys go, and I  was hoping to create a similar feeling. It was also around this point where I had  the idea to name these creatures “Gnorms,”   which is not only inspired by the Gnorps  but is also obviously a play on the word   “Normal.” Which as you will come to  see, reflects their societal values. Next, I slapped together a quick character  controller script. It’s definitely not the   prettiest code…but essentially, all it's doing  is picking one of these 8 directions to go,   normalising that vector, and then multiplying  by a speed. So, very basic movement. With Godot’s input map system,  it was also very easy to hook up   the movement to both the arrow keys and WASD keys. I also had a think about the lore of the  Gnorms, and why the player would be trying   to blend in with them in the first place.  So I came up with the logical conclusion   that the player is actually a monster in  disguise, with unknown but questionable   intentions. To implement this I drew up  a quick monster shape-shifting animation. Not gonna lie it looked pretty silly,  but was a good placeholder to start with. I was still thinking about multiplayer at this  point so next I did some experimenting with an   outline shader. I made it so that when you  hover over a Gnorm, the outline shows up,   and when you eventually click on the  correct one, they turn into a monster. Since I scrapped multiplayer this functionality  was never used in the end, but the outline   shader turned out to be quite helpful for  something else which you will see later on. At this point, it was only ~8:30  pm , so I still had a bit of time   to add more things. I decided next  I would add the rest of the Gnorms   into the scene so I could actually  start testing my idea properly,   and I really start thinking about how to translate  this multiplayer idea I had into single-player. With the kind of random crowd movement  I had in mind, I wasn’t sure how to   make the computer detect when the player is  actually acting differently from the rest. It was at this point I realised it would  be so much easier to have the Gnorms   follow a linear path instead. If the player  steps off the path, then they would be caught. So then, how do we implement a path? Well, Godot  has some nodes for this exact use case. The Path2D   node lets you define a path by adding some points.  Then if you add a PathFollow2D node as a child,   you can modify the progress or progress ratio  fields to automatically move it along the path. There’s also a rotate option which I disabled  since I didn’t want them upside down.   Next, all I needed to do was add one line of code  to get them moving along the path at runtime. As you can see though, they weren't facing the  right direction. So I also added some code to flip   the sprite depending on whether it is moving in  the positive x direction or negative x direction. Now I had the player movement and Gnorm movement  complete, here's what they looked like together.   And not that it matters anymore, but I  think it is pretty obvious which one I   am controlling. Next I needed a way to detect  when the player strays too far out of line. To do this I simply added an Area2D node that  follows along the path where the player should be.   So now, if the player no longer overlaps with this  detection circle, they return to being a monster. And at this point it was now  midnight and I was exhausted,   but I thought that was pretty  good progress for day 1! The next day my goal was to finish the gameplay  loop and prototype a level. First thing I wanted   to fix was that it was way too difficult  to have to move as soon as the game starts. So, I decided to add a countdown. I  experimented with pausing all movement   during the countdown, but the timing  was still difficult once it resumes. Eventually I made it so that everyone still  moves during the countdown like before,   but this time the player’s controls are  disabled. This means you automatically   follow along for a bit before controls  are handed to you, which felt much better. Next I wanted to get started  on the background visuals. So using this image as a reference, I drafted  up some simple tiles in photoshop. Then back in   Godot, all I had to do was draw in this bitmask  to indicate where the tiles should connect. I also thought it would look nice to scatter  these detail tiles randomly around the floor.   Instead of placing them manually though,  I simply just modified their probability   of showing up. So now when I go to fill in  an area, it automatically randomises their   appearance. Then I was able to go in by hand and  add in some extra tiles to indicate the path. Now that the visuals were starting to come  together, I wanted to improve the monster   transformation animation. To create some  more suspense I added this shaking effect,   and updated the sprites for more contrast.  The shaking effect was achieved using code,   where the position is offset  by a random amount each frame. Next I added in a retry button that appears when  you lose, and when clicked it reloads the scene. I   put in some extra effort here to have the UI fade  in and out. That way the game feels more polished. In order to implement these fades I decided to try  using Tweens. For those who don’t know, tweens in   Godot provide a way to smoothly transition  from one value to another by using code. I was also very excited to discover that there  are many types of transitions to choose from. I   ended up using the Sine one, which looked like  this in the code. This code was then applied   to a Polygon2D node which I extended to cover the  whole screen. Now as you can see, it fades nicely. Moving on, you may have also noticed that  at the start of the level it is visually   impossible to distinguish who you are. That  was the point for the multiplayer idea i had,   but since now that’s out the window I  decided to at least add an arrow indicator. In fact I went ahead and drew a bunch of  icons because I also wanted to give the   Gnorms some personality. At  first I had them run away... But it wasn’t really clear why stepping out  of line causes you to turn into a monster. So   instead I reworked it slightly so that if you  step out of line, the other Gnorms will come   and attack you with little swords. Now I guess  the monster form is more an act of self-defence. I thought it turned out pretty hilarious and so  I definitely wanted to keep it. I even updated   the monster sprites further, making  it look sad and defeated. The only   problem is that the Gnorms do bunch  up in the same spot. But I ended up   just leaving them be like that because  it would be kind of complicated to fix. Also since I now had the code  for both attacking and fleeing,   I left one of the Gnorms to  flee as a little easter egg. The Gnorms also get suspicious of  you when you when start straying,   indicated by these question marks. I  thought it was a neat little way to   add a bit of personality and also  warn the player at the same time. At this point I felt like I had the fundamentals  all figured out, so I spent the rest of the   evening planning and prototyping some basic level  designs. The levels would start very simple like   the straight line, but have the potential to get  really complicated which I was excited about. Day three ended up being entirely  focused on sound effects and music,   which was one of my favourite parts of the jam. Firstly, let me introduce you to  this amazing website called sfxr,   which can generate really cute 8-bit  sounds by tweaking some parameters. Using this website, I made some countdown  sounds, a button hover sound effect,   button press sound effect, alert sound  effect, and a level complete sound effect. The death sound effect was a bit more  complicated, but essentially I layered   a few different static-y sounds together and  then added this hit sound that plays on repeat. And with that, the whole morning  had already gone and I was going   to move on to something else, but then an  interesting melody idea popped into my head. I thought it would fit the Gnorms quite well so   I decided to build upon this  idea and see where it goes. But since I obviously don’t have the  rights to use this Undertale sound,   I decided to have a go at creating  my own by configuring a synthesizer. Now I am by no means an expert but I  did wanna share what I know about synths   anyway, cuz I think it's super interesting. As you may know, all sounds are made of waves  which can be visualised like this. For computers,   some of the simplest waves to  generate include sine waves,   triangle waves, sawtooth waves and square waves. So when looking a synthesizer, you’ll often  find a section called “oscillators” that allow   you to select the waveform you want. With  multiple oscillators it is easy to layer   different waveforms together, in order  to create unique combinations of sounds. Different synths have different  layouts, but the same principles apply. From there you can shape the sound  further by applying an envelope,   with parameters called attack, decay  sustain and release. The envelope   can be visualised like this, and watch  how the shape affects the final sound. Anyway I could go on and on, but let me  show you how I configured the synth for   the game jam because it was super  easy. Basically I searched through   the default logic patches for a synth  that had a nice vibrato. Then I simply   switched it’s oscillators to use a square wave  instead. So now, this is what it sounds like. And this is what it sounds like in context. If you wanna check out the full version  I will add a link in the description. After importing my music into the game and  playtesting though, one thing that stuck out   to me was when the player gets caught. Instead  of writing extra music for the retry menu though,   I decided on this hacky fix of adjusting the  “pitch scale” down. So now, it sounds like this. After spending the entirety of the previous  day on sounds, it was time to get back into   some actual feature work. One thing the game  definitely needed was a main menu, so I added   that first. With this level select button you are  easily able to jump ahead in case you get stuck. Next, I had a go at implementing a pause  menu. This had always been a daunting task   for me because I assumed it would be really  complicated. I spent like an hour coding this   absolute mess before realising that I only really  need one line of code: GetTree().Paused = true. This pauses everything - however that includes  the pause menu buttons too! To fix this,   I learnt that all I needed to do was  change their “Process mode” property. “Pausable” mode means the node will only process  if the game is not paused. “WhenPaused” is the   opposite - the node will only process when the  game is paused. That might sound counterintuitive   at first but it is surprisingly useful,  and this was what I used for the pause menu   buttons. Another useful one is the “Always”  mode, which means the node will always be   processed no matter if the game is paused. This  would be applicable to the music, for example. And to finish off the pause menu, I applied a  low pass filter which creates a muffled sound. Sometime during the evening I also went ahead and  designed a new character that would co-exist with   the Gnorms. As you can see I struggled with the  design initially before making it much bigger.   I think I just called them “Big Gnorms”  in the game but during the making of   this video I realised they should have been  called…”Enorms” (because enorm…enormous…get it?). Anyway, their job is to look cute but  actually be a kind of nuisance. In some   of the earlier levels they will just sleep  out in the open, so you gotta be careful not   to wake them up. This also means the rest of  the Gnorms will move much slower than before. Then in a later level, a bunch of them group up  in the centre, forcing everyone to take the long   way around. I had some more ideas which I’ll get  to later, but that brings us to the end of day 4. During the next few days I worked on the  game for small amounts during the evenings,   mostly spending that time making more levels. I had this incident on level 9 where I kept  getting knocked back while playtesting. I   checked the collider debug view…and nothing  was there. I spent ages going through my code,   trying to figure out what was wrong, but  couldn't find anything. Tired and confused,   I decided to sleep on it and  continue looking the next day. And let me tell you, sleep really  does wonders because the next day,   I realised that the issue was actually due  to this invisible Enorm lying on the track.   I forgot it was there after copy-pasting  a previous level. So yeah lesson learned,   colliders can be active even when invisible. At this point on day 9, I had 9 levels so far. But  I didn’t want the entire game to just consist of   walking along a path, because that would get kinda  boring. So here’s what I came up with instead. On level 10, the Gnorms harvest some crops.  You have to make sure to pick the correct   plant - else the Gnorms will be on to ya.  I also made sure to consider what happens   if you don’t pick up a plant…and yeah, the  Gnorms don’t take kindly to that either. Levels 11 and 12 were themed around traffic, so  you sometimes have to give way. It’s actually   quite challenging to get the timing right, and  I definitely made level 12 a bit too difficult. Level 13 however, is probably my  favourite. You have to feed the   Enorms, like this. Then they spit out a blob of  honeydew which you can pick up on your second lap. However due to this, there are now many  ways to fail this level. You could throw   the food too early or late, you  could not throw the food at all,   you could pick up the wrong honeydew or you  could forget to pick up the honeydew completely. Moving on to level 14, I think it  speaks for itself. I wanted to make   it the hardest level in the game and I  can safely say that has been achieved. The last level, level 15, is a nice relaxing walk  into the center where the Gnorms go to deposit   their honeydew. I thought it would make sense  for the Gnorms to store their food in a nest,   kinda like ants. Most importantly,  their gnest would be spelt with a g. Now, all that was left was to add  some intro and ending cutscenes. I kept the intro cutscene really short and simple  with just a basic explanation of the premise.   I must say, the game turned out very  different to how I was expecting,   but I guess that’s not necessarily a  bad thing. Anyway, thanks to the heavy   usage of timers and tweens, this  cutscene was really quick to make. The ending scene took me much longer  however, probably because I went a bit   overboard and painstakingly painted in  a huge area of tiles to depict the nest. Finally, it was time for some playtesting!  The first bit of feedback I got was it is   quite hard to keep track of who you are.  So this is where I added a small outline   to the player - using that outline shader  that I already imported back on day 1. The other feedback was that some of  the levels were too difficult. So I   went ahead and doubled the radius of the  detection area, which I am very glad I did. At this point I was quite exhausted with  this project, but the finish line was really   close! Exporting should be super easy,  just gotta add this setting here and - Yup, after all this time I learnt the hard  way that Web export is not available for   games built with C# in Godot 4. I would still be  able to export a Windows build, but I was really   devastated because people are far less willing to  download games as opposed to play in the browser. All I could do at this point was  upload my builds for windows and   mac and move on - accepting the fact that  the game probably wouldn’t do very well. After a month passed, the judges played  through all 945 games and it was time   for the results to be announced. So,  how did I go? Well…I made the top 5!   I cannot even begin to tell you  how amazed I am with this result,   especially after I genuinely thought I had  no chance. There were so many awesome games   submitted and I would definitely recommend to  watch the results stream if you haven’t already. So there you go, that concludes the story  of how I made “A Gnormal Journey” and I   hope you enjoyed following the full process.  It was a great experience to finally make an   entire game from start to finish and I learnt  many, many things along the way (tier list?). But anyway, it’s time to get back to my  other projects now, so see you later!
Info
Channel: jess::codes
Views: 271,733
Rating: undefined out of 5
Keywords:
Id: MG6mpjDkS44
Channel Id: undefined
Length: 19min 16sec (1156 seconds)
Published: Sun May 19 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.