⬛ ⬛ ⬛ ⬛ ⬛ ⬛ 🟨 🟨 🟨 🟨 🟩 🟩 🟩 🟩 🟩 🟩
At this point, you've heard of Wordle, Josh Wardle's minimal word guessing game in the vein of 70's code-breaker Mastermind. On Thursday, January 6, 2022, I found my way to the game as I watched the now-familiar daily Wordle grid ⬛🟨🟩 go viral on Twitter.
The concept is simple - you have 6 chances to guess a secret 5-letter word. Each guess tells you which letters are present in the secret word and if they are in the correct slot. When the game started gaining traction, players took to Twitter to share their daily game board using a color-coded emoji grid to keep the secret word.... secret. The share method became so popular that Josh added a grid generator and share button to the app (which is just a website right now).
After I finished my first word, I wanted to keep going. But that's the key - there's only 1 word a day.
I added a Random Word button to Wordle. All the same daily words, but you can solve more than 1 word each day.
Downloading the Source
Part of the reason Wordle has exploded is because of its 1 word daily limit. But since I'm impatient and it's just a web app, I popped open the Chrome developer console to try and solve some more words.
The production build is an HTML file and a JS file (and some media assets), and the daily word is pulled out of an array of 2,315 words based on today's date. So I downloaded the 2 files, set the date 1 day in the future, and played the game locally to solve tomorrow's word. I solved about 10 new words this way before wondering if anyone else was longing for extra words. Google, Twitter, and Reddit all confirmed my suspicion - there's a huge community of people who want to keep playing after they finish the daily word.
I still wanted to complete (and share) the daily Wordle, so I decided to simply add a Random Word button to the app to randomly choose a word from the secret word collection that hasn't been solved by the player before. This only required about a few dozen lines of code.
Adding a Random Word Button
As I mentioned, the original app stores a list of all 2,315 secret words in a solution array. It looks at today's date, calculates the number of days that have passed since the app launched, and uses that number as the index for today's word in the solution array. While playing, the app stores game metadata in the browser's localStorage object. When you load the app, if you've already completed today's word, it will load your results from localStorage. This is also where it tracks your lifetime statistics and win streaks. (Fun fact: this is why you only see your results if you use the same device each time - it's stored in the browser. If you switch to a different phone, computer, or browser, you won't see your past game progress.)
I added 2 buttons - "Today's Word" and "Random Word", and I injected some code into the date-finding logic, adding a new localStorage object of my own. I needed a few helper functions to interact with browser storage and generate random numbers and I was good to go. Now when player's click one of these buttons, the app stores the index of the active word instead of relying on today's date to determine the word. This allows player's to play today's word or random words, and if they leave and return to the app it will still load their most recent progress.
Once this was working, I downloaded the production manifest.json file and images folder, pushed my modifications into a git repo, and drag-and-dropped the project into a free Netlify site. I pointed a personal subdomain (wordle.berknation.com) at the new site, and it was up and running 30 seconds later.
If You Build It, They Will Come
I started circulating the app to family members, and it was an immediate hit - especially the ability to play multiple words.
I tweeted that I'd added a randomizer to the app, and a beautifully wholesome 4 people retweeted me. Good thing my app didn't crash from all that traffic 😮💨😮💨😮💨
Then a more influential user saw the app and tweeted it, and traffic spiked.
Since then, it's been averaging a little over 1,000 users a day without much effort on my part.
Except for the Daily Wordle. The Daily Wordle gets Maximum Effort 🤲 🤲
Source Code and Next Steps
The production code is minified, so it's not particularly readable without some work. I've since reached out to the original creator asking if he'd be willing to open-source the project and accept pull requests, but I haven't heard anything yet. He has mentioned in a few forums building a library of past words as well as the possibility of a mobile app. I've already started tinkering with the former - it's a simple next step.