> "Abstractions are useful until they're not." So, I thought this was going to be an easy issue. But alas, it is far from it with my current C lang skills. I started out with some easy example to follow, and moved stuff around as I saw fit. ``` #include <SDL3/SDL_init.h> #define SDL_MAIN_USE_CALLBACKS 1 SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) { // Stuff return SDL_APP_CONTINUE; } SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) { // Stuff return SDL_APP_CONTINUE; } SDL_AppResult SDL_AppIterate(void* appstate) { // Stuff return SDL_APP_CONTINUE; } void SDL_AppQuit(void* appstate, SDL_AppResult result) { } ``` Instead of using a regular `main()`, SDL3 provides this callback pattern which more or less hides its own `main()`, overrides it and performs some magic to become platform agnostic, while passing around `appstate`. From the get-go, this looks pretty simple and it is. But I'm not too fond of the abstraction. The callback system forces a `void* appstate` through every callback, which means heap allocation if you want to pass both an `Engine` and a `Game` struct around. You end up with a wrapper struct, `calloc`, pointer casting on every callback, and manual cleanup. For two structs that could live on the stack. More importantly, the event loop is hidden inside SDL's callback dispatcher. I can't see the `while(running)` loop. I can't set a breakpoint at frame boundaries. For someone learning C, not seeing the control flow means I'm trusting an abstraction I don't fully understand yet. So I want to roll my own `main()`, to become more versatile in C as a whole. Here's the thing though: according to the SDL3 documentation, you can still write a standard `int main()` and reap the benefits of SDL3 handling platform-specific entry points (like `WinMain` on Windows). You just include `<SDL3/SDL_main.h>` and write your own loop. SDL still intercepts at link time and routes platform-specific entry points to your `main()`. The difference is that you own the event loop, the polling, and the lifecycle — which is the whole idea behind this project. This will be an ongoing task for a while, to rewrite `main` and refactor some other components to make it easier and _keep it simple, stupid_. No final code to show yet. This is the messy middle. Next post will have the results. --- _Transparency note: I use Lumo as a technical reviewer for these posts — checking C semantics, verifying claims, and catching formatting issues. The ideas, mistakes, and fixes are my own._