Weaver Exception when load the Fusion Application Loop example

Hi photon engineers,


I have experience with PUN 1 & 2 and was excited to try Fusion. I decided to reverse engineer the Application Loop example, but having trouble getting it to load without errors in Unity. Here's what I've tried so far with no luck fixing the problem...


Application Loop example under Fusion Technical Samples...


I STARTED WITH U2020.3.13 and Fusion SDK 1.1.3

I ENDED WITH U2020.3.41f1 and Fusion SDK 1.1.4 F Build 609


When I load the project out of the box I get a Weaver Exception Error. Initially I was running U2020.3.1 which was older than the sample project version. So I thought maybe it was a Unity version issue. I deleted the whole example project and updated Unity to U2020.3.41f1 then loaded the project again with the same error results. I've tried multiple attempts to fix this:


I deleted the project multiple times and restarted - same result.

I deleted the Library folder and restarted - same result.

I even deleted the Photon folder and re-imported Fusion multiple times.

I updated to the latest Fusion (1.1.4) version - same results.

I double checked that I have correct Mono.Cecil version 1.10.2 running.

I tried running the "Run Weaver" button under the Fusion menu multiple times.


I did comment out the offending RPC_FinishedLoading function just to see what would happen. The project worked up until it loaded the final scene. So at least I got to see how some of the project worked, but I can't get rid of this Weaver Exception.


This is from my Editor.log after the project loads...

Starting ILPostProcessorRunner

- Starting ILPostProcessor 'Fusion.CodeGen.ILWeaverBindings' on Assembly-CSharp.dll

- Finished ILPostProcessor 'Fusion.CodeGen.ILWeaverBindings' on Assembly-CSharp.dll in 0.368939 seconds

ILPostProcessorErrorException: ILPostProcessorRunner 'ILWeaverBindings' had a fatal error processing 'Assembly-CSharp'

 Refer to diagnostic messages above for more details.

Exiting...

 at ILPostProcessorRunner.HandleDiagnosticMessages (System.String ilppName, System.String asmName, System.Collections.Generic.List`1[T] messageList) [0x000e0] in <e361a3fd54d940c583bb8dcd3a08c440>:0

 at ILPostProcessorRunner.RunILPostProcessors (NamedILPostProcessorWrapper[] ilpostProcessors) [0x000e0] in <e361a3fd54d940c583bb8dcd3a08c440>:0

 at ILPostProcessorRunner.Main (System.String[] args) [0x000be] in <e361a3fd54d940c583bb8dcd3a08c440>:0

ILPostPostRunner was started with arguments:

@E:/Unity Test Projects/Fusion Network Examples/AppLoop/Temp/UnityTempFile-9e4496f0d62f1c740b9d25395d10beb3

- Finished ILPostProcessorRunner in 0.499781 seconds

E:\Unity Test Projects\Fusion Network Examples\AppLoop\Assets\Photon\FusionCodeGen\Fusion.CodeGen.cs(3376,0): error Exception thrown when weaving Assembly-CSharp

(0,0): error Fusion.CodeGen.ILWeaverException: Failed to weave behaviour Session ---> Fusion.CodeGen.ILWeaverException: Fusion.RpcInvokeInfo Session::RPC_FinishedLoading(Fusion.PlayerRef): return pattern of RpcInvokeInfo not recognised at IL_00b9: ret. Context: IL_0000: newobj System.Void Session/<>c__DisplayClass14_0::.ctor()

(0,0): error IL_0005: stloc.0

(0,0): error IL_0006: ldloc.0

(0,0): error IL_0007: ldarg.1

(0,0): error IL_0008: stfld Fusion.PlayerRef Session/<>c__DisplayClass14_0::playerRef

(0,0): error IL_000d: nop

(0,0): error IL_000e: ldstr "RPC finished loading!"

(0,0): error IL_0013: call System.Void UnityEngine.Debug::Log(System.Object)

(0,0): error IL_0018: nop

(0,0): error IL_0019: ldloc.0

(0,0): error IL_001a: ldc.i4.0

(0,0): error IL_001b: stfld System.Int32 Session/<>c__DisplayClass14_0::done

(0,0): error IL_0020: ldloc.0

(0,0): error IL_0021: ldc.i4.0

(0,0): error IL_0022: stfld System.Int32 Session/<>c__DisplayClass14_0::total

(0,0): error IL_0027: ldarg.0

(0,0): error IL_0028: ldfld App Session::_app

(0,0): error IL_002d: ldloc.0

(0,0): error IL_002e: ldftn System.Void Session/<>c__DisplayClass14_0::<RPC_FinishedLoading>b__0(Player)

(0,0): error IL_0034: newobj System.Void System.Action`1<Player>::.ctor(System.Object,System.IntPtr)

(0,0): error IL_0039: callvirt System.Void App::ForEachPlayer(System.Action`1<Player>)

(0,0): error IL_003e: nop

(0,0): error IL_003f: ldstr "{0} of {1} finished loading!"

(0,0): error IL_0044: ldloc.0

(0,0): error IL_0045: ldfld System.Int32 Session/<>c__DisplayClass14_0::done

(0,0): error IL_004a: box System.Int32

(0,0): error IL_004f: ldloc.0

(0,0): error IL_0050: ldfld System.Int32 Session/<>c__DisplayClass14_0::total

(0,0): error IL_0055: box System.Int32

(0,0): error IL_005a: call System.String System.String::Format(System.String,System.Object,System.Object)

(0,0): error IL_005f: call System.Void UnityEngine.Debug::Log(System.Object)

(0,0): error IL_0064: nop

(0,0): error IL_0065: ldloc.0

(0,0): error IL_0066: ldfld System.Int32 Session/<>c__DisplayClass14_0::done

(0,0): error IL_006b: ldloc.0

(0,0): error IL_006c: ldfld System.Int32 Session/<>c__DisplayClass14_0::total

(0,0): error IL_0071: blt.s IL_008c

(0,0): error IL_0073: ldarg.0

(0,0): error IL_0074: call Fusion.TickTimer Session::get_PostLoadCountDown()

(0,0): error IL_0079: stloc.2

(0,0): error IL_007a: ldloca.s V_2

(0,0): error IL_007c: ldarg.0

(0,0): error IL_007d: ldfld Fusion.NetworkRunner Fusion.SimulationBehaviour::Runner

(0,0): error IL_0082: call System.Boolean Fusion.TickTimer::Expired(Fusion.NetworkRunner)

(0,0): error IL_0087: ldc.i4.0

(0,0): error IL_0088: ceq

(0,0): error IL_008a: br.s IL_008d

(0,0): error IL_008c: ldc.i4.0

(0,0): error IL_008d: stloc.1

(0,0): error IL_008e: ldloc.1

(0,0): error IL_008f: brfalse.s IL_00aa

(0,0): error IL_0091: nop

(0,0): error IL_0092: ldarg.0

(0,0): error IL_0093: ldarg.0

(0,0): error IL_0094: ldfld Fusion.NetworkRunner Fusion.SimulationBehaviour::Runner

(0,0): error IL_0099: ldc.r4 3

(0,0): error IL_009e: call Fusion.TickTimer Fusion.TickTimer::CreateFromSeconds(Fusion.NetworkRunner,System.Single)

(0,0): error IL_00a3: call System.Void Session::set_PostLoadCountDown(Fusion.TickTimer)

(0,0): error IL_00a8: nop

(0,0): error IL_00a9: nop

(0,0): error IL_00aa: ldloca.s V_3

(0,0): error IL_00ac: initobj Fusion.RpcInvokeInfo

(0,0): error IL_00b2: ldloc.3

(0,0): error IL_00b3: stloc.s V_4

(0,0): error IL_00b5: br.s IL_00b7

(0,0): error IL_00b7: ldloc.s V_4

(0,0): error IL_00b9: ret

(0,0): error  at Fusion.CodeGen.ILWeaver.WeaveRpcs (Fusion.CodeGen.ILWeaverAssembly asm, Mono.Cecil.TypeDefinition type, System.Boolean allowInstanceRpcs) [0x005c3] in <80f3ae0b425540d992bc7d3ead4b4bf8>:0

(0,0): error  at Fusion.CodeGen.ILWeaver.WeaveBehaviour (Fusion.CodeGen.ILWeaverAssembly asm, Mono.Cecil.TypeDefinition type) [0x0154d] in <80f3ae0b425540d992bc7d3ead4b4bf8>:0

(0,0): error  at Fusion.CodeGen.ILWeaver.Weave (Fusion.CodeGen.ILWeaverAssembly asm) [0x0012c] in <80f3ae0b425540d992bc7d3ead4b4bf8>:0

(0,0): error   --- End of inner exception stack trace ---

(0,0): error  at Fusion.CodeGen.ILWeaver.Weave (Fusion.CodeGen.ILWeaverAssembly asm) [0x0014f] in <80f3ae0b425540d992bc7d3ead4b4bf8>:0

(0,0): error  at Fusion.CodeGen.ILWeaverBindings.Process (Unity.CompilationPipeline.Common.ILPostProcessing.ICompiledAssembly compiledAssembly) [0x00219] in <80f3ae0b425540d992bc7d3ead4b4bf8>:0

Comments

  • MHG_Developer
    edited November 2022

    So after doing some testing it seems the return value struct RpcInvokeInfo in the RPC call is the culprit. This is a Fusion struct so not sure why the issue. Surprised no one else is reporting this issue, unless I am missing something. Anyway this is the offending RPC function that resides within the Session.cs script. All I did was change the return type to Void and then commented out anything related to RpcInvoikeInfo.


       [Rpc(RpcSources.All, RpcTargets.StateAuthority, Channel = RpcChannel.Reliable)]

       public RpcInvokeInfo RPC_FinishedLoading(PlayerRef playerRef)

       {

           Debug.Log($"RPC finished loading!");

           int done = 0, total = 0;

           _app.ForEachPlayer(ply =>

           {

               if (ply.Object.InputAuthority == playerRef)

                   ply.DoneLoading = true;

               if (ply.DoneLoading)

                   done++;

               total++;

           });

           Debug.Log($"{done} of {total} finished loading!");

           if (done >= total && !PostLoadCountDown.Expired(Runner))

           {

               PostLoadCountDown = TickTimer.CreateFromSeconds(Runner, 3);

           }

           RpcInvokeInfo result = new RpcInvokeInfo();

           result.LocalInvokeResult = RpcLocalInvokeResult.Invoked;

           //result.SendResult = new RpcSendResult();


           return result;

       }

  • Same issue here,

    I got to this line

    //[Rpc(RpcSources.All, RpcTargets.StateAuthority, Channel = RpcChannel.Reliable)]
    public RpcInvokeInfo RPC_FinishedLoading(PlayerRef playerRef)
    {
    

    something in the attribute is triggering the error for me. I'm not able to dig deeper.

  • It is unfortunate that this example code is faulty. It seems it might be advantageous to check that an RPC has executed or to send specific info back to the calling client. Regardless, I could not get it to work out of the box so I had to remove the return info. However, it may be a technique that can be utilized with some modifications. I just happened to be new to Fusion and not interested in dissecting this problem at the time I posted.

  • I am facing the same problem.

    Can you tell me how to get past versions as I think they worked in older versions?

  • Same problem here. Unity 2021 , Windows 11, Sample 1.1.3

  • MHG_Developer
    edited February 2023

    @Kuriyama @DoubleHitGames

    To get the AppLoop example working if you are getting the weaver error when first opening the project, I Just removed the return type RpcInvokeInfo on the RPC_FinishedLoading function within Session.cs and made the return type void. Then within the Map.cs script I modified the FixedUpdateNetwork() function which calls RPC_FinishedLoading by removing the expected RpcInvokeInfo return value and then adding it manually after the RPC call forcing the result. This is obviously not ideal but it will at least let you run the example without too much headache.

    Session.cs

      [Rpc(RpcSources.All, RpcTargets.StateAuthority, Channel = RpcChannel.Reliable)]
      public void RPC_FinishedLoading(PlayerRef playerRef)
      {
        Debug.Log($"RPC finished loading!");
    
        int done = 0, total = 0;
        _app.ForEachPlayer(ply =>
        {
          if (ply.Object.InputAuthority == playerRef)
            ply.DoneLoading = true;
          if (ply.DoneLoading)
            done++;
          total++;
        });
    
        Debug.Log($"{done} of {total} finished loading!");
    
        if (done >= total && !PostLoadCountDown.Expired(Runner))
        {
          PostLoadCountDown = TickTimer.CreateFromSeconds(Runner, 3);
        }
        //RpcInvokeInfo result = new RpcInvokeInfo();
        //result.LocalInvokeResult = RpcLocalInvokeResult.Invoked;
        //result.SendResult = new RpcSendResult();
       // return result
      }
    

    ------------------------------------------------------------------------

    Map.cs

    	public override void FixedUpdateNetwork()
    	{
    		Session session = _app.Session;
    		if (session.Object == null || !session.Object.IsValid)
    			return;
    		if (_sendMapLoadedMessage)
    		{
    			// Tell the master that we're done loading and set the sessions map so the rest of the game know that we are ready
    			Debug.Log("Finished loading");
    
    			/*The RPC call is necessary to do some checks on the 
    			 * remote client but just remove the original 
    			 * "RpcInvokeInfo invokeinfo =" return value and force create it manually
                             * after 
                             */
                             _app.Session.RPC_FinishedLoading(Runner.LocalPlayer);
    
    			/* Force create the RpcInvokeInfo after calling the RPC function above
    			 * Obviously not ideal but it will remove the weaver errors and at least
    			 * allow you to test the example.
    			 */
                             RpcInvokeInfo invokeinfo = new RpcInvokeInfo();
                             invokeinfo.LocalInvokeResult = RpcLocalInvokeResult.Invoked;
                             invokeinfo.SendResult = new RpcSendResult();
    
                             Debug.Log($"RPC returned {invokeinfo}");
    
    			if ((invokeinfo.LocalInvokeResult == RpcLocalInvokeResult.Invoked) || (invokeinfo.SendResult.Result & RpcSendMessageResult.MaskSent) != 0)
    			{
    				_app.Session.Map = this;
    				_sendMapLoadedMessage = false;
    			}
    			else
    				Debug.Log($"RPC failed trying again later");
    		}
    		if (!session.PostLoadCountDown.Expired(Runner))
    			_countdownMessage.text = Mathf.CeilToInt(session.PostLoadCountDown.RemainingTime(Runner)??0 ).ToString();
    		else
    			_countdownMessage.gameObject.SetActive(false);
    	}
    


  • For some reason RPCs with return value [RpcInvokeInfo] sometimes break the weaver.

    For simplicity you can use 'return default;' to get the RPC info.

    I realized that when RPC targets are set RpcTargets.StateAuthority the RPC has to be void apparently