aws-samples / amazon-gamelift-unity

A multi-player game sample (server and client), developed with the Unity game engine, illustrating basic integration with Amazon GameLift. View the sample source code or build the project and experiment with game server deployment on the Amazon GameLift service.
Apache License 2.0
82 stars 22 forks source link

GameLift Server SDK Error in Built Unity 2019.4.4f1 Player With Managed Stripping Turned On #11

Closed qhdwight closed 4 years ago

qhdwight commented 4 years ago

Hi,

I'm not sure if this is the right place, but I'll give it a shot.

I cloned this repository and ran build.bat. Then, I copied the DLLs generated over to my project in Unity 2019.4.4f1. I have a MonoBehavior in my scene with the following:

private void Start()
{
    GenericOutcome outcome = GameLiftServerAPI.InitSDK();
    if (!outcome.Success)
    {
        Debug.LogError($"Failed to initialize server SDK {outcome.Error}");
        return;
    }
    var logParameters = new LogParameters(new List<string> {Application.consoleLogPath});
    var processParameters = new ProcessParameters(OnStartGameSession, OnProcessTerminate, OnHealthCheck,
                                                  m_ServerPort, logParameters);
    GameLiftServerAPI.ProcessReady(processParameters);
    Debug.Log("GameLift server process ready");
}

Now, this works in the editor. It connects to my local game lift server (the .jar provided in the SDK download from the main Amazon GameLift page).

However, as soon as I build the project for Windows Stadalone x64 (with Mono backend), I receive an error from log4net, which I know is one of the dependencies after calling the InitSDK() function:

ArgumentOutOfRangeException: Parameter: defaultRepositoryType, Value: [log4net.Repository.Hierarchy.Hierarchy] out of range. Argument must implement the ILoggerRepository interface
Parameter name: defaultRepositoryType
Actual value was log4net.Repository.Hierarchy.Hierarchy.

The error happens twice and the Start() function exits so nothing is set up properly. Based on the fact it works in the editor, I think that it probably has to do with a .NET DLL not being copied over into the build properly. See: https://stackoverflow.com/questions/58099681/unitypython-working-on-editor-but-not-on-build for an example of this happening with another plugin.

Even if I modify the Game Server SDK project and remove all logging calls, I get another error:

DescriptorValidationException: com.amazon.whitewater.auxproxy.pbuffer.BackfillMatchmakingRequest.players: Property Players not found in Com.Amazon.Whitewater.Auxproxy.Pbuffer.BackfillMatchmakingRequest.

So something in the final built setup is definitely malformed or missing.

Thanks!

alanmur commented 4 years ago

Started repro

alanmur commented 4 years ago

Build successful on Unity 2019.4.4.f1. Server output looks like:

2020-07-20_18-26-17

All these plugins made it into the server output...

2020-07-20_18-32-32

Deploy successful, Fleet active.

alanmur commented 4 years ago

Test class builds (server only)

2020-07-20_19-13-39

alanmur commented 4 years ago

Building using GameLift Server SDK 4.0.0 (the default since my last commit on 2020-07-16Z18:39). Continuing tomorrow.

qhdwight commented 4 years ago

Thank you for the quick response and testing! It must be something specific to my project. I just tested what you did with a blank project and I had no issues.

I will do some more testing, trying to slowly add components that my project has to the blank one until I get the error again.

qhdwight commented 4 years ago

Found the issue! I set Project Settings -> Player -> Other Settings -> Managed Stripping Level to 'Disabled' instead of 'Low'.

One note is that IL2CPP requires 'Low' or higher so this effectively makes the SDK only work for Mono.

Currently how I see it is that reflection is used by some parts of the SDK. But, Unity only analyzes static usage when running the linker so it glosses over some implicitly used DLLs and does not copy them over.

Looking at the Unity documentation at: https://docs.unity3d.com/Manual/ManagedCodeStripping.html it may be possible for me to add some custom markers (Preserve) to try and fix this. That is what I will try next as ideally I would have my build in IL2CPP due to the performance it allows in my game.

I'm sorry about not trying a blank project first and sending you down that rabbit hole. Oops

qhdwight commented 4 years ago

Success, I have gotten my build to work in IL2CPP and with stripping levels of 'Low' and 'Medium'. I added a link.xml file to my project as per the documentation above and added:

<linker>
    <assembly fullname="System.Reflection" preserve="all"/>
    <assembly fullname="System.Collections.Immutable" preserve="all"/>
    <assembly fullname="System.Memory" preserve="all"/>
    <assembly fullname="System.Buffers" preserve="all"/>
    <assembly fullname="System.Runtime.CompilerServices.Unsafe" preserve="all"/>
    <assembly fullname="log4net" preserve="all"/>
    <assembly fullname="GameLiftServerSDKNet45" preserve="all"/>
    <assembly fullname="Google.Protobuf" preserve="all"/>
    <assembly fullname="Newtonsoft.Json" preserve="all"/>
    <assembly fullname="websocket-sharp" preserve="all"/>
</linker>

Now, this is quite liberal and not all entries are needed. I experimented with removing some (like System.Memory, System.Buffers, and a few others) and my build still worked ( I also noticed, they aren't used in the project?). However, I haven't determined a set of efficient rules that can include the very least possible since I'm not very familiar with the codebase of the SDK.

Side note: I used Unity 2020.1.0b16 to test all this but I presumes it works in the 2019 LTS.

alanmur commented 4 years ago

Very nice. Understand issue resolved by the customer. Appreciate the feedback on usage of IL2CPP with the SDK. Thank you and please allow me to assist further if you need.

Al :)