godotengine / godotengine/godot

Godot 4.5-mono Fails To Probe Shared Framework Assemblies On .NET 10

Open
#112,701 7 comments 1 reaction 0 assignees View on GitHub
needs testing topic:dotnet
Dominant language
C++
Stars
117k
Forks
26.8k
PR merge metrics
PR metrics pending

Description

### Tested versions

tested in v4.5.stable.mono.official [876b29033]

### System information

Godot v4.5.stable.mono - Windows 11 (build 26200) - Multi-window, 3 monitors - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3090 (NVIDIA; 32.0.15.8129) - AMD Ryzen 9 7900 12-Core Processor (24 threads) - 127.0 GiB memory

### Issue description

with .NET10 release this issue is still present. the issue seems to be godot doesn't know where to load the proper dll's. here is my vibe-explained bug report, and attached is a functional workaround: `SharedFrameworkAssemblyLoader.cs`. just call `SharedFrameworkAssemblyLoader.InjectGodotAssemblyResolverFix();` from a `[ModuleInitializer]`

====== Vibed summary in the `` below:

# Godot 4.5-mono Fails To Probe Shared Framework Assemblies On .NET 10

## Summary
On Windows 10 x64, launching a Godot 4.5-mono project that targets `net10.0` triggers `FileNotFoundException` for assemblies that reside in the .NET shared framework (for example `Microsoft.Extensions.Hosting.dll`). Godot’s managed host appears to ignore the default .NET probing rules for shared-framework assets when `net10.0` is selected, so the runtime never looks inside `DOTNET_ROOT\shared\Microsoft.*`. Adding a resolver to `AssemblyLoadContext.Default` that manually scans both the game output directory and the shared framework directories resolves the issue without any MSBuild file-copy hacks.

## Environment
- **Godot Engine:** 4.5 (mono build)
- **Godot.NET SDK:** 4.5.0
- **.NET SDK:** 10.0.100
- **Target Framework:** `net10.0`
- **Operating System:** Windows 10 x64
- **Hardware:** Desktop PC
- **Project Type:** Godot C# project with Microsoft.Extensions.* dependencies

## Symptoms
Launching the game (editor play or exported build) fails immediately with errors similar to:

```
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Extensions.Hosting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
```

Expected behaviour: Godot should resolve assemblies the same way the standard .NET host does—probe the application output directory, then fall back to the shared framework roots declared in the runtime config.

## Workaround
Hook `AssemblyLoadContext.Default.Resolving` and delegate to a loader that probes both the output directory and the official .NET shared locations. Our workflow is:

1. Attach a resolver during module initialization.
2. Attempt to load `/.dll`.
3. If missing, probe a cached list of shared framework directories (`DOTNET_ROOT\shared`, `%ProgramFiles%\dotnet\shared`, `%ProgramFiles(x86)%\dotnet\shared`).
4. Cache positive/negative hits to avoid repeated filesystem scans and load via `AssemblyLoadContext.Default.LoadFromAssemblyPath` when found.

The following helper is sufficient (simplified excerpt from our project):

```csharp
AssemblyLoadContext.Default.Resolving += (_, assemblyName) =>
{
var simpleName = assemblyName.Name;
if (string.IsNullOrEmpty(simpleName))
{
return null;
}

var fileName = simpleName + ".dll";

if (SharedFrameworkAssemblyLoader.TryLoadAssembly(Path.Combine(AppContext.BaseDirectory, fileName), out var localHit))
{
return localHit;
}

return SharedFrameworkAssemblyLoader.TryLoadFromSharedFrameworks(simpleName, fileName);
};
```

The loader caches results and probes the directories under:
- `DOTNET_ROOT\shared` (if defined)
- `%ProgramFiles%\dotnet\shared`
- `%ProgramFiles(x86)%\dotnet\shared`

No other project changes are required; the `.csproj` remains stock Godot.NET.Sdk.

## Impact
Every Windows 10 x64 Godot 4.5-mono project targeting `net10.0` that relies on Microsoft.Extensions or other shared-framework assemblies fails to start without this workaround. This blocks practical use of .NET 10 with Godot unless developers implement a custom resolver.

## Suggested Fix
Update Godot’s mono host to include the standard .NET probing logic (or equivalent) when spinning up the managed runtime for `net10.0` applications so shared framework assemblies resolve automatically.

### Steps to reproduce

I tried loading Microsoft.Extensions.DependencyInjection, got similar error as:

```
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Extensions.Hosting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.
```

## repro

- see https://github.com/godotengine/godot/issues/112701#issuecomment-3534829347

======================
## WORKAROUND

`SharedFrameworkAssemblyLoader.cs` (attached, below).

just call `SharedFrameworkAssemblyLoader.InjectGodotAssemblyResolverFix();` from a `[ModuleInitializer]`

[SharedFrameworkAssemblyLoader.cs.txt](https://github.com/user-attachments/files/23513585/SharedFrameworkAssemblyLoader.cs.txt)

### Minimal reproduction project (MRP)

see workaround above

Contributor guide

Open the contributing guide

Research direction

Start with the attached SharedFrameworkAssemblyLoader.cs and the minimal reproduction linked in the issue comment. Trace how Godot’s managed host initializes assembly loading for net10.0 on Windows, then compare that behavior with the reported shared-framework probing failure. Done means the reproduction loads Microsoft.Extensions assemblies without the custom resolver workaround.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, godot
Domain
devtools, game-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.