DEV Community

Cover image for ecsly - pure dart ecs library / prerelease
Anton Malofeev
Anton Malofeev

Posted on

ecsly - pure dart ecs library / prerelease

I've decided to publish ecsly - small but highly performant ecs written in dart which I started developing to solve the simulation problem while developing a games in flutter and ended up building game engine xD

currently has no public repository, and in pre-release state - contains no graphics, no flutter, almost no dependencies - so it can be used in flutter, jasper - basically in any dart environment..

I'm not sure that I've got benchmarks correct (added file to library), but hopefully it is true - I've tried to push dart to limits - use SIMD where it is possible, reduce any GC, etc..

I didn’t published entire engine - only most important part of it, which in my opinion has stabilized most.

Tiny example will look like this:

import 'package:ecsly/ecsly.dart';

/// Tiny object component for the pub.dev example entry point.
///
/// `ecsly` also supports packed typed-data columns for hotter loops, but an
/// object component keeps the first example intentionally small.
class CounterComponent extends Component {
  CounterComponent(this.value);

  int value;
}

void main() {
  final world = World();
  world.components.registerObjectComponent<CounterComponent>();

  final entity = world.reserveEmptyEntity().entity;
  world.spawnBundle(entity, ComponentBundle.fromLists([CounterComponent(1)]));
  world.flush();

  for (final (_, counter) in world.queryMut<CounterComponent>()) {
    counter.value += 1;
    print('counter=${counter.value}');
  }
}
Enter fullscreen mode Exit fullscreen mode

With SIMD the api looks like this:

import 'dart:typed_data';

import 'package:ecsly/ecsly.dart';

class Velocity4Component extends Component {
  const Velocity4Component();
}

extension type Velocity4._(int index) {
  static late FloatColumn column;

  double get x => column.getValueUnsafe(index, 0);
  double get y => column.getValueUnsafe(index, 1);

  set x(double value) => column.setValue(index, 0, value);
  set y(double value) => column.setValue(index, 1, value);
}

final class Velocity4ColumnFactory extends ColumnFactory {
  @override
  DataColumn createColumn(
    ComponentId componentId, {
    int initialCapacity = 8,
  }) {
    return FloatColumn(stride: 4, initialCapacity: initialCapacity);
  }
}

final class Velocity4FacadeFactory
    extends ComponentFacadeFactory<Velocity4> {
  @override
  Velocity4 create(int index) => Velocity4._(index);

  @override
  void initialize(covariant FloatColumn column) {
    Velocity4.column = column;
  }
}

final world = World();
world.components.registerExtension<Velocity4Component, Velocity4>(
  columnFactory: Velocity4ColumnFactory(),
  facadeFactory: Velocity4FacadeFactory(),
);

final entity = world.reserveEmptyEntity().entity;
world.spawnBundle(
  entity,
  ComponentBundle.fromExtensionList(const [
    (Velocity4Component, Velocity4),
  ]),
);
world.flush();

for (final (_, velocity) in world.queryExt<Velocity4Component, Velocity4>()) {
  velocity.x = 3;
  velocity.y = 4;
}

final simd = Velocity4.column.simdView;
if (simd != null) {
  final gravity = Float32x4(0, -9.8, 0, 0);
  for (var i = 0; i < Velocity4.column.length; i++) {
    simd[i] = simd[i] + gravity;
  }
}
Enter fullscreen mode Exit fullscreen mode

I didn't changed the api for almost half a year so decided to try publish:)

More detailed explanation will try to publish as part of architectural series - in short I believe that ECS is best and most scalable architecture for high performance applications and games. I designed it to be used alongside with Flutter, Jaspr and any other dart framework or to be used separately if needed.

I'm sure that it is possible to do more - more convenient DX, more optimizations

will be glad for any feedback:)

https://pub.dev/packages/ecsly

p.s.: heavily inspired by bevy and entt frameworks and many other libraries
p.p.s: made with AI (I'v started from scratch, so every concept was new to me - it would be impossible to write and understand it in such short time for me:)

Top comments (0)