166 lines
4.2 KiB
Markdown
166 lines
4.2 KiB
Markdown
|
|
# SDL3 + FLECS Template
|
||
|
|
|
||
|
|
A scaffold/template for building games using SDL3 and the FLECS Entity Component System.
|
||
|
|
|
||
|
|
## Features
|
||
|
|
|
||
|
|
- **SDL3** - Modern cross-platform multimedia library
|
||
|
|
- **FLECS** - Fast and lightweight Entity Component System
|
||
|
|
- **CMake** - Cross-platform build system with FetchContent for dependencies
|
||
|
|
- **Clean Architecture** - Separated components, systems, and game logic
|
||
|
|
|
||
|
|
## Project Structure
|
||
|
|
|
||
|
|
```
|
||
|
|
.
|
||
|
|
├── CMakeLists.txt # Build configuration
|
||
|
|
├── include/
|
||
|
|
│ ├── components/ # ECS component definitions
|
||
|
|
│ │ ├── transform.h # Position, Velocity, Rotation, Scale
|
||
|
|
│ │ ├── render.h # Color, Sprite, RectShape, CircleShape
|
||
|
|
│ │ ├── input.h # PlayerControlled, InputState
|
||
|
|
│ │ └── common.h # Name, ToDestroy, Lifetime, Health
|
||
|
|
│ ├── components.h # Master component include
|
||
|
|
│ ├── systems.h # System declarations
|
||
|
|
│ └── game.h # Game context and main loop
|
||
|
|
├── src/
|
||
|
|
│ ├── main.c # Entry point
|
||
|
|
│ ├── game.c # Game initialization and loop
|
||
|
|
│ └── systems.c # ECS system implementations
|
||
|
|
└── external/ # (unused - deps fetched via CMake)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Building
|
||
|
|
|
||
|
|
### Prerequisites
|
||
|
|
|
||
|
|
- CMake 3.20+
|
||
|
|
- C11 compatible compiler (GCC, Clang, MSVC)
|
||
|
|
- Git (for fetching dependencies)
|
||
|
|
|
||
|
|
### Linux/macOS
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Create build directory
|
||
|
|
mkdir build && cd build
|
||
|
|
|
||
|
|
# Configure
|
||
|
|
cmake ..
|
||
|
|
|
||
|
|
# Build
|
||
|
|
cmake --build .
|
||
|
|
|
||
|
|
# Run
|
||
|
|
./sdl3_flecs_template
|
||
|
|
```
|
||
|
|
|
||
|
|
### Windows (Visual Studio)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
mkdir build && cd build
|
||
|
|
cmake .. -G "Visual Studio 17 2022"
|
||
|
|
cmake --build . --config Release
|
||
|
|
.\Release\sdl3_flecs_template.exe
|
||
|
|
```
|
||
|
|
|
||
|
|
### Windows (MinGW)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
mkdir build && cd build
|
||
|
|
cmake .. -G "MinGW Makefiles"
|
||
|
|
cmake --build .
|
||
|
|
.\sdl3_flecs_template.exe
|
||
|
|
```
|
||
|
|
|
||
|
|
## Usage Guide
|
||
|
|
|
||
|
|
### Adding Components
|
||
|
|
|
||
|
|
1. Create a new header in `include/components/` (e.g., `physics.h`)
|
||
|
|
2. Define your component struct:
|
||
|
|
```c
|
||
|
|
typedef struct RigidBody {
|
||
|
|
float mass;
|
||
|
|
float friction;
|
||
|
|
} RigidBody;
|
||
|
|
```
|
||
|
|
3. Include it in `include/components.h`
|
||
|
|
4. Register it in `src/systems.c`:
|
||
|
|
```c
|
||
|
|
ECS_COMPONENT_DECLARE(RigidBody);
|
||
|
|
// In register_components():
|
||
|
|
ECS_COMPONENT_DEFINE(world, RigidBody);
|
||
|
|
```
|
||
|
|
|
||
|
|
### Adding Systems
|
||
|
|
|
||
|
|
1. Declare the system in `include/systems.h`:
|
||
|
|
```c
|
||
|
|
void PhysicsSystem(ecs_iter_t* it);
|
||
|
|
```
|
||
|
|
2. Implement it in `src/systems.c`:
|
||
|
|
```c
|
||
|
|
void PhysicsSystem(ecs_iter_t* it) {
|
||
|
|
Position* pos = ecs_field(it, Position, 0);
|
||
|
|
RigidBody* rb = ecs_field(it, RigidBody, 1);
|
||
|
|
|
||
|
|
for (int i = 0; i < it->count; i++) {
|
||
|
|
// Physics logic here
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
3. Register it in `register_systems()`:
|
||
|
|
```c
|
||
|
|
ecs_system(world, {
|
||
|
|
.entity = ecs_entity(world, {
|
||
|
|
.name = "PhysicsSystem",
|
||
|
|
.add = ecs_ids(ecs_dependson(EcsOnUpdate))
|
||
|
|
}),
|
||
|
|
.query.terms = {
|
||
|
|
{ .id = ecs_id(Position), .inout = EcsInOut },
|
||
|
|
{ .id = ecs_id(RigidBody), .inout = EcsIn }
|
||
|
|
},
|
||
|
|
.callback = PhysicsSystem
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
### Creating Entities
|
||
|
|
|
||
|
|
```c
|
||
|
|
ecs_entity_t player = ecs_new(world);
|
||
|
|
|
||
|
|
ecs_set(world, player, Position, { .x = 100, .y = 100 });
|
||
|
|
ecs_set(world, player, Velocity, { .x = 0, .y = 0 });
|
||
|
|
ecs_set(world, player, RectShape, { .width = 32, .height = 32 });
|
||
|
|
ecs_set(world, player, Color, { .r = 0, .g = 255, .b = 0, .a = 255 });
|
||
|
|
ecs_set(world, player, PlayerControlled, { .player_id = 0 });
|
||
|
|
```
|
||
|
|
|
||
|
|
### System Phases
|
||
|
|
|
||
|
|
FLECS provides built-in phases for ordering systems:
|
||
|
|
|
||
|
|
- `EcsOnLoad` - Load external data
|
||
|
|
- `EcsPostLoad` - Process loaded data
|
||
|
|
- `EcsPreUpdate` - Prepare for update
|
||
|
|
- `EcsOnUpdate` - Main update logic
|
||
|
|
- `EcsOnValidate` - Validate state
|
||
|
|
- `EcsPostUpdate` - Post-update cleanup
|
||
|
|
- `EcsPreStore` - Prepare for rendering
|
||
|
|
- `EcsOnStore` - Render/store output
|
||
|
|
|
||
|
|
## Controls
|
||
|
|
|
||
|
|
- **ESC** - Quit
|
||
|
|
- **P** - Pause/unpause
|
||
|
|
|
||
|
|
## License
|
||
|
|
|
||
|
|
This template is released into the public domain. Use it however you like!
|
||
|
|
|
||
|
|
## Resources
|
||
|
|
|
||
|
|
- [SDL3 Documentation](https://wiki.libsdl.org/SDL3)
|
||
|
|
- [FLECS Documentation](https://www.flecs.dev/flecs/md_docs_2Docs.html)
|
||
|
|
- [FLECS Examples](https://github.com/SanderMertens/flecs/tree/master/examples)
|