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

Add support for multiple .NET languages to have "built-in"-like support. F#, Visual Basic, Etc. #191

Open
willnationsdev opened this issue Oct 30, 2019 · 27 comments

Comments

@willnationsdev
Copy link
Contributor

willnationsdev commented Oct 30, 2019

Describe the project you are working on:
Plugins and a mobile app that uses .NET.

Describe the problem or limitation you are having in your project:
Using non-C# .NET languages in Godot is cumbersome since you have to create C# scripts anyway and then have C# classes inherit a third-party class's features. This is what the Godot F# Tools plugin I wrote assists with. However, I would prefer it if it were easier to add support for arbitrary .NET languages that build on the features in the current CSharpScript implementation.

For example, maybe have a MonoScript that acts as another layer on top of Script and then have more specific CSharpScript, and potentially FSharpScript or TypeScript, implementations in submodules. This would allow other languages to take advantage of some of the GDMonoObject work that has already been done. Even if support for other languages had to be downloaded via the AssetLibrary, I'd still think it could work very well. Though, I must admit, I know very little about the ramifications of dynamically loading in additional languages, but it sounds a lot like what the NativeScript submodule already kinda does.

Describe how this feature / enhancement will help you overcome this problem or limitation:

People who want to use their preferred .NET language to create Godot games would be able to do so much more easily, without having to hack support in through C#.

Show a mock up screenshots/video or a flow diagram explaining how your proposal will work:

I would propose re-organizing the codebase to make CSharpScript files be in a dedicated submodule folder within the mono folder (at mono/csharpscript) and instead replace them with a set of MonoScript-like files. Then provide avenues for plugging in other arbitrary MonoScripts, operating similarly to PluginScript for the GDNative C bindings.

Inheritance hierarchy would look something like this:

- Script
    - MonoScript
        - CSharpScript (built-in)
        - FSharpScript (via addon), can reference .fs files, interops with same MonoScript API.
        - Etc. (via addon), can reference .xx files, interops with same MonoScript API.

Describe implementation detail for your proposal (in code), if possible:

This would involve refactoring a lot of the C# Mono code to remove direct dependencies of C# code and syntax.

Projects would need to be generated and managed from the dotnet cli, more than likely, rather than manually creating the files in Godot's Mono-related C++ code. It would make it easier to operate with an arbitrary language.

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

Involves direct changes to the mono module. Unrelated to scriptable changes.

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

Involves direct changes to the mono module. Unrelated to scriptable changes.

@zetashift
Copy link

Does TypeScript support the .NET CLR as a target?
Anyhow I'm all for this as I have a profound love for F# and using it as a scripting language; related issue here: godotengine/godot#12337 where neikeq mentioned:

The plan is to rename CSharp* ScriptLanguage/Script/ScriptInstance implementations to Mono* and make them abstract classes. Language-specific implementations should derive from these (we would still only support C# officially).

However I'm not sure where the Godot team will find the time for refactoring as I think people really only care for C#.

@willnationsdev
Copy link
Contributor Author

@zetashift Enabling people to use Godot with their preferred language has been a growing concern ever since 3.0 where GDNative and C# were first introduced. Until then it had just been GDScript and C++ (I don't even think 2.1 had VisualScript, but I could be wrong - never used it). The point being that now there are roughly a dozen+ languages that one could choose to use for Godot and the trend has been to continue making it possible for people to use the languages they want. The MonoScript concept (and #119 honestly) would go a long way towards that, so I think there is incentive there. But the real shame is that neikeq is the one who is most familiar with the C# codebase. Like, I think he does around 90% of the CSharpScript-related PRs. There aren't many people that can contribute and/or help with the refactor, so it's basically a bandwidth problem.

@zetashift
Copy link

@willnationsdev I wholeheartedly agree, neikeq is doing awesome work but does also almost all the Mono work alone.
A MonoScript concept would be great, but I fear that a big refactor of the C# code or GDNative code will be postponed or delegated to the community, because the current solutions are ""just enough"" and other stuff might take priority.

So might this refactor be better for the 4.0 release?

@willnationsdev
Copy link
Contributor Author

Oh, for sure. There's no refactoring happening in 3.2 (already in feature freeze, just bug fixes). But I also kinda doubt it would even get done for 4.0. The priority right now is probably going to be getting exports working for mobile/web if possible. And only when there is no more work to be done on those fronts might things get refactored.

@willnationsdev

This comment has been minimized.

@Calinou
Copy link
Member

Calinou commented Nov 9, 2019

@ShalokShalom @willnationsdev Please keep the discussion on-topic about the proposal 🙂

@godotengine godotengine deleted a comment from ShalokShalom Nov 10, 2019
@godotengine godotengine deleted a comment from ShalokShalom Nov 10, 2019
@aaronfranke
Copy link
Member

F#, TypeScript, Etc.

Note that if we ever migrate to .NET 5+ (aka .NET Core), the list of supported languages is more limited. AFAIK currently only 5 are supported: C#, F#, VB, PS Core, and raw IL.

@willnationsdev willnationsdev changed the title Add support for multiple .NET languages to have "built-in"-like support. F#, TypeScript, Etc. Add support for multiple .NET languages to have "built-in"-like support. F#, Visual Basic, Etc. Jan 6, 2020
@panesofglass
Copy link

Would it be possible to also have MonoScript support static classes and static members? @neikeq noted this in godotengine/godot#12337, and I've noticed a lot of newer C# codebases and frameworks supporting this style.

@zetashift
Copy link

This proposal being open, does that mean it's accepted?

@Calinou
Copy link
Member

Calinou commented Jun 11, 2020

@zetashift No, as we don't really have a formal proposal acceptance process.

@Chaosus
Copy link
Member

Chaosus commented May 25, 2021

The only problem I see to implement this feature is the level of support for these languages - For C# I feel only @neikeq and @aaronfranke are busy with it on a regular basis.
Even if we add to support for these languages - who will fix bugs, adds new functionality, and update them to recent versions?
I think we need new contributors to solve this proposal.

@neikeq
Copy link

neikeq commented May 26, 2021

The idea, at least for me, is not to support them officially but to provide the APIs to allow third-parties to make them work with close if not the same functionality as C#. Depending how much functionality they want, this can go from as easy as specifying different file extensions to more complex tasks. From our end it requires just a little initial work to provide the extensibility.

@ShalokShalom
Copy link

ShalokShalom commented May 26, 2021

I highly welcome this initial step and contribute everything I can, in order to see 1A FSharp support.

So far as I can see, is also nothing in the way of in-editor support, other than the integration itself.

@Llamato
Copy link

Llamato commented Jan 14, 2022

I for one would really like to see vb.net in godot. Especially because for many people vb.net is still their frist language. By making Vb.net an option in Godot we would enable all those new developers to start game dev right away. What is more fun then that?

Additionally them starting out with Godot would mean that they will grow their Godot specific skills alongside their general programming skills. I see real potential to make godot more competitive with other engines by just allowing the userbase to expand. I am all for vb.net in godot. As of now I do not feel famillier enough with the engine to just try to develop the needed components myself but If others are interested in unoffical vb.net support, please let me know. I will be happy to help.

@TheWitheredStriker

This comment was marked as off-topic.

@Llamato
Copy link

Llamato commented Jan 14, 2022

For anyone interested in my progress, I spent the last 2 hours setting gdot with mono support up and testing vb support though a dll. That approch works just fine. So to that extend we got VB.Net compatibility already.

I am however not satisfied with that as it is in my opinion more of a workaround then a solution. I think to say that Godot is truely vb.net / CLI compatible we need to at least be able to attach CLI script directy to nodes. As I said I am unfamillier with the engine but I am currently trying to figure out how to integrate Vb.net without having to resort to a dll. if anyone here knows more about how godot handles C# then I will happly accept any help I can get.

@zetashift
Copy link

Does Godot 4.0 and the migration to dotnet 6 change anything concerning this proposal?

@KoB-Kirito
Copy link

KoB-Kirito commented Feb 21, 2023

+1 for VB.Net support, it's a very readable language and easy to learn

For anyone interested in my progress, I spent the last 2 hours setting gdot with mono support up and testing vb support though a dll. That approch works just fine. So to that extend we got VB.Net compatibility already.

Did you make any progress since then? Could you explain how to set it up in more detail?

@ShalokShalom
Copy link

The F# Discord has a thread about the ongoing effort to get this running

https://discord.com/channels/196693847965696000/1021127955579150427

@TheWitheredStriker
Copy link

Awesome to see that there's a concerted effort for F# as we speak. =)

I would like to vouch for VB.NET as well, thus I am in agreement with @KoB-Kirito. @Llamato Indeed, can you elaborate?

@lenscas
Copy link

lenscas commented Mar 28, 2023

Awesome to see that there's a concerted effort for F# as we speak. =)

I would like to vouch for VB.NET as well, thus I am in agreement with @KoB-Kirito. @Llamato Indeed, can you elaborate?

For F# we decided to make our own glue through Myriad. I think that every .NET language will have to basically make their own glue or get C#'s source generators working natively with said language.

Alternatively, the source generator approach gets replaced by some kind of code generation that works regardless of language, however while this would make things easier for other languages I am actually not convinced it would make things better.

As things stand, yes it means that every language will have to spend time creating their own glue generation but on the flip side it also means that every language is able to tailor this generation step as well as the glue that gets generated based on what fits their language the best. For example, for F# we are focusing on a module first approach rather than class based. Once that is done we will also experiment with special glue for Discriminated unions and Records, something that never worked with the old methods and probably would also never work if we kept piggybanking on Godots .NET glue.

Once that is done, and assuming everything goes somewhat to plan this should allow F# devs to write F# code that is much closer to what is idiomatic F# rather than C# with F# syntax like how it was in the 3.X days of Godot.

So, all in all I see the change to source generators as a step in the right direction for overall .NET support despite it making it harder for languages to piggybank on existing infrastructure.

One thing that annoys/worries me still is the hard need for .cs files (and a csproj file?). It would be lovely if there was a nice way for .NET language glue code to expand the file extensions list or similar so the hard dependency on .cs files and the csproj file stops being a thing.

However I don't have a good way to improve that.

@Pac-Dessert1436
Copy link

Pac-Dessert1436 commented Jun 29, 2024

It's such a long story when I have been trying to work on Visual Basic .NET in Godot 3.5. Take my previous game project Avoid the Monsters as an example, the following async method just won't run on my Android phone, even though I've already equipped the project with "Microsoft.VisualBasic.Core.dll"!

Public Async Sub ShowGameOver()
    ShowMessage("End of Game")
    Dim messageTimer = GetNode(Of Timer)("MessageTimer")
    Await ToSignal(messageTimer, "timeout")
    Dim message = GetNode(Of Label)("Message")
    message.Text = "Avoid the
Monsters!"
    message.Show()
    Await Tosignal(GetTree().CreateTimer(1), "timeout")
    GetNode(Of Button)("StartButton").Show()
End Sub

For this reason, I would have to make the above subroutine a MustOverride Sub, and then re-implement the subroutine in the corresponding C# script:

using Godot;
using VBLibrary.AvoidTheMonsters;

public class HUD : HeadUpDisplayVB
{
    public override async void ShowGameOver()
    {
        ShowMessage("End of Game");
        var messageTimer = GetNode<Timer>("MessageTimer");
        await ToSignal(messageTimer, "timeout");
        var message = GetNode<Label>("Message");
        message.Text = "Avoid the\nMonsters!";
        message.Show();
        await ToSignal(GetTree().CreateTimer(1), "timeout");
        GetNode<Button>("StartButton").Show();
    }
}

It's not until last night that I could download the source code of Godot 3.5, but I've only learned a little C++ for the time being, so there's no doubt that I have difficulty modifying the C++ code in order to directly integrate "Microsoft.VisualBasic.Core.dll" into the entire engine. I could basically understand that the C++ code for the C# support aims at extracting C# keywords, calling the methods from C# , and so forth, but integrating this runtime library into Godot 3.5 is totally out of the question for my part, owing to my limited capability.
So the current $64000 question is: Will anyone find an efficient way to integrate Visual Basic .NET into Godot 3.5 for mobile game development?

@KoB-Kirito
Copy link

Or in 4.3? It's so much better than 3.5 nowadays..

@Pac-Dessert1436
Copy link

Pac-Dessert1436 commented Jun 29, 2024

Or in 4.3? It's so much better than 3.5 nowadays..

Yes. I can't agree more with you when it comes to adding VB support to Godot 4.3, but speaking of mobile game development in Godot Engine, some of my opinions are slightly different from yours. Mobile exports using C# in Godot 4.2 are considered experimental nowadays, since the language version for scripting is C# 10.
Godot 3.5 uses C# 7.3 for scripting, so it looks more stable for Android platform exports, but I'm not 100% sure whether it's really as stable as it seems...

@Pac-Dessert1436
Copy link

Pac-Dessert1436 commented Sep 3, 2024

Hello everyone. I've noticed that Godot 4.3 is available for the moment, and that I don't have to manually include the "Microsoft.VisualBasic.Core.dll" library on Godot 4.2 before exporting the VB.NET project to my Android phone. Therefore I can't wait to share with you what I have recently been working on, and I sincerely hope VB.NET bindings for Godot would come true, together with F# bindings.

I have aleady realized that there ought to be a Return ... statement as a modern way to return function values in VB.NET, but I insist that the "stone-age approach" should be made use of, just to make this part of code a little consise.

One more thing, I'm good at writing F# scripts as well, since I can easily define variables by means of let mutable statements, and simple F# functions like let squaredSum (a: float) (b: float) = pown a 2 + pown b 2.

Option Strict On
Imports Godot
Imports Godot.Collections

Public Module WorkingOnJsonFiles
    Public Function LoadJsonData(Of T)(jsonPath As String) As Dictionary(Of String, T)
        LoadJsonData = New Dictionary(Of String, T)
        ' The resulting dictionary is automatically returned after loading the JSON data.
        ' When the conversion is failed, an empty dictionary is returned instead.
        Using jsonFileObj = FileAccess.Open(jsonPath, FileAccess.ModeFlags.Read)
            If jsonFileObj IsNot Nothing Then
                Dim parseObj As [Variant] = Json.ParseString(jsonFileObj.GetAsText())
                Try
                    For Each entry In CType(parseObj, Dictionary(Of String, T))
                        LoadJsonData.Add(entry.Key, entry.Value)
                    Next entry
                Catch
                End Try
            End If
        End Using
    End Function

    Public Sub UpdateJsonData(Of T)(jsonPath As String, jsonData As Dictionary(Of String, T))
        Using jsonFileObj = FileAccess.Open(jsonPath, FileAccess.ModeFlags.Write)
            jsonFileObj?.StoreString(Json.Stringify(jsonData, vbTab))
        End Using
    End Sub
End Module

@willnationsdev
Copy link
Contributor Author

willnationsdev commented Sep 11, 2024

Since there's been questions/comments on this, I will mention (to the best of my very limited knowledge):
(Note: I stopped pursuing this myself since I eventually became disillusioned with F# and grew to prefer C#)

In Godot 3 (I assume this is still the case), Godot proactively scanned the .cs files from the C# project and loaded them using Mono. The relationship was one of Godot determining for itself what information from the Mono runtime is relevant (which put the burden of implementation for class querying more heavily on Godot).

In Godot 4, it uses the more recent, cross-platform .NET runtime(s) instead (dotnet) and instead delegates the information-gathering task to the CLR in order to know which defined classes, if any, extend Godot types. The relationship is one of Godot querying the CLR while dotnet informs Godot of what is relevant (the burden of implementation for class querying is mostly shifted to dotnet).

Thus, in theory, Godot 4 should already be able to have you define F# or VB classes recognizable to Godot Engine so long as they extend the established Godot classes and the classes are publicly visible from the assemblies in the same way (as in, the F#/VB assemblies are project references for the main C# project). If true, this ticket is largely resolved as you no longer need a C# class extending the custom class.

Beyond that, the only 2 things that could be done would be...

  1. Adding the ability for the "main" .NET project to be something other than a .csproj file.
    • Difficult? idk. Worth the maintenance effort? Probably not.
  2. Adding the ability for Godot binding features to work on classes defined by other languages. This would refer to anything that the C# source generators are used to supplement the code in order to make things work with Godot. You'd have to implement these same features in the other languages in order to "support" them fully.
    • This seems largely impractical to me since it would be a HUGE maintenance burden on the Godot team. I also do not know to what degree it would even be possible (maybe with F# type providers supplementing whatever the C# source generators provide; idk if VB has something similar).

@Pac-Dessert1436
Copy link

Pac-Dessert1436 commented Sep 12, 2024

Since there's been questions/comments on this, I will mention (to the best of my very limited knowledge): (Note: I stopped pursuing this myself since I eventually became disillusioned with F# and grew to prefer C#)

In Godot 3 (I assume this is still the case), Godot proactively scanned the .cs files from the C# project and loaded them using Mono. The relationship was one of Godot determining for itself what information from the Mono runtime is relevant (which put the burden of implementation for class querying more heavily on Godot).

In Godot 4, it uses the more recent, cross-platform .NET runtime(s) instead (dotnet) and instead delegates the information-gathering task to the CLR in order to know which defined classes, if any, extend Godot types. The relationship is one of Godot querying the CLR while dotnet informs Godot of what is relevant (the burden of implementation for class querying is mostly shifted to dotnet).

Thus, in theory, Godot 4 should already be able to have you define F# or VB classes recognizable to Godot Engine so long as they extend the established Godot classes and the classes are publicly visible from the assemblies in the same way (as in, the F#/VB assemblies are project references for the main C# project). If true, this ticket is largely resolved as you no longer need a C# class extending the custom class.

Beyond that, the only 2 things that could be done would be...

  1. Adding the ability for the "main" .NET project to be something other than a .csproj file.

    • Difficult? idk. Worth the maintenance effort? Probably not.
  2. Adding the ability for Godot binding features to work on classes defined by other languages. This would refer to anything that the C# source generators are used to supplement the code in order to make things work with Godot. You'd have to implement these same features in the other languages in order to "support" them fully.

    • This seems largely impractical to me since it would be a HUGE maintenance burden on the Godot team. I also do not know to what degree it would even be possible (maybe with F# type providers supplementing whatever the C# source generators provide; idk if VB has something similar).

Thank you so much for providing such detailed information for me. Turning your thoughts to C# isn't a big deal, since C# programming is out of the box in Godot 4, which I'm also good at. Meanwhile I can understand that there will be a tremendous amount of work for the Godot contributors when it comes to adding F# and VB.NET bindings, not to mention the fact that I'm not that capable of writing GDExtensions for these bindings (since I've only learned a little C++ for the time being). For my part, however, the most critical part is that the VB.NET source files should be recognized by Godot script resource, and that these source files can be easily attached to the Godot nodes like C# scripts.

Just now I tried writing "HelloWorld.vb" as follows, based on the VB.NET library that I've created for testing purposes (simply named TestLib). Nevertheless, after adding the project reference TestLib.vbproj into the corresponding .csproj file in a Godot 4 project of mine, the source file "HelloWorld.vb" ::doesn't:: show up in the Godot script resource, even though the C# project has been updated and equipped with the VB.NET project.

Imports Godot

Public Class HelloWorld
    Inherits Node2D

    Public Overrides Sub _Ready()
        GD.PrintRich("[rainbow]Hello world![/rainbow]")
    End Sub
End Class

Therefore, speaking of using VB.NET in Godot 4, I guess the second option for me is to write a large VB.NET module that contains useful variables, functions, algorithms etc. (which are almost everything needed for the specific game I'm making), compile the VB.NET module into a DLL, and then import the module by means of using static syntax when writing C# scripts for the game. As far as I'm concerned, nothing is better than such an "import-export" strategy without available VB.NET bindings, and using F# in Godot 4 might end up with the same approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests