tri_grid_sim
A deterministic, tick-based simulation library for 2D grid worlds with directional triangles.
Overview
tri_grid_sim provides the core simulation engine for games and simulations that use a
rectangular grid where each tile is subdivided into four directional triangles (North, East,
South, West). This structure enables rich directional gameplay mechanics while maintaining
a simple underlying grid topology.
Key Features
- Deterministic simulation: All operations produce identical results given the same inputs, making the engine suitable for replays, networking, and debugging.
- Double-buffered state: The simulation uses two state buffers to ensure consistent reads during tick updates.
- Fixed-point arithmetic: Uses parts-per-million (PPM) integers instead of floats to guarantee cross-platform determinism.
- Extensible entity system: Open ID patterns (
GroupKind(u32),StructureKind(u32), etc.) allow users to define their own entity types without modifying the library. - Trait-based behaviors: Custom game logic is injected via behavior traits rather than hardcoded into the engine.
Architecture
The simulation is organized around these core concepts:
Grid Topology
┌───────────┬───────────┐
│ N │ N │
│ W ● E │ W ● E │ ← Each tile has 4 triangles
│ S │ S │ pointing to cardinal directions
├───────────┼───────────┤
│ N │ N │
│ W ● E │ W ● E │
│ S │ S │
└───────────┴───────────┘
(0,0) (1,0)
- [
Grid]: Defines the world dimensions and provides coordinate/index conversion. - [
Direction]: The four cardinal directions (North, East, South, West). - Each tile contains 4 triangles, one per direction.
Terrain Layer
- [
TerrainMap]: Stores per-tile terrain data and shared edge data. - [
TerrainTile]: Properties like terrain kind, survivability, and danger modifiers. - [
TerrainEdge]: Shared edges between adjacent tiles with passability and movement cost. - [
TerrainGenerator]: Trait for procedurally generating terrain from a seed.
Resource Layer
- [
ResourceMap]: Sparse storage of resources per triangle. - [
ResourceKind]: Open ID for user-defined resource types. - [
ResourceGenerator]: Trait for procedurally generating initial resources.
Entity Layer
- [
Group]: Mobile entities (units, characters) with position and direction. - [
Structure]: Stationary entities (buildings) with inventory and parameters. - Both use open ID patterns for extensibility.
Simulation Loop
- [
World]: The main simulation container holding all state. - [
WorldState]: Per-tick mutable state (danger values, resources, inventories). - [
WorldBehavior]: Trait for injecting custom logic into the tick loop.
Quick Start
use ;
// Create a 10x10 world with default configuration
let cfg = default;
let mut world = new.expect;
// Set some initial danger in a triangle
world.set_danger;
// Run simulation ticks
for _ in 0..10
// Query the resulting state
let danger = world.danger;
println!;
Custom Behaviors
Inject game-specific logic by implementing behavior traits:
use ;
Feature Flags
raiders: Enables exampleRAIDERSgroup kind andRaidersBehavior.structures_example: Enables exampleSETTLEMENTstructure kind andSettlementBehavior.
These features demonstrate how to build on the engine but are not required for normal use.
Coordinate System
The grid uses a top-left origin coordinate system:
(0, 0)is the top-left cornerxincreases rightwardyincreases downward- Direction offsets: North=(0,-1), East=(1,0), South=(0,1), West=(-1,0)
Determinism Guarantees
The simulation guarantees determinism through:
- Fixed iteration order: Tiles are processed in ascending index order; directions
in
Direction::ALLorder (N, E, S, W). - Integer arithmetic: All calculations use
i32/i64with PPM scaling. - Seeded generation: Terrain and resource generators accept explicit seeds.
- No floating-point: Avoids platform-dependent float behavior.
This means: same initial state + same inputs = identical results across platforms.