Enrique AM

#0: The creation of Bug Fiesta!

> Summary

> Intro

Hello everyone! Welcome to this new section of my personal webpage. The main objective of the articles inside this section will be describing to you the programming projects I'm working on, giving different insights and opinions of it, while showing you also some screenshots or different images to illustrate the project. I'll be more technical here than I am in the retro section, so it will be easier for you to understand probably if you have some notion about programming, game design or game development. You're free to go if you are not much into these topics, but welcome to stay. 🙂

Also, to give you some context: I'm a professional software developer, but not a professional game designer or a professional game developer. I mostly do games because I love them, but I don't work (currently, mwahaha) in the industry. Keep that in mind if you see from me a very obvious explanation for a basic thing that you already knew. 😁

On this first entry on my devlog, I want to share with you how we've done Bug Fiesta!, our last small game done for GDNL's Island Jam. Let's start!

Illustration of Jeff the aphid, welcoming you to read this article.

> First ideas and decisions

I already worked with Ely (illustrator and 3D artist in "Bug Fiesta!") in previous projects. You can check her work here. We spend maybe an hour every two months seeing if there's a game jam that fits with our current capabilities and mood. From our experiences, we knew we didn't want to join to game jams that are based on money or a different kind of excellence prizes; our main reason to join a jam is to learn new things and do creative job. If you're working with a team, you have to be sure of this alignment before starting a jam, because the expectations can vary a lot.

Also, on a more personal reason: I think that doing jams that involve money break their main purpose. I respect if any person wants (or needs) to do them. In my case, when I do a jam, I want to put the focus on learning and having fun, not on worrying about the prize. I could do them anyway and try to not bother, but bothering a 1% will be more than I would like. And I think getting competitive because of money is not healthy, at least for me. So I prefer to participate on jams where I can get back that 1% of concentration.

>> Why the jam motivated us

We decided to join to GDNL's Island Jam for many reasons:

  • We haven't joined and finished a jam in a while.
  • No prizes (we haven't saw at least).
  • Organized by a small community.
  • Longer time frame than usual (two weeks instead of 2-3 days).
  • We love island themed videogames.

I hope they didn't mind that we are from Spain and Germany instead of Newfoundland and Labrador. 😅 You can learn more about who they are and what they do here. So, after deciding to join this jam, we talked and set some expectations about it.

>> What were our main expectations

Aside from getting a jam done and try to deliver a small game that fulfills our taste, one of the main expectations that we had is that we wanted to learn to do a 3D game. We played around with Blender before and made some very small steps with some 3D prototype games, but we hadn't done any small and complete 3D game from start to end and published it. That was a very big challenge for us, so it was worth to try to brainstorm with this idea into our minds. We didn't know what we were getting into, haha.

>> Why we used the tools we used

We used Godot Engine (version 4.0.2) and Blender as our main tools because they are open-source tools and are the most accessible ones. Godot Engine currently is not selling its AI work to the military like others do. Also, Godot Engine main contributors are not doing weird comments on Twitter about why removing a verification system in one of the most used social media websites is a good idea.

I don't know that much about Blender main contributors, but the sure thing is that even if we didn't like their creators, we could just clone their repo and fork our own version. Also, one way or the other, we will be avoiding to create a codebase for a closed system that could be changed or restricted from one time to another.

Those kind of things make me sleep a bit better at night. Every person has their reasons to use their tools, but I think it's worth to keep checking ourselves and try to be more aware on what we use and how it impacts our world. Open-source has many alternatives to privative software, not only being more ethical, but sometimes also more useful or easy to use.

We also used Element as a communication tool. It had all the things we needed to communicate, send previews of the game and stay easily in touch. I use it currently every day and it's worth to try as an alternative to other privative apps.

Unluckily, we didn't use open-source for everything. For the other tools that we used as secondary tools, it's worth mentioning:

  • Procreate, to create some textures, logos and concept art.
  • Paint.NET (currently freeware), to modify different logos and splash screens, saving the screenshots of the project and probably to do different editions to images of the game.
  • Trello, to create a Kanban board and organize our work.
  • Cubase 12, for audio recording/editing.

>> Brainstorming and starting

I was a bit scared, because Ely and I tried to brainstorm for different jams this last two years and we early ended them without delivering anything. The main theme of the jam was "Island". Also, we had three optional topics:

  • Black and white.
  • Spring has sprung.
  • You are the villian.

In summary, we had many ideas that we discarded for many reasons, but the main reason to discard them was that we didn't connect with the ideas. So discussing about the spring one, we started talking about Keta, our ladybug friend we took care of last year. "We can make a 3D Keta". "Yes, why not?". "Should we make a game about bugs and call it Bug Island?". And then our eyes shone and we knew that this was the thing we had to work on (dramatization).

At first we had different ideas to accomplish with the second optional topic ("Spring has sprung"), but after a week we only left a small reference in our game. Even if we were not going to fully accomplish with any of the optional topics, we prioritized doing a topic that connected with us, as it would be an extra motivation for us to continue and finish the jam.

> Climbing the learning curve

>> Oh boy, 3D!

For us, it was overwhelming to start with 3D. We played around with Blender many times, but we didn't try to complete any model in those attemps. For me, developing a 3D game has many differences that made the process more complicate for us, compared to 2D.

For me, 2D feels like doing a collage, overlapping pictures and effects until you form the full image that the game is; 3D games for me are CHAOS. You have to deal not only with creating the 3D models and dragging them to the screen, but also care about lighting and shading. Also, messing with a TON of parameters of the textures and everything so the game can look minimally good. I spent more time dedicated trying to make the game look better than programming the main gameplay (I'd say 8.5 days making the game look right, 4 programming the gameplay, 1 doing a custom compilation of the game and 0.5 publishing it).

>>> First steps

I wanted to have a working prototype as soon as possible, so we could start dropping assets there and testing the gameplay. So I started creating a 3D project with Godot, with a main scene called "Game" and started wandering around with the vast amount of parameters that you need to tweak for a scene to start to look good, from adding a basic light, tweak the environment sky, to add the first water plane and primitive island meshes.

It's worth mentioning that I followed this water shader creation tutorial from StayAtHomeDev and tweaked the water parameters and algorithms. Thanks for the useful tutorial! If your interested to learn how to use Godot Engine, it's worth to check the channel!

After playing around with the water for almost one day, I decided to leave it as it was, to start doing the basic gameplay. I added basic meshes to simulate the island shape, added a basic semicircle with a hand-painted placeholder texture for the main character, added some collisions and implemented the movement and jump actions.

Screenshot of Godot Engine showing a basic 3D island, with water and a small simple ladybug.

I ran the game and the collisions were not working as expected. The character was just trembling. I uploaded a video on YT to show you. I'm not embedding it to my webpage to avoid unnecessary tracking cookies, sorry for the inconvenience. So in the end, after fighting to understand the problem and doing some research, I finally understood why usually prototype videogames have pill-shaped characters (or at least I think it's related): I added a square collision to the character, so it has having a hard time calculating the position in slopes.

The solution, as you can imagine, was changing the collision shape to a capsule-shaped one. You can see the difference in this video.

So yay, it worked!

>>> Map mesh, go simple!

One of the main reasons we spent that time just beautifying the game was that we haven't done any 3D games in the past. Aside of the extra coordinate in 3D, gameplay programming follows the same logic as a 2D game. When you learn a new thing, it's difficult to know which would be the best solution to a problem. So when we divided our tasks and I had to create the island mesh, I opted for doing what I already tried in the past: Doing a shader to generate the mesh displacements. I already did it when I tried my first tutorials to generate a water mesh (the current water shader that I did in Bug Fiesta is not my first attempt) and I tested shader displacements in other shader tests, so I decided to go with this approach for the vertex() function:

uniform sampler2D noise;

void vertex() { 
    float height = texture(noise, VERTEX.xz / 2.0 + 0.5).x;

    vec2 st = VERTEX.xz;
    // pct = The DISTANCE from the pixel to the center
    float pct = distance(st, vec2(0.5));

    VERTEX.y += height;
    if (pct > 0.5) {
        VERTEX.y -= 0.1 * pct;

So after dealing with the island creation, creating a NoiseSampler2D to have the basic shape of the island, and starting to try it, everything looked great! The island was showing in my screen and I could even start creating a material for that shape. But when I was starting to generate the collisions for the terrain, they were not working correctly. What was happening? It was looking like it was generating a flat collision instead of... Oh no...

I already knew what was happening, but I was rushing for the jam and I didn't realize. I will explain the problem as simple as possible in my own words:

A shader is a script that modifies what you see in your screen. It processes the data that enters in your GPU and returns an output, that will be the information you can see in the screen. You can process the lighting of an image to be brighter, but the image will remain with the same lighting in the file. The same happens with 3D: You can modify not only the lighting, but the shape of a model using the vertex() function (for example, giving the shape to an island using a noise texture). The good side of it is that this is a very efficient process and allows your computer to generate a vast amount of information from mathematical algorithms. But that will mean the change will only happen visually. So if you try to generate collisions, you can't do it (as far as I know, of course) based on the result of a vertex shader processing. You will need to process the shape outside a shader function.

So the idea I had after that was to do the same calculations I was doing but in a GDScript (Godot scripting language) and save this result to pass it to the shader function AND use it from the code to generate a new collision mesh. I checked the best way to do this properly and I decided that it was a waste of time. Why should I bother to do this? It could make more sense if we had a procedural map, because this would allow us to generate new maps with the correct collisions. But I decided not to go through the rabbit hole: "Why don't I just generate an island in Blender, using a displacement map and export it with the applied modifiers, so then I only need to do a single click to generate a fixed collision mesh with Godot?".

That reason, summed to that I had to go to my hometown with my (not so powerful) gaming laptop, made me decide to install Blender in it and just focus on having a good looking environment until I came back to the city.

So the advice here would be:

When you get stuck in a jam, try to simplify. It works almost all times. Maybe you won't find the best existing solution simplifying, but it will get your game done. You won't have maybe a clean code, but you will unblock yourself and allow yourself to continue. You're learning and you don't have the restrictions of perfection that the typical employer would demand to you, so you have the best environment to try weird and ugly but fast approaches. Experimenting with new ways of doing things maybe will make you realize how good it feels not having any restriction to play around and mix ability and creativity. It just flows, and that's what matters.

It's also worth mentioning that:

Jams usually end having a bunch of ugly code that is not very easy to refactor. It's better not attaching too much with the project, because in the future will mean to have very long cleanup sessions to be able to add new functionalities. But obviously, if you get attached by your magnificient creation, just keep into your mind that it's also ok, just align with your team if you're not working alone, so you can be more organized if necessary. From my point of view, knowing that you're doing a game for a jam and not a big project will allow you to tweak the code quickly in the last moment for this kind of bugfixes or last moment additions that will look awesome in your game, but not as good in your code. But it's just fine.

The last thing I wanted to comment is that if you're interested into learning shaders, one way to start to get familiar with them could be checking The Book of Shaders, by Patricio González Vivo. I got the center distance calculation from there and it's a great resource to learn in a comfortable way, with WYSIWYG (what you see is what you get) text editors and different chapters explaining concepts in a very understandable and concise way. I'd really would like the web to be finished, but when have you seen a great author without unfinished works? 😁

>>> Chaos in a blender

So I started working in Blender with my new environment. Blender is well known for it's pronounced learning curve, but I was decided to at least do what I needed to do: A small island to start testing the collisions.

I chose Bforartists to do the island. It has many UX improvements and for a beginner is easier to use. The downside is that almost all Blender tutorials rely on showing a bunch of quick shortcuts without even explaining what is happening in the back. So I had to make more effort in that sense, but anyway, I prefered Bforartists.

Summarizing here, because this was not an easy process with me, I had to find how to pass a displacement texture (a black and white image showing the 2D height of your mesh) to generate a height map. As far as I remember, there's more than one way to do it. I did it first with a shader using Blender and then I tried to generate the result... Yes, again, HAHA. So I couldn't generate a result because it was a shader, blah, blah, and at the end I found a good way to do it: Using a Displace modifier and passing the height map to it. This was the result:

Blender for Artists fork screenshot, called Bforartists, showing a plane converted to an island using a height map and a displace modifier.

I could export the island without problems until one problem appeared: Collisions were not generating correctly anyway. What was happening? Godot was giving us already a hint: You can't generate collisions correctly if the XYZ scale of your model is not exactly 1.0. Why? I don't know and I didn't care. I was starting to stress, so I just found a way to apply the scale in Blender. Thanks, Erik Selin! As far as I remember, that article could help me.

So after that, island was generating correctly, I could apply a texture for the sand and... Ta da!

Godot Engine screenshot, showing a sandy yellow 3D island in the sea.

After that, we had to polish the map, so Ely created an aerial view of the map and I made a heightmap based on it, painting it digitally in a foreground layer:

Heightmap image with a slightly visible island map layer in the background.

These was very useful to create quickly a final version of the map. I had to spend some time fixing rough edges in Blender and finally painting the mesh.

Blender screenshot showing the basic heightmap creating an island. It has a Displace modifier and a Correction modifier.

After that, I exported the map and it was looking a lot better than I expected! I still had to tweak the environment parameters to remove some fog and do a sunnier ambience, but it was starting to get in shape.

A nice-looking 3D island with some mountains, grass places and coasts. Some fog can be appreciated, making the environment a bit foggy and rainy looking.

So my job was done for this part. I've done what I could and I could improve it, but I needed to start working on the core gameplay and implementing music, sound and all the 3D assets. It was enough and it worked. I only polished it again to make better slopes and avoid the character being stuck, but that was it.

Blender screenshot showing ugly gap manually done before smoothing. Blender screenshot showing the previous terrain but smoothed.

I don't have any particularly wise advice for starting with Blender. In my case, having the urgency to get something done helped me to simplify the process of creating the island. You'll have to deal with a lot of new things when starting with 3D, so don't lose your focus and try to do it as simple as possible. Maybe you'll have time to improve it in the future, but maybe not. Also, tutorials are not always helpful and you'll find yourself trying to search in forums, video webpages and social media at the same time. I think that Blender is a complex tool and it's not only about having a difficult UX; there's a lot of new concepts that you need to grasp before being able to search more specifically for them. After understanding these concepts, you'll be able to go climb another part of the curve. Take it easy!

>> New team member!

We teamed up with a new colleague Marcus Auerbach to work on the audio aspects of the game. It was a great collaboration! It also added some difficulties on our usual workflow, as Marcus was not in the same physical room. I'm very used to work from home, so I could apply the same patterns as in my current job to be efficient:

  • Sync voice (and even cam) meetings. This was crucial to talk about the project, brainstorm and give feedback in a more human way. Also just for chatting.
  • Using productivity tools to organize the work and for having an overview. In our case, as I mentioned before, we used Trello to subdivide all the possible tasks (I wouldn't say we did user stories), added a first column to organize useful link lists and used it to know what we should do every day.
  • Be connected! We used Element to communicate every time we needed to send previews, request feedback or talk about anything. When you work remotely, you have to be sure to include everyone in the conversations and be active in the chats, so everyone is on the same page, without blockers and the work can just keep flowing.
  • New team members are part of the team since the moment they join us, not external people doing "the rest of our game". Treat them the same way as your known partners and be sure they contribute to the brainstorm and ideas of the game. The more the people is involved, the more awesome will be the result!

At the end, we could do an awesome work with him and the game would not be the same without him. Marcus put a lot of dedication in all the things he has done for this small game and it was very fun to work with him. It was very easy for me to see he's very experienced!

Please, listen to his work here. 🙂

> Game design, style and decisions

>> Silly and chilly

Life's pretty much hostile in general and we already had enough games of stomping those... bad guys. One of the reasons I joined the jam it's because the main theme, "Island", evoked me that lost childhood feeling about being completely stressless on summer. We wanted to do a game to forget about everything, create the ambience of a place where you would stay forever and have around these kind of "people" (in this game they are bugs) that you don't know, but you see each summer and they are somehow kind or comfortable to you.

Here's the first concept art for the character. If you played our game, you will notice there's a character that we had not enough time to introduce:

Character concept illustrations, showing: Jeff the Aphid, with a small hat and a stick in his mouth; Slug concept smiling with two big eyes; Spider concept that we didn't had time to implement; Worm with sunglasses that we implemented without sunglasses; Keta the Ladybug, round and with two big curious eyes; Paco the Fly being small with a round belly and the Bee with one big tooth, smiling and showing the sting.

Aside from Ely's designs, Marcus managed to create their dialog and a great part of their personality. I tried, at the same time, to work on the feeling of the game, how the dialogs worked, the environment, lighting, etc. There are still improvements to be made, but the first version came up more or less as we expected, so we're happy with it.

>> Mixing reality and fiction

Another reason that made us connect with the game was because the previous spring (2022), we took care of a little ladybug that Ely found in one of our cactus pots. It was pretty cold that day and she was very quiet. We named her Keta. By the way, fun fact: We assumed always her gender because we're not experts, although we wrote her game dialogs as him pronoun (I guess language is difficult). She couldn't fly, we even tried to free her when we saw her feeling better, but her elytra was damaged. We were feeding here approximately three or four months: Lettuce, red fruits (mostly blueberries), water mixed with honey and sometimes even aphids (ladybug's favourite food). She passed away, we made a small wooden tombstone and buried her in another of our cactus pots, near the place we found her for the first time.

You can see a picture of her here, probably on one of her happiest days of her life, when we found miraculously a ton of aphids in a lettuce we bought and gave to her. She was taking a deserved nap and then's when we took the picture:

Picture of the real life Keta inside her transparent cage. You can see the dirt, some lettuce, watered-down honey in a wet paper, some wooden decoration, her small skull-like ceramic house and a small bottle with her inside, taking a great nap after eating lots of aphids.

Doing a homage to Keta was a effective way to motivate ourselves. Although sometimes the memories of those days are sad, she brought a lot of happiness to our home, so we wanted to do something that made the people happy at the same time that served as a homage for Keta.

When we talked about this with Marcus, we realized he also had the same opportunity to know some bugs that were having some problems to behave on their own: Schnecki, Schneggo and Sibyl (in alphabetical order). We thought it would be awesome to include them in our game and we thought that the island of our game could be the heaven where those bugs went when they passed away. We connected a lot with this approach. You can see a picture for every of them if you play our game and check the credits section, but you can ask me for more pictures if you want! 💚😊

>> Simplified core gameplay

We decided to simplify a lot the gameplay because it was not our main reason to do this game; we just wanted to create a small and comfy story, so that's why the gameplay is not complex in any way. It's a story-driven game where you have to search for the different bugs around the island to celebrate the Spring Festival (Bug Fiesta™️©️). You can move as the main character, Keta, pressing WASD keys or the left stick on your controller. You can jump with Space or the button where the X is on PS controllers.

You can talk the NPCs with the jump button. We remembered that Marcus asked us to add a button to avoid talking automatically everywhere, so I reused the jump button to trigger the conversations, but I forgot to block the jump (and the squeaky sound) from happening. We thought it looked fun, as Keta was requesting the attention from the NPC, so we left it that way. You can even turn left and right while you talk with them!

Menus are very simple to use (if you don't think so, please let me know). You just need to talk with all the characters and go back to the chiringuito to start the party and end the game. That's it. Why so simple? We focused on learning 3D modelling and programming, so it was enough work for us. Also, it could be as simple as you prefer. It's a jam, not your job. 😉

Bug Fiesta screenshot, showing Keta, the main ladybug character in front of Jeff the aphid. Jeff is welcoming Keta to Bug Island and asking her if she remembers how did she arrived there.

By the way: Link's Awakening vibes? 👀

>> What was left out

Flying, Keta being able to roll or fall backwards (and jump to rotate and recover), actions that can affect the storyline, more dynamic animations for the characters, moving grass, better camera, day-night cycle, free roaming after completing the game, being able to save the game, options menu to configure, accessibility, minigames for every character, game UI, more dynamic music and sound effects, browser version, touch controls and mobile support, language selection and more languages, team logo, more models to decorate the island, visual effects... As you can see, so many things were left out to arrive in a good shape for the delivery day. Controller support, better lighting and Keta adapting the position of her body to the terrain were also discarded for the first version, but are currently implemented in the last published version (1.0.1).

We also left out the spider character, Gertrude, because we thought about arachnophobia and, as we couldn't develop an options menu to implement arachnophobia tolerance level (something like Grounded did in a very smart way), we decided to sadly leave out this character in favour of the silliest bois and gals. But although we didn't introduce her, we already had the script for her dialogs!

~ game_spider_collect

Gertrude: Hi, I'm Gertrude, your friendly neighborhood spider!

Keta: ...

Gertrude: You look a little frightened, dear. Is everything ok?

Keta: \*shiver*

Gertrude: Oh, don't be scared! I'm a vegetarian! I mostly eat pretzls!

Keta: Right... Well... that's a relieve, I guess? 
Keta: That guy at the café, Jeff, he asked me to remind you of the Spring Festival tonight.

Gertrude: Well, aren't you a helpful little guy! And handsome, too! Thanks so much! Will I see you at the party?
- Wouldn't miss it for the world!
- \*Shudder the thought.*

=> END

And a small text when you arrived to the festival:

Gertrude: Hey, darling! Thanks again for coming to get me! 
- Sure thing, love!
- I think I left the stove on... gotta run!

Seems like Keta was not going to like a lot Gertrude. 😁

As you can see, we fully focused on the basics: Talk with the characters and reunite them for the Spring Festival (Bug Fiesta™️©️). When you're in a jam, you have to learn what do you wish to deliver at the end and focus to complete at least that. Different people will prefer different focuses, just be sure it connects with your preferences and the team can mostly accomplish the goal.

> Good decisions we've done

>> Talking, a lot

I think one of the most crucial events that happened in this jam was the conversation about mood. When Ely started doing the first sketches of the characters, I was very sure about what was the direction we should take for the game. But when we started mixing the different assets and code we did for the game, something was not working right. It just simply didn't fit as well as we expected. So we decided to open a long voice conversation to discuss about the mood of the game we were creating. We made sure to know what every one of us needed to do in this game, and we made sure it was aligned with everyone's vision.

So after that conversation, we came up with many ideas that could improve the game, about: The way the characters had to move; how they had to look; how the music had to sound; how the sound should work for every character; how they should talk and what they had to transmit to the player. Most of the changes we discussed were very easy to implement and after that it changed drastically how the game looked and felt. Even most important: It made us connect with the game, ensuring it was part of us and we were part of it.

So the main thing I have to recommend you, especially if you're going to participate in your first jam or if you already participated and you're not used to it: Communication is crucial. Is a key aspect in every social interaction and it doesn't come intentionally. You don't only have to talk; you have to be empathetic and listen to the other people; you have to arrive to decisions as a team, not as individuals. And nowadays, working remotely, it is even more difficult to be intentional when communicating. But it's worth to try, keep learning, requesting feedback, improving and doing it again.

Marcus note regarding this section:

Marcus here. :) At this point everything really started to come together. In typical "hey, I just bought new stuff and I wanna use it, too!"-fashion, I had started work on the music in a very close-to-home kinda way: It was ethereal, with pads and strings, very moody and dreamy. The kinda stuff that I enjoy in my favourite video games that go for the kind of experience I figured we were gonna make here.

I had just started, without much input in how it should actually sound like, just doing what I thought was best. And while the results weren't bad, it wasn't "there" yet, either. When talking with Ely and Enrique (yes, talking, super important :)), I soon learned that leaning more into the goofy aspect of the character designs was probably a way better fit for the game. Ely and Enrique were kind enough to provide examples from other game OSTs and just for fun I started trying things out, just using my voice, harkening back to those glorious days of Shiny Entertainment's Earthworm Jim games on the 16-bit consoles of old (something during the conversation made me think of those games and that was the moment when lightning struck). It became apparent quite quickly that we were now on to something and the rest was just a matter of "getting in a silly mood" and blabbering stuff into the microphone until something made me smile.

>> Early compiling and preparing the game page

This is a thing that I learned to do since my first jam: If we want to ensure the game can be delivered correctly, we must be sure we can not just to run the game, but also that we can compile it and upload it to the game page. In our case, we worked with a custom compilation of Godot Engine. This is not a straightforward process and we had to dedicate at least one day playing around with parameters, compiling the engine and being sure the game compiled correctly. So when we were sure everything worked, we had plenty of time to just focus on developing the game.

It was also a good way to have early general feedback of the game, because as the only person developing software in the team, I would have been the only one running the game if we didn't do that. I created many early versions that I early sent to the team, so they could test if it worked or not on their computers. We found and fixed many aspects and errors of the game thanks to that, so I recommend you trying your game and send it to the team as soon as possible.

Also, especially if your doing a web export, it would be very good to start preparing the game page. It can help you to focus and determine the value of your game if you create your description and decide the most notable aspects of your game. And you'll be able to upload it and test it as soon as possible, detect early errors and be sure that you can upload in the last ten minutes without having to worry that much.

> Worth to mention

>> About the music

Marcus wanted to try to do dynamic music for the game. I already had some experience with Godot, but we found that FMOD (the privative music engine that we wanted to use) didn't had yet an stable implementation with the last version of Godot we could get at the moment (4.0.2). We tried a manual approach (changing between different tracks, stopping and resuming them manually) and it looks like Godot Engine did a very very great job, because you can't even notice the song changes (at least with a decent computer, please let me know for low-end machines). We were very lucky and simplified a lot the process for me.

Also, as a fun fact about the game: Every character has their own sound. For example, Sybil the bee does "bzzt, bzzt". As we couldn't use a dynamic music, Marcus sent me a bunch of sound files with the initial letters of the bugs in the filename, ordered alphabetically, and I didn't requested that, but I think it was beautiful and made it very easy to create a gigantic and a bit ugly array that was used to identify every combination of music:

var music_list: Dictionary = {
    "A": load("res://assets/audio/Gameplay Loops/01 Single/Gameplay-Loop-A.mp3"),
    "B": load("res://assets/audio/Gameplay Loops/01 Single/Gameplay-Loop-B.mp3"),
    "F": load("res://assets/audio/Gameplay Loops/01 Single/Gameplay-Loop-F.mp3"),
    "S": load("res://assets/audio/Gameplay Loops/01 Single/Gameplay-Loop-S.mp3"),
    "W": load("res://assets/audio/Gameplay Loops/01 Single/Gameplay-Loop-W.mp3"),
    "A-B": load("res://assets/audio/Gameplay Loops/02 Double/Gameplay-Loop-A-B.mp3"),
    "A-F": load("res://assets/audio/Gameplay Loops/02 Double/Gameplay-Loop-A-F.mp3"),
    "A-S": load("res://assets/audio/Gameplay Loops/02 Double/Gameplay-Loop-A-S.mp3"),
    "A-W": load("res://assets/audio/Gameplay Loops/02 Double/Gameplay-Loop-A-W.mp3"),
    "B-F": load("res://assets/audio/Gameplay Loops/02 Double/Gameplay-Loop-B-F.mp3"),
    "B-S": load("res://assets/audio/Gameplay Loops/02 Double/Gameplay-Loop-B-S.mp3"),
    "B-W": load("res://assets/audio/Gameplay Loops/02 Double/Gameplay-Loop-B-W.mp3"),
    "F-S": load("res://assets/audio/Gameplay Loops/02 Double/Gameplay-Loop-F-S.mp3"),
    "F-W": load("res://assets/audio/Gameplay Loops/02 Double/Gameplay-Loop-F-W.mp3"),
    "S-W": load("res://assets/audio/Gameplay Loops/02 Double/Gameplay-Loop-S-W.mp3"),
    "A-B-F": load("res://assets/audio/Gameplay Loops/03 Triple/Gameplay-Loop-A-B-F.mp3"),
    "A-B-S": load("res://assets/audio/Gameplay Loops/03 Triple/Gameplay-Loop-A-B-S.mp3"),
    "A-B-W": load("res://assets/audio/Gameplay Loops/03 Triple/Gameplay-Loop-A-B-W.mp3"),
    "A-F-S": load("res://assets/audio/Gameplay Loops/03 Triple/Gameplay-Loop-A-F-S.mp3"),
    "A-F-W": load("res://assets/audio/Gameplay Loops/03 Triple/Gameplay-Loop-A-F-W.mp3"),
    "B-F-S": load("res://assets/audio/Gameplay Loops/03 Triple/Gameplay-Loop-B-F-S.mp3"),
    "B-F-W": load("res://assets/audio/Gameplay Loops/03 Triple/Gameplay-Loop-B-F-W.mp3"),
    "B-S-W": load("res://assets/audio/Gameplay Loops/03 Triple/Gameplay-Loop-B-S-W.mp3"),
    "F-S-W": load("res://assets/audio/Gameplay Loops/03 Triple/Gameplay-Loop-F-S-W.mp3"),
    "A-B-F-S": load("res://assets/audio/Gameplay Loops/04 Quad/Gameplay-Loop-A-B-F-S.mp3"),
    "A-B-F-W": load("res://assets/audio/Gameplay Loops/04 Quad/Gameplay-Loop-A-B-F-W.mp3"),
    "A-B-S-W": load("res://assets/audio/Gameplay Loops/04 Quad/Gameplay-Loop-A-B-S-W.mp3"),
    "A-F-S-W": load("res://assets/audio/Gameplay Loops/04 Quad/Gameplay-Loop-A-F-S-W.mp3"),
    "B-F-S-W": load("res://assets/audio/Gameplay Loops/04 Quad/Gameplay-Loop-B-F-S-W.mp3"),
    "A-B-F-S-W": load("res://assets/audio/Gameplay Loops/05 Everyone/Gameplay-Loop-Complete.mp3"),
    "ending": load("res://assets/audio/Party Music/party-loop.mp3"),

So every time you talk with a bug, I add the bug initial to the collected_animals array, calculate a string alphabetically, in capital letters and separated with hyphen symbols. With that string, I can compare with the array keys and continue playing the correct music.

func get_animal_letters_alphabetically():
    var letters: PackedStringArray = PackedStringArray()
    for animal in collected_animals:
        letters.append(animal.substr(0, 1).to_upper())
    return "-".join(letters)

Also, I did it this way because using an array allowed me to keep the directory structure the same, so if any change came from Marcus in the same way, I could just replace the files easily. Another related fun fact: After testing it with different combinations, I found that there was one filename that didn't have the bug initials ordered alphabetically, so I changed it without telling anyone. 😁

Finally, the "ending" key is manually triggered when you return to the chiringuito and trigger the last conversation of the game.

Marcus note:

There is a fun little nerdy easter egg in there as well: Whenever I used reverb for anything, it was the digital reverb found in Sony's venerable first PlayStation. It being home to many of the first 3D platformers seemed fitting in this context, since we were, in a way, also figuring out how to build games in 3D just like the entire industry did so many years ago. And so the matter of simplification played an important role in the music as well. The human voice is the most widely found instrument on the planet. And it is capable of so many things. And I believe, keeping things vocal-based added to the "human touch" the game required. After all, we were also making an obituary for our friends. And rather than mourning their passing I believe we just wanted to celebrate their lives as they had given us so much joy in the time that they chose to spend with us.

And Marcus advice:

Synthesizers and orchestral sample libraries can be a looooooooooooooooad of fun, but sometimes the most basic things turn out to be the most fitting. An AAA-level pro musician friend of mine once gave me very valuable advice for working with others: Stand 100% behind everything you do but don't get attached. When it's not your place to make the call what best fits the project, then just go with the flow and trust that you will deliver. I always keep this in the back of my head and it has served me well. :)

>> About the dialogues

I still don't know how Marcus developed all the dialogues in just one hour or less. We were on the right track and doing a lot of work, we commented the kind of dialogue that we would like. After that, I sent him the format that I needed to use the Godot Dialogue Manager add-on and boom, he appeared like forty minutes later with almost all the dialogues done. Awesome!

He sent me this note after reading the previous comment:

I just have a weird mind! :D I've always loved coming up with stuff like that, it just comes easy to me. I was just happy that Ely and Enrique actually liked it. (Fun fact: When I was in kindergarten, my mom actually once got in trouble with one of the caretakers because apparently I was telling "silly stories" to the other kids that were quite "outlandish". But then again, socialist East Germany was not exactly known for encouraging individuality in people... ;) )

Let's just continue. 🙂

>> About the character steps and animations

Visual feedback is very useful for the player. Is not always easy to focus on this aspect when you're rushing through a game jam. This was my approach for the steps and animations.

>>> Steps as particles

I didn't know and I still don't know the best way to create decals in a mesh. I just knew how to create particles in Godot. So I just created two particle emitters below Keta with a small round black particle. Whenever you move and while you're not jumping, they spawn without any type of velocity and without gravity, so they just keep floating in the air until they disappear. And how did I do the alternating steps? Just adding one emitter at the front part and one at the back part of Keta.

Godot Engine screenshot showing Keta from below, with two particle emitters as described in the previous explaination. You can also see that the gravity values for the particle are showing zero on the three coordinates.

A cheap and easy way to make decals. If you noticed that Keta always starts walking with the same paw and you were thinking why, that's the reason.

>>> Basic animations

We didn't know and we didn't had time to learn how to animate with Blender in this jam. So I just used Godot's AnimationPlayer to create simple animations for walking and jumping. Just playing with different parameters, for example with scale, can give you a simple way to do a jump animation.

Godot Engine screenshot showing the first part of Keta's jump animation, looking a bit crushed. Godot Engine screenshot showing the second part of Keta's jump animation, looking a bit stretched up.

It's a good way to give movement feedback to the player if you don't have enough ability to animate or if you don't have time to deal with it.

>> Random last notes

  • We wanted to do a web version game, but Godot Engine 4.0.2 wasn't supporting them yet (again!).
  • I wanted to experiment with Godot's new version to see the lighting improvements. I had to learn a lot and we still have to release a version with the lighting improvements, so follow me on my social media or in Itch for more news regarding that topic.
  • I didn't sleep much those two weeks. Please, take care of yourselves and do better than me.
  • We called the first prototype of the game "Bug Island" and I got (and still get) confused many times and say it instead of the actual name.
  • The draft for this article was started on this date: 2023-04-26, 20:00.

> What now?

We want to continue developing a bit more our little game. We want to include different improvements, although I'm very reticent about doing a lot of changes to a jam game, because development can take a lot of time and you will not learn as much as you did on those jammy days. So we'll try to keep moving, one way or the other.

In our backlog priorities, we have:

  • Adding more props to the island. If you follow Ely on her social media (especially on her Twitch), you'll see her doing live modelling and painting for some of these assets.
  • Add more sounds and music, also improve the ones that we already have.
  • Fix materials and lighting, so we can transmit the ambience we wanted to transmit the first time.
  • Improve camera movement and camera collisions. 3D development is hard, help!
  • Free roaming, so you can wander around the island after the Spring Festival (Bug Fiesta™️©️) and relax.
  • Quality of life improvements, like being able to configure the music and audio percentage from an options menu.
  • Hopefully, if Godot Engine supports it, a web-based browser version. It's more easy to convince people to try your game if they don't have to download it (it gets worse if you have an alternative version for low-end computers as we do). 😉
  • Do a team logo. We just need it!
  • Many other things.

I don't know how many will arrive into a new version. From my side, I'd like at least to do the first three of them. We'll have to see! 😊

Godot Engine screenshot showing the recent changes in lighting for Bug Fiesta. You can appreciate some water foam in a Voronoi pattern reflecting in the water, the colors look brighter and more balanced.

> And that's it!

I hope you enjoyed this first devlog. I spent so much time writing it. I think there's no conventional format for devlogs, but if you have any feedback, please, reach me on social media, because I'm open to receive the constructive one.

I hope you have a great day, we'll be waiting for you in...

Bug Fiesta's preview screen, with a big title letters at the foreground saying 'Bug Fiesta'. You can see a beach in the background with a dock and a small boat above it, some sandy dunes, a chiringuito and some milk packaging-shaped small buildings far away.

>> Try our game!

(Suggested donation to download is 3$, that would be one dollar per author, but you can download it for free without any problem!).

>> Video summary

Please, take into account that this recording only contains game prototyping and footage of the jam development and the week later. Check it pressing on the preview image below!

Preview image for Bug Fiesta's video called 'Bug Fiesta: From zero to developed', in which you can observe a splitted image, half of the image with the first previews of the development process and the other half with an image of the finished process.

>> Article versions

  • 1.0 (current) - Published article!
  • 0.2 - Second draft with applied feedback!
  • 0.1 - First draft!