ecsly 0.0.1-dev.5
ecsly: ^0.0.1-dev.5 copied to clipboard
Experimental ECS core for Dart/Flutter (early prerelease).
ecsly (Entity Component System) for Dart/Flutter #
⚠️ This package is published as super-experimental prerelease (0.0.1-dev.5).
APIs are actively changing and may break across releases.
ecsly is a high-performance Dart ECS runtime focused on deterministic simulation and low-GC hot loops.
It owns entities, archetypes, resources, events, commands, and schedules.
Use it when you want a small pure-Dart ECS core under games, simulations, tools, tests, or plugin packages. Start with normal Dart object components, then move hot numeric state to typed extension components when GC pressure or iteration speed matters.
Use #
Add to pubspec.yaml:
dependencies:
ecsly: ^0.0.1-dev.5
Import path:
import 'package:ecsly/ecsly.dart';
Tiny story #
Define a component as ordinary Dart data:
class CounterComponent extends Component {
CounterComponent(this.value);
int value;
}
Create a world and register the component storage:
final world = World();
world.components.registerObjectComponent<CounterComponent>();
Spawn an entity with a component bundle:
final entity = world.reserveEmptyEntity().entity;
world.spawnBundle(entity, ComponentBundle.fromLists([CounterComponent(1)]));
// Structural changes are queued; flush makes them visible to queries.
world.flush();
Read or mutate it:
for (final (_, counter) in world.queryMut<CounterComponent>()) {
counter.value += 1;
}
Put logic into a schedule when you want named update stages:
world.createSchedule('Update').add((world) {
for (final (_, counter) in world.queryMut<CounterComponent>()) {
counter.value += 1;
}
});
world.runSchedule('Update');
world.flush();
For hot numeric data, use extension components backed by typed columns. See
example/scheduled_run.dart for a compact EnergyComponent example.
Why it is useful #
- Deterministic structural changes through command queues and explicit flushes.
- Fast iteration through archetypes, query masks, and column storage.
- Flexible object components for simple/cold data.
- Low-GC extension components for compact hot data.
- Schedules, resources, events, and plugins without depending on Flutter.
Examples #
example/basic_world.dart: smallest object-component flow.example/scheduled_run.dart: schedule plus customFloatColumnextension component.example/components.dart: tiny components with dartdoc explaining the storage choices.
Run an example from this package directory:
dart run example/basic_world.dart
Core examples avoid owning gameplay-space components such as PositionComponent
and VelocityComponent. Use sibling plugin packages, such as game2d_plugin,
for shared game concepts.
Benchmarks #
Generate a local report:
dart run benchmark/run.dart --limits \
--markdown-out=benchmark/results/latest.md \
--json-out=benchmark/results/latest.json
The benchmark suite reports hot-path strengths and bottleneck signals: query iteration, raw chunk iteration, command flush, migration, cache hit/miss, events, memory delta, and optional entity-count scaling. Results depend on machine, OS, Dart SDK, and runtime mode, so compare reports from the same environment.
What this package is and is not #
- ✅ Core runtime package: entities, archetypes, resources, events, plugins, and system schedules.
- ✅ Runtime-first with minimal external dependencies and early-prerelease status.
- ❌ Not a code-generator package: use
ecs_codegenonly where annotation-based code generation is needed. - ❌ Not a full application stack: graphics/input/collision/camera plugins live in sibling package folders.
Documentation #
- DX_FAQ.md — how to start, examples, terminology, and practical usage.
- DESIGN_FAQ.md — architecture, trade-offs, and why the API works this way.
- Autogenerated API docs
- CHANGELOG.md
Acknowledgements #
ecsly stands on prior ECS and simulation work. We appreciate ideas and lessons from
Bevy, EnTT, and many other open-source contributors.