Setup Zig for Gamedev
Tags: zig, gamedev, beginners, tutorial
Published: 2021-03-13 17:39:17

**UPDATE 2023-04-02:** Updated the guide for the latest Zig version 0.11.0-dev.2336+5b82b4004

This is a step by step guide on how to get started with game development using the [Zig programming language](https://ziglang.org) on Windows.

TL;DR, here's an 8 min video of every step: 
{% youtube r92cGMcj9Vo %}
Sadly, the video is outdated because it uses an old version of Zig (0.8.0-dev.1463+f950489ed). That's why the written guide is recommended.

#Visual Studio Code

We're going to use Visual Studio Code as our [IDE](https://en.wikipedia.org/wiki/Integrated_development_environment). It will provide us with syntax highlighting, code completion and an interactive debugging experience. So go to https://visualstudio.microsoft.com/downloads/ download and install Visual Studio Code.

#Zig

Out of the box Visual Studio Code doesn't support the Zig language. So, first we need to grab the Zig compiler itself. Since Zig is currently pre 1.0 I recommend getting the latest **master** build from https://ziglang.org/download/ for your platform (at the time of writing [zig-windows-x86_64-0.11.0-dev.2336+5b82b4004.zip](https://ziglang.org/builds/zig-windows-x86_64-0.11.0-dev.2336+5b82b4004.zip)). To make the `zig` command available from the command line extract the downloaded archive to a known location: e.g. `C:\Users\<Username>\Downloads\zig` and add the location to your PATH variable.

This is how you can edit your PATH variable on Windows:
1. Search for "advanced system settings" in your start menu (be careful not to perform a Bing web search 😅)
2. Click on environment variables
3. Now you can edit the PATH for your user
4. Add the location where you extracted Zig to your PATH
5. You can verify the `zig` executable is found by running `zig version` from a new cmd prompt

Now you are able build Zig software from the command line! 😊

#Setup Zig development in Visual Studio Code

In Visual Studio Code we want to install the Zig Language extension (extension id: `ziglang.vscode-zig`) to get features such as completions, goto definition, find references, rename symbol, and format code.

For debugging we want the C/C++ extension (extension id: `ms-vscode.cpptools`). If you're still unable to set breakpoints in your code go to Visual Studio Code's settings and activate "Allow Breakpoints Everywhere".

Now that everything is installed we can start our first Zig project. Choose "File > Open Folder...". I create a folder `hello-gamedev` and click Open. Then press `Ctrl + J` to open the terminal and type in `zig init-exe`. This will create the main source file of your project in src/main.zig and a build.zig file which tells Zig how to build your project.

To build your project we want to create a build task in Visual Studio Code. Hit `Ctrl + Shift + P` and run `>Tasks: Configure Task`. Then choose `Create tasks.json from template`, and then the `Others` tempate. Edit your tasks.json to look like this:

```json
{
	"version": "2.0.0",
	"tasks": [
		{
			"label": "build",
			"type": "shell",
			"command": "zig build",
			"group": "build",
			"problemMatcher": [
				"$gcc"
			]
		}
	]
}
```

Now press `Ctrl + Shift + B` again and your project should build.

Finally, let's run your project from Visual Studio Code. Hit `Ctrl + Shift + D` to go to the debug activity and click on the link to create a launch.json file. You can choose any debugger. We will overwrite the contents anyways with the following:

```json
{
	"version": "0.2.0",
	"configurations": [
		{
			"name": "(Windows) Launch",
			"type": "cppvsdbg",
			"request": "launch",
			"program": "${workspaceFolder}/zig-out/bin/hello-gamedev.exe",
			"args": [],
			"stopAtEntry": false,
			"cwd": "${workspaceFolder}",
			"environment": [],
			"preLaunchTask": "build"
		}
	]
}
```

Your program should run if you hit F5 and the breakpoints you have set in your code should be hit.

# Graphics

Having only text can be a bit boring. So, let's create a window for to draw some fancy graphics! I recommend the [SDL2 library](https://libsdl.org) to do this. Grab [SDL2-devel-2.26.4-VC.zip](https://github.com/libsdl-org/SDL/releases/download/release-2.26.4/SDL2-devel-2.26.4-VC.zip) and extract the archive to a known location such as `C:\lib\`. Edit your build.zig so it looks like this:

```zig
const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "hello-gamedev",
        .root_source_file = .{ .path = "src/main.zig" },
        .target = target,
        .optimize = optimize,
    });

    const sdl_path = "C:\\lib\\SDL2-2.26.4\\";
    exe.addIncludePath(sdl_path ++ "include");
    exe.addLibraryPath(sdl_path ++ "lib\\x64");
    b.installBinFile(sdl_path ++ "lib\\x64\\SDL2.dll", "SDL2.dll");
    exe.linkSystemLibrary("sdl2");
    exe.linkLibC();
    exe.install();
}
```

Now paste this code which draws three colored squares using SDL into your main.zig:

```zig
const std = @import("std");
const c = @cImport({
    @cInclude("SDL.h");
});

pub fn main() !void {
    _ = c.SDL_Init(c.SDL_INIT_VIDEO);
    defer c.SDL_Quit();

    var window = c.SDL_CreateWindow("hello gamedev", c.SDL_WINDOWPOS_CENTERED, c.SDL_WINDOWPOS_CENTERED, 640, 400, 0);
    defer c.SDL_DestroyWindow(window);

    var renderer = c.SDL_CreateRenderer(window, 0, c.SDL_RENDERER_PRESENTVSYNC);
    defer c.SDL_DestroyRenderer(renderer);

    mainloop: while (true) {
        var sdl_event: c.SDL_Event = undefined;
        while (c.SDL_PollEvent(&sdl_event) != 0) {
            switch (sdl_event.type) {
                c.SDL_QUIT => break :mainloop,
                else => {},
            }
        }
    
        _ = c.SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 0xff);
        _ = c.SDL_RenderClear(renderer);
        var rect = c.SDL_Rect{ .x = 0, .y = 0, .w = 60, .h = 60 };
        const a = 0.001 * @intToFloat(f32, c.SDL_GetTicks());
        const t = 2 * std.math.pi / 3.0;
        const r = 100 * @cos(0.1 * a);
        rect.x = 290 + @floatToInt(i32, r * @cos(a));
        rect.y = 170 + @floatToInt(i32, r * @sin(a));
        _ = c.SDL_SetRenderDrawColor(renderer, 0xff, 0, 0, 0xff);
        _ = c.SDL_RenderFillRect(renderer, &rect);
        rect.x = 290 + @floatToInt(i32, r * @cos(a + t));
        rect.y = 170 + @floatToInt(i32, r * @sin(a + t));
        _ = c.SDL_SetRenderDrawColor(renderer, 0, 0xff, 0, 0xff);
        _ = c.SDL_RenderFillRect(renderer, &rect);
        rect.x = 290 + @floatToInt(i32, r * @cos(a + 2 * t));
        rect.y = 170 + @floatToInt(i32, r * @sin(a + 2 * t));
        _ = c.SDL_SetRenderDrawColor(renderer, 0, 0, 0xff, 0xff);
        _ = c.SDL_RenderFillRect(renderer, &rect);
        c.SDL_RenderPresent(renderer);
    }
}
```

Hit F5 and after the build is complete you should have this on your screen:

![three colored squares](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zjdjsztxz58wasmxye4u.png)

Congratulations! 🎉 Now you can finally start programming games in Zig.