colyseus-unity-sdk icon indicating copy to clipboard operation
colyseus-unity-sdk copied to clipboard

Schema-derived types will have their default constructors stripped by Unity's Managed code stripping setting medium or above

Open tonygiang opened this issue 4 years ago • 12 comments

Unity has a feature called managed code stripping to reduce the size of a build. During this process, if the setting is set to Medium or High, all types derived from Colyseus.Schema.Schema will have their default constructors stripped because Unity's linker determine that they are unreachable code, which leads to MissingMethodException during runtime handshaking.

Schema-derived types include all types generated by schema-codegen and also the built-in types used by Colyseus Unity client such as Colyseus.Schema.ReflectionField, Colyseus.Schema.ReflectionType and Colyseus.Schema.Reflection.

While adding the UnityEngine.Scripting.Preserve attribute to each Schema-derived types will preserve their default constructors, it will lead to a "Local schema mismatch from server" exception on High managed code stripping setting, which technically is a different issue from this, but until there is an official fix, the safe option for users of Colyseus Unity client for now is to build with managed code stripping setting set to Low or disabled.

tonygiang avatar Dec 29 '20 02:12 tonygiang

thanks for the heads up!

devPryze avatar Dec 29 '20 11:12 devPryze

Thanks for the heads up @tonygiang!

(I'm just documenting here my findings for future reference, as this issue is not super high priority)

I've tried to configure Managed Code Stripping right now and couldn't make it work for both "Medium" and "High", even if using [UnityEngine.Scripting.Preserve] on every Schema-related structure (both on core classes, and classes generated via schema-codegen)

Screen Shot 2021-05-28 at 19 54 43

Maybe using a link.xml file could be easier to configure.

Possible solutions could be:

  • Using [Preserve] on relevant structures, both in the library and on generated schema code
  • Provide a guide in the documentation on how to configure a link.xml file that works
  • (?)

Cheers!

endel avatar May 28 '21 23:05 endel

I just encountered this issue out of nowhere but with code stripping set to Low. Now it seems like the only safe choice is no code stripping.

Edit: nope, disabling code stripping doesn't work either. Something else is causing the issue and I can't tell what.

I'm starting to think you need to reconsider the reflection approach to schema checking.

tonygiang avatar Jun 08 '21 04:06 tonygiang

Apparently IronSource SDK could cause problem with Schema types' constructors being stripped as well. I don't know how but it does.

tonygiang avatar Jun 08 '21 06:06 tonygiang

Hi @endel, There is no problem with the development. After I build a project for WebGL, when I join the room, I receive this error.

 MissingMethodException: Default constructor not found for type Colyseus.Schema.ReflectionType
  at System.RuntimeType.CreateInstanceMono (System.Boolean nonPublic) [0x00000] in <00000000000000000000000000000000>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <00000000000000000000000000000000>:0 

burhanyilmaz avatar Jun 21 '21 11:06 burhanyilmaz

Hi @burhanyilmaz, which level of Code Stripping are you using? Low, Medium, or High? EDIT: Also if you can provide the version of Unity that can be helpful!

endel avatar Jun 21 '21 13:06 endel

@endel Thanks for the response! unity version is 2020.3.12f1 strip engine code ✅ manage stripping level : Low

burhanyilmaz avatar Jun 21 '21 13:06 burhanyilmaz

I tried these. But I am not sure that these are correct or not :/

MyState.cs

// 
// THIS FILE HAS BEEN GENERATED AUTOMATICALLY
// DO NOT CHANGE IT MANUALLY UNLESS YOU KNOW WHAT YOU'RE DOING
// 
// GENERATED USING @colyseus/schema 1.0.25
// 
using UnityEngine.Scripting;
using Colyseus.Schema;

[Preserve]
public partial class MyState : Schema
{
    [Preserve]
    [Type(0, "string")]
    public string currentTurn = "";
}

link.xml

<linker>
  <assembly fullname="Colyseus">
    <type fullname="Colyseus.Schema.ReflectionType" preserve="all"/>
  </assembly>
</linker>

Thanks!

burhanyilmaz avatar Jun 21 '21 13:06 burhanyilmaz

When the target platform is macOS, there is no problem. I connected to the room and received messages. it is related to WebGL build.

burhanyilmaz avatar Jun 21 '21 14:06 burhanyilmaz

@endel @tonygiang I fixed this issue https://github.com/colyseus/colyseus-unity3d/pull/163

burhanyilmaz avatar Jun 22 '21 06:06 burhanyilmaz

Not so fast. This issue affects all C# types generated by schema-codegen. It will be fixed when schema-codegen is fixed.

tonygiang avatar Jun 22 '21 09:06 tonygiang

Relevant to this discussion, a Discord user has reported this comment: (building for Android)

i can't compile il2cpp because unity only has low striping for il2cpp and not disable.. but it works on Mono backend which has the disable function stripping

endel avatar Sep 21 '22 18:09 endel