# scaffold [![License: BSD 3-Clause](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) `scaffold` is a minimal starter template for building a game on top of [`skele`](https://git.forlornoutpost.ca/anth64/skele) and [`stk`](https://git.forlornoutpost.ca/anth64/stk). It is not an engine of its own, it is the smallest working skeleton that wires the two together: a fixed-timestep game loop, hot-reload polling, and three build targets (software client, OpenGL client, headless server) sharing one game module. Copy this repository to bootstrap a new game and start filling in `src/game.c`. --- ## Key Features - **Three binaries from one game module**: software client, OpenGL client, and headless server, all calling the same `game_init`/`game_tick`/`game_shutdown` contract - **Fixed-timestep accumulator loop** wired to `skele_tick_ns`, correct across variable frame times - **`stk` hot-reload wired in from the start**, polled every loop iteration - **Static or dynamic linking** against skele/stk via `LINK_TYPE` - **Cross-platform build** (Linux, BSD, macOS, Windows, Raspberry Pi 5 GL auto-detect) --- ## Quick Start ### Building ```bash # Unix (Linux/BSD/macOS) ./build.sh debug release # Windows build.bat debug release ``` Builds three binaries into `bin/{debug,release}`: - `_client` - software rendering client - `_glclient` - OpenGL client - `_server` - headless server, no video/input linked Set `LINK_TYPE=dynamic` (default `static`) to link against shared `libskele`/`libstk` instead: ```bash ./build.sh LINK_TYPE=dynamic debug release ``` ### Running ```bash ./build.sh run # software client ./build.sh run_gl # OpenGL client ``` ### Installation ```bash ./build.sh install ``` Installs to `/usr` on Linux, `/usr/local` on BSD/macOS by default. Use `PREFIX` to customize: ```bash ./build.sh PREFIX=$HOME/.local install ``` --- ## Usage ### Starting a New Game 1. Rename `GAME_NAME` in `config.mk` (used to name the built binaries). 2. Implement `game_init`, `game_tick`, and `game_shutdown` in `src/game.c`. 3. Add any additional source files to `GAME_SRCS` in `config.mk`, they are compiled into all three binaries. ### The Game Contract (`include/game.h`) ```c uint8_t game_init(void); /* return 0 to abort startup */ void game_tick(void); /* called once per simulation tick */ void game_shutdown(void); /* called once on exit */ ``` This is the entire surface a game needs to implement. Rendering, input, windowing, and hot-reload are all handled by the client `main.c` files calling into `skele`/`stk`, not by the game module itself. ### Client Loop (software and GL) Both `src/client/main.c` and `src/gl_client/main.c` follow the same pattern: init clock and signal handling, set up `stk`, init `skele`, init the game, then run a fixed-timestep accumulator loop polling input and `stk` each frame before presenting. They are kept as separate files so each can diverge independently as you add renderer-specific setup (window flags, GL context options, and so on) without one client's changes leaking into the other. ### Server Loop `src/server/main.c` runs the same accumulator pattern without any video/input calls, calling only `stk_poll()` and `game_tick()` each iteration, then sleeping out the remainder of the tick. --- ## Project Status Very early. This is a starter template, not a finished project. `game.c` ships as an empty stub (`game_init` returns success, `game_tick`/`game_shutdown` do nothing). No automated tests. --- ## License BSD 3-Clause License --- ## Contributing Contributions welcome! Please ensure code follows C99 standard and works across all supported platforms.