Photo from our minecraft server - taken by Pat.

Setting up a Minecraft blog via 11ty

Posted: 05 Jun 2022. Last modified on 05-Jun-22.

This article will take about 6 minutes to read.


My brothers and I have a inline icon Minecraft server on Realms, and we play on it about once a week. Now that we are nearing our server’s first anniversary, I wanted to take some time and reflect on what we’ve created so far.

What better way to do that than by starting a new blog?

Choosing a tech stack

My current blog is statically generated by Jekyll and hosted on Netlify. These have served me well so far, but I’ve run into issues with downloading the correct ruby version on my machine (and it seems like I’m not alone in that), and I don’t know much ruby.

This has made me question my decision to use a ruby-based framework. The killer application for jekyll has been its github-pages support, but I no longer host the site there. It’s important to have a build system that you are comfortable with and trust, because if anything goes wrong, you’ll need to be able to fix it. Interestingly, this is one of the reasons why the nix package manger has not gained much popularity.

I eventually settled on 11ty. It’s a static site generator which is very similar to Jekyll, with one relevant difference: it’s written in Javascript.

Getting to know 11ty

Love it or hate it, if you’ve been a developer for long you probably know a bit of javascript. It is the lingua franca of the development world.

11ty made the decision to do all of the configuration within a javascript file, .eleventy.js, so you can take advantage of the expressiveness of a real programming language when you are configuring your environment.

It’s nice to be able to set up event handlers and required module in one place, instead of having to rely on a suite of JSON, YAML or TOML files to get the job done. Since I’m primarily an Android developer, it reminded me of Gradle’s approach to creating builds.

Creating a starter project

11ty has a number of great starter projects, which cover a number of use cases. Their integration with Netlify is amazing as well. With one click on the starter page, you can have netlify create a template project on your github account, and take care of your build process.

Choosing the theme was the hardest part. I eventually went with 11ty-midnight. I’m not one to pass on a nice dark theme!

Generating content

Similarly to Jekyll, 11ty uses markdown and templates as part of content generation. Nunjucks is a templating engine very similar to liquid, so I was able to get used to it pretty quickly.

In short, by putting macros like this in the code, we can have the templating engine insert html and javascript as part of a compilation step.

<div>
    {% include layouts/posts.njk %}
</div>    

This makes development faster by promoting code reuse, and it makes the site run faster because we are doing most of the effort at compile time instead of while the app is running. Cool!

Generating images

This part was a little trickier! The first step was finding a place to store the images. I wrote another article on the options that I considered, but I eventually went with AWS S3.

Using S3, I’m able to serve images without putting much of a dent in my Netlify quota. However, the images that are generated by the Minecraft client in ~/Library/Application Support/minecraft/screenshots are each several megabytes, and they are stored as PNG files. Serving these images directly would take far too long, and I’d be downloading higher fidelity images than I would have a chance to actually show.

I’d rather not have to pay extra for all that wasted data! My next step was to better compress the images so that they would be easier to serve.

Image Compression

Whenever I need to modify images, the first tool that I reach for is ImageMagick. It’s the most powerful scriptable image manipulation program I’ve ever seen, and it is great for applying the same transform to all images in a given folder.

The compression script that I ended up using was

imageFix () {
  magick "$1" \
    -quality 50 \
    -define webp:alpha-compression=1 \
    -define webp:alpha-quality=0 \
    -define webp:preprocessing=0 \
    -define webp:lossless=false \
    -define webp:target-size=500000 \
    -define webp:method=6 \
    -define webp:near-lossless=70 \
    -define webp:auto-filter=true \
    -resize '2000x2000>' \
        "$1".min.webp
}
# for i in *.png; do imageFix "$i"; done

There is a lot to unpack here, but I’ll start with the last line, which defines the format. Webp is an image format from google that achieves compression rates as good as or better than JPG, while still allowing for transparency, like PNG. It’s the recommended format for web images now, due to its impressive compression rates.

The other lines here define several of the imagemagick WebP encoding options. They make sure that the image:

All in all, this brought down the size of my files drastically, while keeping the quality high enough that it would be hard to tell the difference.

On average, the files went from about 3 MB to about 100 Kb, for a compression ratio of 96.66%.

One of my images from a whopping 10.1 MB down to 49 KB. That’s a compression ratio of 99.51% 🎉

Why is the compression ratio so high?

That’s a fair question - these are not typical numbers. But let’s not forget that this is for a Minecraft blog, a game which is not known for its graphical fidelity. The original images were PNG files, which store every single pixel individually. By converting it to a WebP image, we are using an algorithm which only cares about the places where the colors change quickly, which happens comparatively infrequently in a minecraft stillframe.

Wrapping up

Now that images and content are in place, the only thing left to do is keep playing Minecraft so we have more to publish!

You can view the current state of the blog here. Thank for for reading!