This is a post-mortem writeup for Bath Time.
This was my 19th time competing in Ludum Dare, and my 11th time working together with xellaya. We ended up making a game called "Bath Time", where you wash cats by tumbling them in circles via touch or mouse controls. This one is notable for being our first game that uses portrait rather than landscape orientation. We also designed it with mobile touchscreens in mind from the start!
First off, let's look at our ratings:
Overall: 23rd (4.199 average from 95 ratings) Fun: 89th (3.859 average from 94 ratings) Innovation: 75th (3.902 average from 94 ratings) Theme: 82nd (4.134 average from 95 ratings) Graphics: 17th (4.570 average from 95 ratings) Audio: 6th (4.366 average from 95 ratings) Humor: 54th (3.961 average from 92 ratings) Mood: 28th (4.178 average from 89 ratings) Average Score: 4.15
Pretty solid all around! We scored a bit lower in the Fun category though, and I think that's most likely due to the compo version being way too difficult for most people!
The development of this game was pretty interesting in that we started by making some quick physics "feel" prototypes before even deciding what the game would be all about. Usually we try to come up with a design idea on paper first and then move onto implementing it, but this time we started by just playing around with Unity physics by using a bunch of 2D rigidbodies and circle colliders.
This is actually a demo of the later prototyping phases, after we had figured out that we wanted to make the game about washing cats (we had some earlier prototypes which were even more basic).
This ended up working out pretty well for us as we were able to make sure that we had something that "felt" fun and was visually satisfying before thinking about how we would use that mechanic to build a game. On the other hand, we did have some difficulty later on thinking about how to expand upon the main mechanic of swirling around the cats. For example, we weren't sure how to handle win/loss conditions, and even though we knew we wanted to have soap, we weren't sure at first how to incorporate it into the actual gameplay.
This is probably something we should have already known by now, but testing your own games for difficulty is a recipe for disaster. You already know exactly how your game works, so things that seem really obvious to you might not be readily apparent to anyone else.
As I was trying to tune the difficulty of the levels, I knew that I should try to compensate for the fact that most players probably wouldn't be moving their mouse (or finger) around and multitasking as quickly as I was. What I didn't account for was the fact that players would be moving their mouse/finger around in all sorts of different ways! There was never any clear instruction (or a very direct visual indication) of what method of movement was the most effective, so there were players that moved their mouse in smaller circles, or other erratic patterns, or tried to scrub over the meowmies, instead of swirling the water in large circular patterns. I also forgot to account for the fact that everyone has different mouse sensitivity settings that would affect how natural it felt to draw circles around the whole screen area (not to mention some people might be trying to play on a laptop trackpad!).
The cats get cleaned depending on the total distance that they travel in the wash bowl, and the physics of the game works out such that using large circles (to the edges of the bowl) in the same direction is the best way to do that, so in the post-jam version we added a new tutorial step explaining that.
It was extremely helpful seeing some twitch/youtube playthroughs of our game, as that let us understand exactly how other people were trying to play it and adjust accordingly!
One other key realization we made was that this game doesn't really necessarily need to be challenging in order to be fun. There are a lot of games where the enjoyment comes more from challenge and having your skill tested, but I think for this one it can be a lot of fun even if you never lose. We significantly toned the difficulty of the post-jam version down because of this, and I think it resulted in a much better experience for most players.
The cats in our game actually use a simplistic physics ragdoll simulation that was inspired by the flailing cats in Hacky Cat. Each cat actually consists of 6 different physics objects (i.e. 6 rigidbodies and 6 colliders total): One "main" parent physics object that is actually used to collide with the other cats, and then subobjects for each of the head, tail, and 4 limbs of the cat. The head, tail, and limb objects are then connected to the main physics object via Unity hinge joints, with a small allowable rotation range.
As with essentially all physics-based game systems, the whole thing took quite a lot of tuning before it really behaved well:
In addition, the whole ragdolling limb system ended up being quite expensive to do when many cats were on screen at once (100+ physics objects trying to collide/interact). To handle this we turn off the nested colliders when there are more than 10 cats, as that's when it starts to get more expensive. Fortunately, that's also the point at which you don't really notice the individual cat limb motion at much. They actually still end up swinging due to the rotation physics of the parent object, but they just don't each have their own individual motions.
We use a similar system for getting the cats' legs and tails to swing from side to side while they are hanging to dry. For this we only use 3 subojects and 3 hinge joints, and we just start them off with a random small rotational momentum as the cat appears.
I'm not much of a shader expert, but I ended up taking a simple shader-based approach for visualizing the amount of "remaining dirtiness" for each cat, as that would be easy to tweak and would allow for a continuous representation from 0-100% without having to draw a ton of new art assets.
The first thing I did was generate a simple noise texture. I forget exactly how I made this in GIMP but it's probably just perlin noise.
It was actually a bit non-trivial getting this to line up properly with the cat graphics because there are multiple sprites involved and they're packed into a spritesheet, so the texture UVs weren't as straightforward as they could have been. I'll skip over that part though since it's not really relevant to the actual technique.
Next we do a simple threshold function, so display the noise texture if the noise pixel is less than or equal to the "dirtiness amount" (which is passed in via scripting), otherwise display the normal cat sprite. That looks like this (with the "dirtiness amount" being animated from 0 to 100%):
And finally, we keep the same thresholding function, but instead of displaying the noise texture itself, show a special "dirt texture":
You can of course tweak the scaling/offset of both the noise and dirt textures to change the look of the "dissolving" effect. We also gave each different cat sprite a different color of dirt texture so they would look a bit different. Finally, for the "extra dirty" cats we just a different (hand-authored) dirt texture. There's more stuff going on, of course, like the particle effects and pulsing glow effect for the cats that are fully clean, but that's the gist of it.