Expand description
§zzstat - Deterministic, Hardcode-Free MMORPG Stat Engine
A stat calculation engine designed for MMORPGs that provides:
- Deterministic stat resolution (same input → same output)
- Hardcode-free design (no built-in stat names like “HP” or “ATK”)
- Event-driven resolution (only resolves when invalidated)
- Phase-based transformation pipeline
§Core Concepts
§Stat Pipeline
Stats flow through a simple pipeline:
[StatSource] → [StatTransform] → [ResolvedStat]- Sources produce base values (additive)
- Transforms modify values (can depend on other stats)
- ResolvedStat contains the final value with full breakdown
§Key Features
- Dependency Graph: Automatically resolves dependencies in correct order
- Cycle Detection: Prevents circular dependencies
- Caching: Resolved stats are cached until invalidated
- Context-Aware: Supports conditional calculations via
StatContext - Debug-Friendly: Full breakdown of sources and transforms
§Example
use zzstat::*;
use zzstat::source::ConstantSource;
use zzstat::transform::MultiplicativeTransform;
let mut resolver = StatResolver::new();
let hp_id = StatId::from_str("HP");
// Register sources (additive)
resolver.register_source(hp_id.clone(), Box::new(ConstantSource(100.0)));
resolver.register_source(hp_id.clone(), Box::new(ConstantSource(50.0)));
// Register transform
resolver.register_transform(hp_id.clone(), Box::new(MultiplicativeTransform::new(1.5)));
// Resolve
let context = StatContext::new();
let resolved = resolver.resolve(&hp_id, &context).unwrap();
assert_eq!(resolved.value, 225.0); // (100 + 50) * 1.5§Modules
Re-exports§
pub use context::StatContext;pub use error::StatError;pub use resolved::ResolvedStat;pub use resolver::StatResolver;pub use stat_id::StatId;pub use source::ConstantSource;pub use source::MapSource;pub use source::StatSource;pub use transform::AdditiveTransform;pub use transform::ClampTransform;pub use transform::ConditionalTransform;pub use transform::MultiplicativeTransform;pub use transform::ScalingTransform;pub use transform::StatTransform;