If you are looking for a relatively simple but full functional 2D Rust powered game engine, the Comfy Engine may be right for you. With a design inspired by other GameFromScratch favorite frameworks such as RayLib and Love2D, Comfy provides most of the functionality you would need to create a 2D game and makes it easy. It is however very early on ( 0.2 version! ) and documentation is very limited, so if you aren’t comfortable jumping into the code, this probably isn’t the right engine for you for now.
Comfy is described it’s version 0.1 release blog as follows:
Comfy is a product of our work at LogLog Games, where we’ve been using it for almost a year now, and have currently a few games in progress that are it. Internally, we have well over 20k lines of game code using using Comfy.
While still in its infancy, Comfy provides a solid foundation for making 2D games in Rust. It offers an immediate mode style API for drawing and audio (similar to macroquad), and a small ECS foundation that builds on top of it.
Comfy is not prescriptive in how you build your games. It’s not an ECS based engine, nor is it a macro-heavy engine. It’s a pragmatic toolkit that lets you focus on your game. We didn’t aim to create the fastest engine, or the most performant renderer, the most flexible render graph, or the most powerful ECS.
We’re not trying to compete with Unity, Unreal, Godot, or even Bevy. If you’re looking for state of the art usage of Rust’s type system, a fully featured PBR renderer, or the most extensible and performant solution, Comfy is not for you.
Our goal was to build an engine where if you’re making a 2D game, you can just run
cargo new game, and start writing game code. Comfy does not require you to study its internals, watch tutorials, or read lots of documentation. Comfy does not want you to do things in any specific way. You’re free to structure your game however you want.
If you want to draw a sprite, you just call
draw_sprite. If you want to play a sound, you just call
play_sound. If you want to access the ECS command buffer, you don’t need to use dependency injection or macros, you just call
c.commands(). If you want to create an egui window, you access the
c.egui. Comfy uses a single
c: &mut EngineContextpassed around your code which can be used to access all of its functionality.
Comfy also uses global variables for state internally. This is intentional, as we haven’t really found performance gains from using implicitly parallel ECS in our past experiments with other engines. We prefer to use data parallelism (e.g. with rayon) where necessary, while keeping the core engine single threaded. This may be suboptimal, but it also massively simplifies everything.
We also use
RefCells, which to many may seem like an anti-pattern, but it also greatly simplifies game code as it lets us work around limitations with partial borrows.
Despite the above, Comfy is still very fast. It’s not as fast as some of the alternatives, and you will 100% be able to create a benchmark that will make it look bad. But game development is not a competition about who can render 100k sprites the fastest. It’s about making games. Comfy has a builtin integration with the Tracy profiler, and we use it heavily throughout our development to make sure our games run fast enough.
The hardest part of making a game engine is actually making the game. Comfy tries to take reasonable sacrifices and just allow its users on the game itself.
By game we mean something a small team of indie developers can make and ship in a reasonable amount of time. Comfy will not power the next AAA game, it won’t help you build a 3D MMO, or an infinite voxel world. It won’t help you beating UE5’s Nanite in benchmarks, we don’t even have a 3D perspective camera (yet).
You can learn more about the Comfy rust game engine and see it in action in the video below.