A few years ago I played Guess Wu (a game like Guess Who featuring members of the Wu-Tang Clan) at a board game cafe in Cleveland. Later, I had the idea to build my own custom version of the game featuring pictures of my friend Frank, who loves to dress up and has sported many different costumes, beards, and hairstyles over the years.
I also wanted to make a version of the game that is more diverse and inclusive of all types of people, because representation matters. That's how Who Dis? was born.
Who Dis? is also my first React app! I wanted to learn about React, and I've found that the best way to learn a new technology is to build something with it, so I used React to build the front-end.
Sometimes I miss the old days when building a website was just dragging plain old HTML and CSS files onto your FTP client. To build a React app, there are so many dependencies, and dependency management is one of my least favorite things to do. Even following some tutorials on getting set up, I ran into issues like:
- Why won't this build? Oh wait, these docs are for a different version than I'm using!
- Why is it so hard to compile SASS to CSS files with Webpack?
- What if I want to organize my files in a different directory structure? I need a different loader for that?
- What even is a loader, and why do I need so many of them???
Differences From Vue
I've built software in Vue.js, so I often expected things to work like Vue. I had to get used to doing things the React way instead.
A lot of the core concepts were familiar, like splitting my app into components and working with reactive elements that update on the fly when the data changes. But there were new React concepts that I had to learn about, like lifting state up.
I also had to get used to the JSX syntax and React's DOM, especially when using certain attributes that work a little differently in React than they do in plain HTML, like
Design & Accessibility
Squeezing a 24-tile grid onto a small mobile screen was a big design challenge! The images had to be small enough to fit most of them on the screen at once, but big enough to be able to discern the features of each face.
Responsive design tip: I include this meta tag on every responsive site that I build:
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
It allows the site to scale nicely on mobile screens while still allowing the user to zoom in if they want to. Disabling zoom is bad for accessiblity, and in this case it was especially important to allow zooming to see the details of each image.
I try to use best practices for accessibility in everything I build, but how do you make a game that's centered around visual differences accessible to everyone? The images are essential to the gameplay and definitely not just decorative, so they should have alt text, but how do you write good alt text to describe images that are randomly generated? These are questions that I don't have a good answer to, but I welcome any ideas or suggestions that could help make this game more accessible.
I used Matthew Nau's Libmoji library to generate the random faces for each game. I love how diverse and colorful the results are - Bitmoji has a huge range of customizations that makes for a really fun assortment of characters.
In an early iteration of the game, almost all of the characters had hats and glasses. I wrote a function called
maybeDisableTrait() (see code on GitHub) to randomly disable some of these traits based on a weighted percentage. I experimented with this, tweaking the likelyhood of enabling or disabling certain traits to end up with a balanced variety of features.
Originally I thought I would find some kind of library to generate random names, but I also wanted to make sure the names would be as diverse as the faces they go with. In researching this, I came across a fascinating paper about the relationship between ethnicity, gender, and naming - definitely worth a read if this is something that interests you!
One thing I was not particularly interested in is trying to match up names and faces based on gender. Doing so feels a bit too much like gender policing, and it adds an extra layer of complexity that seems totally unnecessary. I found a simple and elegant solution in FiveThirtyEight's article about unisex names. I used their data to curate a list of gender-neutral names, editing to remove similar names that might cause confusion, like Kerry, Carey, and Kary.
Building Who Dis? was a really fun way to dive into React. I learned a lot making it, and I hope it will bring a little joy to everyone who plays it.