https://metaplay.io logo
Assembly architectural problems.
# questions-and-feedback
j
Hi, right now we had in our SharedCode assembly some enums and classes that were used by our gameplay too, but that means the gameplay assembly needs to reference the sharedcode/metaplay assemblies, which it makes no sense from an architecture perspective and also makes recompiling times much longer. So we though about doing a new assembly, that contains this classes and enums, and both shared code assembly and gameplay assembly reference this assembly. The issue with this is we don't have access to the required Metaplay attributes. What patterns do you recommend here? Only Idea I had is have the same 2 Enums duplicated in both assemblies and cast them, but that doesn't sound like a good approach...
j
Hey, we've been looking into this exact case and some steps have been taken already to make this easier. Currently on the Server solution there's Metaplay.Attributes project that has been separated to an independent assembly. The intention is exactly that some assemblies could only depend on the Metaplay.Attributes, without needing all of Metaplay. This is not yet exposed on Unity Client. The main complication here is that we have prebuilt CodeAnalyzers depending on
Metaplay.Attributes.dll
, and the assembly name here conflicts with
Metaplay.Attributes
name. I just got this quick idea that perhaps we could work around this and get you unblocked by putting the Attributes folder under some other assembly name, let's say
Metaplay.Core.Attributes
. So here's some untested potential fixes 🙂
Add `MetaplaySDK/Client/Attributes/Metaplay.Core.Attributes.asmdef`:
Copy code
{
  "name": "Metaplay.Core.Attributes",
  "references": [],
  "includePlatforms": [],
  "excludePlatforms": [],
  "allowUnsafeCode": true,
  "overrideReferences": false,
  "precompiledReferences": [],
  "autoReferenced": true,
  "defineConstraints": [],
  "versionDefines": [
    {
      "name": "Unity",
      "expression": "",
      "define": "METAPLAY_CLIENT"
    }
  ],
  "noEngineReferences": true,
  "rootNamespace": "Metaplay"
}
Apply the following diffs
Copy code
--- a/MetaplaySDK/Client/Metaplay.Core.Tests/Metaplay.Core.Tests.asmdef
+++ b/MetaplaySDK/Client/Metaplay.Core.Tests/Metaplay.Core.Tests.asmdef
@@ -5,6 +5,7 @@
         "UnityEngine.TestRunner",
         "UnityEditor.TestRunner",
         "Metaplay",
+        "Metaplay.Core.Attributes",
         "Metaplay.Unity",
         "Metaplay.Unity.Editor"
     ],
--- a/MetaplaySDK/Client/Metaplay.asmdef
+++ b/MetaplaySDK/Client/Metaplay.asmdef
@@ -3,6 +3,7 @@
     "references": [
         "Metaplay.ThirdParty.BouncyCastle",
         "Metaplay.ThirdParty.kcp2k",
+        "Metaplay.Core.Attributes",
         "Unity.Collections",
         "Unity.Mathematics",
         "Unity.Burst"
--- a/MetaplaySDK/Client/Unity/Editor/Metaplay.Unity.Editor.asmdef
+++ b/MetaplaySDK/Client/Unity/Editor/Metaplay.Unity.Editor.asmdef
@@ -3,6 +3,7 @@
     "rootNamespace": "",
     "references": [
         "Metaplay",
+        "Metaplay.Core.Attributes",
         "Metaplay.Unity"
     ],
     "includePlatforms": [
--- a/MetaplaySDK/Client/Unity/Metaplay.Unity.asmdef
+++ b/MetaplaySDK/Client/Unity/Metaplay.Unity.asmdef
@@ -3,6 +3,7 @@
     "rootNamespace": "",
     "references": [
         "Metaplay",
+        "Metaplay.Core.Attributes",
         "UnityEngine.Purchasing",
         "UnityEngine.Purchasing.Stores",
         "com.rlabrecque.steamworks.net",
And then in your Shared Code and the other assembly:
Copy code
--- a/Assets/SharedCode/SharedCode.asmdef
+++ b/Assets/SharedCode/SharedCode.asmdef
@@ -2,7 +2,8 @@
     "name": "SharedCode",
     "rootNamespace": "",
     "references": [
-        "Metaplay"
+        "Metaplay",
+        "Metaplay.Core.Attributes"
     ],
     "includePlatforms": [],
     "excludePlatforms": [],
j
Nice
I've been able to test it
And looks like it's working
At least game runs and server could build and is running
Scared of any potential side effects, but im gonna go with this approach for now since we're not yet released and testing is allowed 😄
a
I understand that conceptually it might feel wrong to reference a Metaplay assembly from something only using it for attributes, but I'm curious about the affect on recompilation times. If there are no code changes in an assembly you depend on, then a recompilation of your assembly should not necessitate recompiling the dependent assembly. While the Metaplay SDK assemblies are built from source, they should update very infrequently.
I suppose if the original setup was that your gameplay assembly was depending on the SharedCode assembly then you'd need to (potentially unnecessarily) recompile the gameplay assembly whenever anything in the SharedCode assembly changes. This could be solved by splitting the type definitions shared between the gameplay and SharedCode assemblies into the "types" assembly that depends on the Metaplay assembly (for the attributes).
Note that some of the tooling (docker builds) expects to find all code shared between client and server under a single directory (by default
Assets/SharedCode
), so the easiest approach is to put both/all of your split assemblies under that directory: for example
Assets/SharedCode/Logic
and
Assets/SharedCode/Types
.
j
Yeah that's what I did.
Thanks ❤️
3 Views