Skip to content

YelenaTor/tri_grid

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tri_grid

A deterministic, tick-based simulation library for 2D grid worlds with directional triangles.

License

Overview

tri_grid is a Rust workspace providing a simulation engine where each tile in a rectangular grid is subdivided into four directional triangles (North, East, South, West). This structure enables rich directional gameplay mechanics while maintaining a simple underlying 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     │
└───────────┴───────────┘

Features

  • Deterministic simulation — All operations produce identical results given the same inputs, perfect for replays, networking, and debugging
  • Double-buffered state — Consistent reads during tick updates
  • Fixed-point arithmetic — PPM (parts-per-million) integers avoid floating-point non-determinism
  • Extensible entity system — Open ID patterns let you define custom types without modifying the library
  • Trait-based behaviors — Inject custom game logic via behavior traits

Crates

Crate Description
tri_grid_sim Core simulation engine
tri_grid_render Renderer-agnostic visualization helpers
tri_grid_cli Demo/example harness (not published)

Quick Start

Add to your Cargo.toml:

[dependencies]
tri_grid_sim = "0.1"
tri_grid_render = "0.1"  # Optional, for rendering helpers

Basic Usage

use tri_grid_sim::{Direction, SimConfig, World};

fn main() -> tri_grid_sim::Result<()> {
    // Create a 10x10 world with default configuration
    let cfg = SimConfig::default();
    let mut world = World::new(10, 10, cfg)?;

    // Set initial danger in a triangle
    world.set_danger(5, 5, Direction::North, 1000);

    // Run simulation ticks
    for _ in 0..100 {
        world.tick();
    }

    // Query results
    println!("Danger after 100 ticks: {}", world.danger(5, 5, Direction::North));
    Ok(())
}

Custom Behaviors

Inject game-specific logic by implementing behavior traits:

use tri_grid_sim::{WorldBehavior, WorldCtx, WorldState};

struct DangerSource {
    x: u32,
    y: u32,
    amount: i32,
}

impl WorldBehavior for DangerSource {
    fn apply(&self, ctx: &WorldCtx<'_>, next: &mut WorldState) {
        let idx = ctx.grid().idx(self.x, self.y);
        next.danger[idx][0] += self.amount; // Add to North triangle
    }
}

Resources and Structures

use tri_grid_sim::{Direction, ResourceKind, StructureKind, SimConfig, World};

// Define your resource and structure types
const FOOD: ResourceKind = ResourceKind(1);
const FARM: StructureKind = StructureKind(1);

fn main() -> tri_grid_sim::Result<()> {
    let mut world = World::new(10, 10, SimConfig::default())?;

    // Place resources on triangles
    world.set_resource(5, 5, Direction::North, FOOD, 100);

    // Spawn a structure with inventory
    let farm_id = world.spawn_structure(FARM, 5, 5);
    world.set_inventory(farm_id, FOOD, 50);

    // Query state
    println!("Food on triangle: {}", world.get_resource(5, 5, Direction::North, FOOD));
    println!("Food in farm: {}", world.get_inventory(farm_id, FOOD));

    Ok(())
}

Architecture

Core Concepts

  • Grid — Defines world dimensions, coordinate/index conversion
  • Direction — North, East, South, West for triangle identification
  • TerrainMap — Per-tile terrain data with shared edges between tiles
  • ResourceMap — Sparse per-triangle resource storage
  • World — Main simulation container with double-buffered state
  • WorldBehavior — Trait for custom tick logic

Coordinate System

Top-left origin:

  • (0, 0) is the top-left corner
  • x increases rightward
  • y increases downward

Determinism Guarantees

  1. Fixed iteration order — Tiles processed in ascending index order
  2. Integer arithmetic — All calculations use i32/i64 with PPM scaling
  3. Seeded generation — Terrain and resource generators accept explicit seeds
  4. No floating-point — Avoids platform-dependent float behavior

Examples

Run the basic simulation example:

cargo run --example basic_simulation -p tri_grid_sim

Feature Flags

tri_grid_sim

  • raiders — Example raider group kind and behavior
  • structures_example — Example settlement structure kind and behavior

License

Licensed under either of:

at your option.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages