# Micro Autotile

[![https://crates.io/crates/micro_autotile](https://img.shields.io/crates/v/micro_autotile?style=for-the-badge)](https://crates.io/crates/micro_autotile)
[![https://docs.rs/micro_autotile](https://img.shields.io/docsrs/micro_autotile?style=for-the-badge)](https://docs.rs/micro_autotile)

_Bring LDTK's autotile feature to your Rust project_

`micro_autotile` provides an implementation of the LDTK auto-tiling algorithm, for use in
programs at runtime. The representation is compatible with that saved by LDTK, meaning that
definitions can be loaded directly from LDTK JSON exports. Great for either building a
compatible editor into your project, or for using LDTK's rule format to decorate generated 
content.

## Installation

Either add it to your `Cargo.toml` dependencies:

```toml
[dependencies]
micro_autotile = "0.1"
```

Or use cargo to add it to your project:

```sh
cargo add micro_autotile
```

## Usage

_For a more thorough usage guide, check out the [docs.rs](https://docs.rs/micro_autotile) page_

Autotiling is, fundamentally, a method of mapping a two dimensional pattern to a single scalar value.
The context for this is usually "tile maps" in video games, and while that is not the sole use case it
is the one that will be assumed throughout the docs for `micro_autotile`.

To start, determine what your input types and output types will be - in this example, we will use integers
to define types of terrain (walls, ground, water, etc) for our input, and the output will be a specific sprite
index in some theoretical sprite sheet.

1. Create one or more rules that define a pattern to match, a value to output, and optionally a percentage
chance for that rule to be chosen. 
   ```rust
   use micro_autotile::AutoTileRule;
   const GROUND: usize = 0;
   const WALL: usize = 1;
   
   let alt_ground_rule = AutoTileRule::single_any_chance(GROUND, vec![123, 124, 125], 0.2);
   let fallback_ground_rule = AutoTileRule::exact(GROUND, 126);
   ```
2. (Optional) Put together your rules in a rule set. This can be skipped and the rule structs used directly
   ```rust
   use micro_autotile::{AutoRuleSet, AutoTileRule};
   let ground_rules = AutoRuleSet::new(vec![alt_ground_rule, fallback_ground_rule]);
   let wall_rules = AutoTileRule::exact(WALL, 35).into();
   let combined_rules = wall_rules + ground_rules;
   ```

3. Elsewhere, generate a slice of level data wrapped in a `TileLayout` struct. This represents a single tile
   (the central element) and its surrounding neighbors. The order of the neighbors is important, and is laid
    out as though in a flattened grid.
   ```rust
   use micro_autotile::TileLayout;
   let layout = TileLayout::filled([
     GROUND, GROUND, GROUND,
     GROUND, WALL, GROUND,
     GROUND, GROUND, GROUND,
   ]);
    ```

4. Produce an output using either the rule set or the rule directly (the same methods exist for both)
   ```rust
   let output = combined_rules.resolve_match(&layout);
   assert_eq!(output, Some(35));
    ```