Polishing the Dog House! Woofice Chair’s Juice and Polish!

Polishing the Dog House! Woofice Chair’s Juice and Polish! Post Banner

Whenever we participate in a game jam, one of the core aspects people always compliment us on is on polish. With the release of Woofice Chair! those compliments came back around and we are very proud of receiving them again!

But what is this dark magical art that people call polish? And what about juice? While both are regarded as something to highlight in jam games, we believe polish is deeply connected with gameplay. Polish not only helps give a game a more complete-feel, but also helps making gameplay more satisfying to the player!

In our previous Ludum Dare entries, we always tried to force polish. This was done by adding in menus, pause screens and tweening as much as possible. While those helped the games feel more like a complete package, in hindsight, we feel the time spent on those could have applied more to the gameplay itself. With our latest entry, all of that focus with polish was put into the core game!

Through this development insight, I’d like to go over some tricks that we used in Woofice Chair! to make the gameplay feel extra good. While polish varies from game to game, there are common tricks that can be applied in all games! I hope some of these work as reference for what you can do with your own game’s polish!

Cameras! Screenshake! Freeze Frames! 🎥

In any article or video that you see about juice, camera smoothing and screenshaking are always mentioned! Being the window of the player into the game, it’s one of the easiest things to manipulate to help represent something is happening and add extra satisfaction to an action in it.

With Woofice Chair! we decided to experiment using the Cinemachine package from Unity to help facilitate camera actions. However, any of these ideas are applicable on their own using the default cameras in whatever game engine you’re using!

Camera Smoothing!

One of the first tricks we applied with Woofice Chair! was making the camera’s movement smoothed-out. Having the camera be constantly snapped to the player works, but doesn’t translate the concept of acceleration properly! And our game is all about that!

Using Cinemachine, we can add a bit of lookahead and smoothing when following the camera’s target. This makes it so the camera has some delay in its movement before catching-up with the player, improving the sense of acceleration. You can also achieve this same effect by code by using a Lerp.

Screenshaking!

Another major trick with cameras is screenshaking, used when there’s a ‘violent’ motion in-game. In Woofice Chair!, we use screenshaking whenever something causes the dog’s chair to suddenly lose speed. These include knocking into walls and obstacles or being hit by an enemy. 

Implementing screenshake is not an arduous task either. You create a function that changes the camera’s X and Y position randomly relative to the player over some frames. Then you can just call that function whenever an action benefits from screenshaking! Cinemachine already comes with a set of Noise properties that achieve the same effect and can be controlled by code. 

Something to note is that, with our non-game-jam releases, we make sure to make screenshake togglable in the settings. Even when balanced to not be too distracting, screenshake can cause nausea to some, and a toggle to turn it off is a nice accessibility inclusion.

Freeze-Frames!

Another method we employ with the camera are freeze-frames. Freeze-frames completely pause the game for a few frames to bring extra impact to an action. In Woofice Chair!, when you knock-out an enemy, the game will pause for a few frames, enhancing the satisfaction of doing a knock-out. It also gives you time to see the knocked-out sprite of an enemy before it’s flung off-stage.

You should use Freeze Frames sparingly! In our game, we added a short cooldown after each set of freeze-frames before they can happen again (less than half a second). This is to make sure if you defeat enemies in quick succession, it feels like a deliberate effect. Repeating the effect too often or making it too long can make it seem like the game has performance issues.

There are many more tricks when it comes to camera work, including screen flashing, zooming the camera in and out depending on the situation, and more!

Giving Players Feedback! ✨

While developing Woofice Chair!, we wanted to make sure all actions that the player takes felt tight and responsive. Controlling the chair should feel satisfying and hitting the enemies even more so! While the camera techniques go a long way, there are more ways to give the player feedback from their actions!

By using a combination of assorted effects, shaders and animations, you can make otherwise static instances and effects come to life!

Input Feedback!

One of the simplest ways we give feedback to the player is by displaying a sprite over the office chair whenever the player presses space to accelerate. This sprite shows some speed lines with animation that imply the player is rotating the chair. By giving a player a visual indication of their inputs, you gratify them with immediate confirmation!

Not only do you get the speed lines, but the rotation animation of the chair also loops faster with the acceleration. We also added Trail Renders to the wheels of the chair that increase their distance the faster the player is going. These, together with dust particles that appear whenever the player does a sharp-turns, give extra satisfaction to the player controlling it.

By mix-matching types of sprites, particles and other features that your game engine has, you can improve the satisfaction of the player doing their inputs! And that applies to the UI too, with buttons changing colours and sizes when hovered or clicked over! Make sure the player really likes pressing those keys and buttons!

Flashing!

We made it so certain objects would flash here and there to call quick attention to them! Sharp changes in sprite colours and tints are an easy way to give feedback to the player that an action has been performed.

These are done when there’s a successful hit against an enemy, or whenever the player gets hit! In Woofice Chair! we use sprite flashing when the player hits a buff-animal, causing them to flash white for a few frames, confirming a hit. If the player gets hit, its sprite flashes a bit between opaque and transparent indicating that they can’t speed-up.

It’s important to note though, If you’re going to flash the whole screen, consider that it can actually cause discomfort to players. If you must add them, use them sparingly or even consider adding accessibility options to disable said feature!

Depending on your engine, these flashing effects can be straightforward to setup! For example, in Unity, if you’re using a render pipeline, you can set up a shader graph shader for different types of tinting effects. In our case, we followed the tutorial by Code Monkeys to replicate the shader that we use! We also mix these effects up with some AnimationCurve and Gradient to setup the rest of the effect.

Outlines and Tweenings!

When an enemy is defeated in our game, they’ll drop a weapon or a score biscuit of various types and shapes. For these, we use a white outline to denote their status as a pick-up. With this outline, these pick-ups stick out from the background, and also from both player and enemy.

By pairing the outline with a bouncing, positive tweening animation, these pick-ups immediately attract the attention of the player. They’re always there for whenever the player feels like swapping weapons and to remind them to pick-up biscuits!

Animations, as mentioned previously, are one of the easiest ways to add juice to a game! Through the animation systems for each engine, or through a dedicated tweening library, it’s easy to go an extra mile and add a bit of tweening to some more static elements! Make sure those pick-ups really stand out!

Sound Design goes a long way! 📢

For this Ludum Dare, we chose to use FMod as an audio middleware! If you’re unaware of FMod, it is a special audio engine that uses an external studio editor to setup audio events, and plugs it on top of both Unity, Unreal or direct-code integrations.

The benefit of using a middleware, compared to the built-in audio engine, is that you have more control over several audio aspects of the game! With FMod, you can use parameters to dynamically tweak aspects of the game’s audio work in a more flexible way, allowing for more audio polish. If you’re going to use an audio middleware like this during a game jam, you’ll most definitely need a dedicated audio team member!

One thing to note though is, if you want to use FMod in your game jam games, you need to make them non-commercial (including donationware)! If you want to get revenue from your game, you’ll have to register your game on their portal, with max of one game a year for free.

Dynamic Music!

If there’s one thing with audio that’s always been a hot-topic and an aspect players appreciate immensely, it’s dynamic audio! Dynamic audio works by either crossfading tracks, or adding in instrument layers depending on the actions that the player is doing in-game. It creates an engagement loop, where the player wants to keep a combo or an action going to get a more satisfying beat! 👏

For Woofice Chair! , we tied the rotation speed of the chair to assorted layers of instruments that make up our main music track. The faster the player is spinning, the more happy and instrumental the track gets. The moment you get into lower speeds, or crash the chair, the music lowers until silence. Also, there are ambient sounds to really sell-in on that park atmosphere.

Remember that dynamic audio needs to be thought ahead of time, and settled in with the audio team member as soon as possible! If a music composition is planned ahead of time to have layering instruments, its easier to break it into dynamic pieces!

Sound Variation!

Another audio aspect we are particularly proud of is the weapon hit sounds! In fact, we could argue some like the meat-bone sound very… juicy! Terrible puns aside, the weapons sounds have been one of the aspects people have praised the most regarding the sound design of the game!

We broke the repetitiveness of weapon hit sounds by having a different sound for each weapon. A newspaper doesn’t sound the same as a blunt bat! And to go one step further, each weapon also has three to five sound variations paired with small pitch variations! That way we assure they always sound new when you first hear them!

By using slight variations in sound, even if they’re just pitches, you can make them feel a lot less repetitive! While we used FMod to set this randomness up, you can use a script together with an Audio Source. From there, you randomly change the pitch and pick a sound to play whenever you want varied sounds!

Themed Audio!

Picking the correct sounds for the right project is a very important aspect of audio design! In a rush and without a dedicated audio person you can always settle for the first sounds you find. Although, if you do have the possibility to spend more time researching audio, then the more theme appropriate your sounds are to your game, the more impact the audio will have!

The most notable example is, when you pick up one of the aforementioned pick-ups in the game. When you equip any of the weapons, you’re rewarded with a very satisfying dog bark! Might seem like a minor detail, but since you’re a dog riding a chair, it feels appropriate! Samewise, when you are hit by an enemy, you hear dog whimpers. It’s saddening, so protect the dog at all costs!

Depending on the game that you’re working on, different sounds will be needed for different situations. If you’re doing a game involving puzzles, feedback whenever you interact with the game’s mechanics will feel like extra juice to the player. The same can be said regarding any genre’s game. And there are always multiple ways to go around getting sounds, such as using BFXR for a retro-themed game!

The Dog is in the Details! 🐶

One thing that we’ve realized as we’ve participated in game jams, is that a lot of the small details together make the most impact. While the polish techniques mentioned over the past techniques make an impact, these are the things that really give that warm feeling of “having paid attention to detail”!

Executable Icons!

One thing that is immediately noticeable before you even boot up the game is the executable icon. If you’re using a game engine like Unity, swapping the executable icon is a matter of assigning it an asset in the build settings.

While most leave it as the default during game jams, it’s pleasant to see changed up during a jam! If you build a set of folders for rating like our team does, it can be a very easy way for people to identify your game! Plus, it’s likely the first thing they’ll see of your game, so make that first impression count!

Pick on any asset you’ve done for the game, assign the sprite, and you’re already sticking out from the crowd!

Cursors!

Another small detail that hits home for players and is always a pleasant surprise is having a custom cursor! If your game uses the mouse for the menus as the main input then it’s nice to have something that turns that boring default cursor into something more thematic! In the case of Woofice Chair! It’s a clear as day dog paw, complete with a comfy pointing finger!

There are different ways to implement cursor images depending on the engine that you’re using and your preferred methodology. Engines like Unity also allow you to specify a hardware cursor, where a texture pretty much replaces the default OS cursor while still running at the screen refresh rate. 

However, if you want more control, you can make a software cursor. That way, the cursor will be an image in-game and updates at the refresh rate of the game. The benefit of a software cursor is that you have more control over it. For example, you can make it any size you’d like, rather than be restricted to 64×64.

The Game Page!

And finally you can also polish your actual game page! Yes, the place that you upload your game to! While previous advice aims at in-game content, the game page also helps you make a very good first impression on the player! Since this article is meant for game jam games, we’re not talking about Steam pages or any commercial pages, but rather Itch.io’s!

If you’ve only uploaded a few jam games to Itch.io until this time, chances are that the default page editor will be enough! Change a few fonts, give it a nice background, and even spice the description with a few custom header images! Ta-da! You have a nice looking page!

If you want to go an extra mile, you can contact itch.io staff to have CSS customization enabled. This essentially unlocks any web customization rule that you’d like to use freely with Itch.io’s existing layout! You can change individual header fonts, add hovers, custom cursors, etc. and really strive to make an impact! We advise that you stick to the customization guide, to assure that you don’t break other features of the page while at it.

Finally, while Ludum Dare doesn’t allow much for customization within the site, you can still use some tricks you’ve used for the itch.io page here! For Woofice Chair!, we used paw-print separators to divide different sections about the game. We also used the same custom headers we made for the itch.io page, and put them to use there! You can also add some section-cap GIFs between sections to really attract people to your game too!

The game page can also be worked on past the submission hour of the jam! You always have the chance to come back and polish it up with new screenshots or touch-ups!

Wrapping it up with a shine! 🎉

And that’s a wrap up! Hopefully this development insight has given you ideas about how you can add some polish and juice to your game. All of these came from the way we did them in Woofice Chair! Their implementation always varies from the type of project, theme and controls!

One thing is clear though, is that there are a ton of different ways to go about doing it! While it might be hard to find the time to fit this sort of detail into a project during the time-frame of a game jam, they really go a long way striking an extra smile on players and jammers faces! If you ever find the time in-between tasks to add that lil’bit of extra polish and juice, I dare say go for it!

Discord Banner

On behalf of our team at Whales And Games, if you ever want to talk about game development or the ways you do polish your own games, you can hang out with us at our Discord server!

We hope that you had a fantastic time during this Ludum Dare! While we still don’t know if we will be around to participate next time, we certainly look forward to! See you next time and cheers! 🐳

Art Fight 2020 Post Mortem – A Spicy Art-Sharing Duel!

Hey there! It’s hard to believe that this year passed so fast that we have already participated in an Art Fight event again!

Just like last year, we want to offer some artist insight, and since I, Moski, am the lead artist that’s in charge of the art-side of things around here. I’ll be telling you all about Whales And Games’ participation in Art Fight 2020!

In last year’s post-mortem, we explained what the Art Fight event is, our reasoning to participate and our overall experience taking part in it. But things changed a lot with Whales And Games since last year, which in turn affected how spicy things got this past July! Let’s get into it and see, shall we?

Moski Profile in Art Fight

Starting from the top and recapping from last year, Art Fight is an event where artists get selected into one of two different teams, submit their own original characters and score points for their team by drawing characters belonging to artists from the rival team. It’s two teams drawing characters from each other for a whole month, which results in one of the most wholesome art-trading wars that you can participate in on the internet!

Clip Studio Paint open in an Attack
‘Y2K’ by Akumanorobin

This time around, since we wanted to take the opportunity to wrap up some of the ideas from Whales And Games and Bunny Copulation, we decided to participate in the event by updating our character sheets as well as creating some new ones for characters from both brands. I also wanted to improve my skill on my new drawing program of choice, Clip Studio Paint, which I had recently switched to from Krita for both promotional and game artwork. 

At some point, we thought about a twist to wrap up the event and, well, things went off the rails in the best way possible, merging both our artwork and game development prowess together!

Art Fight Duel Gameplay Screenshot

In this year’s edition of Art Fight, the teams to choose from were between Sugar and Spice. I opted to draw under the flag of Spice out of preference, and, before I knew it, I was creating art left and right!

Art Fight Teams for 2020 Sugar and Spice

Character Sheets and Artwork! Just the usual…?

For Art Fight 2020, we wanted to update a lot of our characters to properly reflect how we’ve evolved since our first participation. Last year, we had plenty of sheets for people to draw built from previous promotional and game art, but we hid them all at the beginning of the event to make new versions of them. 

These new versions, featuring completely original new art created just for these sheets, took a lot longer than expected, eating away the first two weeks of the event. However, despite the delay, they allowed us to introduce some brand new and freshened up designs for several of our mascot characters! Whalechan and Dapperchan are now officially looking nicer and dapper than ever!

Once we finished the character sheets, it was finally time for me to create some awesome art. Since we needed to make up for the time lost, we decided to start strong, picking characters from pending revenges from last year and bookmarks (found by randomly hopping around users) that we thought looked striking. My first piece of art featured an animated background, and as soon as we uploaded the attack, we started getting attacked as well, which was great! We liked the final result of the first attack so much, we made it a goal to animate every attack from there on out. 

Showcase of Attacks for Art Fight 2020
‘Y2K’ by Akumanorobin, ‘Mr. Crow’ by Kun (Ceshoh), ‘Prisma’ by Greteh and ‘Ahvi’ by Wearepopcandies

Halfway through the event, we had finished 6 attacks. We roughly had around 15 by the same time in the previous year. I originally intended to continue making standalone artwork until we were done, but then, we had a wild idea.

Art Fight Duel Gameplay Screenshot

Art Fight Duel, an actual playable game?!

As we were midway through the event, we conceptualized an actual playable card game based on Art Fight. Art Fight Duel, with a pitch document written and all.

I didn’t sleep that night. It was just the perfect mix of, well, everything! We’re game developers and artists, it was a game that involved both Art and Fighting, it could feature over a dozen artists, put some of our own characters into a new game, and it could be just the thing we needed to reignite our game development spirit!

Art Fight Duel Title Screen

From the moment we had the concept down, we decided to make the game rather than to continue making artwork for several reasons:

  • A game jam sounded like a very innovative idea for the event, since it’s usually reserved for finite pieces of artwork. Turns out, it was very novel, since more people made games about Art Fight this year too.
  • The game pitched card game mechanics mixed with auto-battler mechanics. This resulted in the possibility to add as many characters as we could and putting them in a setting where they were actually fighting. Thematically, it made perfect sense with the event.
  • It made use of a lot of concepts from the history of the event. Art Fight Duel is team based, just like its namesake. We also added affinities based on previous event themes and a few nods to things that are well known by the event’s community and past participants.
  • We had the opportunity to put some of our new character sheets to use. Finally, we were able to give Whalechan (and Dapperchan) a proper participation in a game!
Showcase of Sprites for Art Fight Duel
‘Dapperchan’ by WhalesAndGames, ‘Ricketby Nights2Dreams and ‘Penny by CuckyUncle

The execution of the development didn’t go flawlessly, but the result speaks for itself. By spending every single day of what was left of the event in developing the game, we managed to feature 20 artists, with animated sprites for all the 24 featured characters. We took heavily into consideration their designs and bios when creating their sprites, attacks and stats.

We submitted the first version of the game in the last two minutes before Art Fight was over. No stress! After the event, we spent some extra weeks tweaking and adding in audio, a proper title screen and our usual settings and credits, bringing the game right up to our jam-standard!

Art Fight Duel Gameplay Screenshot

Art Insight, Learning and Results

We wrapped up Art Fight, and I was finally convinced that switching from one drawing program (Krita) to another (Clip Studio Paint) was the best thing to do at this point in my artist career. 

Clip Studio Paint open in an Attack
‘Hoshiri’, ‘Jax’ and ‘Makuru’ by PurplePlatypus73

While I didn’t learn as much as last year, I still tried to innovate in my style in some aspects:

  • Layer Clipping – There are many methods to mask and group across different drawing programs. Due to the limited time, I needed one that could be easily organized and managed quickly. In Krita, I used Alpha Inheritance to create shadows, but it required pesky layer management. In Clip Studio Paint, Layer Clipping does similar results in a more simple fashion.
  • Airbrushing I had practised with airbrushes before, but I wanted to experiment with it here too, with great results. Turns out they get along great with Layer Clipping and help give a nice-finish oomph to my pieces!
  • CSP’s Asset Library – My new drawing program comes with a community-driven marketplace where people can create tools and assets. In a few situations, I wanted to make use of some brushes from there, and so I learned how to properly download and install them.
  • Masking – Similar to Alpha Inheritance and Layer Clipping, Masking allowed me to work with each artwork in non-destructive ways, delimiting the areas where some layers could be visible. While one would think that they’re all just different ways of doing the same thing, it turns out that combining either of the two with Masking allows for fantastic results.
  • Special Layers – For some pieces, I needed to experiment with things that I could easily do in Krita which I had not been able to replicate on CSP yet. 
    • One of those was halftones. While not the same, I found out that CSP has full functionality for Tone Layers, which allows making layers filled with simple patterns and which helped me create some fancy effects. 
    • I also learned about Object Layers, which are like Photoshop’s equivalent to Smart Objects. These allowed me to put files in a layer and be able to resize them without destroying their properties.
Clip Studio Paint open in an Attack
‘Mr. Crow’ by Kun (Ceshoh)

Beyond Art into Game Development!

Beyond the standalone artworks, Art Fight Duel represented equal opportunities to learn differently. It helped me understand things I could do better on Krita before, like the character sprites and the use of mirroring tools. However, I did end up using pretty much the same techniques for the duration of the development, as there were not as many opportunities to try new styles.

Clip Studio Paint open in the Art Fight Duel background

Aside from its artistic point of view, there are some takeaways to explore too when it comes to the development of the game. While we had previously discussed considering making a game for Art Fight, it didn’t become a serious consideration until late into the event. Yet, once we got started, we couldn’t stop.

We did as much good to Art Fight Duel as it did to us. It had been a long time since we last made a short self-contained game, and it felt fresh to go back to that. We chose a genre we have never challenged and went with mechanics we had never used. Since Art Fight is an endless ocean of characters, designs and concepts, we rarely had troubles in finding any particular thing that could fit any of our design’s needs.

Art Fight Duel Gameplay Screenshot

As a result, Art Fight Duel became one of our most ambitious games, mixing strategy, fast-based mechanics, a distinctive style, and plenty of cards. Plenty of the people who had their character featured in the game have been pleasantly surprised. Given the circumstances, we’d say that the game was quite popular among the social circle it was made for, and it has plenty of opportunities to grow!

However, since it had been a while since we last developed a short self-contained game, we heavily under-estimated the implementation of some features. As a result, we had to spend some extra weeks following the end of Art Fight implementing quality-of-life inclusions such as settings and audio without otherwise would make the game feel lackluster.

Art Fight Duel Settings Screenshot

With us participating in Ludum Dare 47 in the coming week, and with Bunny Splash Casino resuming development, it’s important we take these short-comings into consideration, and make sure we prepare in advance. For example, features such as re-usable settings menus can be prepared ahead of time of the event to avoid spending precious jam time adding basic quality-of-life features.

Art Fight Duel Gameplay Screenshot

Numerical Feels-Good

Spending so long in making character sheets and changing gears from making artwork to making a game jeopardized our opportunity to receive cool artwork a bit, and ended up receiving less artwork than last year. However, the game was fantastically received to the point that it even got featured! 

Art Fight Duel featured in the Art Fight Website

Aside from that, and just like last year, there are still numerical results we’d like to evaluate, and which help us gauge our participation and performance in the event:

  • My account has 1124 followers at the time of this post. It had 401 last year, so that’s a massive leap! It helps that this year we knew about the event in advance, which allowed us to network ahead of time.
  • This year, I made 6 drawings and one Mass Attack in the form of Art Fight Duel. Last year, I made 26 drawings. While I had less to show than last year, all of it was animated, and the game was a great success!
  • We updated 6 of our 12 character sheets from last year. Aside from that, we finally closed-off Whalechan’s new design, formalized Dapperchan and showcased a bunch of new Bunny Copulation designs!
  • We received 42 defences. That’s lower than last year’s 60. This is the result of roughly being “active” for a lot less than last year, since we were busy with the character sheets and the game. But the notoriety of making the game should cause some interest in 2021!
    • Of those 42 defences, the Whalechan redesign was the most popular, getting 15 defences, with Buns Buns following second at 11 defenses.
    • Bluessom triumphed over Jazzy this year, with 5 versus 3 defenses.
    • While other participants were quick to fall-to-love with Whalechan’s ​new design, Dapperchan still needs to warm up to people, as she only got 3 defenses overall.
    • Some characters which we didn’t even do new sheets for, such as Caffie and Mr. Woofman, got 1 defense too!
Showcase of Defenses from Art Fight 2020
‘Dapperchan’ by Orange-Kiwi, ‘Whalechan’ by Tianmasaki, ‘Buns Buns’ by Minimep, Cheqmate’ by Reinsroom, ‘Autumn Whalechan’ by Amuerion, ‘Cheqmate’ by Sosha, ‘Whalechan’ by Akumanorobin and ‘Jazzy’ by Sckookum

Feelings and Emotions

While the experience overall was fantastic, Art Fight occurred in a very tumultuous moment for us. At times, it was difficult to grasp that the expectations and the reality didn’t match up perfectly. However, it was also proof that some of the best things in life are not really planned, and that even when plans don’t match expectations, one can have a great time.

Clip Studio Paint open in an Attack
‘Prisma’ by Wearepopcandies

Last year, I came to the conclusion that I really enjoyed drawing characters. And I still do, perhaps even more, but the experience came around with the idea that I’ve also got to grow in maturity. The novelty of having this brand-new event was gone, and we needed to up the ante. This resulted in us participating in the event as if it was a self-imposed opportunity, and wanting to make the most out of it across character sheets, thumbnails, animation and even a game. Rather than treating Art Fight as a leisure, as we probably should have, we ended up feeling fatigued as the days went by.

However, doing art leisurely or for the sake of improvement are not necessarily contradictory statements. The saying says “find a job you enjoy doing, and you will never have to work a day in your life”. I’d say that’s partially true, but one has to also cope with things like health and fatigue, and adjust accordingly. But even when things go dire, I really do like drawing. I may be older than the average participant and have been doing art since my teens, but drawing fun, interesting characters is still part of my DNA.

Showcase of Attacks from both 2019 and 2020

Final Remarks

Applying my artistic skills to make an actual game really opened up the possibilities of what I, and we can do during Art Fight. Regardless of making regular artwork, animations or even games, it’s important to play to one’s strengths at times, but also to take risks in others. I don’t feel so bad about having missed out on doing more character artwork when I see that people really enjoyed playing the game.

Unity open in an Attack
‘Ahvi’ by Greteh

We have evaluated the possibility of making it a tradition to update Art Fight Duel every year, with new mechanics, adding content to match the new themes, and, of course, even more characters from more artists! We still need to make more character sheets, and, if things go right, we’ll be plenty busy with Bunny Splash Casino alongside it. For now, we’ll wait and see, but it’d be a fantastic time to update it going forward!

Showcase of Defenses from Art Fight 2020
‘Whalechan and Polite Whale’ by Sweetkooky, ‘Bluessom’ by Mantiskin, ‘Buns Buns’ by HammyandFriends and ‘Whalechan’ by Esmahasakazoo

For the time being, I’ve got a whole year ahead of me to further polish my skills so that, if I do join Art Fight next year, I am even better than I was this year! Even if fatigue or personal worries get in the way, I still see myself creating artwork for the foreseeable future and I’ll do my best to enjoy it.

That will be something to look forward to! For now however, we have to prepare for Ludum Dare 47, and the challenges our new commercial projects bring us! Thank you for reading and I hope you join us along for the ride! Cheers! 🐳

Scripting Super Sellout’s Sponsors and Behaviours!

The first week of the Ludum Dare rating and judging season has passed! Time certainly flies when you’re busy playing and rating different entries, preparing material to be posted, and recovering sleep due to the unescapable claws of self-inflicted game jam crunch. Sounds like our usual way of doing things here at Whales And Games indeed!

We were expecting to post a blog post going in-depth about how the characters for our latest entry, Super Sellout (which has just smashed our last entry’s record!) were created in terms of art, but unfortunately, our artist has gone internet-less for the weekend and just recently recovered it, meaning that probably for the first time ever, our first in-depth blogpost will be about the programming instead!

So let’s dive right in! This post goes into the technical deeps on how the different Sponsors in Super Sellout were made, how the scoring system of the game works, and the overall benefits of Scriptable Objects and why we keep using Unity! Hope you’re ready, because it’s a long one!

We’re still in ? with Unity

In case you haven’t seen our latest in-depth programming post from Jazzy Beats, our team at Whales And Gamesmostly develops projects through Unity. At least for me personally, it has been my engine of choice for five years and, as expected, I’ve grown comfortable with it in terms of workflow. Our other programmer, Kroltan, has also got some experience in Unity but also has his own hand-full of qualms with it. Our IDE of choice is Visual Studio, and Kroltan utilizes ReSharper on top of it. Visual Studio is pretty much the standard IDE for everything related to programming, being utilized together with other game engines beyond Unity (such as the Unreal Engine) as well.

For this edition of the jam in specific, we decided to risk it and utilize the beta of Unity 2018.3, hopefully to get accustomed to utilizing the new nested prefab workflows that are being introduced in this version (at long last!!) for development. While we did catch a few crashes here and there, and a lot more of them than usual, if we hand’t decided to stick with this version, we probably wouldn’t have been able to properly complete the game during the allocated jam time.

While our post on Jazzy Beats was mostly about Inheritance and how different behaviours were inherited by different characters to perform different actions, with Kroltan‘s inclusion in the Whales And Games team we’ve been trying to do things a lot more through composition. This means, breaking much more behaviours into Components and more specifically, some very underrated data containers in Unity called Scriptable Objects, which allow for fast data management and insertion without necessarily affecting the rest of the game’s structure.

Scriptable What? ?

If you’ve been following Unity in the past years, then certainly you must have already seen them trying to promote the concept of Scriptable Objects through articles, tutorials and talks especially during the last year. While they certainly have been around for a while, there’s still a lot of potential case-scenarios where people could be using them but end up utilizing the standard tools instead. We were guilty of this too, and only recently with us rewriting one of our past Ludum Dare projects for a future update we’re planning did we realize just how handful they can be.

In a short explanation (you can read everything about them in the documentation), Scriptable Objects are essentially instances of classes that can be stored and re-used as if they were assets. If you’re already accustomed with C# and using it in Unity, you’re probably already accustomed to the idea that you can have classes dedicated to holding data without them necessarily having to inherit from Monobehaviour.

Scriptable Objects take this concept further by allowing you to create these data classes as if they were project assets, rather than having them be created by either code, or exposed to an inspector through Monobehaviour. These data assets can then be added to other behaviours, read from the project, etc.

Our Sponsors in Super Sellout utilize Scriptable Objects. Each different sponsor is a different asset, composed of their name, icon, explanation, how many rounds they take to unlock the sponsor, etc. While you can add logic to Scriptable Objects, we strive to keep all of the logic that is not relevant to the concept of the object itself (such as creating objects on the scene, storing runtime values associated with it) on the Scriptable Object class itself. This allows these objects to be independent on their own, serving only as data references, meaning that all of the state related to them (such as if a Sponsor is equipped or not) is stored elsewhere, and not keep with the Scriptable Object when it is serialized and deserialized.

(It should be noted that Scriptable Objects show the Unity standard asset icon by default, whereas we display icons thanks to the Asset Icons extension available on the Asset Store.)

As such, what we do is add all of these sponsors to our GameManager and then utilize that list through the game. The sponsors screen is the best example of this. All of the buttons for the different sponsors are created at runtime, and the icon and name of the sponsor are filled-in at the start. This would allow us to scale this screen and system infinitely if we wanted. We’d have to make graphical changes to accommodate, but we wouldn’t have to directly change anything in the logic itself if we were to add more sponsors.

Each sponsor is delegated to these buttons by creating their EventTrigger when the buttons are instantiated, keeping all the logic in a single place. Sponsors that are picked by the player are then added to another list that keeps track of the sponsors that the player has equipped, and removed accordingly (such as if the player changes their mind on the sponsor equip screen). This list is frequently checked, and helps establish the magic of the following section.

With the sponsor system in place, and with the UI and GameManager wired in, the next part is to wire the different sponsors to actually affect the different facets of the game related to them.

If you have played Super Sellout by now you will have understood the whole gimmick of the game is that you sacrifice movement and your comfort while playing (which we so called sacrificing your integrity) by enabling different sponsors that cause a variety of different effects and obstacles to react to you in exchange of getting an higher score when you rescue people throughout the game (and depending on some sponsors, even based on time you have left).

It’s also worth noting that most Sponsors also have different cosmetics that are overlaid on top of the character. These are stored in arrays together with the rest of the Scriptable Object, and are checked every frame to check if the cosmetic frame matches the one of the current player’s frame.

There are a few gimmicks that are standard and re-used through the game due to the limited time-frame that we had to put the whole game together. For each of these sponsors, their logic is kept in different places, most notably being the ones that the sponsor affects. Sponsors that affect a player’s abilities or controls are kept together with the player, while sponsors that affect objects are kept with those objects.

One of the most standard gimmicks, for example, is the speed reduction gimmick with different sticker sponsors you can add to you which reduce your character speed (while keeping the world speed increasing as always) in exchange of score over time. Being a sponsor that affects the player, the logic for the sticker sponsors are kept together with the rest of the player’s scripts under a PlayerAffects class.

When the game begins, the scripts checks through each of the sponsors to check if they’re activated, and applies the correspondent speed reduction, reducing the player’s speed on the spot. The same is done for other sponsors that also affect the player, such as the Dog Sitters sponsor which applies random forces on the player’s velocity at regular intervals.

As for other behaviours that are affected by sponsors, such as metal objects following you, the check is done on each individual behaviour instead. One such example is the MoveToPlayerBehaviour which causes both metal objects and the dogs to follow the player if their sponsors are active. These perform a similar check to the previous speed-affecting behaviours, checking if the sponsors that are needed to run that behaviour are equipped by the player, before actually executing it’s logic in Update.

Finally, there are the sponsors that make certain objects appear on the stage if they are enabled, such as the billboards and the different puddles. Just as you might expect given the way the logic of the previous objects is checked, these are actually placed on the different rooftop segments ahead of time (or are spawned in at randomly on places dedicated to random obstacles). Once the game starts, they make the same check on ConditionalObjectSpawn likewise to the following behaviour, and depending on the result, choose to disable the object (if the sponsor is not equipped) or leave as it is (if the sponsor is equipped).

If we were to look back and think of a few ways we could have improved the way sponsors are managed and utilized throughout behaviours, we could have potentially done a single SponsorBehaviour class (for objects other than the player) to hold the checks if a sponsor is active or not in a single-place, and then inherit that class to add each specific behaviour.

Inheritance isn’t inherently (heh) bad, however it can very quickly lead to a complicated upkeep of classes and deeper-than-they-need-to-be inheritance levels on top of the classic diamond problem. However, depending on very specific situations, they can potentially reduce project complexity as well, making it a double-edged sword. However, that’s beyond the scope of this post, and instead we will be talking about dough, moolah, simoleans, money, because at the end of the day, that’s the scoring of our game.

Money Dough’ and Scoring ?

Similar to the SponsorsScore Types are also a Scriptable Object in our project. This allowed us to create different score types and rates that are affected by the different behaviours and actions without having to individually declare each of them by code and creating adequate functions. Instead, having them as Scriptable Objects allow us to re-use the different score types, and even derive score types from each other.

We wanted to have a score breakdown screen, and for that the game needed to track where each amount of score came from. We started by making some Scriptable Objects that had some basic information about each score source, where, for example, one “Grandma Saved” would be worth $10. That worked perfectly for simple proportions, but for anything more complicated it was a bit limited.

When sponsors started being implemented, we carefully employed inheritance and created a new kind of Derived Score Type, which in addition to the base multiplication-based monetary value (where each score-type adds a certain amount of score each time) can query the value of other score types to calculate its final value. This was used in some sponsors, which awarded money proportionally to a specific type of heroic act or time.

This approach allowed quick balancing by non-programmers, as well as a clean implementation for the graphical interface, which didn’t need to differentiate between derived and pure score types. It also allowed us to quickly connect any given Sponsor or character in need of rescue to a score-type, and implement them on the scoreboard without any new overhead. Of course, even with such systems in place, there was still a lot of content ideas that had to be cut.

The Cutting Room Floor ✂

Even with all these systems in place, there were still a lot of ideas for different sponsors and modifiers that didn’t make the final cut into the game due to it’s scope. Here are some highlights of these ideas in order to not extend this post by much longer but that we still wanted to share for pure curiosity:

  • Sponsors that would invert or change your controls to random keys.
  • Sponsors that would make you be followed by bees or ghosts, stunning the player when they caught up with them.
  • Sponsors that would play startling sounds every now and then to keep the player on their toes.
  • Sponsors that would cause characters to randomly interrupt the game and talk over it, allowing as little visibility as possible.
  • Sponsors that would add way more visual modifiers to the game, such as making the whole game grayscale, make it look retro, etc.
  • Sponsors that would hid how much money you have achieved or how much time you have left.

With the current system in place, we could theoretically add these new effects and scenarios without much challenge other than creating their respective Scriptable Objects and adding-in their respective behaviours where it’d make the most sense to keep their functionality.

At the moment we have no plans to do an this nor update the game with new sponsors and content. However, if that was to ever become the case, the introduction of several of these ideas would definitely be one of the plans for an expansion!

Phewsh, and that ends that! I hope for those that are into programming this post is at least an interesting read or that it sheds some light in the way that we have decided to handle things with creating our sponsors in our entry, Super Sellout. Likewise to our previous jams, we still have our usual post-mortem on the way, not to mentioned the aforementioned art-cantered post.

In behalf of our team, thank you once again for all the support you have given us so far in terms of ratings and coverage. Ludum Dare is a very important and heartful event for us, and it’s specially thanks to it that we are able to grow as a team and spread our word around. If you haven’t had the chance to play Super Sellout, we invite you to do so, and make sure to send us your game too!

Finally, we also invite you to join us at our team’s Discord server! We have a whole room dedicated to #gamedev and for talking about this type of technical jargon, and we’d love for you to share your own entries with us there!

If you’ve managed to reach this far, cheers, and thank you for reading! ?

Getting the Ball Rolling in Wizsnooks – A Success Story

This has been my favorite LD so far, I had the opportunity to work with great teammates: Moski arting (he’s who drew Skeletorb, seen above), Robin sounding and me coding, and debuting as part of Whales and Games. I had partnered with @Moski earlier, in LD39, and sticked around their Discord annoying everyone until stockholm syndrome hit them again and we decided going for LD41.

Our entry is Wizsnooks, a billiards dungeon crawler!


This is a telling of the Jam’s events through my eyes, but not the game’s post mortem! Not yet at least. Stay tuned for that one some-when this week!

Day One

Our team decided quite early on on the Snooker RPG idea, so I immediately started working on a prototype for snooker physics so the artist’s eyes bled and gave him motivation so we could see with our own eyes.

Then we got the first batch of sprites and I started working on some animations and flair. This will be a repeating theme within this post: make a base mechanic, then fluff it up so it looks good before moving on to the next.

After that, we knew that an RPG needed an inventory, naturally. At the time we thought it would be nice if we had attack and defense stats that would affect how balls respond to collision:

  • A higher Defense stat would increase ball stability after bouncing on enemies, effectively a “knockforward” on hit;
  • As for Attack, it would increase the knock that the enemy ball takes, so a wielder of a strong weapon would need only small nudges to send enemies flying.

I had a lot of time while the artist worked on a crapton of equipment sprites, so I spent a lot of the time writing up a very flexible attribute system based on ScriptableObjects (more on that later) and making the inventory UI with stat comparisons.

Day the Second

After spending a million years perfecting a satisfying loot animation, I bodged together some more code to drop items based on a percent chance. And sneakily, I inserted a new requirement for the code: item rarities! No idea how would they matter, but I wanted colors so I put them in.

We decided going more RPG and less Snooks so we added health and made attack and defense stats affect that.

Oh, and also, the initial tileset was in so I had to learn how to use Unity’s tilemap in 30 minutes. I sorta did, but the repercussions are visible to this day.

Now, obviously, the priority was adding disembodied hands to the game, like any sane person would naturally choose to do.

Had to add events to every possible situation in the universe so soundman could add sounds to them.

Doomsday

Day One’s meneacing seemed to have worked, the artist was quite motivated. All menu sprites were done even faster than I could see them being pushed to the git repository. Tilesets flooded the Assets folder.

I also reused the drop animation’s sprites for a death screen, and burdened myself with the tiny visual detail that the death screen’s sprites are actually the player’s currently-equipped items.

The rest of the time was spent fixing bugs and polishing mechanics, while artman drew more items and soundman made more maps, and balanced artman’s items.

We hit publish, having needed the holy Submission Hour, with the game clocked at 19 items, 4 rarities, 4 monsters and 13 levels. Turns out a lot of items hadn’t been balanced and added to the loot tables (I mean, poor soundman having to do everything today, but such is life), otherwise we’d have 23!

Day the After-th

I spent this day using my webdevguy skills to polish the fuck out of the Itch game page, while secondary platforms were built (Win32, Linux, OSX). I mean, just look at it! So pretty!

Thuswhile

I think this was a fantastic jam, finally with a Theme That Didn’t Suck, awesome teammates and no social interruptions (for once)!

So many great games! Now goodbye while I go hunt for some more entries!

Building the Character Logic in Jazzy Beats!

These weeks certainly went fast, didn’t they? It’s kind of amusing to think that judging phase ends in less than 24 hours! However, we at Whales And Games still feel like there’s still so much we could talk and post about the game’s development that we didn’t get the chance to cover during this judging phase (for a multitude of reasons).

In similar fashion to how our graphics designer has written a insight about creating the characters and the art direction and to how our music’s composer wrote another in-regards to his workflow and challenges in composing music, now it’s my turn to talk about the programming structures and methodologies I used for developing the different character’s logic in our Ludum Dare 40 game – Jazzy Beats.

Whales And Games ❤ Unity

For Jazzy Beats, we decided to stick to what we know and use Unity as the engine to develop the game once again. It’s been my tool of choice for almost four years now and I’ve used it on the past four Ludum Dare‘s we’ve participated on. As such, it’s an engine I’ve grown comfortable with, both in terms of workflow, as well as in terms of it’s scripting structure (built on top of C#). As for the IDE itself, I use Visual Studio, not only because of all the tools and integrations it offers when paired with Unity, but also because of how standard of an IDE it is for pretty much everything programming, be it standalone programming, be it with other game engines.

Even so, after all these years using the Unity engine and programming, I still find myself learning better and different ways of getting around, and improving my methodologies when it comes to managing code. Looking back to just a few months ago, when we were updating our Ludum Dare 36 game, Colossorama, for it’s anniversary update I ended up spending a great amount of time just restructuring some of it’s early code in order to optimize it and make it easier to introduce the new mechanics we wanted to add with the new update.

The point is, even while working with the same engine for years, you always end up learning more and further stuff that always helps you refine your future projects as you go, and the past projects we’ve developed were what allowed us to develop Jazzy Beats as it currently stands. One of the programming aspects that ended up being the most important for the game’s development that I only really understood the flexibility as off recently, for example, was Inheritance.

The point is, even while working with the same engine for years, you always end up learning more and further stuff that always helps you refine your future projects as you go, and the past projects we’ve developed were what allowed us to develop Jazzy Beats as it currently stands. One of the programming aspects that ended up being the most important for the game’s development that I only really understood the flexibility as off recently, for example, was Inheritance.

The Power of Inheritance

Although Jazzy Beats‘ behaviours and characters aren’t anything ground-breaking or extraordinary, without some code management and methodologies, it would have been hard to develop and iterate on every single character’s behaviours at the iteration rate necessary during a game jam.

As a consequence, one of my priorities when it came to the game’s development was the code’s re-usability, especially when several of the character’s actions are shared between all of them – be it the Player, the Enemy, or the Fans. One basic example of these actions was the basic punch, which all of these past three characters feature. In order to aid with this re-usability, one of the things I turned too was abstraction and inheritance.

Some of the most basic actions are shared between all of the characters, be them controlled by the player or not. For example, all of the characters use and require components such as a Rigidbody2D, and have variables such as healthdamageDealtvelocity and feature functions such as TakeDamage()and Knockback(). All of these functions are shared between all of these characters and feature no differences. However, functions that require more specific functionality depending of the character, such as Movement() and Attacking() are marked as abstract and are later overridden, and filled in depending on the character we’re working on.

As such, all of the characters on the game derive from one base and template abstract controller known as the CharController which has all the base fields and functionality for a working character. This controller is later inherited and expanded into new and more specific controllers such as the PlayerController in which, for example, the abstract function Movement() is overridden with the code used for recognizing the player’s input. These controllers are also expanded with new functions exclusive to that character, such as ApplySparkAttack() function, which allows the player to use their ranged attack and which is exclusive to their controller only.

This allowed any specific base check or tweaking to be made to all the characters at once, if justified, or specifically tweaked according to the functionality of each individual character. With this structure, I was able to save time with several of the programming tasks that would have been needed if I tried to make separate individual controllers for each of the characters.

However, inheritance is always a mold-able and relative. While writing this section, I can think of several points in which this design and template could be improved further upon. However, given the time limit, you can’t be a perfectionist in regards to it either. Don’t let code perfectionism hold you back while there are features you could be implementing at that moment, but make sure that your code is maintainable to the point you can quickly make changes and adaptations to it.

Character Controllers & Pseudo-AI

With inheritance applied to the characters, the next step was to start connecting this controller structure to the actual gameplay logic of the characters. As referred in the last section, since the base CharController class Movement()and Attacking() functions are marked as abstract, each of the extended controllers have their own different logic for that same function.

For the PlayerController these functions mostly check which input the player has done, such as applying a velocity to the Rigidbody2D depending on the axis that the player is currently inputting, and deploying different attacks depending on their button presses. Not too shabby and a set of controls most likely similar to what most Ludum Dare contestants did with their games as well.

It’s worth side-noting that, for the concern of getting up to speed with Player input and being able to include Gamepad Support out of the box, we used the Unity plugin Rewired as an input wrapper, instead of the default one. It’s a great extension that I absolutely recommend to everyone that has been struggling with expanding Unity‘s input for a while now.

However, it’s when it comes to other characters that the controllers need to be thought of differently. As opposed to the Player, neither Enemy nor Fans have a direct input, meaning that all their actions and decisions needed to be made through code. As such, both of these feature what I like to call a pseudo-AI through a set of checks that are made to see what types of actions the controller should make depending on their situation. I call it pseudo-AI because their decisions are made up of conditional statements, rather than an adaptive artificial intelligence algorithm (such as machine learning which would be insane for a game jam).

The most basic example of these condition checks is with the EnemyController. For Bluessom’s movement and attack patterns, she will check for any opposing-affiliation Fans (in this case, Player fans) in a wide zone around her and target the one closest to her. Depending on the attacks that are currently available and not on cooldown, she will roll a random number to decide which attack she should use on the currently target fan, and will continue attacking them until they eventually turn over to her side again. Since the amount of fans quickly ramps up during the game, eventually, one Bluessom’s attack will hit more than one fan at a time, converting multiple fans in one ago.

The FanController works in a similar fashion to the Enemy one, except instead of Fans moving only when one of the idols is near them, they’ll will always be walking towards the idol opposed to their affiliation (Bluessom’s – the Enemy – fans will always move towards Jazzchan – the Player). They’ll stop when it’s time to perform an attack, at which point they’ll perform the same base attack (the punch) that both the main characters have, followed by a cooldown to avoid them constantly doing the attack. Fans don’t have any other attacks such as the kick or a ranged attack as to avoid having the player having to think on dodging different Fan attacks, making their main focus avoiding and converting fans as fast as possible.

One of the earlier issues we faced upon once the fan count started increasing was that all the fans targeting a specific idol would eventually converge into a single moving line since they’d all be moving towards a single point (the Player’s position) at the exact same velocity. In order to circumvent this, we introduced a slight random variation in their movement speeds (rolled when the fan is spawned), together with a position displacement that’s added to their target’s position, making each fan target a point around the character, rather than the character’s absolute position itself. These two variations alone are enough to make Fans walk and ‘mob’ in a much more believable fashion.

Finally, for the actual hit-checking when one of the characters performs an attack, each of the controllers will perform a box cast in front of their feet to check for any opposing-affiliation colliders in a small zone in front of them. These box casts are placed by their feet as due to the game world’s perspective, as making a box cast of the same size as of the player would make the check return characters that, perspective-wise, seem above the player.

Pictured is the example of these box casts for the different attacks performed by the player. The yellow box represents the zone checked when the player performs a basic punch and the red one for the kicking. Finally, the green circle shows the area of fans converted when the player performs a Ultimate Sax Drop.

As a somewhat trivia piece, one of the original designs we had in mind for the Ultimate Sax Drop involved the play having to perform multiple combos in order to charge it before being able to use it. However, concerned that it could create a contrasting design with the other abilities, we eventually decided to stick with having a cooldown for it.

Unfortunately, this ended up making the Ultimate a safe-guard ability, causing most players to just stick to just using it by late-game, and avoid using it during the remainder of the game. Most of the feedback in regards to the game turns around this, which goes on to prove that, sometimes, playing risky in terms of the design can be a much more rewarding, and it’s a note we will take in mind for future jams.

The Game Manager & State Management

And, finally, the last thing important to the management of the characters is the dungeon master GameManager! The Game Manager is a singleton entry that is responsible for managing the overall state of the game and keeping references to other, single-entity objects that are used through the game.

One example of these objects is the FanSpawner which will continuously spawn more Fans (which always start with affiliation to the Enemy) as to ramp up the game’s difficulty as the game progresses. Having the game starting with only a single Fan allows the player to get a general understanding of the controls before reaching late-game where they have to take multiple Fans into consideration. The FanSpawner will stop spawning new Fans when the total count of them in-game reaches 40 – because y’know, it’s Ludum Dare 40.

To avoid performance and other issues – especially in WebGL – as the amount of Fans spawned increases, the higher the chance of them spawning without an AudioSource becomes higher. This not only saves a lot of memory allocated exclusively to audio (which was causing some music cut-off issues in early development), but also stops the player from hearing 40 different AudioSources all playing footsteps at the same time.

Finally, the GameManager also keeps track of the current GameState which check what state the game is currently on between three different states (StartingOnGoing and Over). These states exist to stop the remaining objects in the game of performing certain tasks when they’re not supposed too (like the FanSpanwer spawning Fans after the game is Over or Starting). Likewise, the character controllers also check this state for this very same reason, and will, for example, stop characters from moving once the game is Over.

Some food for thought for the future is creating a state system for game characters. This would allow for more complex logic and conditions that are not exclusively limited to conditional statements, without potentially creating much additional workload when it comes to programming character and character actions during a game jam.

And that pretty much wraps up this overall programming post! Getting it out in time was one big challenge due to the snowball of occurrences that happened during the whole of the judging period, but here it is, even if it’s just a few hours from the end of judging phase. We still have our Timelapse and Post-Mortem on the way which we hope to make available as soon as we can. However, those will most likely have to wait until after the judging to see the light of day.

In behalf of our team thanks for keeping up with us during this Ludum Dare. Yesterday, when Moski made a post about the coverage we got during this edition, we were baffled that we had almost made it to 200 ratings. However, as of today, we’ve managed to smash that very goal! A whale of thank you to everyone who has made that possible and to everyone which has played our game during these last three weeks. The feedback and engagement by all of the other developers was amazing and completely broke all of our expectations. ? If you haven’t had the chance to play and rate Jazzy Beats yet, now would be the perfect time to do it!

If you’d like to keep up with us at Whales And Games after this Ludum Dare ends, we have our very own Discord channel! It’d be wonderful to see you there! Again, Thank you! ?