tinygame-core 0.0.2

Minimal SDL-based game runtime core with a plugin-driven world
Documentation
# tinygame-core

`tinygame-core` is a minimal SDL-based runtime core for small game projects.

The crate is built around two ideas:
- a `World` that stores typed resources
- a static `Plugin` lifecycle that drives initialization and frame execution

It intentionally stays small. The goal is to provide the runtime core, not a full engine stack.

## Example

```rust
use tinygame_core::CorePlugin;

tinygame_core::app!(|world| {
    world.add_plugin::<CorePlugin>();
});
```

## World

`World` is the shared runtime container.

Plugins use it to:
- insert resources during `init`
- read resources with `get<T>()` / `try_get<T>()`
- mutate resources with `get_mut<T>()` / `try_get_mut<T>()`

Resources are typed and stored once per type.

## Plugin system

Plugins are static types implementing the `Plugin` trait.

Each plugin can define:
- `get_meta()`
- `init(&mut World)`
- `pre_step(&World)`
- `step(&World)`
- `post_step(&World)`
- `exit(&World)`

### Lifecycle

Startup:
1. your setup code adds plugins to the world
2. `run_init()` calls plugin `init` hooks

Frame execution:
1. `pre_step`
2. `step`
3. `post_step`

Shutdown:
1. `exit` hooks run in reverse plugin order

All plugin hooks run on the main thread. `World` is single-threaded by design, and it checks that lifecycle methods are executed from the thread where the world was created.

### Dependencies

Plugins declare dependencies through `PluginMeta`:

```rust
PluginMeta {
    name: "render",
    depends_on: &["core"],
}
```

Dependencies are checked when plugins are added to the world. Missing dependencies cause a panic during setup.

## CorePlugin

`CorePlugin` is the built-in SDL integration plugin.

It is responsible for:
- initializing SDL during `init`
- inserting the `Core` resource into `World`
- collecting SDL events each frame into `Core::sdl_events`
- calling `SDL_Quit()` on shutdown

`Core` is the main runtime resource exposed by the plugin. Other plugins can read SDL events from it during frame execution.

If you need to customize SDL startup, insert `CoreSettings` before adding `CorePlugin`.

## app! macro

`app!()` generates the SDL callback entrypoints for you.

You only provide setup logic:

```rust
tinygame_core::app!(|world| {
    world.add_plugin::<tinygame_core::CorePlugin>();
});
```

That setup closure is where you:
- add plugins
- insert startup configuration/resources

The generated runtime then:
- creates the `World`
- runs plugin init hooks
- dispatches frame hooks
- forwards SDL events into `Core`

## SDL bindings

`tinygame-core` publicly re-exports `sdl3_sys` so external plugins can use the same low-level SDL types.

## Features

The crate forwards a focused set of common SDL build features to `sdl3_sys`.

Default features:
- `sdl-lean-and-mean`
- `build-from-source-static`