bevy_map_scatter
Bevy plugin for rule-based scattering with asset loading, async execution, and ECS-friendly results.

Features
Asset-driven scattering for Bevy with async execution and ECS-friendly results:
- Asset-based authoring of scatter plans (RON): load
*.scatterfiles viaAssetServer. - Texture integration: snapshot Bevy
Images to CPU textures with configurable domain mapping. - Asynchronous execution: runs scatter jobs on
AsyncComputeTaskPool. - ECS-friendly: placements become entities; components can be attached for rendering, gameplay, or tooling.
- Streaming helper: manage chunked scatter around moving anchors (optional plugin).
- Diagnostics: forward core events as Bevy messages (
ScatterMessage,ScatterFinished) with configurable filtering.
Use cases
Use cases: decorative dressing, resource distribution, or any placement driven by textures and rules.
Workflow notes:
- Plans are assets and can hot-reload
- Tweak textures, thresholds, or layer order and rerun
- Deterministic seeds by default; vary them per run when needed
Examples:
- Stylized forest: trees sparse, mushrooms where tree probability is low, grass fills gaps.
- Town dressing: benches in plaza masks, lamp posts along roads with spacing, clutter where nothing else landed.
- Dungeon encounters: camps in large rooms, enemies avoid camp influence, rare loot in dead ends with minimum spacing.
Integration details:
- Assets:
*.scatterplans loaded byAssetServer - ECS: placements become entities you can tag and decorate
- Async: jobs run on
AsyncComputeTaskPool - Determinism: same seed + plan + textures = identical placements
- Events: listen to
ScatterFinishedorScatterMessageto drive gameplay or tooling
Examples
See the example crate for curated demos you can run locally.
Quick start
Add the crates to a Bevy application:
# Cargo.toml
[]
= "0.18"
= "0.3"
= "0.3"
Create a scatter plan in assets/simple.scatter:
(
layers: [
(
id: "dots",
kinds: [
(
id: "dots",
spec: (
nodes: {
"probability": Constant(
params: ConstantParams(value: 1.0),
),
},
semantics: {
"probability": Probability,
},
),
),
],
sampling: JitterGrid(
jitter: 1.0,
cell_size: 1.0,
),
selection_strategy: WeightedRandom,
),
],
)
Trigger a single scatter run once the asset is ready:
use *;
use *;
;
/// Loads the scatter plan asset on startup.
/// Triggers a scatter request once the plan asset is loaded.
/// Observes the `EntityEvent` when a scatter run has finished.
Run the application with cargo run. After the scatter job completes, a summary appears in the log; continue with placement logic as needed.
Streaming (optional)
For moving worlds or endless maps, use MapScatterStreamingPlugin and attach
ScatterStreamSettings to an anchor entity. The plugin will spawn/despawn chunks
around the anchor and emit placement entities tagged with ScatterStreamPlacement.
Alternatives
bevy_feronia: more opinionated, art-focused scattering with built-in wind/material/LOD workflows; likely a better fit if you want an end-to-end visual pipeline rather than a low-level, data-driven scatter core.
Compatibility
bevy_map_scatter |
map_scatter |
bevy |
|---|---|---|
0.3 |
0.2 |
0.18 |
0.2 |
0.2 |
0.17 |