Skip to content

Conversation

@raulsntos
Copy link
Member

Use Mono embedding APIs statically linked to load the Mono WASM runtime.

  • The Mono runtime is fetched using the GetRuntimePack C# project. It needs the wasm-tools workload.
  • The GetRuntimePack defines stub functions for all the function pointers we need to retrieve from C#, so the PInvokeTableGenerator includes them in the generated pinvoke-table.h file.
  • Globalization doesn't work, so for now we're always enabling invariant mode.
  • The Mono runtime uses stubs for their exported JavaScript functions, these need to be replaced with the real implementation in their dotnet.runtime.js module but we don't have an easy way to do that yet, which means some BCL APIs will not work (i.e.: crypto APIs)
  • Closes Readd support for web platform exports when using the C# (.NET) version of the engine #70796

Warning

This is still a work in progress, but it should be possible to export a C# game to web with some manual changes to the exported .js afterwards.


This PR was tested with the demo project: Web .NET prototype

Note

The demo project requires multi-threading, so make sure to change the <WasmEnableThreads> property to true to use the right Mono runtime.

Use Mono embedding APIs statically linked to load the Mono WASM runtime.
@Aisht669

This comment was marked as off-topic.

@WithinAmnesia
Copy link

WithinAmnesia commented May 8, 2025

@raulsntos Will this and other Godot C# full features run smoother in the long run as Godot 5.x? As in developing if Godot 4.x gets prototype C# features (such as web support) running and then in Godot 5.x it is optimized with the 'would be nice' features like size and security optimizations? I say this after reading your and the creative community's comments on the C# suite features and the prototype type work and potential for better solutions ( #70796 (comment) ).

I wonder this in order to better plan big projects (like a working vertical slice C# MIT Smooth Voxel MMORPG template for Godot) be it Godot 4.x and or Godot 5.x due to API and other complex team coordination which requires a stable software platform / game engine to first under take. If a Godot 5.x alpha with C# full features is being built soon (Godot 4.x may already be past its mid-life cycle once 4.5 is stable) it might be better for the 'power users' / big movers / proper game studios of the creative community to 'Wait for Godot' than to force teams of people to re-engine from Godot 4.x to Godot 5.x. Software long term stability is very critical for long term planning.

A lot of senior game studios are re-engining now and it is by default UE5 but personally I'd like it to be Godot also. A lot of studios are re-engining from the Unity implosion and I want Godot to succeed where Unity failed. Yet long term stability is very critical for the old grumblers of the industry.

Thus starting on a prototype Godot 5.x alpha with full C# features and optimizations and long term stability (and other details that require stability like Godot C# API issues being fully addressed) after ~Godot 4.5 stable is probably a practical way forward for the Godot creative community to keep both near future growth of Godot game engine progressing well and also keep Godot 4.x stable. Godot should get ready for the next gaming generation come 2027 / the late 2020's. Official Godot 5.x alpha plans for a feature roadmap can do a lot to also powerfully grow and future proof the Godot game engine creative community for today's and tomorrow's game building adventures.

It seems like Godot 4.x will get unified C# support as a GDextension and full C# parity support; yet this might be as prototype form. Once the Godot 4.x full C# features are operational this whole suite of C# features might require optimizations that are only properly done with seeing everything on the table first in working form and then in a big strong unified effort lead a proper engine rewrite to properly integrate the features to be optimized for being the best they can be. As from what can be currently done as the creative community for this console generation and the next console / gaming generation planned for 2027 / late 2020's with the PS6 / new Xbox / next gen consoles and gaming hardware.

The work of https://github.com/raulsntos and friends is very helpful to the creative community and I wish to thank the people involved greatly. This kind of work helps the creative community to make great games for everyone.

@enxas
Copy link
Contributor

enxas commented May 12, 2025

When using Firefox with the privacy.resistFingerprinting value in about:config set to true, the demo project at https://lab.godotengine.org/godot-dotnet-web/ loads briefly before displaying a black screen with console errors. It loads fine when privacy.resistFingerprinting is set to false.

@MadBunnyGames
Copy link

Can confirm, with this solution it is possible to make a project with godot4 + .net, and run it on itch.io.
Proof of ... proof of concept? :
https://mad-bunny-games.itch.io/godot-45-net-web-test

@timothyleerussell

This comment was marked as off-topic.

@icavalheiro

This comment was marked as off-topic.

@thehugwizard

This comment was marked as off-topic.

@ahopness
Copy link

any updates on this? any chances this pr gets included in 4.5?

@Calinou
Copy link
Member

Calinou commented Aug 19, 2025

any updates on this? any chances this pr gets included in 4.5?

4.5 is in feature freeze, so any new features can only be merged in 4.6 at the earliest.

@thehugwizard
Copy link

Can confirm, with this solution it is possible to make a project with godot4 + .net, and run it on itch.io. Proof of ... proof of concept? : https://mad-bunny-games.itch.io/godot-45-net-web-test

Hey @MadBunnyGames - is there any chance you would be willing to share how you got the .net build working?

I would be happy to hack together whatever I needed, but it seems like there is minimal action on this recently so would be great if I could get something working for prototyping

@Gnumaru
Copy link
Contributor

Gnumaru commented Sep 12, 2025

I suspect that this PR will be turned down in favor of #110441 ( which superseded #90510 and will turn #106125 unnecessary in the future). As soon as we become able to compile and run godot as a shared library, It will be preferable to compile godot as a wasm sidemodule that will be loaded and initialized by standard .net instead of mono, or am I misunderstanding something?

@zorbathut
Copy link
Contributor

zorbathut commented Sep 12, 2025

Worth noting that #110441 does not yet support running C# programs from C# because there's some fiddly changes that need to happen to prevent the two uses of the same environment from stomping on each other, but assuming 110441 is accepted, I'll be putting up a PR for those shortly afterwards; I've been using that on my own framework for months now, so this is at least somewhat battletested.

I haven't yet tried to use this to support web export .NET but I don't know of any expected roadblocks.

@thehugwizard
Copy link

@Gnumaru @zorbathut would that substantially change how we have to export web builds for dotnet compared to the current process?

For current web exports there's simply an export template required to build the web version - will devs now need to compile the godot engine from source to use as a shared library, or will all that be hidden away from users?

For example with your framework @zorbathut it requires setting up a whole toolchain for building from source. I'm happy to do it if necessary for the moment, but it's not an ideal experience compared to the current process of just downloading the editor and a template, and then running the web export from inside the editor...

@zorbathut
Copy link
Contributor

zorbathut commented Sep 13, 2025

My personal framework requires a compilation framework because I'm a tinkerer and make custom changes to the engine all the time :) I can think of no reason a properly-upstreamed libgodot-based .NET-web-export platform would require that though, it'd be the same user experience as it is today for all the other platforms.

A big part of the reason I'm trying to get libgodot upstreamed is so people can take advantage of its features without having to mess around with custom vendoring frameworks like mine.

@sdepouw
Copy link

sdepouw commented Sep 16, 2025

Very excited to hear about the progress on this! Wishing you all the best of luck in getting this out the door. Once this is in place I can build Godot stuff in C#!

@thehugwizard
Copy link

My personal framework requires a compilation framework because I'm a tinkerer and make custom changes to the engine all the time :) I can think of no reason a properly-upstreamed libgodot-based .NET-web-export platform would require that though, it'd be the same user experience as it is today for all the other platforms.

A big part of the reason I'm trying to get libgodot upstreamed is so people can take advantage of its features without having to mess around with custom vendoring frameworks like mine.

@zorbathut Ah I understand, yeah it would be great to get it integrated. Getting a web build for C# is the only thing that's giving me a headache at the minute, as otherwise I've found working with Godot such a nice experience to use...

@MadBunnyGames
Copy link

MadBunnyGames commented Sep 21, 2025

Hey @MadBunnyGames - is there any chance you would be willing to share how you got the .net build working?

Basically pulled the changes from here into a 4.4.1 (or some nightly 4.5 dev, not sure), edited the .csproj file to match .net version and threading support, built the editor and the templates (as Godot documentation says... note: I use windows and had to switch to WSL when building the web template, because emscc command was too long for PowerShell), also set up a local nuget store for godot package during build (its in godot docs too), matched my project file, referenced the newly built nugets, needed to add entrypoint to the project (main function), then built and exported the project with the new templates, manually removed the DOTNET.setup(...) call from the .js that was generated for the c# project, then just uploaded to itch as is.
Had some road bumps along the way, but I don't really remember them, because it was 2+ months ago.

@xr0gu3
Copy link

xr0gu3 commented Sep 28, 2025

If you want to try out the solution made by @raulsntos and reproduced by @MadBunnyGames and you aware how to use Docker you could try my "one liner" to achieve the web build. Nothing is guaranteed, it's all experimental and may break.
I’ve created a Docker image to streamline the HTML5 export process for Godot .NET projects using Godot 4.5. You can run it with the following command in your project folder:
docker container run --rm -v ".:/src" kstgrd/godot-mono-web:4.5.dev
This will generate a build directory with the exported project and an index.zip file ready for upload to itch.io. As a proof of concept, I’ve successfully built and uploaded a prototype here: https://kstgrd.itch.io/godot45net?secret=lc3VjeGNpn4PXlzJZRattN79s

P.S. ~4gb will be downloaded by docker to get the image
Update:

  • demo project source: here
  • your .csproj should use <TargetFramework>net9.0</TargetFramework> as image was built relying on that version of .NET
  • don't forget to create an empty Program.cs file in your project root with an empty public static void Main() function in it
public class Program
{
    public static void Main(string[] args)
    {
        
    }
}

@captain-otter
Copy link

captain-otter commented Oct 4, 2025

image

@xr0gu3 Did you run into this issue and if so how did you solve it?

@xr0gu3
Copy link

xr0gu3 commented Oct 4, 2025

@captain-otter on itch.io open the "Edit project" page and enable "SharedArrayBuffer support".
image

@Zearain
Copy link

Zearain commented Oct 6, 2025

@xr0gu3 did you need to do something special with the project to get your prototype to build using your docker image?
I keep getting the following error when running the docker image, even on a brand-new project with just a cube and a camera:

System.InvalidOperationException: Failed to build project.
at GodotTools.Export.ExportPlugin._ExportBeginImpl(String[] features, Boolean isDebug, String path, Int64 flags) in /workspace/godot/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs:line 288
at GodotTools.Export.ExportPlugin._ExportBegin(String[] features, Boolean isDebug, String path, UInt32 flags) in /workspace/godot/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs:line 162

@thehugwizard
Copy link

thehugwizard commented Oct 6, 2025

@xr0gu3 I get the same error as @Zearain.

I'm on windows, I created a very simple project with one Sprite2d, and a single script on it to tween the scale. That is the entirety of the project.

When I run the docker command provided I get the following error in my output

        dotnet_publish_project: step 0: Running dotnet publish
dotnet_publish_project: end
ERROR: Export .NET Project: Failed to build project.
   at: add_message (./editor/export/editor_export_platform.h:249)

   C# backtrace (most recent call first):
       [0] void Godot.EditorNativeCalls.godot_icall_3_470(nint, nint, int, string, string) (/workspace/godot/modules/mono/glue/GodotSharp/GodotSharpEditor/Generated/EditorNativeCalls.cs:134)
       [1] void Godot.EditorExportPlatform.AddMessage(Godot.EditorExportPlatform+ExportMessageType, string, string) (/workspace/godot/modules/mono/glue/GodotSharp/GodotSharpEditor/Generated/GodotObjects/EditorExportPlatform.cs:295)
       [2] void GodotTools.Export.ExportPlugin.AddExceptionMessage(Godot.EditorExportPlatform, System.Exception) (/workspace/godot/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs:113)
       [3] void GodotTools.Export.ExportPlugin._ExportBegin(System.String[], bool, string, uint) (/workspace/godot/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs:162)
       [4] bool Godot.EditorExportPlugin.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&) (/workspace/godot/modules/mono/glue/GodotSharp/GodotSharpEditor/Generated/GodotObjects/EditorExportPlugin.cs:617)
       [5] bool GodotTools.Export.ExportPlugin.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name&, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant&) (/workspace/godot/modules/mono/editor/GodotTools/GodotTools/obj/Release/Godot.SourceGenerators/Godot.SourceGenerators.ScriptMethodsGenerator/GodotTools.Export.ExportPlugin_ScriptMethods.generated.cs:140)
       [6] Godot.NativeInterop.godot_bool Godot.Bridge.CSharpInstanceBridge.Call(nint, Godot.NativeInterop.godot_string_name*, Godot.NativeInterop.godot_variant**, int, Godot.NativeInterop.godot_variant_call_error*, Godot.NativeInterop.godot_variant*) (/workspace/godot/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs:24)
System.InvalidOperationException: Failed to build project.
   at GodotTools.Export.ExportPlugin._ExportBeginImpl(String[] features, Boolean isDebug, String path, Int64 flags) in /workspace/godot/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs:line 288
   at GodotTools.Export.ExportPlugin._ExportBegin(String[] features, Boolean isDebug, String path, UInt32 flags) in /workspace/godot/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs:line 162

@xr0gu3
Copy link

xr0gu3 commented Oct 7, 2025

@Zearain @thehugwizard I believe you both forgot to include a class with an empty main function into your project.

@Zearain here, I've built the project in your repo https://kstgrd.itch.io/managetherer?secret=J8cSHNlpuZqmjeo6jMbyGfBifjw

Just add a new class like this into your source folder:

public class Program
{
    public static void Main(string[] args)
    {
        
    }
}

@thehugwizard
Copy link

Thanks @xr0gu3 - I have a dummy project here https://github.com/thehugwizard/Dummy and I created a Program.cs file with an empty main function like you said, but I still get the same error...

Do I need a specific src folder? Or do I need to add that file inside the docker image somewhere? Or am I just doing something silly?

@xr0gu3
Copy link

xr0gu3 commented Oct 7, 2025

@thehugwizard the docker image has been built with net9.0, so use <TargetFramework>net9.0</TargetFramework> in your .csproj file

@thehugwizard
Copy link

thehugwizard commented Oct 7, 2025

@xr0gu3 Ah thank you - I managed to get it building with that change

I immediately get a bunch of errors in the console when it starts up however, so I'm probably running into some of the limitations of it still being incomplete...

image

@xr0gu3
Copy link

xr0gu3 commented Oct 8, 2025

@thehugwizard please take a look on my demo sources. I used Tweens too and they are working.

@RetroSpecter
Copy link

@thehugwizard @xr0gu3 I've been doing some testing with the exported web builds on some old game jam projects. I also get a similar tween error if I call TweenProperty(this, ...). It's been pretty easy to work around though.

@thehugwizard
Copy link

@RetroSpecter

@thehugwizard @xr0gu3 I've been doing some testing with the exported web builds on some old game jam projects. I also get a similar tween error if I call TweenProperty(this, ...). It's been pretty easy to work around though.

Thanks @RetroSpecter - that did get my test project running!

However I have a real project I've been working and I still get a pile of errors in the console. I've edited all the uses of TweenProperty(this, ...) to remove them, but I these seem like they're related to animation/audio:

image

@thehugwizard
Copy link

thehugwizard commented Oct 9, 2025

@xr0gu3 - it does work for a new project I'm starting on, so it seems like it should be perfect for creating game jam stuff!

I'll just remember to test the web builds regularly in case I run into any more edge cases, and that should help me narrow down any funny behaviour I run into.

Really appreciate you getting something like this working, makes such a difference being able to put a web version up!

@renanrcp
Copy link

Hey folks! I saw a few people running into the same hurdles I had when building the Web export templates, so I wrapped the whole process in a Docker Image: https://github.com/renanrcp/godot-web-dotnet-building. (Thanks to @xr0gu3 for the original base-image idea.)

I also tried compiling the templates from the 4.5-stable branch with this PR applied: https://github.com/renanrcp/godot/tree/feat/add-mono-web. The build loads and the C# scripts execute, but nothing is rendered on-screen (blank canvas). Let me know if anyone had better luck or spots what I might be missing!

@thehugwizard
Copy link

thehugwizard commented Oct 22, 2025

FYI for anyone else using this:

I have discovered another bug/issue with this docker workaround. I think GD.RandF() (and possibly other Rand functions) are broken on dotnet web exports. For me it didn't even throw an error, the logic would just stop when it hit that point. (I discovered this by using a long list of GD.Print()s, but pinned it down to the GD.RandF() calls.)

My workaround was to create my own static RNG class and replaced all uses of GD.RandF with that.

using System;

public static class RNG
{
	private static readonly Random _random = new Random();

	public static float Randf()
	{
		return (float)_random.NextDouble();
	}

	public static float RandRange(float min, float max)
	{
		return min + (float)_random.NextDouble() * (max - min);
	}

	public static int RandRangeInt(int min, int max)
	{
		return _random.Next(min, max);
	}

	public static int Randi(int max)
	{
		return _random.Next(max);
	}
}

@AR-DEV-1
Copy link
Contributor

cc @raulsntos

@BenMcLean
Copy link

I hope the plan is just to allow building with docker, not to require hosting with docker. Godot web exports should work on static web sites regardless of server technology.

@thehugwizard
Copy link

@BenMcLean - I believe the current docker usage is just a workaround for creating dotnet builds until it get resolved in the main branch. It won't (or shouldn't anway) be required in any capacity after the work is finished

@renanrcp
Copy link

Yep, I've using docker only for build, always when I try without it I have some erros related to emsdk.

@YuriArthas
Copy link

I’m currently planning to package my project as a Web build to showcase progress to collaborators. Compared to distributing Windows executables or Android packages, the Web is by far the most convenient way to share and test progress.

I’d like to ask: will the ability to export C# (.NET) projects to the Web platform be officially released in Godot 4.6?
If the probability is high, I’m happy to wait for the official release. Otherwise, I may try to manually merge PR #106125
and build the engine myself.

However, that approach comes with a drawback — a self-compiled Godot editor may not be easily distributable to the rest of my development team, which could complicate collaboration.

Could you please share any insights on how likely this feature is to land in 4.6, or if there’s an estimated timeline for it?

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Readd support for web platform exports when using the C# (.NET) version of the engine