jengine-swarm
Flocking / swarm AI for jEngine - spatial-grid boids that scale to thousands of entities.
| Kind | Built-in: linked into the stock runtime and editor viewport |
| Source | packages/jengine-swarm |
| Version | 0.1.0 |
| Entry point | jengine_swarm::SwarmPackage |
Using it
Section titled “Using it”The stock runtime, web build and editor viewport are compiled with this package, so there is
nothing to link. A project that has a settings.enabled_packages list must name it there, since
that list is an allow-list once it exists; a project without the key gets every built-in.
{ "settings": { "enabled_packages": ["jengine-swarm"] } }A scene that uses its components must be a v2 scene ("version": 2): a v1 scene has no field
for a package component and keeps it as inert custom data.
Components
Section titled “Components”| Scene key | Rust type | |
|---|---|---|
swarm_spawner | SwarmSpawner | package only: needs a v2 scene |
boid | Boid | package only: needs a v2 scene |
Scenes that use it
Section titled “Scenes that use it”projects/engine-test-lab/assets/scenes/131-swarm-steering.sceneprojects/engine-test-lab/assets/scenes/61-swarm.sceneprojects/visual-showcase/assets/scenes/17-murmuration.scene
From packages/jengine-swarm/src/lib.rs.
Swarm AI for jEngine — flocking that scales to thousands of entities.
A jEngine package: it registers its own components and a system, and the
runtime’s PackageHost runs that system each frame. See
docs/writing-packages.md.
What it does
Section titled “What it does”One entity carries a SwarmSpawner. The package’s system keeps the boid
population matched to the spawner’s count — spawning and despawning as
needed — then flocks them with a spatial grid (see flock).
Spawning from inside the package rather than from a script is deliberate. Creating thousands of entities through the script bridge would be thousands of deferred commands per frame, and the whole point here is to measure the simulation, not the bridge.
Changing the count at runtime
Section titled “Changing the count at runtime”A script sets Entity.set_custom(spawner, "Swarm", "count", n). The system reads
that override in preference to the authored value.
Steering it
Section titled “Steering it”The same way, and in every runtime: Swarm/target_x, target_y and
target_pull draw the flock toward a point (a murmuration wheeling over
its roost), and threat_x, threat_y, threat_radius make every boid
inside the radius flee it (a falcon through a murmuration). The authored
target_pull and threat_strength are the defaults a script’s values
override; with neither set the flock only keeps to its area, as it
always did.
Steering goes through CustomComponents rather than script commands of
its own. That choice predates register_script_commands - when it was
made, a package’s script functions were installed by the native Lua bridge
only - and it still has one advantage: a script can read the values back
with Entity.get_custom, which a command (returning nothing) cannot offer.
Why it owns its integration
Section titled “Why it owns its integration”It writes Transform directly instead of steering a Velocity2D and
letting the engine integrate. The runtimes order their velocity pass
differently relative to the package phases — native integrates after
PreUpdate, the editor viewport before it — so relying on that would make
the same scene behave differently in each, which is useless for a scene
whose job is comparing their frame rates.