Skip to content

Conversation

Getup98
Copy link

@Getup98 Getup98 commented Jan 19, 2025

Closes #56

Removing code when "AOT_ENABLED" is set is no longer necessary with .net9.0, thanks to Intrinsic APIs marked RequiresDynamicCode now including MethodInfo.MakeGenericMethod.

I annotated the entire library (and tests) with the required attributes and provided overloads that don't require dynamically accessed code to the few methods that still require it (mostly due to json serialization).

Also made Backdash.Analyzers compatible with visual studio on the way, for convenience.

Tests succeed both with and without PublishAoT, the Godot sample also exports and plays with PublishAoT with a single minimal change: the export setting "Embed Build Outputs" makes it crash on startup.

@Getup98
Copy link
Author

Getup98 commented Jan 19, 2025

I forgot i had to do it, but to make the Godot sample work with PublishAoT another necessary change is to the json serialization used to communicate with the lobby server, have it use JsonTypeInfos (or JsonSerializerContext source generation) instead of reflection.

@lucasteles
Copy link
Collaborator

Hi, thanks for the contribution,

I will get some time to review these changes

@Getup98
Copy link
Author

Getup98 commented Feb 11, 2025

My pleasure!
I'll have more to come hopefully, do you mind if I also open some issues?

@lucasteles
Copy link
Collaborator

I'll have more to come hopefully, do you mind if I also open some issues?

I don’t mind; you are welcome to open issues and/or discussions.


Regarding this pull request:

  • I recently made a large update, and now we have some conflicts.
  • I would like to maintain support for .NET 8 for now. Could you please wrap the new features with #if NET9_0_OR_GREATER; ...; #endif?

@Getup98
Copy link
Author

Getup98 commented Feb 19, 2025

Sure, I won't have time to work on it this week but I think I'll manage for the next one.

@lucasteles lucasteles force-pushed the master branch 4 times, most recently from 7cac1c1 to a4f5aa8 Compare February 24, 2025 15:10
@Getup98
Copy link
Author

Getup98 commented Mar 9, 2025

I solved the conflicts and kept .net8.0 support, although I had to make a few compromises to do it:

  • Some user-facing methods (such as those in the RollbackNetcode static class) have "conditional warnings", but there is no way to do conditional warnings, therefore I just wrote messages along the line of "make sure the serializer is not null, then suppress the warning".
  • Some tests cannot run in AoT at all (those made with AutoFakeIt), others have no way to do it when <.net9.0.
    I found no way to rewrite them to work with AoT without losing their meaning, therefore I just set them to be skipped in such cases.

@Getup98
Copy link
Author

Getup98 commented Mar 10, 2025

Saw the build failing and realized I forgot to downgrade the sdk version in the global.json file, should build fine now.

@@ -15,7 +16,7 @@

namespace Backdash.Backends;

sealed class RemoteBackend<TInput> : INetcodeSession<TInput>, IProtocolNetworkEventHandler
sealed class RemoteBackend<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] TInput> : INetcodeSession<TInput>, IProtocolNetworkEventHandler
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why Interfaces? usually, the input type is a raw unmanaged structure.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In BinarySerializerFactory.Get there is a call to typeof(TInput).GetInterfaces(), which requires the annotation, and it bubbles up from there.
The call is there to check whether the type can be serialized by an IntegerBinarySerializer.

I agree it makes little sense for the whole backend's input to be something serializable as an integer and it's for sure an edge case, but removing the edge case would lead to restricting functionality, which I'm not comfortable doing as my first PR to a repo.
Especially when you consider that the SpaceWar demo uses an enum as TInput, which is close enough to an integer for me to consider that edge case not so "edge" after all.

In theory when TInput is a raw unmanaged struct without any interfaces that annotation does nothing but clutter the source code a bit, no performance or trimmed size impact. (I say in theory because I have not personally tested it to be true, just relying on documentation)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I look at the latest changes, it seems like you removed BinarySerializerFactory.Get, I'll update the branch and see if these annotations are at all necessary anymore.

@Getup98
Copy link
Author

Getup98 commented Mar 18, 2025

Updated to the latest version, the NetcodeSessionBuilder change is great!
It made the library way less "conditionally compatible", you'll see the scope of the changes is way smaller now.

The only place annotations were needed was JsonStateStringParser.
Still needs to skip some tests when in "AoT mode" due to AutoIt not working, but otherwise tests are compatible with no changes.

There's more corollary fixes than anything else in this PR now, I can split it into multiple if you think it'd be cleaner.

@lucasteles
Copy link
Collaborator

Hi, I will come back to these changes when .NET 10 releases

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

Successfully merging this pull request may close these issues.

AOT Support
2 participants