nativeAOT/CoreRT output?

As several commercial monogames (Carrion and SoR4) have already used AOT, I thought I would try AOT compiling following this tutorial:

I successfully compiled the blank project for both non-AOT and AOT (which outputs the blue screen), however, I ran into problems with the NeonShooter/Platformer2D samples.

The language of the tutorial isn’t very clear where it says you need to “transplant links to sample sources and assets”, I interpreted this to mean to overwrite the references to the Content/Game in ‘.csproj’ and ‘Program.cs’, respectively. This compiled with no errors, and the non-AOT version of the game worked (screenshot 1), however, the AOT version crashed (screenshot 2). I tried debugging the AOT version, and the error seems to originate from loading the Content (screenshot 3).

Can someone ( @harry-cpp ) offer some advice on how to do AOT properly? AOT support is a pretty big deal, especially the imminent wasm output, which is expected to bring monogame to a far larger audience than ever before. Thus, incorporating a workable AOT guide into the official documentation would seem like it would help many developers.

PS: I am on VS2019 16.9.0 preview 2.0, Windows 10 and Monogame 3.8.

1 Like

I managed to make this work. Here are my steps and a github of a minimal working example for the NeonShooter sample.

STEPS:
1. Add the Nuget package ‘Microsoft.DotNet.ILCompiler’ into your VS2019 preview project
2. Create and reference the rd.xml file
3. run x64 Native Tools Command Prompt for VS 2019 via: dotnet publish -r win-x64 -c release

TROUBLESHOOTING:
1. NU1101 Unable to find package nuget error.
The official tutorial advocated adding the nuget source into the project file, but for some reason that did not work for me. Instead I added the experimental Nuget source for VS (Tools > Nuget Package Manager > Package Manager Settings) with settings:

dotnet-experimental
https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json

2. Some of the Nuget Packages don’t work. The one I used was 6.0.0-preview.3.21153.3 which did.

3. You get the error “fatal error LNK1112: module machine type ‘x86’ conflicts with target machine type ‘x64’”.
You run dotnet publish in the Developer Powershell / Command prompt, which are x86. You must start up an external x64 Native Tools Command Prompt.

4. You get "EXEC : error : Failed to load assembly ‘Microsoft.Xna.Framework.Content.ContentTypeReader’"
Delete this from the csproj file:

  <ItemGroup>
    <TrimmerRootAssembly Include="Microsoft.Xna.Framework.Content.ContentTypeReader" Visible="false" />
  </ItemGroup>

5. Compiles but will produce runtime crash on
"Font = content.Load<SpriteFont>("Font");"
You forgot to add the rd.xml file to your project with the appropriate contents:

<Directives>
    <Application>
        <Assembly Name="MonoGame.Framework">
            <Type Name="Microsoft.Xna.Framework.Content.ListReader`1[[System.Char,mscorlib]]" Dynamic="Required All" />
        </Assembly>
        <Assembly Name="mscorlib" />
    </Application>
</Directives>

6. Runtime crash referencing the Content.
You tried to launch the compiled .exe under the subfolder \native. The one that will work is under \publish.

7. Here is a minimal example for the Neonshooter sample game that should just compile.

3 Likes

Have you tested how much faster is the AOT version compared to the default version?

I’m assuming it’s obviously faster, but wondering how much.

For GPU bound games like the Neonshooter, I don’t think there would be any benefit.
For CPU bound games, think strategy games with 000s of units, or generating worlds via Perlin noise etc, there I would expect to be some improvement depending on how you do it. However, I haven’t fully tested AOT for performance yet. I may post some more results if/when I have the time. In anycase, I am pleased to say that as far as compatibility goes, pretty much everything works so far, including multiplayer, threading and Myra UI.

2 Likes

For number 5, I also had to add the following to my .csproj

  <ItemGroup>
    <RdXmlFile Include="rd.xml" />
  </ItemGroup>