Introducing the GodotEx C# Extension Library

Hi all! :saluting_face:

I have just uploaded the GodotEx C# extension library package to Nuget. Please check it out and leave any comments. Here are some extra links to the Github repository and the documentation website.

Love :yellow_heart:


GodotEx

Godot Extra provides a set of extension libraries for Godot in C#.

Currently available extension libraries:

GodotEx

Basic extension library for Godot:

GodotEx.Async

Asynchronous extension library for Godot:

GodotEx.Hosting

Hosting extension library for Godot:

  • A Host node that provides hosting functionalities with ServiceProvider

  • Dependency injection through the above Host

Installation

Choose the package(s) you need and run the following command(s) to install the nuget package(s).


dotnet add package GodotEx

dotnet add package GodotEx.Async

dotnet add package GodotEx.Hosting

Documentation

Please refer to this page for a detailed documentation on all available extension libraries.

License

Distributed under the MIT License. Copyright (c) 2024 altamkp.

4 Likes

This looks useful and well-documented. I have a few random questions and thoughts, having looked over the docs and code (mainly for the base package) but not having tried it out yet. Apologies if I misinterpret something.

  • The “get children of type” helpers are definitely something I would use.

  • Coming from a .NET Core MVC background, the Hosting library seems generally interesting.

  • Automatic resolution for NodePath: when using this feature, and not using GodotEx.Hosting.Host, my interpretation is that while the root node of the scene being instantiated will have Resolve() called automatically, all of the children will need to call it manually.

  • Have you done performance profiling to compare the Godot and GodotEx equivalents in the docs? In particular I’m curious about the impact of additional reliance on reflection for various attribute checking/reading. I know the .NET folks have chipped away at the reflection cost over time though, including that of GetCustomAttributes().

A few nitpicks:

  • It’s unclear why TweenExtensions.Default inverts the actual default behavior in Godot.

  • The InputEventExtensions.Key section seems possibly ill-advised, in the sense that it makes it slightly easier to hardcode “standard” input mapping. :slight_smile:

  • NodeExtensions.GetAllChildren indicates it gets children and grandchildren, but will recursively descend indefinitely. The method name is ambiguous in either case, and the description is arguably wrong. My suggestion: GetDescendants.

  • NodeExtensions.GetAncestor is also vague. It gets the closest ancestor of the specified type, which is probably reasonable, but not clearly communicated by either the description or the method name. My suggestion: GetClosest (similar to the Closest() DOM traversal method in JS) or GetClosestAncestor.

2 Likes

Massive thank you for such a detailed reply, and some very helpful comments too. I will try to answer you questions as best as I can.

Automatic resolution for NodePath: when using this feature, and not using GodotEx.Hosting.Host, my interpretation is that while the root node of the scene being instantiated will have Resolve() called automatically, all of the children will need to call it manually.

Absolutely correct, Resolve() only handles the node which calls the function itself but not its children. In fact, you need to call Resolve() manually on all nodes that have dependencies marked with [NodePath], which is why using GodotEx.Hosting.Host is recommended as it provides a background service that monitors the SceneTree’s NodeAdded signal and resolve the newly added node. As a result, you can simply label your dependencies with [NodePath] and don’t need to worry about resolving every single class.

Have you done performance profiling to compare the Godot and GodotEx equivalents in the docs?

Good call, I will do some profiling to compare GetNode() and resolving using reflections, hopefully uploading the results here and on the docs as well.

It’s unclear why TweenExtensions.Default inverts the actual default behavior in Godot.

This is based on my own humble experience with using Tween, other developers may disagree, but they can always choose not to use the Default() in GodotEx.

The InputEventExtensions.Key section seems possibly ill-advised, in the sense that it makes it slightly easier to hardcode “standard” input mapping.

You are correct, and they are polluting the library a bit as well. I shall remove InputEventExtensions.Key and InputEventExtensions.Mouse all together, IsMousePressed/Released and IsKeyPressed/Released are powerful enough.

NodeExtensions.GetAllChildren indicates it gets children and grandchildren, but will recursively descend indefinitely. The method name is ambiguous in either case, and the description is arguably wrong. My suggestion: GetDescendants.

Certainly, I will rename this function to GetDescendants and update the docs.

NodeExtensions.GetAncestor is also vague.

Also agreed, will update to GetClosestAncestor.

2 Likes