cute_headers - Game Framework in C/C++

For collision detection I used tinyc2.h and for the physics I implemented a little snippet of code:

 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
// quote's physics integration
quote_vel_y += dt * -250.0f;
quote_x += dt * quote_vel_x;
quote_y += dt * quote_vel_y;
quote_circle.p = c2V(quote_x, quote_y);
quote_sprite.x = quote_x;
quote_sprite.y = quote_y;

// quote's collision detection and collision resolution
for (int i = 0; i < tile_count; ++i)
{
    tile_t tile = tiles[i];
    if (tile.shape_id == -1) continue;
    shape_t shape = shapes[tile.shape_id];
    shape = get_transformed_tile_shape(tile, shape);
    c2Manifold m;
    c2Collide(&quote_circle, 0, C2_CIRCLE, &shape.u, 0, shape.type, &m);
    if (m.count)
    {
        // move quote out of colliding configuration
        float depth = -m.depths[0];
        c2v n = m.n;
        quote_x += n.x * depth;
        quote_y += n.y * depth;

        // "slide along wall"
        // remove all velocity in the direction of the wall's normal
        // v -= n * dot(v, n)
        c2v v = c2V(quote_vel_x, quote_vel_y);
        v = c2Sub(v, c2Mulvs(n, c2Dot(v, n)));
        quote_vel_x = v.x;
        quote_vel_y = v.y;
    }
}


For a real game more work would need to be done to prevent Quote from floating off the ground at odd times. Logic to detect "on the ground" or not would need to be implemented. Some downwards raycasting, or maybe a Time of Impact solver, need to be used to make Qoute stick to the ground even when running over bumps, when is he "on ground". A bunch of other features would probably need to be implemented too, for a real game.

Edited by Randy Gaul on
Renamed all headers to *cute* headers !!!

I'm organizing a local game jam with some friends coming soon. We'll be using my cute headers to form some kind of 2D tile based game :) It will be a good chance to test out how all the headers interact together among a group of people. One more header will be coming out, an algorithm header. Algorithms to be included:

* General purpose array sorting Quicksort (very fast, in place, non-stable), mergesort (fast, not in-place, stable)
* A* for grids
* BFS for grids
* Array shuffle

This will probably be the final header for a while, and the focus will instead shift on improving the current ones. The end goal is to eventually open source a wrapping of all the headers into one framework, much like Mattias Gustavsson's Pixie framework. Mattias's framework focuses on creating CRT era games, and implements a lot of platform layer specifics. My framework will instead focus on 2D art pipelines, fast iteration time, and rely on SDL for platform stuff.

Unlike other game creation tools (such as Unity, Love2D, or Game Maker), cute headers are focused on solving specific problems with meticulously well-crafted APIs. Each problem is isolated and well defined, allowing the headers to be integrated, or plucked from a codebase and brought to a new environment without any hassle. Cute headers aren't an all-encompassing solution for game creation. Each header solves individual problems in a very specific manner. When brought together, the headers define a consistent pattern and demonstrate a transcendental strategy for granting the utmost creative opportunity.

The goal is for this pattern to eventually become self-evident :)

Edited by Randy Gaul on
Realized I didn't have any threadpool or synchronization primitives ready to go. Implemented a threadpool header. It wraps SDL2 synchronization primitives, but uses some macros so the API could be implemented by something else as well (like pthreads, or Windows).

I was considering implementing a read-write lock. Go has a really nice reference implementation here: https://github.com/golang/go/blob...15554537572de/src/sync/rwmutex.go

Will release the synchronization header soon.
Sync header ready to go: https://github.com/RandyGaul/cute_headers/blob/master/cute_sync.h

Favorite part by far is the read/write lock and the threadpool/task system. Each one is very useful for solving a wide variety of game implementation problems! The next extension (that I will probably never get around to implementing) is to let tasks say they are dependent on other tasks. In my experience task dependency is a huge annoyance, and 95% of all tasks (even in AAA games or engines) are straightforward in terms of dependencies. Explicitly stating task dependencies has not been a very important feature, in my experience. But, once in a blue moon it can be necessary.

Lastly, tasks are stored in FIFO order. This can be changed to LIFO order without too much trouble (it's actually almost a trivial change), but meh. It's not high priority :)

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// Construct threadpool. Size number of threads relative to number of core present.
threadpool = cute_threadpool_create(cute_core_count() * 2, 0);

...

// Add tasks. They are placed in FIFO order.
cute_threadpool_add_task(threadpool, func, param);

...

// Wake all threads and complete all tasks before returning.
cute_threadpool_kick_and_wait(threadpool)
Setup repo for the game jam I mentioned a few posts ago. This will be a great showcase on setting up a "cute framework" by hooking up all the cute headers together! The only external dependencies are SDL2, stb_vorbis.c, hashtable.h, and strpool.h, assetsys.h. The rest of the code is powered by cute headers. https://github.com/RandyGaul/cute_jam_2018

The framework is modeled heavily after this design I posted back in 2017: http://www.randygaul.net/2017/02/24/writing-a-game-engine-in-2017/

Some features (nearly exhaustive):
* dll hotloading
* asset hotloading
* sprite batching
* audio streaming, music crossfade
* tile loading from Tiled editor
* 2d collision detection + resolution
* entity system for polymorphism
* OpenGL/ES support
* 2d frame-based animations
* Font atlas and rendering support via baked BMFont atlases
* utf8 text (and font rendering support)
* 2d vector math and 3d graphics matrix routines
* leak checking
* job/task system
* SDL2 support (can run on nearly anything)
* file system abstraction
* png image loading

Pretty much everything for the majority of 2D games that would want right up until release!

Still working on A*/algorithm header. This has been de-prioritized for now. Will get back to this another day.

Edited by Randy Gaul on
Randy Gaul
Pretty much everything for the majority of 2D games that would want right up until release!

Reflection + IMGUI
And some way to hotswap entities (create new entity types, change entities, data structs, add/remove variables etc).

Admittedly that is way harder than anything else here so far. But it is important.
Parsing full C99 is very, very hard and error prone.
And non-shitty IMGUI is just lotsa work.

Everything else is comparatively very easy to make.

I also think that having an in-game embedded tile editor is way better than relying on an external one.
Since then you have to massage in between the data formats and work within the limitations of Tiled or whatever else.
Creating an embedded tile/object placement editor is very easy and totally worth it for the amount of flexibility it gives.


Edited by pragmatic_hero on
I’ll be using Dear Imgui for all UI needs during development.

As for reflection, I have considered a few different ways of implementing and using reflection. After much consideration have decided it’s simply a waste of time, at least for this project. Serialization can be achieved by writing to/from disk routines using a reader/writer helper to place or read ints, floats, and strings. Anything else would be, in my opinion, over-engineering.

The problem with reflection systems is they are themselves huge dependencies. They also require continual maintenance and updating. They are code intrusive, demanding everyone that comes along to learn their peculiararities.

In-game editing of tiles isn’t necessary. Sure it can be nice, but personally I don’t think anyone would be able to makeup time lost creating and in-game editor if they could use Tiled instead. Especially if the tiles can be live reloaded from the game.

Similarly, I don’t think supporting entity hotloading and data layout changes is a good use of developer time. In the end these kinds of systems turn out to be slow, error prone, and often incur a huge dependency on anything they touch. In my experience the end effect is a big clunky system nobody really ends up using at the end of the day.

This is just my take after implementing these systems and trying out the different styles. Big or complicated systems, like the ones you have mentioned, have been intentially foregone because they do not bring enough value to justify their own existence, or, have been offloaded to a 3rd party solution (like dear imgui, glad, or SDL2).

My project goals probably do not align perfectly with the other handmade projects around here. But that’s OK. Instead cute headers focus on dependency minimization, self-containment, and carefully balance cost vs benefit in all aspects. In this way some of my decisions probably won’t align very strongly with Casey’s style.

Edited by Randy Gaul on
Here are some slides I wrote about this sort of API topic for university guest lecture: http://www.randygaul.net/wp-conte.../2018/02/R.Gaul_APIs_ITCarlow.pdf
Randy Gaul
I’ll be using Dear Imgui for all UI needs during development.

Yes, dear Imgui is brilliant.

Randy Gaul
In-game editing of tiles isn’t necessary.
Sure it can be nice, but personally I don’t think anyone would be able to makeup time lost creating and in-game editor if they could use Tiled instead.


First, this statement only holds true, if features the game requires are fully satisfied by what Tiled provides - and it's not much, it's only the very basic primitives.
Second, this statement also ignores amount of time and effort it requires to write code which maps between data representation of Tiled and your game. This increases complexity significantly. In-game editors can easily avoid this cost entirely.

Third, it implies that time creating in-game editor is lost. I would argue that - for many games - creation of in-game editor is a fundamental part of making the game, because the generic editors simply don't cut it.

It also sort of implies that it takes a lot of time to create in-game editor, which is sort of only true - if the editor has to end up being end-user facing and pretty.

The "hard", time consuming parts of creating ingame editor are - 1) IMGUI and 2) Reflection.
If you have code-hotswapping, good IMGUI and Reflection, making in game editors are very easy, and low LoC endeavor with fantastic ability to iterate on it.

The ability to switch over editor and game with a single keypress is unparalleled.
The ability to add new entities and change structs and have them instantly appear in the editor while the game is running is unparalleled.

Randy Gaul
As for reflection, I have considered a few different ways of implementing and using reflection. After much consideration have decided it’s simply a waste of time, at least for this project. Serialization can be achieved by writing to/from disk routines using a reader/writer helper to place or read ints, floats, and strings. Anything else would be, in my opinion, over-engineering.

The problem with reflection systems is they are themselves huge dependencies. They also require continual maintenance and updating. They are code intrusive, demanding everyone that comes along to learn their peculiararities.

What you've written here is more like a set of arguments why C is one of the worst programming languages ever made.
It's not a good argument against reflection.
Reflection is of one the core, fundamental parts of programming. It so vitally important in game-development.



Edited by pragmatic_hero on
I agree, the mixture of some good UI creation tools, code hotloading, reflection, and serialization can be really cool! It's just that I have very specific requirements that lead to specific decision making, and these kinds of features don't quite match up. I'm happy to chat more about specifics if you like though :)

Edited by Randy Gaul on
Hey Randy, looks cool!

Have you seen this list of single-file libraries: https://github.com/nothings/single_file_libs

Seems like your headers would be a good addition :)
Some of his headers are already there :)
tinysound, tinyfiles, tinymemfile, tinyfile.
Ended up having that small game jam I mentioned. Was a success! I had no feedback on the headers -- they did their jobs really well. Instead people only had feedback for the rest of the code using the headers. People were generally interested in how I might form higher level abstractions for common game needs, like level loading/switching, cameras, and shaders.

I think this is a sign to start focusing a lot more on piecing together a coherent framework. I'll probably name it cute framework.

For now I don't think any new headers will appear for a while. Instead I'll be focusing on using the headers, iterating on them when needed, and will put more thought into next steps on releasing the framework.