realism

Crates.iorealism
lib.rsrealism
version0.2.2
created_at2025-12-11 16:30:20.517397+00
updated_at2025-12-26 09:28:07.305499+00
descriptionA high-performance, production-ready scene management crate for Rust game engines
homepage
repositoryhttps://github.com/saptak7777/Realism
max_upload_size
id1980048
size171,182
saptak santra (saptak7777)

documentation

README

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:

[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

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

// 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

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

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

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

// 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:

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.

Commit count: 0

cargo fmt