UNO is one of my favorite card games. Unfortunately over time I kept losing some of the cards, so I thought I could give it a go to recreate it as a multiplayer LAN game to play with friends and eliminate the fear of losing or bending cards altogether. Little did I expect that this app would become a great lesson to creating a real-time application with multiple users interacting with each other as well as demonstrate the importance of user testing.
Each of the cards were created as SVG graphics. This has many benefits for this application, especially for reducing the dependent files. Instead of creating a card for each color, and each number, I could create one file for all the numbered cards, and one for each of the special cards and just programatically adjust the colors and numbers. This also allows for dynamic resizing with no pixelation.
I rapidly created a Laravel project to run the game within a few hours. Although I foresaw this, I quickly reefirmed that serving static pages via PHP certainly wasn’t the way to play a game. Asking a user to refresh their page every few seconds was ridiculous. After a few minutes I had built a clunky auto-refresher, that would re-render the whole page every couple seconds. It was at least playable, however it required extensive server power to handle all the page requests.
As players were clicking cards faster and faster, I never disabled clicks immediately to process, therefore when players emitted events such as playing a card on their turn, they often would accidentally click so fast that two cards would be played at once instead of one, throwing off the game mechanics. This was a quick fix, however as I would disable clicks immediately on the client end until the server returns back with updated information.
Interfaces & user testing
Trying to create an interface for a game you normally play visually with cards was interesting. Showing how many cards a user had, and their score was a bit tricky, but the most confusing part was that UNO has a player order that would constantly reverse itself.
Originally, I had the players displayed horizontally across the top of the screen, which ended up lowering the main card below the fold, so a user would constantly have to scroll up and down to see who’s turn it was and what card was played. In addition, showing the current direction of play was done by having a rotating arrow. This just simply caused too much confusion. I researched a bit how to present this and came across baseball lineup screens. Like these screens, I split the players to the left vertically, and the game action to the right. Then when the player order changed, the names and stats animated to their new position. This change made a huge improvement in the overall game playability.