Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Godot C# GDExtension Roadmap Discussion #7895

Open
reduz opened this issue Sep 27, 2023 · 166 comments
Open

Godot C# GDExtension Roadmap Discussion #7895

reduz opened this issue Sep 27, 2023 · 166 comments

Comments

@reduz
Copy link
Member

reduz commented Sep 27, 2023

NOTE: This proposal aims to be a public technical discussion regarding the future of C# in Godot. The idea is to get help from the community to reach implementation direction consensus.

Describe the project you are working on

Godot C# Bindings

Describe the problem or limitation you are having in your project

The current implementatio of C# in Godot is done on top of the script layer directly and in C++ using the .NET hosting API.
This is due to how Godot worked in version 3. It currently has the following problems:

  • Large amounts of C++ are required to glue Godot to the C# runtime, this makes it difficult to maintain and redundant with the new extension system in Godot 4. It is a lot of C++ code that supplies the same function as GDExtension.
  • Many of the APIs exposed to C# currently are lagging behind what GDExtension provides, preventing many optimizations.
  • It makes it harder to have a single version of Godot, because the large amount of glue code encourages users to switch it off when not needed to save space.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

The proposed solution is to move C# support to the new extension system in Godot 4.0.
This will give C# in Godot effective first class support at the same level C++ has, bringing the following features:

  • The entirety of the C# glue layer (currently done via C++ .net hosting API) will be majorly replaced by GDExtension, using the extension interface common to all binding languages (GodotCPP, Rust, etc). The modules/mono folder will be removed from the codebase and likely replaced by only by a tiny boostrapper to load the .net runtime on demand if installed in the project.
  • Because the entirety of the C# support will use the shared extension system (GDExtension), a single, unified version of Godot and the export templates will be possible.
  • Some of the C# API, including the native Godot collections, will be changed for more efficiency (Example #7842).

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

NOTE This is a medium term goal for C#. Currently, our immediate priorities are fixing C# support on mobile
and web
. What is described in this proposal is work that would happen in parallel.

Ideally, we want to move Godot to use the GDExtension API instead of the
current custom glue glue. Unlike GDExtension, though, we don't want to
depend on a glue API, it should be possible to open the .NET DLL
containing the Godot C# library and have it register itself via the
GDExtension API through a tiny boostrapper that detects if a .net runtime is installed.

This would make the entire C++ side far simpler, easier to maintain,
and easier to implement new features (such as many additions on the
GDExtension side currently are not supported in in the current module, such as GDVIRTUAL,
struct pointers, Godot collections, enhanced performance due to less glue, etc).

Additionally, it would make it easy to have a single Godot executable
and export templates, where C# can be plugged at run-time easily.

Here are the steps to evaluate that would be required to do this:

Creation of a Godot Library in C#

The main idea is that C# should act as if it was a C++ extension. A library
(in the shape of a .net DLL), probably GodotLibrary.dll, can be added to
a project and this automatically is recognized and opened by Godot as if
it was a native shared object, but done actually via the .NET runtime.

In other words, if the C# runtime is installed in the Godot project (or
supplied by the platform to Godot), it is used to open GodotLibrary.dll
and call an entry point that should be the same as a regular GDExtension,

Rewrite the extension interface in C#

Godot has a C extension
interface

defined in C. This extension interface should be available as part of
the GodotLibrary.dll C# source code. Probably something like
ExtensionInterface.cs.

This means making all the structs and C funtions available in unsafe
mode as their C# counterparts.

Binder generation

Once we have the extension interface defined in C#, we can start working
on the binder generator. Before going into this, I think it's important
to reach consensus
on whether we want to generate the bindings as scripts or
extension.

Bindings as extension or script?

Godot has two possible workflows today and both are supported in GDExtension: Script Workflow and Class Extension Wokflow.

Normally, script workflow is very quick and intuitive for GDScripts, as the steps to create a new script are:

  • Select a node.
  • New script wizard button.
  • Automatically start editing it im the built-in editor.
  • See changes and exported properties in editor automatically.

Blazingly fast. In contrast, for C# the script workflow is more cumbersome:

  • Creating a script and placing it as a node in the scene tree:
    • Switch to the C# IDE
    • Create a new file in C#, tag it as script, compile.
    • Switch back to the editor, reload happens.
    • Create a new base node of the right type.
    • Look for the script file, assign it to the node.
  • Or alternatively:
    • Create a new base node of the right type.
    • Use the new script wizard to create a template .cs script
    • Switch to the C# IDE
    • Edit the script
    • Compile
    • Return to the editor.

The alternative is to implement C# using the Class Extension workflow. This workflow is the one compiled languages like GodotCPP, Rust, Swift, etc. uses.

In C#, it would work like this:

  • Creating an extension class:
    • Switch to the C# IDE
    • Create a new class (no need to be new file) inheriting a node type, tag it as extension class.
    • Edit it.
    • Switch back to the editor
    • Create the node directly as this class.

As you can see, when using compiled languages, there are not significant differences.

The question is, should C# using script or extension class bindings?

Here are the pros and const:

Script

Pros:

  • Easy to switch one script by another during run-time.
  • Soft reloading is a bit safer.
  • Can edit C# scripts in the engine itself (though nobody really uses this, everyone uses external editor).
  • Can theoretically debug C# in the editor (theoretically, but not currently supported and most users seem fine with the C# debugger of their IDE).

Cons:

  • Less efficient for performance (more indirections). Many of codepaths goes via Variant conversion, which less efficient.
  • Not great for add-ons. If you create a Terrain add-on, it will appear as a Godot node with a C# script rather than a native C# class.
  • Not possible to replace parts of the engine (no custom audio formats, custom renderer, custom multiplayer driver, custom physics engine, etc.).
  • Bindings code a bit more difficult to maintain.

Extension class

Pros:

  • Very performant, integrates very well as if it was a native engine class.
  • GDVIRTUAL (which is used for engine callbacks such as _Process, _Ready, etc.) a lot more optimal than in scripts.
  • Struct pointers can be used in high performance APIs.
  • Ability to replace internals of the engine.
  • Simpler binding code.

Cons:

  • Can't easily replace in run-time, must delete a node and replace by a new one.
  • Soft reloading will work, but may be troublesome in some unexpected corner cases due to this process being a bit more complex (need to add and remove from ClassDB).

Should we use Script or Class extension workflow? That is up to you community.

My personal recommendation would be to go with Class Extension workflow primarily due to performance reasons. With this workflow you will be able to always have optimal performance in all situations and the alternations to ease of use are very minimal.

EDIT: I added a small poll a few coments below.

I put together a quick FAQ:

**Q**: Will I be able to reload extensions like scripts?
**A**: Yes

**Q**: If when loading a project, some extension class is missing, is this 
       lost upon scene load?
**A**: No, extensions create placeholders so you can re-save your scene and open 
       it again when the class exists.

**Q**: Can both workflows be provided?
**A**: There is some discussion on the GodotCPP side with this same question. 
       Its hard the same class is provided as both script an extension, so one 
       possibility is to have something like `CSharpScript<BaseClass>` you inherit, 
       then you access the actual engine class via a "base" property, example you 
       change position by doing `base.position = Vector2(20,30)`. This would allow both workflows.

**Q**: Will I have to redo my C# project if we go with Extension Class workflow?
**A**: Minimal changes will be needed and a converter for scenes can be provided 
       so the work you need to do is minimal.

New Bindings Generator

The new bindings generator would comprise of the following parts:

ExtensionInterface

As mentioned before, the
extension_interace
file from Godot rewritten in C# as ExtensionInterface.cs.

Everything else will use this and it replaces the glue/ code in the
existing modules/mono codebase.

Glue

The C# side of the glue that previously existed in mono/glue, which will
need to be used by both Godot Types and the bindings generator. This
talks to ExtensionInterface.cs to ensure that types such as
Callable, Signal and a few low level behaviors in the class bindings can
be implemented properly.

Godot Types

These are the basic Godot types (Vector3, Vector4, Transform2D, etc)
exposed to C#. They are currently located in this
directory
.
As mentioned before, not all need to be written natively, some now can
be done 100% by using the binding generator.

The Godot collections (the way C# calls Godot PackedArrays, Array,
Dictionary) currently are not properly implemented in C#, C# always does
conversion from native C# types to Godot types on every call. Ideally
this should be kept because it makes the API easier to use, but all the
Godot array types and dictionary should be properly supported as
Godot.Collections. This will allow properly implementing proposal
#7842.

Additionally, as mentioned, some may need minor changes, such as
Callable or Signal, which now need to use ExtensionInterface.cs.

Bindings Generator

This is the largest part of the work. The new bindings generator can
be written in Python, C# or whathever decided best. It takes an
extension_api.json file and dumps the whole Godot API as C#.

All the classes, utility functions (currently hardcoded), and several
other binding information is used to create the Godot API in C# entirely
in procedural form. Again, no C++ glue code should be needed anymore. Everything accessed via ExtensionInterface.cs.

Additionally, this should use the compatibility hashes system in
GDExtension, so we can ensure that backward compatibility is also kept
in C# when Godot releases new versions.

Currently, Godot C# uses API hashes, again those need to be dropped entirely and API hash support removed from Godot.

Editor Tools

Finally, porting the existing editor tooling to the new system. Most
code probably will remain unmodified.

Boostrapper

A small piece of code to load the .net runtime (if installed by the user), that calls the C# entry point.

Assembling the GodotLibrary.dll

The GodotLibrary.dll will be built from the existing and generated C# files created by the bindings generator script.

On PC platforms, It will be shipped in Godot together with:

  • C# runtime (where applies)

  • Respective additions to export templates to enable deploying using C#

  • Respective tools to help users build C# in their project using the
    GodotLibrary (in editor build).

Compiling the game

C# games in Godot would simply be a library compiled against
GodotLibrary.dll and other .net dependencies. This step is the same as now.

Deploying to platforms

An important question here is how will this be ported to different
platforms (iOS, C#, etc).

Essentially, nothing should really change. Platforms that run JIT will
ship with the runtime.

Platforms that use NativeAOT will need to just change how the entry
point is accessed, but all the work is now done inside C#, so all Godot
cares is reaching that entry point and that's it.

Closing words

Thanks for reading the C# roadmap so far. Feel free to discuss what you think in this proposal!

If this enhancement will not be used often, can it be worked around with a few lines of script?

N/A

Is there a reason why this should be core and not an add-on in the asset library?

The tiny boostrapper will be core, the rest obtainable separately.

@paulloz
Copy link
Member

paulloz commented Sep 27, 2023

Since I don't see it mentioned anywhere, I just want to paste below the minutes from last week's .NET contributors meetings regarding this specific topic. Note that I'm just quoting, I don't personally share the same opinion on all of the points.

Editor unification (.NET integration as a plugin/extension) (switch to integration as gdextension or just always bundle it)

  • Good way to move forward. Decouple C# support from the core. If anything is missing in GDExtension, it would be missing for other languages too.
  • Would need to drop the entire interop code and rewrite it from scratch. Module uses a number of APIs which might not be exposed to GDExtension yet.
  • C++ extension would not needed to be reloaded, and it would be able to reload C# assemblies just like the module does currently.
  • Performance difference need to be assessed - attendees not convinced this would make a difference to the current approach.

@Visne

This comment was marked as off-topic.

@reduz reduz changed the title Godot C# Rodmap Discussion Godot C# Roadmap Discussion Sep 27, 2023
@reduz

This comment was marked as resolved.

@JoNax97
Copy link

JoNax97 commented Sep 27, 2023

For my current/future use case (using C# to heavily modify Godot itself, basically creating a new editor), the extension class workflow would be hugely beneficial, if not outright necessary.

@reduz
Copy link
Member Author

reduz commented Sep 27, 2023

Quick poll!

If you favor script workflow (slightly better usability, but more limited in performance and extensibility), give this comment a 🚀
If you favor class extension workflow (better performance, ability to override engine internals, simpler code to maintain): give this comment a ❤️

@Zylann
Copy link

Zylann commented Sep 27, 2023

Some questions:

  • What about the specific behaviours of extension classes? Extension classes work as if they were core classes. One of the main behavior differences is that they always run, i.e there is no extra concept of optional @tool or [Tool] (whatever this is in C#), the classes will be really instantiated and code will run in the editor when added to the scene, as a side-effect to be integrated in a more low-level manner. Will it be the way it will work, or will [Tool] be added to C# extensions? (which means ClassDB I guess) That might also affect what we consider to be the "extension workflow". That said, the fact functions of a class are called in editor doesnt seem to be closely (or at all) related to having a more efficient binding system.

  • What about classes from other extensions? If I have a C++ extension that defines a bunch of classes (in my case, addons), will they automatically become available to C#? Inversely, if C# classes often change due to edits done in the project, will that affect C++ extensions? (even if they don't depend on C#). This also raises the question of dependencies between extensions, which I dont think was really explored with C++ and other native languages because it seems too cumbersome, though it might be a bit different for C#.

@LauraWebdev
Copy link

I just want to weight in that the current dev experience is pretty comfortable. I usually have my C# IDE on my second screen with the Godot Editor opened from the IDE.

There is one odd behavior where the Godot Editor sometimes seems to reset a source file (which I can revert easily) but I'm not entirely sure if that's a problem connected with the general structure.

One thing I'd like to know is how dependencies would be resolved in a user-scenario? Let's say I want to publish a tool written in C#, how would the user experience (of those who download said tool) be affected?

@moonheart08
Copy link

moonheart08 commented Sep 27, 2023

Just going to weigh in that ideally whichever workflow is chosen should avoid Variant/Godot object overhead. I've seen the whole discourse over GC recently and think it was missing the forest for the woods that is having to interface with the engine using an indirect reflection-like system instead of direct function calls.

I really think that forcing non-scripting languages to go through a dynamic API is a bad idea in general, strongly typed languages have strong typing for a reason and it should be utilized at every level of the API (including at the FFI point)

Thus, I'd advocate for the use of extensions here.

@c-schembri
Copy link

c-schembri commented Sep 27, 2023

My opinion is that if you're using C# in the first place, you're only worrying about performance and maybe third party libraries. I'd wager most C# developers care more about the former. On that point, whatever allows greater performance (or enables code which can facilitate greater performance), should be the option chosen.

Developer usability should be prioritised behind this. If we want nice usability, we can just use GDScript.

@moonheart08
Copy link

My opinion is that if you're using C# in the first place, you're only worrying about performance and maybe third party libraries. I'd wager most C# developers care more about the former. On that point, whatever allows greater performance (or enables code which can facilitate greater performance), should be the option chosen.

Developer usability should be prioritised behind this. If we want nice usability, we can just use GDScript.

Hard disagree here, GDScript is unsuitable for large scale/modular/moddable projects due to lackluster language design (lack of interfaces and composition tools, lack of reliable typing i.e. you can fall back into pure dynamic types pretty easily and no longer get error checking, lack of compile time type verification, etc), but that's another ballpark for another day.

@reduz
Copy link
Member Author

reduz commented Sep 27, 2023

@Zylann Exposing a [Tool] interface is probably the same, a placeholder class is created and used during editor run.

Classes from C++ extension should become available easy if the headers are generated for them, but there is not an easy way to do this yet. Its not technically complex, just that some UI/UX needs to be designed.

@JoNax97
Copy link

JoNax97 commented Sep 27, 2023

if you're using C# in the first place, you're only worrying about performance and maybe third party libraries. (...)

Hard disagree here, GDScript is unsuitable for large scale/modular/moddable projects due to lackluster language design (...)

While I don't agree GDScript is badly designed (I believe it seeks different design goals), I think it's true and important to highlight that modularity, scalability and refactorability are important aspects for choosing C#.

@SamPruden
Copy link

SamPruden commented Sep 27, 2023

This is really exciting! I just have a few clarifying questions:


This means making all the structs and C funtions available in unsafe
mode as their C# counterparts.

Am I understanding correctly that the plan here would be to expose low level APIs directly to C# (in an automated way based on GDE) but that high level APIs would be built on top of this (semi automated) for good user experience?

I would generally support that approach. Allowing each language to tailor the API design to its idioms rather than directly exposing GDE seems very important.


Is it in scope to make modifications to how the core APIs and GDE work to better support this, for C# and for other languages?

For example, is it reasonable to think about defining the core APIs (as registered in ClassDB) to work with very general purpose collection types (maybe even iterator like constructs for array inputs) and for languages to have the freedom to bind to those APIs using whatever wrapper is appropriate?

More about the motivation for that is here in my comment on the other thread.


To what extent would the plan be to try to retain backcompat with existing C# APIs, and to what extent can this be treated as a blank slate? Would it be reasonable to take a blank slate approach and ship both versions side by side for a while (perhaps billed as Stable and Experimental) so the user can choose one or the other on a per project basis, allowing the freedom to make breaking changes? (A cool feature of shipping a new version as Experimental is that breaking changes could continue in minor releases until it gets upgraded to Stable, giving more freedom to respond to feedback over a longer time period.)

@Zylann
Copy link

Zylann commented Sep 27, 2023

Classes from C++ extension should become available easy if the headers are generated for them

I mainly asked about the C# side having access to the C++ classes, I suspect C++ depending on C# is way less common in practice.

@dsnopek
Copy link

dsnopek commented Sep 27, 2023

@Zylann:

  • Extension classes work as if they were core classes. One of the main behavior differences is that they always run, i.e there is no extra concept of optional @tool or [Tool] (whatever this is in C#), the classes will be really instantiated and code will run in the editor when added to the scene, as a side-effect to be integrated in a more low-level manner. Will it be the way it will work, or will [Tool] be added to C# extensions? (which means ClassDB I guess)

This is something we should discuss in general, outside of the context of C#. Now that we have a solution for hot reload, the next thing down the list that people using GDExtension for gameplay code complain about is "everything runs like a tool script!?" :-) We need an answer to this for C++ and all the other languages as well

@rodrigofbm
Copy link

My opinion is that if you're using C# in the first place, you're only worrying about performance and maybe third party libraries.

This kind of comment is unnecessary. You're just giving assumption what others people cares about. Focus on the thread or speak for yourself.

@andy-noisyduck
Copy link

andy-noisyduck commented Sep 27, 2023

@reduz

Quick poll!

If you favor script workflow (slightly better usability, but more limited in performance and extensibility), give this comment a 🚀 If you favor class extension workflow (better performance, ability to override engine internals, simpler code to maintain): give this comment a ❤️

A poll given to a tiny subset of Godot's total C# userbase, framed with reasonably biased context from the engine lead? C'mon, this is not useful data. We can surely do better than this.

@c-schembri

My opinion is that if you're using C# in the first place, you're only worrying about performance and maybe third party libraries. I'd wager most C# developers care more about the former. On that point, whatever allows greater performance (or enables code which can facilitate greater performance), should be the option chosen.

Developer usability should be prioritised behind this. If we want nice usability, we can just use GDScript.

Let's not go making massive sweeping statements. There are many reasons people want to use C#. It indeed has better library support as you have mentioned. Tooling is more mature - be that the available editors, CI/CD environments, testing tools, build tools, 3rd party developer support etc.

Many developers choose C# because they have an existing pool of knowledge they use - whether that's their own existing knowledge a solo dev, or for studios where employees are more likely to have existing C# experience. They might want it as the path of least resistance to convert from Unity, something we've seen a lot of the last few weeks.

Outside of a few heavy algorithmic cases (proc gen etc), the engine should be doing all the heavy lifting and the performance of the scripting language is immaterial. The suggestion to make something less usable for everyone in order to benefit those cases seems off the mark.

@c-schembri
Copy link

@reduz

Quick poll!
If you favor script workflow (slightly better usability, but more limited in performance and extensibility), give this comment a 🚀 If you favor class extension workflow (better performance, ability to override engine internals, simpler code to maintain): give this comment a ❤️

A poll given to a tiny subset of Godot's total C# userbase, framed with reasonably biased context from the engine lead? C'mon, this is not useful data. We can surely do better than this.

@c-schembri

My opinion is that if you're using C# in the first place, you're only worrying about performance and maybe third party libraries. I'd wager most C# developers care more about the former. On that point, whatever allows greater performance (or enables code which can facilitate greater performance), should be the option chosen.
Developer usability should be prioritised behind this. If we want nice usability, we can just use GDScript.

Let's not go making massive sweeping statements. There are many reasons people want to use C#. It indeed has better library support as you have mentioned. Tooling is more mature - be that the available editors, CI/CD environments, testing tools, build tools, 3rd party developer support etc.

Many developers choose C# because they have an existing pool of knowledge they use - whether that's their own existing knowledge a solo dev, or for studios where employees are more likely to have existing C# experience. They might want it as the path of least resistance to convert from Unity, something we've seen a lot of the last few weeks.

Outside of a few heavy algorithmic cases (proc gen etc), the engine should be doing all the heavy lifting and the performance of the scripting language is immaterial. The suggestion to make something less usable for everyone in order to benefit those cases seems off the mark.

The performance of the scripting language is not immaterial. Such a statement does not even make sense.

@reduz
Copy link
Member Author

reduz commented Sep 27, 2023

@dsnopek

This is something we should discuss in general, outside of the context of C#. Now that we have a solution for hot reload, the next thing down the list that people using GDExtension for gameplay code complain about is "everything runs like a tool script!?" :-) We need an answer to this for C++ and all the other languages as well

In C# this is not so terrible because you can sort of expose the property metadata (type, hints, etc) with a tag, which you can parse from C# itself before instantiating the class, then when instantiating in the editor a placeholder class is supplied that lets you update the properties.

In GodotCPP this is kinda a bit harder, you have this information from _bind_methods, so /at least/ this has to be registered. The problem is that when we instantiate a tool class we have to also give a separate placeholder instance that edits those properties.

IMO most of this can be solved from the Godot side without that much issue, but will require scratching our heads a bit.

@jolexxa
Copy link

jolexxa commented Sep 27, 2023

I would be okay with moving to a GDExtension implementation if (and ONLY if):

  • it will be officially supported by Godot until the end of time with a sworn statement from Godot leadership (people have been concerned about Godot's stance on C#, I think there needs to be official reassurance once and for all).
  • there will be a higher degree of possibility for performance improvements
  • reloading assemblies will never break in the editor on mac/win/linux (a huge problem these days)
  • c# editor plugins will at least be as stable as GDScript ones (current conditions make them basically unusable)

I would still prefer a C# entry-point where Godot is used as a library over either approach, but I doubt that would be a popular choice since it would probably take a lot of effort. I also recognize that C# can't be the entry point on all platforms (i.e., consoles), so there would have to be a second type of integration, anyways.

@vikram3
Copy link

vikram3 commented Sep 27, 2023

I want to use GD script, can gdscript converted into c# code 😶‍🌫️

@mahdisml
Copy link

Does this idea or proposal make a difference in the output with Native AOT in dotnet 8?

@andy-noisyduck
Copy link

andy-noisyduck commented Sep 27, 2023

The performance of the scripting language is not immaterial. Such a statement does not even make sense.

Don't crop off the half the context and complain it makes no sense. It was specifically framed with "Outside of a few heavy algorithmic cases...".

The scripting language is not doing the heavy lifting in most cases - the engine is. Does it matter if your scripting language is x% quicker if the engine is doing an order of magnitude more work? For most people the answer should be no. It's the same reason there isn't a simple answer when people ask "will my Godot game be faster if I make it in C#?" - it depends. You're arguing to make the experience worse (for everyone) to benefit a small subset of use cases.

It's not even all algorithmic cases that benefit either. Its algorithmic operations that do reasonably heavy engine-interop. I'm sure that will benefit some developers. I remain unconvinced however that it will benefit most developers, and I remain less convinced by the argument that it's OK to trade developer usability in exchange for this gain.

@reduz
Copy link
Member Author

reduz commented Sep 27, 2023

@definitelyokay

I would be okay with moving to a GDExtension implementation if (and ONLY if):

Just to clarify, the current binder code and GDExtension are redundant and the same thing. The main advantage of this is that it costs much less to keep C# up to date for contributors.

I would still prefer a C# entry-point where Godot is used as a library over either approach

This was discussed, but ultimately rejected because Godot is not a C# focused engine. There is some ongoing discussions on allowing Godot to be compiled like a library, so it may be usable like this, but using it this way (say you get Godot itself on NuGet) would not be endorsed officially.

@reduz
Copy link
Member Author

reduz commented Sep 27, 2023

@andy-noisyduck I understand the point you are trying to make, but a large majority of users and contributors want a performance focused C# integration. Its a matter of preference that dictated the priority, from there we work on making the usability as good as possible.

@JoNax97
Copy link

JoNax97 commented Sep 27, 2023

I agree that the poll may be biased. Most people seeing this proposal are probably the ones that followed last weeks drama and are interested in performance, after all.

@nockawa
Copy link

nockawa commented Sep 27, 2023

To me this is not script versus class extension, both are good, they are targeting different usage.
But I wouldn't like .net/C# to be constrained as a Script ecosystem, yes it can do it, but it's a very small part of its capabilities.
Unity employed C# at first for scripting, then looked to use it for more.

Going only to the Script Workflow path would be such a waste IMHO. Both would be ideal, but only if the cost of developing/maintaining the script part were low.

With the class extension scenario, you can "develop" and not only do small scripts and I think that's what people want and need. C#/.net is a good compromise (at least compared to C++) to develop big projects with good performances.

Working with an IDE like Rider and having a hot reload in the Godot editor upon compilation/save in Rider is quite suffisant I think. And if it's not good enough, we should work to improve this, because replicating the user experience of a full-featured IDE like Rider in the Godot editor would be a huge (if not poinless) effort.

@theraot
Copy link

theraot commented Sep 27, 2023

In my opinion, the Extension class approach gives both a better workflow for the users and performance in runtime. Thus, that would be my preference. In fact, if C# classes get registered in ClassDB - unlike GDScript ones - I'd be inclined to do more C# code for Godot in the future (I've been doing GDScript only for over a year now).

I'm guessing having both would be too much trouble. In particular regarding whether or not one can switch a project from one to the other. If possible, perhaps some people would find it accesible to prototype with scripts, and then switch for extra performance. I wonder if that would be attractive for people not familiar GDScript (personally I would prototype with GDScript, and C# with extension class workflow seems like a good complement for it, also I remember the advice of migrating CPU intensive parts from GDScript to C# or C++ which makes sense for this and also supports the idea that we would expect performance from C#).

I'd rather not have C# using the script workflow only, in that case I would continue using GDScript, yet I understand that for some people GDScript is not an option (let us skip on why and if that makes sense), and I'm guessing this is more for them than for me.


About the listed cons, they do not seem too much trouble:

Can't easily replace in run-time, must delete a node and replace by a new one.

The editor will try to map property values when you change the type of a node from the context menu of the scene dock. Thus, I believe this is already mitigated.

Soft reloading will work, but may be troublesome in some unexpected corner cases due to this process being a bit more complex (need to add and remove from ClassDB).

It seems like the main benefit of using the script approach is some safety on this regard.

Yet, I'm confident crashes would be worked out in general.

Furthermore, if I'm not mistaken, there is already a solution for reloading, which might be improved or supplemented upon if necessary. And any work on this area might also benefit third party language projects, thus, even this is a challenge I think there is an starting point and it would be worth doing.


My main concerns would be on breaking compatibility, and how much of this work can actually be done in parallel. I was expecting this would be put off for a while.

@Ragath
Copy link

Ragath commented Oct 3, 2023

Lots of good discussion - I just have a quick question: If we use the class extension route, can the engine make use of dotnet watch with or without hot reload to speed up the C# workflow or make it more convenient? Not sure how feasible it is, just a thought.

If Godot is hosting the C# runtime, then dotnet run might not do the thing we want. But we actually have an additional proposal called "libgodot" which will allow the C# runtime to start first and then load Godot, and then register the GDExtension-based C# support that is discussed in this thread. In this setup, the app will look like a regular .NET app, and the hot reload should work as expected.

This would be absolutely vital in order to play nice with existing dotnet tooling and enable things like stripping native builds of unused parts. Having a dotnet executable should also make it much easier to stay up to date with the latest dotnet versions as they become available(potentially even being able to support new releases without any changes at all).

@Repiteo
Copy link

Repiteo commented Oct 6, 2023

Can we start muting/banning/whatever people that constantly derail discussion? This has been unfortunately common for this proposal in particular, and I'd prefer to not recieve notifications about ongoing flamewars

@godotengine godotengine locked as too heated and limited conversation to collaborators Oct 6, 2023
@godotengine godotengine deleted a comment from michieal Oct 6, 2023
@QbieShay
Copy link

QbieShay commented Oct 6, 2023

I'm temporarily locking this discussion to give the participants time to cool down.

@michieal Please keep your interactions constructive and avoid personal attacks. Your own bad experiences with users modding your game is not a valid argument to attack anyone that holds a different opinion than you.

@BenMcLean this issue is not the ground of ideological battle pro or against DRM. Please respect other's point of view.

@godotengine godotengine deleted a comment from JimmyCushnie Oct 6, 2023
@godotengine godotengine deleted a comment from michieal Oct 6, 2023
@godotengine godotengine deleted a comment from michieal Oct 6, 2023
@godotengine godotengine deleted a comment from GabrielRavier Oct 6, 2023
@godotengine godotengine deleted a comment from michieal Oct 6, 2023
@godotengine godotengine deleted a comment from GabrielRavier Oct 6, 2023
@godotengine godotengine deleted a comment from michieal Oct 6, 2023
@godotengine godotengine deleted a comment from GabrielRavier Oct 6, 2023
@godotengine godotengine deleted a comment from michieal Oct 6, 2023
@godotengine godotengine deleted a comment from BenMcLean Oct 6, 2023
@godotengine godotengine deleted a comment from michieal Oct 6, 2023
@godotengine godotengine deleted a comment from kisg Oct 6, 2023
@godotengine godotengine deleted a comment from ryanabx Oct 6, 2023
@godotengine godotengine deleted a comment from michieal Oct 6, 2023
@godotengine godotengine deleted a comment from BenMcLean Oct 6, 2023
@godotengine godotengine deleted a comment from michieal Oct 6, 2023
@godotengine godotengine deleted a comment from BenMcLean Oct 6, 2023
@godotengine godotengine deleted a comment from michieal Oct 6, 2023
@godotengine godotengine deleted a comment from michieal Oct 6, 2023
@akien-mga
Copy link
Member

akien-mga commented Oct 6, 2023

I deleted all the offtopic comments posted today. If someone wants to discuss modding restrictions and obfuscation, do that in a separate proposal, it's completely offtopic here. And it was pointed out as such, so doubling down and starting to call people names is a breach of our Code of Conduct: https://godotengine.org/code-of-conduct/

So I'm issuing a one-week ban to the user who started this and doubled down. Please be respectful of our discussions and the people involved if you come back afterwards.

I'm reopening the proposal for discussion on the topic. Please do not comment further on the offtopic discussion from today.

Edit: Geez, locked again, when folks start making sockpuppets to critize moderation, there isn't much room for healthy debate.

Additionally, since this proposal has a lot of engagement (80 participants according to GitHub), I ask everyone to keep interactions constructive and strictly on point. Moderation on this issue will be heavy handed. Please keep it civil and be mindful of the amount of people that will receive a notification for every new comment on the proposal.

@godotengine godotengine unlocked this conversation Oct 6, 2023
@godotengine godotengine locked as off-topic and limited conversation to collaborators Oct 7, 2023
@godotengine godotengine deleted a comment from LiamLocke Oct 7, 2023
@godotengine godotengine deleted a comment from LiamLocke Oct 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests