Best graphics library that you’re not using (yet)raylib, the library that brings joy to engine development |
Date | ||
---|---|---|---|
Updated | |||
Author | Fix | License | CC0 |
If you’ve done any game engine programming, you know what hassle it can be to just start. Before you can even begin to draw anything onto the screen, you need to make a window. How do you do that? Well, it depends on your OS, your Desktop Environment and display server. So when you accommodate all of that, then you need to think about how do you talk to the GPU: OpenGL, Vulkan or perhaps even DirectX? So, you get all of that working and only then can you move on to everything else, like audio or input, which come with their own challenges.
Naturally, 80% of us just use a library to manage all of this. SDL is my poison of choice, with GLFW being another popular library. But even they ask for you to be pretty involved in the inner workings (for a good reason, they’re here to just help you get building, they leave the software design up to you). What if you just wanted something that takes in simple commands and does exactly what you want, without demanding deep involvement from you?
|
That’s the whole thing! Even without any explanation, this code is easy to understand:
If you suspect that I’m cherry-picking the simplest example, just take a look at this one-file Pong example or any of the examples provided on raylib’s page.
As you can see, it removes a lot of the complexity that usually comes with making a game engine. But most people are not using that complexity to their advantage, anyways. In fact, people are copying the same tech-stack over and over, without making any modifications, to the point that people have created several different template repositories. (just in case it doesn’t come across, there are 4 separate hyperlinks in that sentence!).
At that point, I must ask: why? If your goal is to make a game, but you’re not willing to make changes to your libraries, why bother with so many of them? Just have one library that will manage the stuff you’re not willing to deal with, and focus on making the game and doing the optimisations in your game code. That’s exactly what raylib is perfect for! And there’s a good chance that if you’re new to making engines, raylib will simply outperform your engine in the same task.
raylib still gives you a lot of freedom in how you want to design and structure your engine and code. On its own, raylib does nothing, it doesn’t even implement a basic runtime loop. It just gives you a lot of tools to use so, you can focus on what the game does with the provided tools, without necessarily focusing on how it’s done. Just the basic library offers input management, window management, drawing shapes, collision checking, font management and drawing. And each module is self-contained, so they can be swapped out if you wish to go with a solution of your own.
If you want to use the full ‘raylib ecosystem’, there’s a lot to choose from as raylib comes with optional libraries for audio, maths, model management, GUI and I probably forgot about some of them. But of course, you can always substitute it for whichever library you prefer. raylib is intentionally kept ‘open-ended’ and simple, so it can integrate nicely with other libraries. I can personally confirm that it’ll play nicely with GLM (admittedly, once I apply my own wrapper functions).
If you need a bit more flexibility or control over drawing, you can always use rlgl, OpenGL-like API that raylib uses internally. It can also target multiple versions of OpenGL, supposedly all the way down to OpenGL 1.1 and up to 4.3. I would recommend this route if you plan on going 3D, since it provides a lot of utilities that will help you do more advanced techniques, like batching and instancing.
Besides games, raylib is amazing for tools, especially when mixed with raygui or Dear ImGui. raylib technologies themselves have created several tools running on raylib + raygui. Just look at how simple it is to get started! Compared to the complexity of something like Qt (which mostly stems from over-designing, but more on that some other day), this is just a marvel to work with. If your game requires a custom launcher, consider giving raygui a shot. It can even be used without raylib, if you’re willing to fill in some wrapper functions! For those of you who simply prefer Dear ImGui, you can write a simple wrapper to make it work with raylib, since raylib is built on top of GLFW. Alternatively, you can use this pre-made wrapper or, this template.
You might’ve picked up on it, but I’ve not expressly mentioned it - I tend to use raylib with C++. There is no special reason, I just like some features like C++ provides (yet another topic for another day). Since it is a C library, it plays rather nicely with C++, no surprises there. There is a C++ wrapper for raylib, but since it’s ‘object-oriented’. I tend to just write my own, around bits I need, when I need them.
However C++ is not the only language that plays nicely with C libraries. Of course, the popular new kid on the block is Rust, but options also include D, C#, Lua, Python, I even made a ‘binding’ to FTE QuakeC!
|
I’ve come this far without even mentioning portability. Naturally, Linux, Windows and MacOS are supported, but the official support extends to Android, FreeBSD and Web (through emscripten). As far as unofficial ports go, there’s one for Nintendo Switch, Nintendo 3DS (abandoned?), PlayStation 4, and my personal favourite - PlayStation Vita. It should run anywhere GLFW runs, so getting it running on PlayStation 3 or Xbox 360 might be possible, but it’s just not a very popular target anymore.
On the topic of popularity, let’s talk about some raylib projects! Sidestep Legends is top-down roguelike, made by a single person, who even livestreamed going through their code, explaining it. Tsoding, a streamer I highly recommend checking out, uses raylib to visualize his neural network. Code is available on GitHub. I myself am working on a settlement management game called Afterthought, done purely in C, with the intention of livestreaming the dev process. The code is available on GitHub and GitLab. And a bunch of others, you can check out in the June 2023 Showcase video or this GitHub discussion.
But of course, however much I enjoy raylib, it has issues. While we go over them, keep in mind that I’m purposefully ignoring issues which arise from the fact it’s a C library.
The biggest issue is the lack of documentation. Not completely, raylib page contains a cheatsheet and a lot of examples, which is enough for people comfortable programming. Sadly, the cheatsheet is sometimes out of date, so you’re recommended to read the raylib.h header itself. And if you’re about to mention the GitHub Wiki, check its content. It’s about getting started and porting to other platforms, but it contains very little documentation about the code itself.
Another issue worth pointing out is that it’s still limited to
OpenGL. Granted, it has a wide range of supported versions of OpenGL,
but the world is slowly moving towards newer APIs, like Vulkan. I do
believe this is likely to change (although, not necessarily in the very
near future).
The previous block is wrong! As I have discovered during the editing process, the OpenGL ES 2.0 API is actually going through Google’s ANGLE library, which takes in OpenGL ES 2.0 requests and translates them to Vulkan, Metal, DirectX 9 or 11, or just passes them through to use OpenGL ES. The only reason I found this out is because raysan did an AMA in the raylib discord server, where he mentioned it, and I had to dig through the code! Does this not reinforce my first point?!
Some consider this a nitpick, but I must point it out: It has a tendency to “steal” labels. Usually, C libraries will have the labels of their structs and functions start with a prefix (e.g. SDL uses the prefix SDL_, Sean Barret’s libraries use the stb_ prefix, etc.). raylib doesn’t do that, and since C doesn’t have namespaces, you might run into clashes if you ever wanted to define a colour constant, like LIGHTGRAY. However, Tsoding brought up an interesting ‘counterpoint’ during one of his streams: raylib tends to use PascalCase in its labels, which is very uncommon for C. In a way, the naming style acts as a form of namespacing, at least for non-constants.
Last issue I’d like to mention is one I don’t really consider an issue, but I see it often whenever raylib is mentioned: No editor, like Godot or Unreal have. This is always odd to see because there seems to be a misunderstanding on the difference between raylib and full-blown game engines. Godot/Unity aims to be an (almost) All-in-One solution, where you are only meant to put your assets in and make them act the way you want, with some scripting. raylib is intended to help you build your own framework, where you decide how your assets and scripts are processed. Think of this way: Unity pulls you into its sandbox, where you can build sand castles using their sand. raylib gives you a wide choice of wooden planks and sand so you can build your own sandbox, where you will then build the sand castles, just the way you want them to be.
That’s all for now! I hope you try raylib for one of your projects or at least watch this Handmade Seattle talk, where raysan compiled his presentation made in raylib, live, right before presenting it!