Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Getting started

You need a recent stable Rust (rustup update stable). On Linux, also the headers for sound and gamepads: sudo apt-get install libasound2-dev libudev-dev (Debian, Ubuntu).

Run the examples

Clone the repository and run any example:

git clone https://github.com/ponkoengine/ponko
cd ponko
cargo run --release --example boids
ExampleWhat it shows
windowThe smallest game: a window, input, one sprite
spritesDrawing many sprites with tint, rotation and scale
ecsEntities, components and systems, with sim controls
bunnymark / bunnymark_ecsSprite throughput, immediate mode vs ECS
boidsFlocking with a spatial grid on all cores
antsAnt colonies: pheromone trails, foraging, growth; up to millions of ants
headlessA million agents with no window or GPU
examples/cpp/boids.cppThe boids example in C++ (build with CMake, see C and C++)

Always use --release for anything with many entities; debug builds are 10–50× slower.

Your first game

Add the engine to a new project:

cargo new my_game && cd my_game
cargo add ponko

Then in src/main.rs (Rust) or main.cpp (C++, see C and C++ for building):

use ponko::*;

fn main() {
    Game::new("My Game", 800, 600).run(|ctx| {
        let crab = ctx.load_texture("crab.png");
        let mut pos = vec2(400.0, 300.0);

        move |ctx: &mut Ctx| {
            if ctx.key_down(Key::Right) { pos.x += 200.0 * ctx.dt(); }
            if ctx.key_down(Key::Left)  { pos.x -= 200.0 * ctx.dt(); }
            if ctx.key_pressed(Key::Escape) { ctx.quit(); }
            ctx.draw(&crab, pos);
        }
    });
}
static void my_game() {
    crabby::texture crab{};
    crabby::vec2 pos{400, 300};
    crabby::game("My Game", 800, 600)
        .system([&](crabby::ctx& ctx) {
            if (ctx.key_down(CRABBY_KEY_RIGHT)) pos.x += 200 * ctx.dt();
            if (ctx.key_down(CRABBY_KEY_LEFT))  pos.x -= 200 * ctx.dt();
            if (ctx.key_pressed(CRABBY_KEY_ESCAPE)) ctx.quit();
            ctx.draw(crab, pos);
        })
        .run([&](crabby::ctx& ctx) { crab = ctx.load_texture("crab.png"); });
}

setup runs once and returns a closure that runs every frame. In C++, the per-frame code is a frame system and the state lives in variables it captures. Variables you create in setup and move into the closure are your game state. For small games that’s all you need; when things grow, move to entities and systems.

Everything comes in with use ponko::*;: Game, Ctx, Vec2, Color, Key, the ECS types and the built-in components.