If your browser is set to dark mode by default, you've probably noticed the site looks different! I now have some dark mode CSS, so this blog isn't eye-searingly white if everything else is dark on your screen.
So this is a post that's been bouncing around my head for a while, in one form or another. I created and maintain Quicksilver, a 2D game framework for creating games for desktop and the web. The reason I'm writing this post is that I also haven't used Quicksilver to make anything for over a year.
This blog post has been a long time delayed, but late is better than never! The Quicksilver alpha is humming along, with bugs and API problems being addressed. While that work continues, I want to unveil
elefont, a crate that I've developed for font caching.
Out with the old, in with the new! After some frustration with Hugo, I've moved to Zola and some light CSS.
This year has been great for Rust gamedev on the web. Huge progress has been made towards a full game stack being available more-or-less "for free:" most of the foundational crates have available web support, in one way or another.
The graphics API of Quicksilver isn't as dire need of a rework as the lifecycle APIs, but I wanted to take the next breaking change as an opportunity to address some long-standing issues.
Quicksilver has always had some major API compromises to deliver on its core promise: write a game once, and it targets desktop and the web with no changes. The two ugliest compromises are the
Asset APIs, for managing your application's core loop and file loading, respectively.
golem is a mostly-safe graphics API that targets OpenGL 3.2 and WebGL 1 that helps make writing GL less painful.
With the recent update to
winit, it gained web support! This is great, and it means that Quicksilver doesn't need to have its own parallel implementation of windowing. However, there is room for an abstraction that's a little simpler than Winit, and takes advantage of
async/.await, which is where
blinds comes in.
Often your application might want to store gamestate or configurations, but the web has no filesystem access. Additionally, you don't want to just dump files in the user's home directory; each desktop operating system has a different preferred location for storing application-specific data, and often different locations for different kinds of data.
gestalt, a library that bundles up your data and stores it away so you don't have to.
This year saw the release of
async/.await in stable Rust, marking a huge change in how asynchronous code is written. Previously, one would have to chain a series of combinators onto a
Future instance to accomplish asyncrhonous tasks. In Quicksilver, this was used for asset loading (for compatibility with the web backend), and has been a frequent source of pain.
I started this year with a blog post about the state of Quicksilver where I set a goal for myself: get web support for important game development crates upstreamed. At the end of the year, I'm happy to update this work (by me and many others!) has been a success, and the core of Rust's game ecosystem is now-web enabled. In the future, I want to write a brief overview of those changes, but for now I want to focus on their relevance to Quicksilver.
So www.ryanisaacg.com has a very new look, powered by Hugo and my (fairly small) fork of the hello-friend-ng theme.
For anyone who doesn't know, Quicksilver is my 2D game framework that targets desktop and web. It is a pure-Rust library that focuses on ergonomics and simplicity.
Quicksilver is part of a small (but growing) set of Rust game engines. Notable are the Amethyst project, an open-source game engine, and ggez, a LOVE-inspired 2D game framework. Increasingly it is practical to build an entire game with only the Rust toolchain: winit provides windowing, a variety of crates allow access to platform graphics APIs, rodio provides sound, rusttype for font rendering, etc. A pure-Rust game framework is getting easier to make all the time.