Perro is an experimental, open-source game engine written in Rust. With a focus on performance and simplicity without sacrificing either.
- Simple To Learn: start with scenes, nodes, and Rust scripts without large registration steps or boilerplate.
- Flexible To Use: reduces borrow-checker friction with direct APIs and scoped closures for mutable access. Separating state from script behavior prevents runtime borrow failures.
- Fast In Release: nodes and scripts are laid out for efficient node and state access, all resources are statically baked in release for efficient and quick retrieval
- Full Game-Making Scope: 2D, 3D, and UI all matter. Perro aims to support both 2D and 3D performantly, with high frame rates and a workflow that stays simple.
- Simple Start: get first scene and script running quickly, with minimal setup and no script-registration boilerplate.
- Compiler-Managed Workflow: let Perro sync scripts, generate glue code, and prepare supported assets so project setup stays small.
- Split Model: scripts are just Rust files (lifecycle + methods); they store #[State] structs which each instance gets a copy of.
- Safe Mutation: access through
NodeIDclosures and engine-managed storage avoids borrow-contention edge cases in normal gameplay code (no "try_get_mut" fails). - Fast Access: flat ID lookups keep common node/script operations efficient, with room to cache IDs for hot paths.
- Quick Iteration: project scripts build and reload in usually less than 1 second after initial compilation.
For more details, see the full documentation: perroengine.com/docs.
Local reference:
- Docs Index
- WASM / Web Target
- ResPath
project.toml- Feature Matrix
- Performance + Flexibility Philosophy
- Perro CLI
cargo check --workspace --all-targetscargo test --workspacecargo clippy --workspace --all-targets -- -D warnings -F clippy::all
- Behavior Scripts + Per-Node State: a script is function entry points (lifecycle hooks + methods), not a mutable behavior object. When a node binds that script, runtime uses that node’s
ctx.idto run behavior and resolve that node’s own#[State]viawith_state!/with_state_mut!. - Object-Centric Scene Model: parent/child relationships, concrete node types, and traditional game-object structure stay front and center.
- Compiler-Backed Asset Flow: dev stays flexible with plain files, while build/export bakes supported assets into fast static lookup paths and packs the rest.
- Powerful UI System: UI is built as a real engine system with relative sizing, clamping, and layouts designed to scale from simple menus to larger game interfaces.
- Flat ID-Based Runtime Access: node and script data are addressed by
NodeID, enabling constant-time lookups for common operations and efficient cross-system interaction. - Predictable Failure Modes: most runtime misses come from real-world state changes (deleted node, missing tag/name match, unbound script), not from borrow contention between unrelated systems (no
try_get_mutruntime errors). - Powerful Query Layer: if you prefer query-style access, filter by type, base type, tag, name, and subtree to gather
NodeIDs, then operate directly through script/node APIs. See Query System.
Perro is, of course, open source, and contributions are always appreciated: issue reports, new features, system optimizations, and other improvements. Everyone is welcome to join the project.
Donations help fund full-time development, faster features, and better tooling. If you want to support the project:
Perro is licensed under the Apache 2.0 License. See LICENSE for details.