April: Arenas, no-engine gamedev and some reflections
April! What happened? I did a lot of blogging about Odin-related things.
I wanted to give people some insights on memory arenas. So wrote about that. Then there was a bunch of blogging related to libraries and software I’ve made. I summarize it all below.
At the end of this newsletter I also show a sneak peek of my latest gamedev experiments, along with some reflections on Odin, Sokol and Raylib.
Memory arenas and handle-based maps
A thing I often see is people trying to combine arena allocators with dynamic arrays. You can sometimes do that, but you need to be aware of a bunch of potential pitfalls. There are also a bunch of cool tricks you can use to your benefit. With that in mind I wrote a blog post and also made a video on the topic:
Some of the ideas in that blog post actually made me re-design my “handle-based map” package.
A handle-based map is used to associate array items with robust identifiers. The handle is essentially an index plus a generation counter.
In particular, I made that package use virtual memory arenas in smarter ways. I wrote a whole post about that as well! In it I explain three different approaches of implementing a handle-based map. The updated source code can be found on GitHub.
I made a video about this as well:
I’ve chosen to write about handle-based maps because it’s something that many game developers run into. But there are lots of small nuances related to how one implements it. When making CAT & ONION I rewrote my handle-based map several times and figured things out as I went. I hope I can save people some of that time.
My Odin C Binding generator
At the start of April I wrote a blog post that explains how to use my Odin C binding generator and what the benefits of a generator can be.
This binding generator takes C headers and tries to output Odin bindings that utilize Odin features such as bit_set
. It also tries to generate bindings that actually look good and are easy on the eye. I think that bindings should be as easy to learn from as the original headers. With that in mind, it also makes sure to bring along comments and documentation.
If you try to use it and run into any problem, then please post an issue on GitHub! I’ve also recieved a bunch of Pull Requests that have added features and fixed bugs. Thanks a lot to those who helped me!
No-engine gamedev using Odin + Raylib
I realize that some people may find “making games from scratch” daunting. By “from scratch” I mean not using any big engine.
Exactly what “from scratch” means varies from person to person. Some may say that it means building everything on top of Operating System APIs and rendering APIs such as Vulkan. To me it just means that you use a programing language and some kind of basic library, such as Odin + Raylib. But you don’t have any big engine such as Unity or Godot.
Recently, I’ve also tried to use the term “no-engine gamedev”. But that also confuses some. Then people debate about what an engine is instead! By engine, I again mean a big engine like Unity. So “no-engine gamdev” means making a game without such software.
In any case, I wrote a blog post called “No-engine gamedev using Odin + Raylib” that attempts to be a quick crash course on the super basics of Odin + Raylib. Those basics are followed up by some pointers on how to manage entities and how I approach making level editors. I hope it can make the idea of no-engine gamedev less daunting. The post is almost like a little “summary post” of all the different things I’ve done in this area, with links to videos, blog posts and articles where you can learn more about specific things.
The Zylinskiverse
I’ve made it so you can buy my Odin book on the domain store.zylinski.se — My own store, so profesh! I’ve also made it so that this newsletter is hosted on news.zylinski.se. Welcome to the Zylinskiverse!
In the future, perhaps I’ll also start selling CAT & ONION on my store.
Some thoughts on Sokol and Raylib
The last few days me and my partner have been poking around with some little video game experiments. I don’t have much to show other than the strange image above.
But I do have some technical notes to share. Initially, I started doing it in Sokol, using my sokol-hot-reload-template. I was trying to do a 3D game with flat, paper-like characters and trees and stuff.
I went with Sokol because I did have some trouble using 3D in Raylib before. In what way? The 2D support in Raylib is great. But the 3D support often forces you to go into the C code of Raylib and port some functions over to Odin, so that you can modify them. This is because Raylib’s 3D code makes a bit too many assumptions about how you want to set things up. For example, I didn’t like how `rl.DrawMeshInstanced()` worked internally. So I ported it to Odin and adapted it to my own needs.
Initially everything went great with Sokol! I got shadowmapping working and managed to create flat, paper-like characters that used my partner’s art. Sokol is more low-level than Raylib (it’s more like a rendering API and less like a “game creation library”), so none of the annoying assumptions bit me.
But then I wanted to make an editor. For CAT & ONION I had a very fun time making editors using Raylib’s 2D drawing features. A button was just a rectangle with some text in it. I got a lot done, very quickly! Without any extra IMGUI library or anything.
Sokol didn’t have such things built in. Naturally. It’s more low-level! Less assumptions! But I also didn’t want to pull in Dear IMGUI or something like that. So I started making my own “rectangle drawer” procs, similar to rl.DrawRectangle
etc. Quite quickly I was totally lost in the sauce of making utility procs, when what I really wanted to do was to make my editor. I wanted to just quickly layout some panels with some buttons on them to spawn some graphics!
People may scream at me “well, then, just put in Dear IMGUI or something!!”. But I don’t want to! I like writing my own IMGUI stuff, because I come from a tools programming background. I just don’t want to write the code that draws the rectangles and a million different variations of such procedures.
Also, I was actually missing some of the basic collision detection features of Raylib. Not that it’s very hard to implement them. But I was just starting to feel tired from having to implement so many small things. I got side-tracked every time I tried to implement something for the game.
At this point it dawned on me: I wasn’t having fun. I love when the level at which you’re programming is such that you feel like you can easily do the part that is “most fun” to you. For some people perhaps the graphics programming is most fun. But for me the most fun part is bolting together gameplay, shaders, making editors, thinking about data formats. Making it all work together. But I also love the “from scratch” feeling of not using a big game engine. I love when my game is just a program that uses a library. I want it to be as simple as possible, but still give me a suitable amount of features.
In any case, since I wasn’t having fun and just wanted all my good old Raylib stuff, I just re-wrote it all using Raylib. I know there may be some issues down the road regarding the assumptions in Raylib 3D, but I think I can work around them. It’ll be OK!
By all this, I don’t mean to tell anyone what libraries to use. The important thing here is that you find something that makes it possible for you to quickly get to the parts that are most fun for you. Find that sweet spot!
Thanks for reading!
If you want to hang out and discuss Odin or game development, then join my Discord server: https://discord.gg/4FsHgtBmFK — It’s a friendly place!
/Karl Zylinski