RCW
My first experience with Unity and game dev, RCW is an endless minigame about matching the right colors and words together.
Tech
C#, Figma, Unity
Play online via itch.io!
aczw.itch.io/rcwSource
GitHub repoDate
May — June 2023
I’ve always wanted to make games, and so this summer I took the plunge and decided to start learning Unity. The end result is this quick-n’-dirty game that I made in a month or so. More than anything, this was a learning experience to get my feet wet; you’ll find that none of the stuff here is very original or game-changing, but that’s okay.
In this post I wanted to talk a little about how I approached coding, designing, and making assets for the game in the eyes of someone new to Unity, C#, and game dev in general.
Overview
In Random Color Words (RCW) you are constantly trying to pair the correct combination of colors and words together. Both of these are randomly generated at the start of each round.
I saw this project as a way to involve myself with every part of a game development cycle. This led to me getting my hands dirty with things other than programming, like the audio and UI. And being new to… well, everything, I focused my attention on simple but polished and fleshed out results. And hopefully, the game’s fun to play as well.
I think I achieved that goal. I’m proud to be able to publish RCW as a “complete package.”
Brainstorming gameplay
To begin, I started brainstorming simple gameplay ideas that didn’t take too much time to implement. This means that the gameplay loop should be simple, and the best way to achieve that is to make the game infinite and have no ending, like an arcade game.
No ideas came to mind, and so I turned to other sources for inspiration…
Recently I had been playing this game called OLDTV. The premise is that you’re a gifted child sitting in front of a TV, and you’re trying to switch between every single channel in the world.
But uh, you’re not exactly pressing next on the TV remote. What’s happening here?
Explanation
Essentially, each round we’re given a color word, and a word color—uh, that’s just as confusing. Actually, lemme restart. Ignore the game for a sec—let’s just consider these two words below.
One word is colored purple, and the other is colored red. If I were to ask you what color the word on the right is, you might find yourself saying “purple” on instinct, which is wrong!
It turns out that it’s easier for us to name the color of the left word than the right word, because the word itself matches its color. When the word reads “purple” but is actually colored red, this throws us off and delays our answer.
This is OLDTV’s gimmick. Given the current word and color combination, left click if the color matches the word, and right click if it doesn’t. To make your life even more fun, OLDTV can (and will) flip your screen upside down, change the background color, and even reverse the controls. Oh, and there’s a time limit so you’re forced to react quickly.
Using the Stroop effect
Turns out this phenomenon has a name. It’s called the Stroop effect, a psychological phenomenon where “reaction time becomes delayed when the stimuli is incongruent.” In simpler human words, stuff that catches you off guard slows you down.
I thought this would be an awesome mechanic to shamelessly rip from OLDTV implement. On paper it doesn’t sound too hard: just randomly pick a word and color each round, and check whether the correct user input was entered.
There are some differences between RCW and OLDTV though:
- I use these five colors: Red, Yellow, Green, Blue, Purple.
- OLDTV instantly boots you out the moment you mess up. Instead, I have a lives system, where you get three chances.
- I also have a score system that depends on how fast you react.
With the gameplay decided, it was time to code.
Programming the game and learning C#
I will admit that RCW’s code is a little bit overengineered. If I were to redo everything today, I would definitely structure things differently (read: simplify things). But in order to actively learn Unity idioms and C# features, I tried out many different things throughout the codebase.
Singleton pattern
Everytime I searched up something related to “singletons” or static instances, the resources I find seemed to always discourage it. See:
- Singletons in Unity (done right). “Done right” implies people usually do it wrong…
- What are drawbacks or disadvantages of singleton pattern? Here I wasn’t even trying to look for disadvantages, this was just one of the first results for “unity singleton.”
- Singletons: are they ALWAYS bad? Yeesh.
From what I’ve read some disadvantages include having to modify/keep global state and increased inflexibility. To be fair, people from the links above aren’t arguing to never use it, but to consider whether it’s suitable for the current context; it seems like it’s misused/overused often.
I can see how keeping global state in a large codebase can be scary and hard. But RCW is not that, and in my case singletons really helped. For instance, I have an Audio
class which manages all my sounds in the game. Here it is:
Awake()
makes sure there only exists one instance of this class throughout the project. Repeat similarly for AudioClips
, which stores all the sound files in the game. Then, I can just play music or SFX wherever I want, whenever I want, like when my cursor enters an on-screen button:
I also use the singleton pattern for my main game manager, the Rcw
class. It’s important I can easily access this class because it contains all gameplay-related events, which other components need to subscribe to. Speaking of events…
Events and UI
I discovered the existence of C# events in the middle of development, and started converting many things over, realizing not everything works, and then back; so the game runs in a singleton/observer hybrid. Again, learning new things! It’s okay.
In Rcw
, I define events for most things that can happen in-game, like winning a round, losing a life, or starting a new game.
The event
keyword prevents it from being invoked in other files. This encourages me to constrain all gameplay logic within Rcw
, and broadcast out changes when necessary.
I found the most use out of events for updating the UI. Before discovering events existed, I saw two options:
- Store a reference to a UI-related component within
Rcw
, and use it when necessary. - Use more singletons. Maybe a
UIManager
, for instance.
Both options cluttered up the code and made tracking things harder. With events, however, only Rcw
needed to be accessible, things are more centralized, and C# scripts are free to subscribe to whatever they need within their own file.
The additional freedom that events warranted me made me go a little crazy with separating UI stuff into their own files, I think. But it really kept things modular, and kept behaviors within their own domains. For example, this is a simplified version of the script that controls the score UI:
This component’s sole purpose is to display the score, and it does it very well. But if I wanted to add some new functionality that occurs when the score changes, I just create another script that subscribes to the same event. It’s great.
Other stuff
Obviously there was so much more that I learned and played around with, but talking about it is a bit dull and quickly turns into a C# tutorial, which is not my intention. But I’ll list some stuff:
- Coroutines and being able to pause logic until the next frame is amazing.
- The different types of C# data structures. I used a
struct
for storing the colors and their associated names, for example. - Getters, setters, and avoiding Java-esque methods via properties. God these are amazing.
Funnily enough I feel that the least interesting part of the codebase is the RoundProp
component which actually generates the color and word for each round. I try to maintain a counter so that a matching color and word is generated every 2 to 7 rounds. Here’s the source file if you’re interested in taking a look though.
Music and SFX
I know I said I wanted to dabble in a little bit of everything, but I wasn’t exactly going to start learning music production, so this time I turned to the internet for some help.
To make the game feel more alive I wanted most interactions to play sound, and for them to be unique. It took me quite some time to compile together sounds, and I had certain criteria I wanted to hit:
- For the main menu I wanted something that sounded like “elevator music.” In-game should be upbeat and exciting, and the game over screen should be slower and sound sadder.
- I wanted the sound effects to sound “juicy,” if that makes any sense.
In the end I’m really happy with what I found. So a big thank you to Eric Matyas from soundimage.org and SubspaceAudio from opengameart.org for making awesome free music (and obviously sounds are also credited within the game itself).
Art direction and design
RCW is an endless, fast-paced minigame about getting the highest score. I was therefore inspired by arcade games and in particular, became obsessed with the art of Rhythm Heaven Fever, a 2012 Wii game. I wanted to channel its chaotic vibes, candy-looking buttons, and generous use of thick borders. I mean, the buttons had to look delicious.
I also liked the button hover effect in The Battle Cats, which flashed bright yellow and magenta. Here, I tried to recreate it in Figma.
Buttons buttons buttons
I use both the button design and hover effect in RCW. The nice thing about this art style was that it could be consistently applied everywhere, not just buttons.
- Add skeumorphism through the use of light, shading, etc.
- Wrap it in a thick black border
- Add a drop shadow underneath
- If I want to attract the player’s attention, add some color. Else, use gray
- I love Inter
Originally I was going for a factory setting, with words coming down a sort of assembly line. But honestly, this was out of my Unity skill scope, so I scratched that idea. You can still see it in the metallic plates and muted gray backgrounds.
Making literally everything in Figma
One thing that may surprise you is that all the art assets were made in Figma. This includes the start screen, in-game, and game over screen, as well as all the UI.
In order to animate different parts of the UI, I exported assets as individual pieces that I could put back together in Unity. This allowed me to, for instance, only animate the border around a button but not change its inside color.
I kept most things grayscale so that I could reuse the asset. In Unity, I simply colored each instance differently.
It was really nice being able to see the final product within Figma, without needing to tweak anything in Unity. It made adding small changes much faster.
Animating the UI
The checkerboard on the start screen randomly zooms and changes colors every five seconds. This was done by constantly manipulating the uvRect
of the checkerboard RawImage
.
The other thing I’m really happy about are the button animations. When the instructions or credits button are activated, the same button is used to go back to the start screen.
The “Go back” text slides out, and the outside border becomes a panel for the text to exist in. I spent too much some time getting it to feel just right. I would like to thank this easings cheat sheet for providing copy-and-paste animation curves.
Future updates??
How would I update this game in the future? The current gameplay loop is a blatant rip of OLDTV. I’ve floated some ideas around, including:
- Shop system. Earn currency for each game you play that can be spent on power-ups (score multiplier, increased time, more lives, freeze time, etc.)
- Round streak. For every additional round you win in a row, a score multiplier is added.
- Expanding Reversed mode. To make the player’s life even harder, more distractions could be added (flipping the game upside down, smaller words, fake clones, etc.)
- Levels. When your score reaches a certain threshold, new challenges appear. Old stuff is swapped out. Maybe add a way to continue from a certain level after losing.
…but for now, I’ll just enjoy the current results. Thanks for reading!