| Crates.io | realism |
| lib.rs | realism |
| version | 0.2.2 |
| created_at | 2025-12-11 16:30:20.517397+00 |
| updated_at | 2025-12-26 09:28:07.305499+00 |
| description | A high-performance, production-ready scene management crate for Rust game engines |
| homepage | |
| repository | https://github.com/saptak7777/Realism |
| max_upload_size | |
| id | 1980048 |
| size | 171,182 |
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
Realism is a scene manager built specifically for Charge. It sits between your gameplay code and renderer, handling:
It's not an ECS. It's not a physics engine. It's the "glue" that connects them.
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.
Streaming systems are baked in. Load/unload chunks based on player position. Memory tracking tells you how much RAM you're using.
No GC pauses. No hidden allocations. Everything is either dense arrays or sparse sets with known bounds.
Add to your Cargo.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)
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);
// Compute world positions for everything
scene.propagate_transforms();
// Now your weapon's world position is (0.5, 1.8, 0.0)
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);
}
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);
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();
// Attach child to parent
scene.attach(child, parent);
// Detach (becomes a root)
scene.detach(child);
// Child keeps its world position automatically (no drift!)
If you're using a physics engine (Rapier, Jolt, etc.), implement the PhysicsBackend trait:
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);
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.
This version addresses the critical issues from v0.1:
Three main storage systems:
The BFS transform propagation processes one hierarchy level at a time, batching 4 entities per SIMD instruction.
propagate_transforms() after attaching/detaching.SyncMode. Dynamic = Physics drives scene; Kinematic = Scene drives physics.scene.memory_usage() to monitor RAM usage.Apache 2.0 - See LICENSE file.
Built for the Charge game engine with 💪 and optimism.