bevy_northstar 0.3.2

A Bevy plugin for Hierarchical Pathfinding
Documentation
# Grid Updates
You can modify the navigation data of individual cells at runtime using `Grid::set_nav()`. 
After making changes, you **must** call `Grid::build()` to update the internal state.

When `Grid::set_nav()` is called, the affected chunk and its adjacent chunks are automatically marked as dirty. During the next `Grid::build()` call, only those dirty chunks are rebuilt. If the default parallel feature is enabled, chunk rebuilds are performed in parallel for better performance.

Calling any of the `Grid` pathfinding methods on a dirty grid will log an error and return `None`.

Example:
```rust,no-run
if input.just_pressed(MouseButton::Right) {
    if let Some(position) = clicked_tile {
        let mut grid = grid.into_inner();

        if let Some(nav) = grid.nav(position) {
            if !matches!(nav, Nav::Impassable) {
                // If the cell is passable, we set it to impassable.
                grid.set_nav(position, Nav::Impassable);
            } else {
                // If the cell is impassable, we set it to passable with a cost of 1.
                grid.set_nav(position, Nav::Passable(1));
            }
        } else {
            return;
        }
        // You must call `build` after modifying the grid to update the internal state.
        grid.build();
    }
}
```

## Performance Notes
Rebuilding a single chunk takes approximately **0.2ms** on modern systems. Note that updating a cell in a single chunk may require updating neighboring chunks if it touches an edge. If you enable `GridSettingsBuilder::diagonal_connections()` or use an ordinal `Neighborhood`, the number of adjacent chunks needing rebuilds may increase.

* With the default `parallel` feature enabled, multiple dirty chunks can often be rebuilt in the same frame with a ~35% speedup.
* If `parallel` is disabled (e.g. for WASM), rebuilding a large number of chunks sequentially may exceed your frame budget. In that case, consider:

    * Limiting updates to small, localized areas per frame.

    * Spreading updates across multiple frames.

    * Adjusting chunk size to find the best performance fo your use case.