# jok A minimal 2d/3d game framework for zig. [Project has been moved](https://git.sr.ht/~jackji/jok) **Documentation:** https://jack-ji.github.io/jok ## What you need? * [Zig Compiler](https://ziglang.org/download/) (Main branch follow latest zig) ## Features * Friendly build system, very easy to setup new project * Able to cross-compile between Windows and Linux (thanks to [ziglang](https://ziglang.org)) * Excellent rendering performance (thanks to SDL3's [geometry rendering](https://wiki.libsdl.org/SDL3/SDL_RenderGeometryRaw)) * Fully integrated Dear-ImGui * Asset system (via [physfs](https://github.com/icculus/physfs), supports fs/zip/7zip/iso etc) * 2D batch system * 2D geometry types * 2D primitives rendering (line/rectangle/quad/triangle/circle/ellipse/bezier-curve/convex-polygon/concave-polygon/polyline) * 2D sprite rendering (scale/rotate/blending/flipping/depth) * 2D sprite sheet generation/save/load * 2D animation system * 2D particle system * 2D scene management * 3D batch system * 3D geometry types * 3D skybox rendering * 3D mesh rendering (gouraud/flat shading) * 3D model support (glTF 2.0/wavefront) * 3D rigid/skeleton animation rendering/blending * 3D lighting effect (Blinn-Phong model by default, customizable) * 3D sprite/billboard rendering * 3D particle system * 3D scene management * Pixel shader support (desktop platform) * TrueType support, atlas generation/save/load (including kerning table for basic Latin) * SVG loading/rendering * Sound/Music playing/mixing * WebSocket client (webassembly platform) * Tiled editor support (tmx/tsx loading/rendering) * Lua scripting support * Misc powerful utils, such as easing/timer/signal/fsm/plugin system ## Supported platforms * Windows * Linux * MacOS * WebAssembly TIPS: To eliminate console terminal on Windows platform, override `exe.subsystem` with `.Windows` in your build script. ## How to start? 1. Add *jok* as your project's dependency Add jok dependency to your build.zig.zon, with following command: ```bash zig fetch --save git+https://github.com/jack-ji/jok.git ``` For a tagged version: ```bash zig fetch --save git+https://github.com/jack-ji/jok.git#0.16.0 ``` 2. Use *jok*'s build script to add build step In your `build.zig`, add: ```zig const std = @import("std"); const jok = @import("jok"); pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const exe = jok.createDesktopApp( b, "mygame", "src/main.zig", target, optimize, .{}, ); const install_cmd = b.addInstallArtifact(exe, .{}); b.getInstallStep().dependOn(&install_cmd.step); const run_cmd = b.addRunArtifact(exe); run_cmd.step.dependOn(&install_cmd.step); const run_step = b.step("run", "Run game"); run_step.dependOn(&run_cmd.step); } ``` If you want to add emscripten support for your project, the build script needs more care: ```zig const std = @import("std"); const jok = @import("jok"); pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); if (!target.result.cpu.arch.isWasm()) { const exe = jok.createDesktopApp( b, "mygame", "src/main.zig", target, optimize, .{}, ); const install_cmd = b.addInstallArtifact(exe, .{}); b.getInstallStep().dependOn(&install_cmd.step); const run_cmd = b.addRunArtifact(exe); run_cmd.step.dependOn(&install_cmd.step); const run_step = b.step("run", "Run game"); run_step.dependOn(&run_cmd.step); } else { const webapp = jok.createWebApp( b, "mygame", "src/main.zig", target, optimize, .{ .preload_path = "optional/relative/path/to/your/assets", .shell_file_path = "optional/relative/path/to/your/shell", }, ); b.getInstallStep().dependOn(&webapp.emlink.step); const run_step = b.step("run", "Run game"); run_step.dependOn(&webapp.emrun.step); } } ``` 3. (Optional) Using pre-built SDL3 libraries By default, jok builds SDL3 from source. However, you can use pre-built SDL3 libraries, by passing build options: ```bash zig build -Dsdl-lib-path=/path/to/sdl3/lib -Dsdl-include-path=/path/to/sdl3/include ``` Where: - `sdl-lib-path`: Directory containing the SDL3 library (e.g., `libSDL3.so`, `libSDL3.a`, `SDL3.dll`, or `libSDL3.dylib`) - `sdl-include-path`: Directory containing SDL3 headers (should have `SDL3/SDL.h` inside) **Using in your build.zig:** You can also pass SDL3 paths programmatically in your build script for desktop applications: ```zig pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); // Get SDL paths from build options const sdl_lib_path = b.option([]const u8, "sdl-lib-path", "Path to SDL3 lib"); const sdl_include_path = b.option([]const u8, "sdl-include-path", "Path to SDL3 include"); const exe = jok.createDesktopApp( b, "mygame", "src/main.zig", target, optimize, .{ .sdl_lib_path = sdl_lib_path, .sdl_include_path = sdl_include_path, }, ); // ... rest of build script } ``` **Note:** Web builds (WASM) always use Emscripten's SDL3 port and do not support custom SDL3 paths. 4. Write some code! You may import and use jok now, here's skeleton of your `src/main.zig`: ```zig const std = @import("std"); const jok = @import("jok"); pub fn init(ctx: jok.Context) !void { // your init code } pub fn event(ctx: jok.Context, e: jok.Event) !void { // your event processing code } pub fn update(ctx: jok.Context) !void { // your game state updating code } pub fn draw(ctx: jok.Context) !void { // your drawing code } pub fn quit(ctx: jok.Context) void { // your deinit code } ``` Noticed yet? That's right, you don't need to write main function, `jok` got your back. The game is deemed as a separate package to `jok`'s runtime as a matter of fact. Your only responsibility is to provide 5 public functions: * init - initialize your game, run only once * event - process events happened between frames (keyboard/mouse/controller etc) * update - logic update between frames * draw - render your screen here (60 fps by default) * quit - do something before game is closed You can customize some setup settings (window width/height, fps, debug level etc), by defining some public constants using predefined names (they're all prefixed with `jok_`). Checkout [`src/config.zig`](https://github.com/Jack-Ji/jok/blob/main/src/config.zig). Most of which are still modifiable at runtime. Now, compile and run your game using command `zig build run`, have fun! Please let me know if you have any issue or developed something interesting with this little framework. ## Limitations **Jok** is short for **joke**, which is about how overly-complicated modern graphics programming has become. People are gradually forgetting lots of computing techniques used to deliver amazing games on simple machines. With so many tools, engines and computing resources at hand, however, gamedev is not as fun as it used to be. **Jok** is an effort trying to bring the joy back, it's being developed in the spirit of retro-machines of 1990s (especially PS1), which implies following limitations: * Custom vertex shader is not possible * Only support [affine texture mapping](https://en.wikipedia.org/wiki/Texture_mapping#Affine_texture_mapping) * No [depth buffer](https://en.wikipedia.org/wiki/Z-buffering) The limitations demand developers to be both creative and careful about game's design. ## Third-Party Libraries * [SDL3](https://www.libsdl.org) (zlib license) * [SDL3 using Zig build system](https://github.com/castholm/SDL) (zlib license) * [miniaudio](https://github.com/mackron/miniaudio) (MIT license) * [zig-gamedev](https://github.com/zig-gamedev/zig-gamedev) (MIT license) * [imgui](https://github.com/ocornut/imgui) (MIT license) * [cgltf](https://github.com/jkuhlmann/cgltf) (MIT license) * [meshoptimizer](https://github.com/zeux/meshoptimizer) (MIT license) * [par_shapes](https://github.com/prideout/par/blob/master/par_shapes.h) (MIT license) * [FastNoiseLite](https://github.com/Auburn/FastNoiseLite) (MIT license) * [physfs](https://github.com/icculus/physfs) (zlib license) * [stb headers](https://github.com/nothings/stb) (MIT license) * [nanosvg](https://github.com/memononen/nanosvg) (zlib license) * [zig-obj](https://github.com/chip2n/zig-obj) (MIT license) * [zigfsm](https://github.com/cryptocode/zigfsm) (MIT license) * [ziglua](https://github.com/natecraddock/ziglua) (MIT license) ## Used Fonts * [Classic Console Neue](http://webdraft.hu/fonts/classic-console/) (MIT license) * [Orbitron](https://github.com/theleagueof/orbitron) (SIL Open Font License) ## Games made in jok * [A Bobby Carrot Game Clone](https://github.com/TheWaWaR/bobby-carrot)