-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
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
Readd support for web platform exports when using the C# (.NET) version of the engine #70796
Comments
There are no C# export templates for HTML5 yet due to missing upstream support in .NET 6 (.NET 7 didn't address this). That said, there are significant issues with the HTML5 export in 4.0, such as #68647 and #70691. I would recommend using 3.x if targeting HTML5 for now, regardless of whether you're using C# or not. |
What is the missing upstream support from .NET we're waiting on to get HTML5 support? Can we link that item here and then in whatever documentation gets created? Not having HTML5 support for Godot 4 is preventing me from using Godot 4 when participating in game jams as I prefer uploading web builds. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Since several people now independently wrote this same bug report, and the situation is as it is with Godot 4 stable, maybe it might make sense to mention Web export for Godot 4/Mono as "unsupported for now" somewhere central in the Godot mono docs. |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
I propose we make a Tracker ticket to collect things: why C# Support is missing, what can be done about it (split in: what can we do about it. What can dotnet devs do about it) and what can be done to make it verbose to the user. I also recently stumbled upon it just missing and I also consider it an important feature. I saw here, on other tickets and on the release notes of 4.0 that there was supposedly a communication between core godot-devs about it, but there isn't really a transparent Ticket for us. |
What upstream support is missing, exactly? Is it something that we could expect in, say, the next year? |
We can't give an ETA as we don't know when contributors will be available to do the required work on both the .NET and Godot side. I wouldn't expect it to be ready for this year though, especially if you want to use a stable version and not a pre-release. If you need to use C# to target the Web platform right now, stick to Godot 3.x. |
Is there a group of participants I could connect to? I'd like to help working on that. |
@Sythelux Try Godot contributors chat at https://chat.godotengine.org/channel/navigation |
it is thanks to XNA 4. |
Curious to get Godot lead weigh-in on the latest comment on the .NET-related thread (see here: dotnet/runtime#75257 (comment))
@akien-mga I remember that Godot-as-a-library was kind of a no-go option when we all discussed this on a call — is that still the case? |
@jolexxa Both ways are You may launch a Godot instance through project Suppose we are really planning to leverage the project |
While I'm not an engine contributor, I'd argue having an inadequate yet functional web export implementation would be better than having none at all for 1-3 more years. |
Couldn't agree more with @FlooferLand — added something to the bounty that was started above (now at $650). |
Adds initial support for exporting C# Godot projects to WebAssembly: - Implements WebAssembly runtime integration - Adds export template system - Creates build tooling for WASM compilation - Adds test project for verification Fixes godotengine#70796
I remember hearing talks about transforming .NET Godot into a GDExtension-style support, where .NET code is compiled and turned into GDExtension libraries that can be loaded and used in-engine and referenced via GDScript. Something to point out is that I noticed that the Godot-Rust project has added experimental web support last year: godot-rust/gdext#493. I've personally written a small game project with it, exported it to web, and it works fine. Wondering if this is a possible avenue worth investigating or if this is already what's being tried with LibGodot support? Also, I added $50 to the ongoing bounty, as of writing this the entire bounty stands at $970 |
The underlying technique connecting the .Net and the Godot Engine is the same, so what we can't do in GodotSharp (the mono module) also applies to the new GDExtension-based binding. |
Hello folks, we wanted to update you on the current state of C# web exports. We know there's a lot of people interested in exporting their C# games to the web platform, and we'd love to add support as soon as possible. Unfortunately, there are a number of challenges that have to be solved first and we haven't been able to find a good way to do it. We've been exploring multiple ways of getting C# web export support, each of them have their own strengths and weaknesses, I'll try to explain what we've tried and why it didn't work. dotnet.jsThis is the most straight-forward way to get run C# on the web platform today. You can just publish a C# project using the import { dotnet, exit } from './_framework/dotnet.js';
try {
const { getAssemblyExports, getConfig } = await dotnet.create();
const config = getConfig();
const exports = await getAssemblyExports(config.mainAssemblyName);
exports.Greeter.SayHello();
} catch (err) {
exit(2, err);
} It's very simple, and since we let Why this didn't workEvery WASM is executed isolated on its own reserved memory, so loading the Godot WASM and the C# WASM separately means they can't communicate with each other. The only way for WASMs to interact with each other is to link them, and that requires all the WASM libraries to be compiled with compatible flags. In this case, the WASM file built by .NET and the Godot WASM are built with incompatible flags. But what if we built the .NET WASM ourselves with the right flags? See the NativeAOT-LLVM section below. NativeAOT-LLVMThere is a promising runtime experiment in the dotnet/runtimelab repo that adds support for building a WASM using NativeAOT. Godot already supports loading C# using NativeAOT, so the changes required to make this work should be minimal. The reason why this is a very promising option is that, since NativeAOT means you are using native compilers, you get a chance to set custom flags to use in that native compilation. This would allow us to ensure the WASM built for the C# project matches the flags used to build the Godot WASM, and thus make it compatible. Why this didn't workUnfortunately, adding the
The It's possible that this could be fixed by compiling the entire .NET runtime instead, but I don't think it'd be a good approach. I've discussed with Microsoft employees, and I've been told that they tried to compile the .NET runtime as a side module a long time ago unsuccessfully, they haven't tried since so it's likely not going to work. Statically linking MonoSince dynamically linking WASMs won't work, we could try statically linking Mono instead. This is the worse approach we tried by far, we ended up duplicating a lot of the setup in the .NET runtime to compile the WASM, it'd be a lot of work to maintain this and keep it in sync with upstream, not to mention supporting multiple .NET versions, since we don't know what TFM the user project targets at the time of building the Godot templates. Why this didn't workGodot's C# bindings rely on function pointers to communicate with the engine. However, when we set this up we were unable to get Mono to retrieve function pointers. It seems, Mono has a mechanism to build a table of function pointers at compile time so it can retrieve them later, but we were unable to get this to work. We also tried MonoAOT, but since GodotSharp doesn't support trimming, it seems this assembly is too big and won't compile. This approach would be very brittle and hard to maintain, but I was willing to give it a try so we could at least get some experimental support to at least unblock the users that have been patiently waiting. Unfortunately, it didn't pan out. ConclusionWe are sorry to say that web support is still not available for C# projects. We know this is disappointing to hear, but we are constantly looking at new ideas and would love to get this working as soon as we can. |
Can we compile the Godot WASM with flags that match the dotnet WASM? I apologize for my lack of knowledge of WASM technology, which might make this question sound silly. |
That's a great question. It has come up before and I'm sorry for not being more clear about it in my previous post. As I understand it, to link 2 WASM libraries dynamically we need one of them to be compiled with the Compiling the dotnet WASM with one of those flags is mentioned in the NativeAOT-LLVM section of my previous comment. |
Thanks for the clarification. So, to overly simplify the concept, does that mean the dotnet Wasm itself cannot be linked to or linked to any other Wasm module? I'm also curious about how Avalonia achieved its web export, considering that they use SkiaSharp, the Managed wrapper for a native library, for rendering. Or are they? |
@raulsntos, is there a repository available where we can reproduce this scenario? |
Side modules is for dynamic linking, they may be statically linking dependencies. But that also has some requirements, the WASM you're linking needs to be relocatable.
No, just build a Godot project with NativeAOT-LLVM. See instructions in their documentation. Here's an example <Project Sdk="Godot.NET.Sdk/4.4.0-dev">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
</PropertyGroup>
<PropertyGroup>
<PublishTrimmed>true</PublishTrimmed>
<SelfContained>true</SelfContained>
<MSBuildEnableWorkloadResolver>false</MSBuildEnableWorkloadResolver>
</PropertyGroup>
<ItemGroup Label="NativeAOT-LLVM browser-wasm packages">
<PackageReference Include="Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-*" />
<PackageReference Include="runtime.$(NETCoreSdkPortableRuntimeIdentifier).Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-*" />
</ItemGroup>
<ItemGroup>
<TrimmerRootAssembly Include="GodotSharp" />
<TrimmerRootAssembly Include="$(TargetName)" />
</ItemGroup>
<ItemGroup Label="NativeAOT-LLVM browser-wasm linker args">
<LinkerArg Include="-sSIDE_MODULE=2" />
</ItemGroup>
</Project> Then use this command to build:
|
I guess this implies that the Godot Wasm can't be relocatable and hence cannot be statically linked to the Dotnet user Wasm? |
@raulsntos I'm curious if it's valid solution (or why not) to leverage Godot as a library just for C# web exports and have a C# managed entry point. I imagine that'd need a bit of effort on the export side of things in Godot, but then at least the effort would be constrained to Godot itself and not dependent on .NET (which is clearly moving at its own pace). Unrelated, but the bounty is now at ~$1,600 😄 |
If the Godot and .NET can't be linked together, why not try running .NET code using a WASM interperter like WASM-3 |
@raulsntos I'd be interested in discussing what godot need on the .NET side to unblock this scenario so that we at least understand what the work is involved here. It sounds like you're blocked on dotnet/runtime#75257, correct? Is there anything else? |
Hello @danroth27 👋, thanks for reaching out. Yes, dotnet/runtime#75257 seems to be the main blocker. We intend to load the .NET WASM dynamically from the main Godot WASM. To give more context, the main Godot WASM is pre-built and distributed to users so they don't have to build the engine themselves. We also tried the experimental NativeAOT-LLVM which allows us to specify additional emscripten flags with As I understand it, Microsoft had a lot of problems with emscripten's dynamic linking in the past, so I assume it's unsupported but I'm not aware of the specific issues you ran into. We also tried linking Mono statically and in this case we run into issues with retrieving function pointers. It seems .NET is supposed to build a table of function pointers out of methods annotated with There's more details about what we've tried in my previous comment: #70796 (comment) |
@lewing Any ideas on what might be happening here? |
Sure, here are the details of what I've done: I'm building the main Godot WASM including the sources from Microsoft.NETCore.App.Runtime.Mono.multithread.browser-wasm/9.0.0 (I've also used 8.0.0 in the past and I had the same results). Then, on C++ I use For our initialization, we take the function pointer of some C# methods and pass them to the C++ side so we can invoke them from the native engine side. The problem is that these function pointers all seem to be using System;
public static class InitializationClass
{
[UnmanagedCallersOnly]
private static int Sum(int left, int right)
{
return left + right;
}
public unsafe static void Init()
{
delegate* unmanaged<int, int, int> sumPtr = ∑
Console.WriteLine($"sumPtr = {(nint)sumPtr}"); // Prints 'sumPtr = 0'
}
} No errors or exceptions, but since the value is Here's the command we use to publish the .NET project: dotnet publish UserProject.csproj -c ExportDebug -r browser-wasm --self-contained true -p:GodotTargetPlatform=web -o /tmp/godot-publish-dotnet/192660-ExportDebug-browser-wasm Note that, since we have custom configurations, we also set the property |
Unity Chinese version engine(团结引擎) converts Dll into WebCIL and interprets it through mono runtime. Can Godot use this method to run? https://docs.unity.cn/cn/tuanjiemanual/Manual/WeixinMiniGameDotNetSupport.html |
unity(团结)Engine mentioned some implementation details. The il2cpp solution for generating WebAssembly will package the user code and the engine code together, and also deal with the generation of generic template code, which makes the Wasm file very large. Therefore, the il2cpp solution was abandoned and the Microsoft Blazor solution was adopted to separate the user C# code and Wasm runtime to interpret and execute C# code. The DotNet Wasm solution is based on .NET8, relies on the Emscripten tool chain to build WebAssembly, and uses the trimmed and optimized mono as the .Net runtime. |
Godot version
v4.0.beta10.mono.official [d0398f6]
System information
macOS Monterey 12.5.1 (21G83)
Issue description
In a fresh project created with v4.0beta10 and export templates downloaded and installed, the web export templates files are missing at the expected path. This makes it impossible to create web builds afaik.
Steps to reproduce
Minimal reproduction project
N/A
The text was updated successfully, but these errors were encountered: