realism 0.2.2

A high-performance, production-ready scene management crate for Rust game engines
Documentation
# Realism Scene Manager

A lightweight, fast scene graph for the Charge game engine. Handles hierarchies, spatial culling, and open-world streaming without bloat.

**Status: Beta (v0.2.2) - Use at your own risk**

## What is Realism?

Realism is a scene manager built specifically for **Charge**. It sits between your gameplay code and renderer, handling:

- **Entity hierarchies** (parent-child transforms)
- **Fast spatial queries** (what's visible right now?)
- **World streaming** (loading/unloading chunks as the player moves)
- **Physics synchronization** (keeping bodies in sync with transforms)

It's not an ECS. It's not a physics engine. It's the "glue" that connects them.

## Why Use Realism?


### You have deep entity hierarchies

Characters have bones. Vehicles have wheels and doors. Props attach to other props. Realism processes all of them in parallel using **SIMD**, not serially like a naive engine would.

### You're building an open world

Streaming systems are baked in. Load/unload chunks based on player position. Memory tracking tells you how much RAM you're using.

### You want predictable performance

No GC pauses. No hidden allocations. Everything is either dense arrays or sparse sets with known bounds.

---

## Installation

Add to your `Cargo.toml`:

```toml
[dependencies]
realism = "=0.2.1"
glam = "0.30.9"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
```
**Requires: Rust 1.70+ (stable)**

---

## Quick Start


### Spawn Some Entities

```rust
use realism::{Scene, transform::Transform};
use glam::Vec3;

let mut scene = Scene::new();

// A simple entity
let player = scene.spawn_with_transform(
    Transform::from_xyz(0.0, 1.8, 0.0)
);

// A child entity (like a weapon in hand)
let weapon = scene.spawn_with_transform(
    Transform::from_xyz(0.5, 0.0, 0.0)
);

// Attach it
scene.attach(weapon, player);
```

### Propagate Transforms

```rust
// Compute world positions for everything
scene.propagate_transforms();

// Now your weapon's world position is (0.5, 1.8, 0.0)
```

### Find What's Visible

```rust
use glam::Mat4;

let camera_vp = Mat4::perspective_rh(
    70.0_f32.to_radians(),
    16.0 / 9.0,
    0.1,
    1000.0,
);

let visible = scene.extract(Some(camera_vp));

// visible is a Vec<RenderCommand> ready to send to GPU
for cmd in visible {
    // renderer.draw_mesh(cmd);
}
```

### Stream Chunks

```rust
use realism::streaming::{ChunkManager, ChunkLoader};

let mut manager = ChunkManager::new(500.0, 1000.0);
let mut loader = ChunkLoader::new();

// Each frame
manager.update(player_pos);

for chunk_id in manager.chunks_to_load() {
    loader.load_chunk_async(
        chunk_id,
        &format!("world/chunks/{:?}.json", chunk_id),
    );
}

let loaded = loader.poll();
realism::streaming::integrate_chunks(&mut scene, &mut manager, loaded);
```

---

## Common Tasks


### Moving an entity

```rust
if let Some(t) = scene.transform_mut(entity) {
    t.local_position = Vec3::new(10.0, 5.0, 0.0);
    t.mark_dirty();
}

scene.propagate_transforms();
```

### Attaching/detaching

```rust
// Attach child to parent
scene.attach(child, parent);

// Detach (becomes a root)
scene.detach(child);
// Child keeps its world position automatically (no drift!)
```

### Physics sync

If you're using a physics engine (Rapier, Jolt, etc.), implement the `PhysicsBackend` trait:

```rust
use realism::physics::{PhysicsHandle, SyncMode};

// Mark entity as physics-driven
let handle = PhysicsHandle { id: 42, mode: SyncMode::Dynamic };
scene.add_physics_handle(entity, handle);

// Later, sync physics back to scene
scene.sync_physics(&mut your_backend);
```

---

## Performance Notes

Real-world results with v0.2.0 optimizations:

| Task | Time | Notes |
| :--- | :--- | :--- |
| **Propagate 100k flat entities** | ~1.2ms | All via SIMD |
| **Propagate 100k in deep hierarchy** | ~2-3ms | Full SIMD coverage with BFS |
| **Octree query (frustum cull)** | <0.5ms | Even with boundary objects |
| **Spawn/despawn entity** | <0.1ms | Generational index reuse |

*These are realistic numbers, tested with actual hierarchies and boundary cases.*

---

## What's Fixed (v0.2.0)

This version addresses the critical issues from v0.1:

- **SIMD batching** works for all hierarchy levels, not just roots
-**Compiles on stable Rust** (no nightly required by default)
-**Transform decomposition** is fixed (detaching preserves world position)
-**Octree is loose** (boundary straddling doesn't cause O(N) slowdown)
-**Physics sync** is complete (Dynamic/Kinematic bodies work)

---

## Known Limitations


- **Skeletal animation**: Realism doesn't handle skinned meshes or bone IK. That's your renderer's job.
- **LOD management**: Multiple mesh variants for different distances? That's handled in your renderer.
- **Terrain deformation**: Moving terrain patches? You'll update their bounds and let Realism re-query.

---

## Architecture Overview

Three main storage systems:
1. **Dense entity list**: O(1) alloc/dealloc with generational safety.
2. **Component sparse sets**: Cache-friendly iteration, O(1) random access.
3. **Hierarchy links**: Doubly-linked sibling lists for O(1) detach.

The BFS transform propagation processes one hierarchy level at a time, batching 4 entities per SIMD instruction.

---

## Troubleshooting


- **"Detached child appears at wrong position"**: Make sure you call `propagate_transforms()` after attaching/detaching.
- **"Physics body not syncing"**: Check your `SyncMode`. `Dynamic` = Physics drives scene; `Kinematic` = Scene drives physics.
- **"Out of memory with streaming"**: Use `scene.memory_usage()` to monitor RAM usage.

---

## License

Apache 2.0 - See LICENSE file.

*Built for the Charge game engine with 💪 and optimism.*