The Month of Games #4

The Month of Games ends here with a big surprise.

Having given up on a game would be pretty on brand for me, but I didn't give up on these - just did some scaling back. And, that's right, I said these. As in more than one.

Introducing Filmsies, Gamesies, Showsies and Songsies, all playable right now in your browser.

After getting into Wordle earlier this year, I wanted to make a clone. The idea behind that clone was that you'd guess the name of a song, but I quickly discovered the implementation I had in mind would not work.

Several months later, just before I went to bed, I sat down to revisit this idea from a couple of different angles - it was now with movies, and I had an implementation that should work.

Key differences between this and Wordle were that the titles would not be restricted to a certain number of characters, and that a hint would appear after each guess. In addition to that, it would not show previous guesses in favour of  letters that were in the right place getting locked in.

Incorrectly guessing Mario Party revealed the game was released in 2009, and had an R in the second word.

The hints would follow a pattern - first the year the movie came out, then the director, then names of some people who were in it, and finally a quote. Just as I'd finished working that out, I also decided that once I was done building this game that I could create a version of this for games using a similar pattern of hints - the year it first released, the developer, the genre, and then the platforms it released on.

Even though it was 1am, I wasn't really tired so I grabbed my laptop and took that with me to do some proper bedroom coding because I wasn't just in my bedroom, I was actually in my bed.

With VS Code, I wrote a class to define the movie data, a list of movies that was just populated with one for now, and a function to get a movie from that list. I'd written this in Typescript and then discovered that the browser didn't like it and that most Typescript files get packaged into Javascript that gets loaded when the HTML renders. And since packaging them up seemed to require Node, I decided to just write everything in Javascript instead since Node has already caused me enough problems in my lifetime and I never want to deal with it again.

After getting a test page setup, I wanted to prevent cheating. With Wordle, it was easy to dip into the source code and see all the words. If you knew the previous day's word, you could just search for that and then the next word along would be the current day's word. If you didn't have the previous day's word, then it was still possible to work out the current day's word but it required a bit more unpicking.

One option would be to not have the list of movies in the files that get loaded by the browser. Each time it needed to get a movie, it would make a call out to an API and load it from a database. Except that required me to have to setup APIs and databases, and it would cost money to do that. And it would also reveal the name in the Network tab as part of the API's response, so that would be a lot of effort to not even prevent the thing I want to prevent.

The second option would be to keep the list of movies so they were accessible to any users that wanted to cheat, but they would be encoded. Anyone who wanted to cheat would be able to, but they'd have to figure out how to decode the name first.

The problem with that second option was that now I not only had to come up with a list of movies and populate them with hints, but I had to encode them all. The solution was to have a raw JSON list with everything in English, then paste it into a text box on a web page and click a button which would then call a function to encode everything.

Encoding the list of TV shows.

A couple of days later, I started working on writing out a list of movies so I could populate the game with data. And in doing so I realised how much work I had in front of me. If the data was simply a list of movies, it would have been easy to rattle movies off the top of my head, then look on the shelves behind me, and then look up the highest rated and most successful movies of all time on the internet. But thanks to the hint system, I needed to look up the year, director, stars and find a quote.

Also, because the on-screen keyboard I'd created only contained letters and an Enter and Backspace button, any symbols like apostrophes and all numbers were ruled out. So goodbye, Iron Man 2 and Iron Man 3 (but hello Thor Ragnarok).

I found an API for IMDB that I could write a small program to interact with, but I'd be restricted to 100 queries a day unless I paid for it. And from the looks of things, I would only be able to scrape the year, director and some stars. Quotes would still require me to look through every single one.

As an alternative to coming up with a list of 1000 films, I could release with 50 and then more in chunks, but I wanted to release it complete so I didn't have to worry about coming back to it all the time. To complicate that further, I'd also decided I was going to do 4 different versions of this game - movies, games, TV shows and songs. So as well as having the problem of populating a list of movies, I now had to populate another 3 lists on top of that.

I decided to avoid populating any lists at this point in favour of getting everything else working. I added popups to explain how to play and change the settings, and then began the battle against CSS to put things in the right place on my PC before making adjustments to get it displayed nicely on mobile. I was originally intending to support both vertical and horizontal display, before deciding that anyone playing in horizontal was insane.

Since I was only going to come up with a finite list, I needed a way of making it so that once it had made it to the end of the list of movies, it would cycle back through them again. This would mean that players who stuck with the game for more than a couple of years would end up seeing duplicates, but I thought the chances of that happening would be fairly low.

The initial bit of code I wrote would have used the same day and month, but changed the year - so in 2024 you'd get a title that appeared in 2022, and in 2025 you'd get one from 2023. I thought it would be better to just cycle back to the start by working out the difference between the current date and the final id in the list and use that generate an index, but the code for that did not work the way I wanted it to and would always return the same movie no matter what dates I threw in. Eventually I got it working by seeing if there was a movie for the current date, and if not then do some maths to get an index based on the current date and the date of the last movie.

Completing each puzzle would come up with a timer showing how much time was left until the next puzzle. Because JavaScript dates are some of the dumbest things to have ever been invented, the code for this was longer than I thought it would be, but it wasn't as involved as the date calculations to get the puzzle. The timer would also include links to the other 3 games as suggestions for the player to move on to.

I started on writing out the list of games, which was must faster than populating the list of movies - in part because I either already knew all the information, or the list of highest rated games on Wikipedia had most of the information to hand with a simple scroll up or down the page. I figured I'd be able to do something similar with songs, and started thinking about how I could make the movies list simpler. So I removed Quotes and replaced it with Genre. Between the 4 games, I decided there would be 2 years worth of puzzles, so had to come up with nearly 3,000 sets of clues.

When setting up the games list, I was jumping around between years so that there wasn't a clump of games from the mid-00s. But this was slowing me down, so I made a tool where I could enter all the data without worrying about placement and then made shuffle them all before I exported it. It would also be able to tell me when I had tried to enter a duplicate, which I was also trying to avoid.

The tool. And the greatest Christmas movie of all time.

Another feature I added was unlockable badges. Each game has 8 badges that can be awarded for solving the puzzles. 5 are for simply getting a certain number of names right, 2 of them are for achieving win-streaks, and 1 is for getting the name on the first try. The likelihood of getting it on the first try seemed very unlikely to me, but my cousin got the name of the first puzzle she tried on her first guess compared to me who got it on guess 4, and I'm the one who setup all the clues.

Correctly guessing a title and unlocking a badge.

I worked out that if I spent the entirety of July slowly chipping away, I'd need to add about 100 puzzles a day. I hadn't taken into account that this also included weekends, so realistically I needed to hit more than that. Although it was mid-June when I did this calculation, so if I started early then I wouldn't need to do as many, which would probably help whenever I got stuck.

Once I started getting properly into it, it turns out that getting to 50 is relatively easy, 100 is a stretch that requires the internet for help, and after hitting 200 it becomes really problematic to find names of things that are probably known by enough people that they aren't really obscure, and have them fit within my restrictions. So I decided to cut back, but still having enough clues to see out the remainder of 2022, and all of 2023 - bringing the total from nearly 3000 to just under 2000.

The games list was done first. Then movies. And then shows. Songs was problematic because one of the clues was lyrics which didn't immediately come up when searching for them, and I didn't think most of these lyrics would actually be helpful. Setting targets for each day was extremely helpful, even if most days I never reached them because I ended up in several dead ends trying to find things that I didn't already have.

After going through songs that were including on Rock Band and Guitar Hero, I then scoured through the UK charts from the past 5 decades to see what reached number 1 and somehow still ended up with nearly 200 songs still to go. Being selective was kind of an issue too. Ed Sheeran is not included because if he's supposed to be one of the best musicians of all time then how come I can't name any of his songs? There's no Beatles either because fuck 'em. Although I think I'm justified in not including songs from convicted sex offenders like the Australian pet hospital man.

Once the lists were hooked up, I gave some family members the link and they requested an ability to earn points. I was planning on adding a share feature but didn't really know what to share, so points fit into that slot nicely. Between 10 and 50 points are rewarded depending on how many guesses it took, and there is a bonus that increases each day when achieving a streak. So, theoretically, if you had a streak of 190 and got the answer in the first guess, you'd get 1000 points for that day.

And then it was all done.

Except for small changes like favicons, setting up the pages with Google because they weren't automatically found unlike when creating posts on this blog or adding games to Itch, and then adding links to the other games I released this month.

Plus I've also fixed a few minor bugs as I've come across them, since I've now been playing this for a month - there were two bugs with being able to guess without having filled all the spaces.

And so the Month of Games is now over. A little experiment to get me to actually finish 4 projects, and instead I've done 7.

All of these have released for free which is not sustainable so whatever I work on next is going to have a price attached to it. I've been busy learning things as I have been tinkering away at getting something working, and have set some targets that seem doable so we'll see what happens.

Popular posts from this blog

Getting Started with the FireRed Decompilation

Phoning It In

Tonight Matthew, I'm Going to Make...