Two readers were given the library, the art, the chapter, and no reference
program, and told to compile and run. Both got a working game. These are the
defects that only came out because a compiler and a frame loop were involved --
four earlier read-only reviews had missed every one.
libakstdlib's header was never named. The chapters used aksl_strncpy,
aksl_snprintf and aksl_atoi throughout and said only "libakstdlib is documented
in deps/libakstdlib"; the obvious guess from the function prefix is <aksl.h> and
it is wrong. That was the only compile error the sidescroller reader hit, and it
was the chapter's fault. Both chapters now carry a per-file include table and say
which header it is.
The sidescroller's asset directory defaulted to ".". The chapter said the code
"falls back to `.`" without showing the #ifndef or that assetdir is initialised
from the macro, so a reader gets a game that only finds its art when launched
from exactly the right directory.
The sidescroller's summary line reported 0.0,0.0 airborne while the screenshot
showed the player standing on the ground. Teardown runs in main's CLEANUP block
and releases the actor pool before the summary prints. The chapter published an
example output a reader could not reproduce; the capture that makes it true is
now shown beside it.
The JRPG's CMake block interpolated ${JRPG_REPO_ROOT}, which is this repository's
own variable and undefined for anybody else -- so the font path came out wrong
and akgl_text_loadfont failed long after everything else had loaded. It is
${CMAKE_CURRENT_SOURCE_DIR} now, and the chapter says why both definitions are
needed rather than one.
Chapter 21 described --demo and a summary line in its build section that no step
wrote. Both are now a section: the script table, playback through
akgl_controller_handle_event rather than the handlers, the fixed clock step, and
printing the position before teardown. It also now says libakgl keeps no frame
counter, which a reader assumed it did.
Both map sections now say to draw it in Tiled and point at chapter 13, naming the
fields the loader needs that Tiled fills in automatically -- both readers
hand-wrote a .tmj before being given one and hit exactly those.
Excerpts across docs/ go from 190 to 198.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
The libakgl manual
libakgl is a C library for building 2D games on SDL3. It is not an engine: there is no
editor, no scripting layer, no inheritance and no runtime malloc. Behaviour attaches to a
struct as function pointers, objects come from fixed pools, and every call reports failure
through an error context you cannot silently ignore.
This manual teaches the library. It deliberately does not re-document its dependencies
— libakerror owns the error-handling protocol, SDL3 owns renderers and events, Tiled owns
the map format, jansson owns the JSON API. Each chapter says what libakgl adds or
constrains, shows what a caller actually writes, and links out for the rest. For
per-function reference, build the Doxygen output with doxygen Doxyfile.
| 1. Introduction | What libakgl is, what it refuses to be, the frame budget, and who owns which documentation |
| 2. Design philosophy | Bounded pools, pluggable backends, bit flags, name-based registries, one world at a time |
| 3. Getting started | Dependencies, add_subdirectory vs akgl.pc, and the smallest program that opens a window |
| 4. Errors and status codes | The status tables, what each code means here, and the traps that fail silently |
| 5. The heap | The eight pools, akgl_heap_next_*, akgl_String, and why exhaustion usually means a missing release |
| 6. The registry | The eight registries, configuration properties, and the id-0 silent no-op |
| 7. The game and the frame | Startup order, akgl_game_update, the state lock, iterators, savegames |
| 8. Rendering | The backend vtable, the frame contract, cameras, and embedding a host's own SDL_Renderer |
| 9. Drawing | Points, lines, rectangles, circles, flood fill, and saving a region |
| 10. Spritesheets and sprites | One texture shared by path, the sprite JSON format, frame animation |
| 11. Characters | State-to-sprite mappings, movement constants, the character JSON format |
| 12. Actors | The state bitmask, the seven behaviour hooks, parents and children, layers |
| 13. Tilemaps | Tiled TMJ, libakgl's three extensions, and the limits that bind a map |
| 14. Physics | Thrust, environment and velocity; the null and arcade backends; what is not implemented |
| 15. Collision | Shapes, masks, tiles as geometry, the response hook, and the two partitioners |
| 16. Input | Control maps, push-not-poll dispatch, the keystroke ring, gamepads |
| 17. Text and fonts | Loading, drawing, measuring, and the teardown order that matters |
| 18. Audio | The three-voice synthesizer, and the separate background-music path |
| 19. Utilities | Rectangle overlap, path resolution, the JSON accessors, static strings |
| 20. Tutorial: a 2D sidescroller | Thirteen steps from an empty directory to a game with gravity, a jump, coins and hazards. Start here |
| 21. Tutorial: a top-down JRPG | Thirteen more, for four-way movement, NPCs, a text box, a follower, and freezing the world |
| 22. Appendix | Every limit, every status, every configuration property |
If you are new, read chapter 20 first and read it in order. It builds a working game from
an empty directory and teaches the library as it needs each piece; chapter 21 assumes it.
Both are complete programs under examples/ — they build with the library and
run headless in CI, and the chapters quote them rather than restating them, so a tutorial
cannot drift from a program that compiles. The picture at the top of each chapter is a frame
out of the game itself, regenerated by cmake --build build --target docs_game_figures.
Every example here is checked
The examples in these chapters are compiled, linked, run, and cross-checked against the
source tree by the test suite. A snippet that stops compiling, an excerpt that no longer
matches the header it quotes, or a JSON document the loader would reject turns
ctest -R docs_examples red.
This exists because the documentation it replaces had drifted badly: the previous FAQ's
examples did not compile — two unbalanced PASS() calls, a sprite->frameids = [0, 1, 2, 3];
that is not C in any dialect, and, in the first snippet a reader ever saw, the exact
strncpy call AGENTS.md forbids. The prose had drifted with it, and writing these
chapters turned up twenty-seven header claims that were false against src/.
Where a chapter documents behaviour that is a known defect rather than a design decision,
it says so and points at TODO.md. See MAINTENANCE.md if you are editing an example.
Assets
The tutorial art, tiles and music are CC0, vendored under
tutorials/assets/ with provenance recorded per file in
PROVENANCE.md and geometry documented in
README.md. CC0 specifically, not merely free: a reader who
copies a tutorial into their own game inherits no obligation.