An attempt to be able to use Dart as a scripting language for Godot.
Because I like Dart.
And I want to use it in Godot.
Currently, Dart can be initialized as a language usable as a GDExtension, but not as a scripting language. This means you can create Dart classes and Nodes and add them to you scene tree, and they will execute both in editor and in game.
Here's a list of planned features and work still to be done ( ✅ - Seems to be working, 🟨 - Partially working, ❌ - Not working)
Feature | Support | Note |
---|---|---|
Dart as a Godot Extension Language | 🟨 | |
Ref counted object support | ❌ | |
Dart Debugging Extension | ✅ | Attach to http://127.0.0.1:5858 |
Dart Available as a Scripting Language | ❌ | |
Hot Reload | ❌ | |
Simplified Binding using build_runner | ❌ | |
Dart native Variants | ❌ | Needed for performance reasons |
Memory efficiency / Leak prevention | ❌ |
Some notes about the current state:
- The binding is likely leaking both Dart objects and native allocations. I intend on making a pass through to make sure all of that is cleaned up at some point and correctly utilize native finalizers.
- Right now Godot will crash on exit because the binding isn't cleaning up after itself and it tried to free Dart objects after Dart has aready been shut down.
I have only tested this on Windows. I know for certain it will only work on 'float_64' builds of Godot.
- A clone of this repo.
- Dart (2.19 Current Stable, not tested with 3.0)
- Godot 4.0.2 or a custom build compatible with 4.0.2
- A build of the Dart Shared
Library. Windows x64 .dlls
for Dart 2.19 are provided in
src/dart_dll/bin/win64
. - A way to build
src/cpp
. A Visual Studio solution is provided if you have Visual Studio. If not, use your favorite tool to build the provided files.
To use the extension, you need to:
- Copy both your
dart_dll
dynamic library and thegodot_dart
dynamic library to your project directory. - Copy
simple/example.gdextension
to your project directory (note this is only configured forwindows.64
builds and will need to be modified for any other OS). - Create a
src
directory in your project directory to hold your Dart code. This should be a proper Dart package, complete with apubspec.yaml
file. Add amain.dart
to this directory. - Run the Binding Generator
# From tools/binding_generator
dart ./bin/binding_generator.dart
- Add a reference to the
godot_dart
package that is defined insrc/dart
. You will need to use a path dependency for this for now. - Add a
main
function to yourmain.dart
. This is where you will register your Godot classes
You should now be able to write Dart code for Godot! But, there are some
requirements for any Godot accessible Dart class. Here's the Simple example
class in simple/src/simple.dart
class Simple extends Sprite2D {
// typeInfo is required. Make sure that your class name
// and the inheritted name are both correct.
static late TypeInfo typeInfo;
static void initTypeInfo() => typeInfo = TypeInfo(
StringName.fromString('Simple'),
parentClass: StringName.fromString('Sprite2D'),
);
// a vTable getter is also required. If you are not adding any
// virtual functions, just return the base class's vTable
static Map<String, Pointer<GodotVirtualFunction>> get vTable =>
Sprite2D.vTable;
// An override of [staticTypeInfo] is ALSO required. This is how
// the bindings understand the what types it's looking at.
@override
TypeInfo get staticTypeInfo => typeInfo;
double _timePassed = 0.0;
// Constructor is required and MUST call [postInitialize]
Simple() : super() {
postInitialize();
}
// All virtual functions from Godot should be available, and start
// with a v instead of an underscore.
@override
void vProcess(double delta) {
_timePassed += delta;
final x = 10.0 + (10.0 * sin(_timePassed * 2.0));
final y = 10.0 + (10.0 * cos(_timePassed * 2.0));
final newPosition = Vector2.fromXY(x, y);
print('vProcess - $x, $y, ${newPosition.x}, ${newPosition.y}');
setPosition(newPosition);
}
}
Classes also need to be registered to Godot in main.dart
:
void main() {
Simple.initTypeInfo();
gde.dartBindings.bindClass(Simple, Simple.typeInfo);
}
I know this is a very complicated setup. I'll be looking to simplify it in the future once more features are working.
This utilizes my custom built Dart shared library for embedding Dart, the source for which is available here. I've included the win64 prebuilt binaries in this repo for simplicity.