Skip to content

huhlig/pecs

Repository files navigation

PECS - Persistent Entity Component System

Crates.io Documentation License Build Status

A high-performance, minimalist Entity Component System (ECS) library for Rust with integrated persistence capabilities.

Current Status: Phase 3 Complete (202 tests passing) - Ready for Phase 4 (Release Preparation)

Features

  • 🚀 High Performance: Archetype-based storage, cache-friendly queries, optimized for modern CPUs
  • 🔄 Dual ID System: Fast ephemeral IDs for runtime, stable UUIDs for persistence
  • 💾 Pluggable Persistence: Binary and JSON formats out of the box, extensible for custom formats
  • 🧵 Thread-Safe Commands: Deferred operations via command buffers for parallel systems
  • 📦 Zero Dependencies: Core library has no dependencies (serde optional for JSON)
  • 🎯 Type-Safe Queries: Compile-time validated component access
  • 📚 Library, Not Framework: Integrate into your application, don't build around it

Quick Start

Add PECS to your Cargo.toml:

[dependencies]
pecs = "0.1.0"

Basic usage:

use pecs::prelude::*;

// Define components
#[derive(Debug)]
struct Position {
    x: f32,
    y: f32
}
impl Component for Position {}

#[derive(Debug)]
struct Velocity {
    x: f32,
    y: f32
}
impl Component for Velocity {}

fn main() {
    // Create a world
    let mut world = World::new();

    // Spawn entities with components
    let player = world.spawn()
        .with(Position { x: 0.0, y: 0.0 })
        .with(Velocity { x: 1.0, y: 0.0 })
        .id();

    println!("Created player: {}", player);
    println!("Total entities: {}", world.len());

    // Save the world
    world.save("world.pecs").unwrap();

    // Load the world
    let loaded = World::load("world.pecs").unwrap();
    println!("Loaded {} entities", loaded.len());
}

Documentation

Performance

PECS is designed for high performance with extensive optimizations:

Operation Performance Status
Entity spawn (single) ~538ns ✅ Optimized
Entity spawn (batch) ~118-318ns per entity ✅ Optimized
Entity lookup ~5-10ns ✅ Optimized
Component access ~5ns (cache hit) ✅ Optimized
Query iteration 2-5x faster (optimized) ✅ Optimized
Binary persistence ~0.36ms per 1000 entities ✅ 58% faster
JSON persistence Human-readable format ✅ Complete

Recent Optimizations (Phase 3):

  • 58% faster binary serialization (117.6µs → 48.6µs per 1000 entities)
  • 2-5x faster query iteration with caching
  • 10-20x faster entity location lookup (HashMap → Vec)
  • 50-70% fewer allocations during entity creation

See the Performance Guide for detailed benchmarks and optimization techniques.

Architecture

PECS uses an archetype-based storage system for optimal query performance:

┌─────────────────────────────────────────────┐
│                   World                      │
│  ┌────────────┐  ┌──────────────────────┐  │
│  │  Entities  │  │    Components        │  │
│  │            │  │  ┌────────────────┐  │  │
│  │ EntityId   │──┼─▶│  Archetype 1   │  │  │
│  │ StableId   │  │  │  [Pos, Vel]    │  │  │
│  │            │  │  └────────────────┘  │  │
│  │ Manager    │  │  ┌────────────────┐  │  │
│  │            │  │  │  Archetype 2   │  │  │
│  └────────────┘  │  │  [Pos, Health] │  │  │
│                  │  └────────────────┘  │  │
│  ┌────────────┐  └──────────────────────┘  │
│  │  Commands  │                             │
│  │  Buffer    │  Deferred Operations        │
│  └────────────┘                             │
└─────────────────────────────────────────────┘

Key design principles:

  • Dual ID System: Fast runtime IDs + persistent UUIDs
  • Archetype Storage: Cache-friendly component layout
  • Command Buffers: Thread-safe deferred operations
  • Pluggable Persistence: Flexible save/load system

See Core Concepts for detailed architecture information.

Persistence

PECS provides built-in persistence with multiple formats:

use pecs::World;

// Binary format (fast, compact)
world.save("world.pecs") ?;
let world = World::load("world.pecs") ?;

// JSON format (human-readable)
world.save_with("world.json", "json") ?;
let world = World::load_with("world.json", "json") ?;

// Streaming API for large worlds
use std::fs::File;
let mut file = File::create("world.pecs") ?;
world.save_binary( & mut file) ?;

Features:

  • Version-aware serialization
  • Checksum validation
  • Transient component support
  • Custom plugin system

Examples

Check out the examples directory for complete applications:

Run examples with:

cargo run --example 01_hello_world --release

See examples/README.md for detailed documentation.

Roadmap

Phase 1: Core ECS ✅ Complete (2026-02-13)

  • Entity management with dual ID system
  • Component storage with archetypes
  • Query system with filters
  • Command buffer system
  • World integration and API
  • 94 tests passing

Phase 2: Persistence ✅ Complete (2026-02-13)

  • Binary serialization format (< 0.4ms per 1000 entities)
  • JSON serialization format
  • Plugin system with delta persistence
  • Version migration framework
  • Change tracking and transient components
  • 164 tests passing

Phase 3: Polish & Optimization ✅ Complete (2026-02-14)

  • Performance optimization (58% faster serialization, 2-5x faster queries)
  • Query system integration and bug fixes
  • Comprehensive documentation (4,500+ lines, 100% API coverage)
  • 6 working examples
  • API refinement (component access, query execution)
  • Error handling improvements
  • 202 tests passing

Phase 4: Release 🔜 Next

  • Tutorial series
  • Additional complete applications
  • Beta testing
  • Community feedback
  • Cross-platform testing
  • 1.0 release

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Development

# Clone the repository
git clone https://github.com/yourusername/pecs.git
cd pecs

# Run tests
cargo test

# Run benchmarks
cargo bench

# Check code quality
cargo clippy
cargo fmt --check

Design Philosophy

PECS follows these principles:

  1. Library, Not Framework: Integrate PECS into your application
  2. Performance First: Zero-cost abstractions, cache-friendly design
  3. Type Safety: Compile-time guarantees, no runtime type errors
  4. Flexibility: Minimal constraints, maximum freedom
  5. Simplicity: Small API surface, clear documentation

See ADR-005: Library Not Framework for details.

Comparison with Other ECS Libraries

Feature PECS Bevy ECS Specs Legion
Archetype-based
Built-in Persistence
Dual ID System
Zero Dependencies
Library (not framework)
Query Performance High High Medium High

License

Licensed under either of:

at your option.

Acknowledgments

PECS is inspired by:

  • Bevy ECS - Archetype-based design
  • HECS - Batch entity operations
  • Specs - Component storage patterns
  • Legion - Query optimization
  • EnTT - Entity recycling

Special thanks to the Rust gamedev community for their insights and feedback.

Support


Made with ❤️ and 🦀 by Wyldlands team

About

Persistent Entity Component System

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages