Back to the blog

Mach (Zig) Adventures - Part 1

Video games are fun, and many programmers got into the field to create their own games. Some successful indie games are a result of this passion.

Programming (web, software, IoT, so on) can also be fun. However, the last few years (maybe longer) seem to prove that the industry tends to be lazy. I harken back to the days when restrictions on hardware and programming languages required creatively robust solutions. Maybe I am wearing rose-colored glasses.

I fall into both categories above which are that I love video games and I love programming. I have always wanted to make a video game. I want to have an extremely, perhaps impossibly, high level of code quality that I can be proud of.

The final "piece" that leads to me to writing this blog series: I think we have the technology to have a "write once, deploy everywhere" system. Yes, some do exist, but they all have substantial limitations in one way or another, from my perspective. I want something flexible. What does that mean? I might spend another page in my blog series describing my ideal flexible system but, for now, I have never been more excited about anything than I am about...

Mach

My initial overview of Mach was that it was meant to be a video game engine. I was right but my overview was incomplete. After talking with Stephen a bit, I realized it's much more than that. It will be a graphics toolkit which, of course, can be used to create video games.

It is based on Zig and I like Zig more than I like C (which I already love). Everyone seems to have considerably unreasonable (in my opinion) love for frameworks like React and Electron (you're certifiable at this point) and languages like Rust. I understand the utility of such things but not the love for them as if they are some sort of magical solution(s).

To be completely open, I am pretty biased against frameworks in general. I think they obfuscate underpinnings that programmers truly need to wrangle with so they can learn high quality programming. That obfuscation can stunt growth, not enhance it, even if you are getting a speed increase in areas where problems are solved for you. This is not always true. I really enjoy Laravel, for example. I really enjoy Mach, as another example. These frameworks ride the line between "enough to get going" and "I better learn how to do this properly". Obviously, I have exceptions to the rule.

Zig is also in this domain, I believe. I get it. I love it. I would recommend you check it out, if you have not already.

Putting it all together

Mach seems to have everything I need, including the ability to render to web, desktop, and mobile with one codebase; leverage low-level hardware for performance; use webassembly; and create the kinds of video games and desktop experiences I have in mind.

  • Can render to web, desktop and mobile with one codebase
  • Can leverage low level hardware for performance
  • Can use webassembly (this is more for my own benefit because I want to use it and learn it more)
  • Can be used to make the kinds of video games I want to make (which are pretty crazy, never been done before stuff, easy for me to say, I know)
  • Can be used to create incredible desktop experience (again, I have some radical ideas about what a desktop OS should be)
  • Can be performant (and maybe should be out of the box unless you write very lazy code)

Just to be clear, Mach does not currently render to web although it does have an example that sort of does this. From my research, there is absolutely no barrier for Mach to get there, especially with WASM (Web Assembly) and WebGPU now. Zig is already a proven compiler for wasm and Mach should have no issues leveraging that further. This is generally the same for mobile. Mach is not there yet but I see no reason that it cannot do this.

The list is bigger than above but, again, I am only trying to be brief and hit the broad strokes. Mach seems to fit the bill here. I would go so far as to say that Mach is the only framework I could find that fits the bill here.

Getting going

Of course, the first thing I did was spend time on Google trying to nail down the right engine for what I wanted to achive. I spent months doing this and all roads kept leading to Mach.

After months of research, I joined Mach's Discord community and found a group of friendly, skilled, and brilliant people whose goals aligned with mine. I even shared some of my gripes with the state of the developer/programmer industry as a whole, and some members agreed that we could do much better.

I talked to Stephen, the person who essentially built Mach, and asked all kinds of questions. I am positive I was annoying especially as I stumbled around learning things that were way out of my scope. For example, how to interact with shaders directly. Stephen helped me out immensely (as did others), without complaint.

As I played around with Mach a bit more, I offered to help build out a simple ability. A rendering pipeline with customizable shaders that pulled in a spritesheet (atlas) with some data about it. Once a "sprite" is rendered on the screen, do simple interactions with the keyboard.

You can see the ultimate results in this example and I had to go through a few growing pains. I knew very little about rendering pipelines. I knew very little about shaders. I knew very little about Zig, to be honest, aside from a few simple hobby projects I had done. I was learning as I was building. I almost wish I had recorded some video content for Youtube so others could learn from my experience.

I have always learned by reading, doing and failing. Rinse and repeat many times over. I feel like these experiences are adventures for me. I hope others are inspired to overcome any fears they have about going on such adventures. Expect failure, learn to love it, learn to embrace it and I guarantee you will go far.

What did I learn?

Well the first thing I had to do was start with something basic. I figured the most basic start was to try and use the 3d engine in Mach to display something as if it was 2d. My game will be 2d but I have always dreamed of having 3d capabilities for 2.5d options down the road.

Stephen led me to the first example that I needed to understand: the textured cube. It had everything I needed to get going, even though I did have to ask a bunch of questions. Essentially, this example demonstrated how an image might be read into a texture, mapped over top geometry and meshed together to render a rotating cube.

During my foray into this example, I also learned some neat tricks. For example, there are some things that we can get for "free" from the GPU. Shapes, like a cube, are really just a bunch of triangles (I am speaking broadly) butted up against each other the right way to form what is rendered as a cube. You could, if you wanted to, write the vertices of each triangle manually (each x/y/z coordinate pair is a single vertex, more info here), but if you just tell the GPU that you want to have, say, 6 vertices, it will just generate them for you. In your shader (more info here and my shader example here), you can have very simplistic code as to how those vertices are drawn.

I also learned that there are some limitations (or at least some performance issues) with how you use a pipeline or using multiple shaders or how you might change the image you're using for a spritesheet/atlas.

I updated my example (the PR is here) to use multiple shaders and multiple pipelines. It honestly was not as bad as I thought it would be.

The biggest thing I actually had to learn was Zig. For example, the idea of structs make total sense to me but the "structure" of structs (if that makes any sense at all) was new. For example, the return type of a method inside of a struct makes a pretty significant difference when you're trying to use that method and it has an error that you might expect. Thanks to a member of the Mach Discord community, that was easily solved.

I wish I could remember everything I learned but I unfortunately do not. I will make sure to keep better notes in the future.

What now?

Well, I have an idea for a video game I would like to make that I think lends itself well to all platforms. I want to prove that this kind of thing can be built with great code quality, resilience, performance and as few bugs as possible.

I will also be giving my game out for free and I hope that Mach might be able to use it as a real world example of what Mach can do.

Part 2 of this adventure will include me setting up an initial repository with the Mach engine and the beginnings of some Zig functions that will make up core aspects of the gameplay.