A raylib alternative written in Odin
It's work-in-progress, but I'm quite excited. Also: Trying Jai and a better odin-c-binding generator.
Summer is dying here in Sweden. I last wrote to you near the end of June. Then I went on vacation. Now two months have passed; August has just ended.
My vacation was four weeks long. I barely used computers at all during that time, except for playing Stardew Valley in splitscreen for very many hours. Coming back to the computer I felt strangely curious about some old projects.
During my last newsletter I did some philosophizing about game engines. The newsletter included a link to a repository with some sketches on a plugin-based architecture for an Odin engine.
I haven’t done much more on that specific project, due to it feeling too unbounded, to unconstrained. Instead, what has happened is this: When I came back from the vacation I opened up my old “Metroidvaniaish” project. It’s a prototype I worked on last year that looks like this:
I dusted it off and easily got it running, thanks to Odin not having changed much. However, after that something else happened. I started thinking: What if I want to work on this project again; how would I want to do go about it?
The project used Raylib. While I managed to ship CAT & ONION using Raylib, I thought it would also be nice to have something “native” written in Odin that I also have more ownership of.
With that in mind I started making an Odin wrapper for Raylib. The long-term goal being to replace the Raylib parts (that are written in C), with native Odin code. The project-dusting-off followed by the start of this wrapping can be seen in this stream:
Since then I have worked a lot on it. My aim is this:
Make a native, Raylib-like library for creating video games.
The library doesn’t have to be identical to Raylib, the initial API is just inspired by Raylib because I like it. But I can also correct things that I don’t like about Raylib. I know the library very well, even how the internal C code works.
Use as little dependencies as possible. Use the “most native” APIs on each platform. Currently I’m working on a Windows version that uses win32 for windowing and d3d11 for rendering. I will not use GLFW, SDL, Sokol or any abstract thing like that. Hopefully I can get very far with just some
core
libraries and a few rendering libraries invendor
.
One big technical difference from Raylib will thus be support for multiple rendering backends. A big benefit of this is that I’ll eventually be able to make a WebGL or WebGPU backend that has no need for emscripten. It’s quite exciting!
Raylib uses OpenGL on all platforms. In order to make it work on web it uses emscripten to “translate” the OpenGL into WebGL. It’s a huge amount of magic that comes with many limitation and possible issues.
I have given the library the name “karl2d”, and you can find the repository here: https://github.com/karl-zylinski/karl2d — Note that it is not ready for any kind of use and missing lots of features. At the moment of writing I’m working on making a proper “rendering backend” interface.
I have already gotten rid of the Raylib wrapper. Right now only a Win32/D3D version exists. Somewhere down the line I’ll hop into Linux and try to figure out the most suitable rendering backend and windowing solution.
My current biggest issue is choosing a shader language. I’m trying to figure out which shader infrastructure that comes with the least number dependencies. Remember: I want to minimize strange library dependencies. However, for shading compilation I may be forced to use some dependency.
I might use the new slang language. But then I cannot use OpenGL on Linux: I’ll be forced to use Vulkan. Vulkan is quite overkill and overcomplicated for this kind of thing. But I’ll do what makes most sense.
If I make a Vulkan backend, then perhaps I’ll use it on Windows too, we’ll see. As noted, I still need multiple backends for web, mac and possible consoles.
There are more shader language alternatives: I might use GLSL and some cross-compiler, I might use HLSL and some cross-compiler. I’m gonna try my best to find a low-friction pipeline.
Another alternative is to just use the format of whatever rendering API you run on right now and provide a separate “cross-compilation library”, so that the karl2d library stays simple. That’s good for actually shipping games, since you don’t have this weird cross compiler smack in the middle of it all.
We shall see how it goes. I’ll do more streams on YouTube where I work on the library.
I recently tried Jai
Just after the vacation ended, I did two live streams where I tried the Jai language, which is currently in closed beta. The two live streams are here:
People naturally want me to provide comparisons of Jai and Odin. Pros and cons. Which is best? etc
I haven’t used Jai enough to say anything definite. What I can say is this:
Jai works. I had no trouble with compiling my first program.
I was able to make a small 2D game thingy quite easily: https://github.com/karl-zylinski/learning-jai-by-making-a-game
The package system in Jai is more relaxed than Odin. This may or may not be a good thing. You can do a bit more whatever you want and load separate files into a package. It is not as bound to a specific folder as Odin is.
I didn’t really try any of the famous Jai meta-programming, because I don’t find meta-programming that interesting. When I need meta-programming in Odin I just generate .odin files. That has filled all my needs so far.
I’m not planning on doing any more Jai in the near future. It seems like an OK language. But it is less polished than Odin and none of the additional features interest me that much.
odin-c-bindgen: A big update
The odin-c-bindgen, which generates Odin bindings for C libraries, now uses libclang instead of the clang executable. This means that it no longer has to write a JSON file to disk and read it back. Instead it just uses libclang to process the C headers, directly in the code.
Almost all this work was done by Xandaron, who I now see as “co-author” of the program, because he has done so much work on it. Huge thanks! You can read more about the release here: https://github.com/karl-zylinski/odin-c-bindgen/releases/tag/1.1
Odin gamedev architecture
I’m thinking of making a video or blog that is a bit more in-depth on how to do the architecture of a video game in Odin. It’s a huge topic where I need to limit myself. So I’m thinking: “Architecture for small, 2D, single-threaded games, probably using Raylib for simplicity”. If you have anything you’d like to see in such a video or blog, then let me know in the comments.
Thanks for reading
Have a great September! If you enjoyed this newsletter, then perhaps you want to subscribe? You’ll get roughly one newsletter, similar to this one, per month.
Have a nice day!
/Karl Zylinski
Are you planning for it to have a Metal backend on Mac in future?
A cool thing to see covered would be separation of simulation and rendering, it's a classic that I've had problems finding good posts where all is detailed.
I know this may be a bit off-topic but bear with me: I'm currently working on a client raylib + server ENet little multiplayer top-down demo, all in Odin, and I'm struggling with the separation of simulation and rendering in combination with networking. I'm making use of the "render tick" technique/method described by Jon Blow and Jakub (https://jakubtomsu.github.io/posts/fixed_timestep_without_interpolation/).
How do you avoid rubber-banding when very quickly tapping and releasing D to move, so quickly that you don't get to execute your simulation step (every 1/30s when you send your MOVE packet), but you do execute your render tick (as it happens every frame, 175hz in my monitor). This is my current issue. Maybe you have some thoughts thanks Karl :)