good

Game Overdrive On Dart. The kernel every good engine is built on: the ECS, the fixed-tick loop, scenes, native component storage, input, assets and coroutines.

Building a 2D game? Install goo2d instead. It re-exports everything here, so you get this package anyway and a renderer with it. Depend on good directly when you are writing a renderer, a headless server, or a package that should work under either engine.

flutter pub add good

The one idea

Components are not objects. A field declared on an entity kind is a column in native memory, and an entity is a row index into it:

import 'package:good/good.dart';

class Player extends EntityStruct {
  final speed = Field.float64(220);   // the default every new row starts at
}
speed[entity] = 400;   // write one row

That is what keeps the frame loop free of allocation, and it is the thing worth understanding before anything else. Systems then query for the entities they care about and walk those columns:

class PlayerSystem extends GameSystem with FixedTickable {
  late final Query players;

  @override
  void describeQuery(QueryDescriptor descriptor) {
    super.describeQuery(descriptor);
    players = descriptor.query().withAll(Player).build();
  }

  @override
  void onFixedUpdate() { /* ... */ }
}

Next

It does depend on Flutter, because GameView is a widget and StateChannel is a ValueListenable.

The ECS, memory pool, scheduler, scenes, hierarchy, input, assets, coroutines and timelines work today. Audio playback and array-typed fields are not implemented, and the web is unsupported because this needs dart:ffi and isolates. What works today.

Libraries

good
Dimension-agnostic engine kernel: ECS, shared memory pool, ring buffers, scenes, fixed-tick loop, hierarchy, and the generic asset registry.