| Crates.io | bevy_map_scatter |
| lib.rs | bevy_map_scatter |
| version | 0.4.1 |
| created_at | 2025-08-28 18:23:11.067688+00 |
| updated_at | 2026-01-17 20:18:21.758058+00 |
| description | Bevy plugin that integrates the `map_scatter` core crate for object scattering with field-graph evaluation and sampling |
| homepage | |
| repository | https://github.com/morgenthum/map_scatter |
| max_upload_size | |
| id | 1814426 |
| size | 1,243,984 |
Bevy plugin for rule-based scattering with asset loading, async execution, and ECS-friendly results.

Asset-driven scattering for Bevy with async execution and ECS-friendly results:
*.scatter files via AssetServer.Images to CPU textures with configurable domain mapping.AsyncComputeTaskPool.ScatterMessage, ScatterFinished) with configurable filtering.Use cases: decorative dressing, resource distribution, or any placement driven by textures and rules.
Workflow notes:
Examples:
Integration details:
*.scatter plans loaded by AssetServerAsyncComputeTaskPoolScatterFinished or ScatterMessage to drive gameplay or toolingSee the example crate for curated demos you can run locally.
Add the crates to a Bevy application:
# Cargo.toml
[dependencies]
bevy = "0.18"
bevy_map_scatter = "0.3"
map_scatter = "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 bevy::prelude::*;
use bevy_map_scatter::prelude::*;
#[derive(Resource, Default)]
struct PlanHandle(Handle<ScatterPlanAsset>);
fn main() {
App::new()
.init_resource::<PlanHandle>()
.add_plugins(DefaultPlugins)
.add_plugins(MapScatterPlugin)
.add_systems(Startup, load_plan)
.add_systems(Update, trigger_request)
.add_observer(log_finished)
.run();
}
/// Loads the scatter plan asset on startup.
fn load_plan(mut handle: ResMut<PlanHandle>, assets: Res<AssetServer>) {
handle.0 = assets.load("simple.scatter");
}
/// Triggers a scatter request once the plan asset is loaded.
fn trigger_request(
mut commands: Commands,
mut once: Local<bool>,
handle: Res<PlanHandle>,
assets: Res<Assets<ScatterPlanAsset>>,
) {
// Only run once.
if *once {
return;
}
// Wait until the asset is loaded.
if assets.get(&handle.0).is_none() {
return;
}
// The domain size for scattering.
let domain = Vec2::new(10.0, 10.0);
// Create run configuration and seed for (deterministic) randomness.
let config = RunConfig::new(domain)
.with_chunk_extent(domain.x)
.with_raster_cell_size(1.0);
// Spawn an entity to track the request (attach your own components if needed).
let entity = commands.spawn_empty().id();
// Trigger the scatter run.
commands.trigger(ScatterRequest::new(entity, handle.0.clone(), config, 42));
// Mark as done.
*once = true;
}
/// Observes the `EntityEvent` when a scatter run has finished.
fn log_finished(finished: On<ScatterFinished>, mut commands: Commands) {
info!(
"Scatter run {} finished: placements={} evaluated={} rejected={}",
finished.entity,
finished.result.placements.len(),
finished.result.positions_evaluated,
finished.result.positions_rejected
);
// Clean up the entity used for the request (keep it if you need it later).
commands.entity(finished.entity).despawn();
}
Run the application with cargo run. After the scatter job completes, a summary appears in the log; continue with placement logic as needed.
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.
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.bevy_map_scatter |
map_scatter |
bevy |
|---|---|---|
0.4 |
0.4 |
0.18 |
0.3 |
0.3 |
0.17 |
0.2 |
0.2 |
0.17 |