kon-engine 0.2.0

A modular 2D game engine for Rust, built with a focus on ECS performance and simplicity.
Documentation
<p align="center">
  <img src="assets/kon_stacked.svg" alt="Kon Engine" width="210">
</p>

A modular 2D game engine in Rust with a custom SparseSet-based ECS. Built from scratch to learn how game engines actually work.

> ⚠️ **Heads up:** This is an experimental/educational project. I'm building this to understand engine internals, not to compete with existing engines.

## What's Inside


The project is split into workspace crates:

**Currently Working**
- **`kon_core`** - App lifecycle, plugins, events
- **`kon_ecs`** - Custom ECS
- **`kon_macros`** - Proc macros for `#[system]` and `#[component]`
- **`kon_window`** - Winit-based window management
- **`kon_input`** - Input handling

**Still Cooking 🍳**
- **`kon_math`** - Math stuff with Glam integration (WIP)
- **`kon_renderer`** - WGPU renderer (WIP)
- **`kon_physics`** - 2D physics (Planned)
- **`kon_editor`** - Editor tools (Planned)

## Features


- [x] Plugin-based architecture
- [x] Custom SparseSet ECS with O(1) component access
- [x] Write systems as regular Rust functions
- [x] Ergonomic query API
- [x] Event system for decoupled communication
- [x] Window context management
- [x] Keyboard/mouse input
- [ ] Hardware-accelerated 2D rendering
- [ ] Collision detection and physics
- [ ] Integrated editor

## Quick Example


Here's how you write a simple simulation:

```rust
use kon::prelude::*;

// Define your data
#[component]

struct Position { x: f32, y: f32 }

#[component]

struct Velocity { x: f32, y: f32 }

// Setup runs once
#[system]

fn setup(ctx: &mut Context) {
    ctx.window().set_config(WindowConfig::default().with_title("A beautiful title"));
    
    ctx.world()
        .spawn()
        .insert(Position { x: 0.0, y: 0.0 })
        .insert(Velocity { x: 1.0, y: 0.0 })
        .tag("player")
        .id();
}

// Movement runs every frame
#[system]

fn movement(ctx: &mut Context) {
    ctx.world()
        .select_mut::<(Position, Velocity)>()
        .each(|entity, (pos, vel)| {
            pos.x += vel.x;
            pos.y += vel.y;
            println!("{:?} moved to ({}, {})", entity, pos.x, pos.y);
        });
}

// Update runs every frame
#[system]

fn update(ctx: &mut Context) {
    if ctx.input().just_key_pressed(KeyCode::Escape) {
        ctx.quit();
    }
    
    ctx.on::<WindowCloseRequested>(|_, context| {
        context.quit();
    });
}

// Wire everything together
fn main() {
    Kon::new()
        .add_plugin(DefaultPlugins)
        .add_startup_system(setup)
        .add_system(movement)
        .add_system(update)
        .run();
}
```

## How to Use


**As a dependency:**

```bash
cargo add kon-engine
```

Or in your `Cargo.toml`:

```toml
[dependencies]
kon-engine = "0.2.0"
```

**From source:**

```bash
git clone https://github.com/cey0225/kon.git
cd kon

# Run examples

# Linux/macOS

./kon.sh ecs_demo/query_demo
./kon.sh ecs_demo/tag_demo

# Windows

./kon.ps1 ecs_demo/query_demo
./kon.ps1 ecs_demo/tag_demo
```

## License


Dual-licensed under MIT or Apache 2.0, pick whichever works for you.

- MIT: [LICENSE-MIT]LICENSE-MIT or http://opensource.org/licenses/MIT
- Apache 2.0: [LICENSE-APACHE]LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0