1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
# KONENGINE
## KonAki's Small C99 Game Engine


## About
This is my game engine. It's built out of my own small libraries, and it's meant to be for game jams and videos. Things like doom-likes, RTS games, rpgmaker-style games, visual novels, metroidvanias and the weird indie stuff that messes with the window itself.
It's made so that you call it, not the other way around. There is no framework that owns your main loop unless you want one. If you do want one, [konprogram](kon/konprogram.h) opens the window, runs the loop and cleans up, and you hand it a few callbacks.
Everything is written in [c99](https://en.wikipedia.org/wiki/C99) and drawn by a software renderer, so no gpu is needed.
### What's in it
The reusable stuff is single-header and lives in [kon](kon). Those are the ones you can drag into any project:
- konwinlib: windows and input events
- konsofren: the software renderer, 2D always, 3D when you define `KONSOFREN_3D` (the 3d, model and sector modules do it for you)
- konmath: vectors, matrices
- konfont: text, built-in bitmap font or a ttf
- kontime: timing and sleeping
- kontoml: a very minimal toml parser
- koninput: input state on top of konwinlib
The engine modules are a `.h` and a `.c` pair, they depend on each other a bit, and you pick which ones to build:
| module | what it does |
| --- | --- |
| font | konfont |
| toml | kontoml |
| tile | tilemaps and sprite sheets |
| 2d | what any 2D game needs: a scrolling camera, frame animation, drawing frames of a sprite sheet |
| fx | whole screen effects done on the pixels: fade to a colour, flash, shake and tone (adds 2d) |
| particles | pooled particle emitters (sparks, dust, glows) and rain, snow and storm presets |
| picture | RPG Maker style pictures: moved, faded, turned, tinted and blended over the screen |
| script | event scripts: say, menus, switches, variables, jumps and calls as a flat list of commands, with the program doing the showing. can be read from text with labels. what converters write to |
| battle | turn based fights with RPG Maker style rules: stats, states, skills with damage formulas, hit and critical rolls, elements, turn order, escaping. nothing drawn, you show the results |
| party | actors with classes and levels, equipment, the party, gold and the bag, shops, and using items from the menu (adds battle and save) |
| save | save files: tagged chunks with a checksum, read and written in a buffer, each module saves its own part; the party saves with it (party adds this) |
| stage | sprites and pictures on a stage for visual novels and cutscenes: slots, layers above or below your text box, fades, moves, scale, rotation, blend modes, a background (or CG) that stretches, covers or fits and can pan and zoom (adds 2d) |
| textbox | a text box for any game: wrapped pages, typewriter, name plate, a face inside, menus, a panel that can be a colour, an image or a nine patch (adds 2d, font) |
| platformer | a box that runs and jumps through a tilemap, with coyote time and jump buffering (adds tile) |
| rpg | top-down games on tilemaps: actors that walk a tile at a time, events on tiles (talk, touch, step), directions (adds tile) |
| 3d | first person kit: mouse look body, walls from a tilemap, editable hill terrain (adds tile) |
| sector | maps made of rooms (vertices, floors, ceilings, walls) with entities like doors and buttons, in a text format |
| world | one place to move bodies through sector maps, terrain, tilemaps and your own boxes, cylinders, spheres and planes (needs 3d, sector) |
| pack | encrypted asset packs |
| assets | named asset cache with reference counts, loose files or a pack |
| image | stb_image so assets can load pngs |
| audio | sound playing, looping, pitch, buses, fades, positional sound, music crossfades |
| mic | microphone level, talking detection, last few seconds as a sound |
| rm | one host function for the RPG Maker commands the converters write: sound, screen effects and pictures, for whichever of those modules are built |
| rmmap | the const data shapes mzmap writes for RPG Maker maps, events, pages and tilesets, which page an event shows, reading a tile, and walking: passability, terrain tags, regions |
| rmtile | where the pieces of an RPG Maker tile are on its sheet: autotile shapes for floors, walls and waterfalls, animation frames (adds rmmap) |
| rmdraw | draws an RPG Maker map from its tileset sheets: layers, shadows, tiles that go above the actors, looping maps (adds rmmap, rmtile) |
| rmfield | the player and the events of an RPG Maker map walking around it: steps at the speed of the character, wandering and routes, what blocks what, what starts an event by touch, action or autorun, random fights by steps and regions, and the script commands for moving characters, map transfers and self switches (adds rmmap) |
| rmplugin | the plugin commands of RPG Maker games (356 and 357): you give a table of names and functions, the commands a game still needs that are not in it are counted so you can see them |
| rmdata | the database of an RPG Maker game as const data: classes, actors, items, weapons, armor, enemies and troops, how an enemy picks what to do, when a battle event page runs (adds party) |
| sound | RPG Maker style audio channels: BGM, BGS, ME and SE, fades, a saved BGM, loop points (adds audio) |
| model | glTF models and animation, converted to my own `.kmdl` format |
| ui | immediate mode ui: panels, scroll areas, menu bar, tabs, tree nodes, text input |
| debug | developer console and asset view |
The 3D part of konsofren (cameras, triangles, meshes, billboards, fog) is only compiled when a module that draws in 3D is picked, so a 2D game does not carry it. Using konsofren.h on its own, define `KONSOFREN_3D` before including it.
### Supported Platforms:
- linux
- bsd
- windows (build.c with gcc or clang from w64devkit or llvm-mingw, or cross compiled with mingw, not tested much yet)
- web (planned)
## Usage
Use the build script from the project root. Pick the modules you want:
```sh
./build.sh -m font,assets,image,audio
```
yes, it's just that. If a module needs another one it adds it for you, so `debug` pulls in `font` and `assets`.
<details>
<summary>All the build options</summary>
```
./build.sh [-d] [-D] [-v] [-j jobs] [-p platform] [-m module,...] [-o objdir] [target ...]
```
- `-d` is a debug build. It also turns on the developer build.
- `-D` is the developer build without debug. This lets loose files override the pack and turns on the developer-only stuff like the console.
- `-p` is `linux`, `bsd` or `windows`. It finds your own if you leave it out.
- `-m` is the list of modules from the table above.
- `-o` is where the objects go, `obj` by default.
- `-j` is how many files to compile at once, one for each processor if you leave it out.
- `-v` shows the compiler commands as they run.
targets are `all`, `run`, `clean`, `tools`, `pack` and `examples`.
</details>
build.sh is only a bootstrap. It compiles [build.c](build.c) with your C compiler once and runs it. build.c does the real work, and all it needs is a C compiler, so it is the same on Windows where there is no sh and no make:
```sh
cc -o build build.c
./build -m font,assets,image,audio
```
The compiler that built it is the one it builds the engine with, set `CC` to use another. It compiles several files at once and only rebuilds what includes a header that changed. It rebuilds itself when build.c changes. `make` works as well, the [Makefile](Makefile) only calls it: `make ARGS="-d -m font,ui" run`. The build program is made with [konbuild.h](kon/konbuild.h), a small single header for build programs written in C.
### Your own program
The shortest way to a window is konprogram:
```c
#include "konprogram.h"
static void draw(kon_program_t *program, kon_framebuffer_t *game, void *user) {
kon_clearFramebuffer(game, 0xFF1B1826);
}
int main(void) {
kon_programConfig_t config = {0};
config.title = "hello";
config.draw = draw;
return kon_programRun(&config);
}
```
Every field of the config can be left at 0 and every callback is optional. The game is drawn at a small resolution and scaled to the window.
### Developer build
With `-d` or `-D` the console opens with the grave key. It knows window commands, your own commands and variables, and it shows what assets are loaded. Without those flags the console is not built at all.
Loose files in the `assets` folder override the ones in the pack only in the developer build.
## Tools
`./build.sh tools` builds these into the object directory.
- konpack: puts a folder into an encrypted `.kpk` pack
- konmodel: converts a glTF/glb into a `.kmdl` model
```sh
obj/konmodel art/models/Fox.glb assets/models/fox.kmdl -t models/
```
## Examples
The examples are their own little programs, in the [examples](examples) folder. Each one says how to build it at the top of the file.
- [modelview.c](examples/modelview.c) shows a model and plays and blends its animations
- [sound.c](examples/sound.c) is an audio and mic playground, everything is made in code so no files needed
- [ui.c](examples/ui.c) is a character card maker made with the ui module
- [dialog.c](examples/dialog.c) is a small scene with sprites, a text box and a menu, built from the stage and textbox modules
- [script.c](examples/script.c) is a konscript script driving the stage and text box, with a menu, a hidden option and a variable
```sh
./build.sh -d -m audio,mic,debug obj/sound
obj/sound
```
## Third party
I use stb_image, stb_truetype, miniaudio and cgltf. The example model is the Fox from the Khronos sample models. All the credits and licenses are in [THIRD_PARTY.md](THIRD_PARTY.md).
## License - [MIT License](LICENSE)
|