The @smsgems bot

Posted on 30 Oct 2019

I’ve always felt like a lot of Sega Master System game box artwork looks like someone slapped 90’s clip art onto a piece of graph paper. I decided to make a Twitter bot that generates fake Master System games by doing just that.

This is the aesthetic we are going for:

I first needed to find a good source for clip art images. I came across this Microsoft clip art collection uploaded to archive.org. The archive contains roughly 60,000 clip art images in Windows Metafile format (WMF). I did a rough search for stuff like picture frames and horizontal dividers that clearly wouldn’t work as cover art but kept everything else.

The WMF files were a tricky to work with, so I decided to convert everything to SVG format instead. Luckily, Inkscape is able to open WMF files and works in headless mode, so converting the images was trivial.

for i in $(find . -name '*.wmf'); do
    inkscape "$i" --export-plain-svg=svg/$(basename $i .wmf).svg
done

Inkscape generally did a great job of converting the WMF files, but did sometimes produce quite messy paths with visual artifacts.

Next, I had to generate names for the games that match the used clip art. Each clip art came with a set of keywords embedded in the corresponding HTML file, which provided a nice starting point.

<!-- from MC900019169.htm -->
<meta name="WT.oss" content="(1 OR dinosaurs OR extinct animals OR reptiles OR T-rex)" />

Let’s extract all the keywords using the rvest package:

library(rvest)
library(readr)

ids <- list.files("C_OK")

contents <- sapply(setNames(ids, ids), function(id) {
  read_html(sprintf("C_OK/%s/%s.htm", id, id)) %>%
    html_nodes(xpath='//meta[@name="WT.oss"]') %>%
    html_attr("content")
})
  
tags <- contents %>%
  gsub("[()]", "", .) %>%
  strsplit(" OR ") %>%
  lapply("[", -1)
names(tags) <- names(contents)

out <- data.frame(id=names(tags), tags=sapply(tags, paste0, collapse="|"))
write_csv(out, "tags.csv")

In order to generate titles that somewhat resemble game titles, I came up with a number of templates to build from. The bot builds a name by randomly choosing one of the following templates and filling in the blanks ({}) with random keywords matching the clip art, e.g. {} in {} World becomes T-rex in Dinosaur World.

{}                      {} Land            {}'s {}          
{} {}                   {} of {}           Adventures of {} 
{} {} {}                {} Quest           Final {}         
{} 2                    {} Star            Mega {}          
{} 3D                   {} vs. {}          Power {}         
{} and {}               {} Zone            Super {}         
{} and the {}           {}: {}             The {}           
{} II                   {}!                The Legend of {} 
{} in {} World

Most noun keywords were pluralized, so I randomly converted the chosen keywords to singular or plural with 50/50 probability using the pluralize package. This did at times produce some strange results like trying to pluralize “golf” into “golves”, but I guess that’s part of the charm.

I created two cover layouts that most games resemble: one with the Sega logo on top and one with the logo in the bottom-right corner. Each cover is also given a genre stamp in the top right corner (e.g. “ACTION”, “FAMILY” or “SPORTS”) and possibly a subtitle like “The Mega Cartridge™”.

In order to make the covers look less computer-generated and more like a scan I used imagemagick to overlay a paper grain texture, apply a subtle gaussian blur and rotate the picture slightly.

Finally, I also wanted to give each game a release year. In order to make it a bit more believable, I grabbed a list of all SMS games released and used the distribution of games released each year to sample from.

Overall I’m quite pleased with the results given the relatively small amount of work it took. The results are rarely funny, but they are often pretty believable.

Here is a collection of some of my favorites so far: