With this being our first game jam, we weren’t quite sure how to plan or how to manage our time. As the jam started at 02:00 in our time zone, we decided the best idea would be to check what the theme would be, then to go to sleep hoping that we’d subconsciously come up with some ideas overnight.
By the time we were actually ready to start (after recording and editing the weekly Interference update video), it was Saturday afternoon – about 11 hours in to the jam. We’d had time to think about the theme (“A small world”) for a while, and decided to do something based around looking at a petri dish through a microscope. We’re both fans of puzzles, so decided to make some kind of simple puzzle game.
Berni quickly came up with the idea of showing the player a petri dish with various “bugs” in that would have several attributes (eg colour, shape) and the player would have to apply the correct drugs to make the bug shrink (but using the wrong drug would cause it to grow). For example, a spiky yellow virus would grow if given a round yellow drug (wrong shape), but would shrink if given a square yellow drug (correct colour, correct shape (well, it has corners!)).
I’ve been spending my spare time learning about Unity, so decided this would be a good excuse to play around with that. My experience consisted of reading “Teach Yourself Unity Game Development in 24 Hours” and doing half of a Unity course on Udemy, but I hadn’t actually made anything from scratch. Still, never hurts to have a go at things.
For the first few hours, I had a go at implementing the system Berni had devised, but – if I’m completely honest – didn’t have much success. I managed to set something up where you could drag coloured shapes onto other coloured shapes, and then they’d change size depending on whether the colours matched or not. It sort of worked, but didn’t feel very fun – you just piled drugs on to one bug, then moved on to the next. Berni suggested making different bugs grow at different rates, and introducing bugs that had two colours, but I thought it was getting a bit complicated (and whilst I could cope with changing the colour of a sprite renderer in Unity to make different coloured bugs, I had no idea how to handle things with two colours – swap in different sprites, rather than colouring the same sprite?).
I suggested that we keep things simple: display the bugs in a grid, then have the player add drugs which would affect adjacent cells. You’d have to work out the correct placement in order to get the right combinations of colours. To make it a bit more interesting, we’d make the grid out of hexagons. I mean, that can’t be too hard to work out, can it?
Several hours (and a few pages of scribbled notes) later, I’d finally made a system that could generate a “circle” of hexagons, given a number of layers. The problem with hexagons compared to squares is that it’s harder to refer to a particular hexagon – in a square grid you can say something like (1,4) and it means “one along, four up”. The problem is that whilst one row of hexagons will fit into that, when you do the next row everything is shifted across by half a hexagon. I eventually implemented this by assuming that rows would alternate between sitting on even numbers and odd numbers on the grid. It seemed like a good idea at the time (just shift everything by 0.5 on every other line), but in hindsight I think there’s probably a better solution involving adjusting the Y axis of your grid to go at an angle. By the time I realised this, I’d already done a lot of implementation, so decided to leave things as they were.
Next was dealing with drugs being dropped into the grid cells (or “hexes”, as I called them in the code). That was pretty simple – Unity’s collision system took care of most of it. Whilst a drug was being dragged, we kept track of any hexes that it collided with, and when the mouse was released we dropped it into the last empty hex it touched. This just involved setting its position to the same as the hex and setting the drug’s parent to the hex. At this point, we also check the colour of the drug, and then set the colour of the hex to match. If a drug is picked up again, we set the colour of the hex that was its parent back to white. To change the adjacent cells, we check the two above, the two below, and the ones to the left and right – six in total. Well, I say six – one of the obvious things that I forgot to check was whether those hexes actually exist (eg if the cell is on the far left of the grid, then there won’t be any cells to the left of it). Fortunately, that was easy to fix once I’d realised my mistake.
I’d written a lot of code in the last few hours, so decided to do something else for a bit – making some sprites. I’m not much of an artist, but thought I could probably manage something that looked a bit like a virus. Using the excuse that I was aiming for a minimalist style, I came up with a few varieties that looked OK. They did seem a little boring, though. One of the things that had just been covered in my Unity course was animation, so I messed about with that quickly, setting a simple animation that made the sprite shrink a bit then grow (as if the virus was breathing). Surprisingly (for a change that took about two minutes), it looked pretty good and made a big difference. It gave me the idea that the viruses shouldn’t be removed when treated, just suppressed – so they’d become active again if you moved a drug away or added the wrong drug next to it. I quickly made another animation that made the virus shrink and stop moving.
To test things out, I made a script to pick random hexes and spawn viruses of random colours, then edited the “do stuff when a drug is dropped” script to check the colour of any adjacent viruses and set an “isSuppressed” flag if the drug colour matches the virus. That triggers the animation to change from “idle” to “suppressed”. I was rather pleased when I ran the game, saw a few viruses spawn and start “breathing”, then stop when I placed drugs next to them. It was starting to feel like a game! We made a minor adjustment to the drug sprites here – adding a “C” to the centre of them – to make it more obvious when a hex contained a drug.
Something that I’d learnt from the Unity course was that adding sound makes a big difference, even if it’s just a small thing. I didn’t want to spend ages looking though lists of sounds, so just grabbed a microphone and recorded myself making a “pop” sound. Playing that when a virus spawned made things feel better, but it still seemed that something was missing. We thought that perhaps a sound for when a drug was picked up or dropped would help, so I recorded a “chk” sound. Almost there – but the whole thing was a little quiet when you weren’t doing anything. We added a bit of background music (a track from our friends at Vivid Muzik), and everything came together 🙂
It started to feel like things were almost done, but then I realised the big oversight that I’d made. Whilst the virus spawning system seemed to work well, it was just picking random hexes with no consideration for whether the puzzle would actually be solvable. I’d not had to write anything like this before, so wasn’t sure if there was a standard approach for it. In the end, I reasoned that if I made the game generate a solved grid, then pick viruses to spawn based on that, it would always be solvable. It appears to work, but perhaps there’s an edge case that I haven’t thought of!
I spent a few hours on Monday putting together a basic UI, instructions for the game (just some simple buttons and images), and a “plot” (you’re a scientist trying to prevent a pandemic) and the whole thing started to look like an actual game. On Monday afternoon we packaged the game, uploaded it to itch.io and submitted it to the Ludum Dare site – a few people have already tried it and left encouraging feedback.
I’m proud of what we managed to get done in a weekend (I think that our active time on the game was probably under 40 hours), and I’m tempted to add a bit more polish and release an updated version after Ludum Dare is finished. There’s a few things that would need changing, like trying to increase the replayability: at the moment, the grids are programatically generated – it would be interesting to generate levels based on a seed value (so different players could try the same level, and see who could solve it the fastest). Another improvement would be to calculate the optimal solution for each grid, so players could see how many steps over par they are.
Having spent a good few hours playing around in Unity, I’m very impressed with it – things that I expected to be tricky to implement were a lot easier than I anticipated, and being able to build for web, Windows, MacOS and Linux at the same time is excellent.
We’re definitely looking forward to the next Ludum Dare, but have decided to try and make a small game each month as a break from our big projects – it’ll give us a chance to try out random ideas without having to work out a long term plan for them. If everything goes to plan I’m going to document the process and share the results at thelab.wearecentrifuge.com.
If you’d like to try the finished game, then you can find it at centrifuge.itch.io/superbugs – we’d love to hear your feedback 🙂