Unity Ninja Battle Tutorial - "Failed initializing runtime modules","error":"TypeError: matchSignal not found"

Can do.
Below is the code if I move a unit:

        public void Move(Tile targetTile)
        {
            Vector3 unitPos = transform.position;
            Vector3 targetPos = targetTile.transform.position;

            long opCode = (long) MultiplayerManager.Code.MoveUnit;
            string state = GetJsonPositionAndAbilityInd(unitPos, targetPos,0);
}

        public string GetJsonPositionAndAbilityInd (Vector3 selectedUnit, Vector3 targetTile, int abilityIndex)
        {
            var values = new Dictionary<string, string>
            {
                {"SelectedUnitPos.x", selectedUnit.x.ToString() },
                {"SelectedUnitPos.y", selectedUnit.y.ToString() },
                {"SelectedUnitPos.z", selectedUnit.z.ToString() },
                {"TargetTilePos.x", targetTile.x.ToString() },
                {"TargetTilePos.y", targetTile.y.ToString() },
                {"TargetTilePos.z", targetTile.z.ToString() },
                {"AbilityIndex", abilityIndex.ToString()}
            };

            return values.ToJson();
        }

This is the first part of the client code when receiving the match state:

        private void OnReceivedMatchState(IMatchState matchState = null)
        {
            Debug.Log("Received OpCode: "+matchState.OpCode);
            string state = Encoding.UTF8.GetString(matchState.State);
            Debug.Log("Received State: "+state);

In the client console I get:
Received OpCode: 1
Received State: “{"SelectedUnitPos.x":"-3.75","SelectedUnitPos.y":"0.1","SelectedUnitPos.z":"6.4875","TargetTilePos.x":"-3.75","TargetTilePos.y":"0.1","TargetTilePos.z":"0","AbilityIndex":"0"}”

This is the client code that is meant to perform the unit movement action when receiving this match state:

            if (matchState.OpCode == (long)Code.MoveUnit)
            {
                var stateDictionary = GetStateDictionary(matchState.State);
                Vector3 unitPos = new Vector3(float.Parse(stateDictionary["SelectedUnitPos.x"]), float.Parse(stateDictionary["SelectedUnitPos.y"]), float.Parse(stateDictionary["SelectedUnitPos.z"]));
                Vector3 targetPos = new Vector3(float.Parse(stateDictionary["TargetTilePos.x"]), float.Parse(stateDictionary["TargetTilePos.y"]), float.Parse(stateDictionary["TargetTilePos.z"]));

                UnityMainThreadDispatcher.Instance().AddActionToQueue(MoveUnit(unitPos, targetPos));
            }

        private  IDictionary<string,string> GetStateDictionary(byte[] state)
        {
            return Encoding.UTF8.GetString(state).FromJson<Dictionary<string, string>>();
        }

The error I get in the client console is:

System.NullReferenceException: Object reference not set to an instance of an object
at Nakama.Helpers.MultiplayerManager.OnReceivedMatchState (Nakama.IMatchState matchState) [0x00089] in C:\Unity Projects\Projects\Valorous\Assets\Nakama\Scripts\MultiplayerManager.cs:253
at Nakama.Socket.ProcessMessage (System.ArraySegment1[T] buffer) [0x001ed] in <127981172e4e4a2b9b7ef01979f29de9>:0 UnityEngine.Debug:LogError (object) Nakama.Socket:ProcessMessage (System.ArraySegment1)

Note: this is what I used when I had it setup to be client to client. But seems to not work with server authorative. Unless I am just completely missing something here!

Thanks!

@Rob161 I’m confused about what triggers this error. It looks like it’s originating in our .dll but being reported from an error handler that you’ve wired up in ReceivedError - can you confirm that you’ve wired up this handler and tell me what triggers the error occuring?

Could you also file this as an issue on our Unity or .NET github repositories so we could discuss there instead?

Well in the end, I decided to write up the code from scratch again - and it now works. Still not sure where the error came from, but all I know is that it now works! But thanks for assisting with this anyway.

Couple last questions:

  1. If I want to now leave matches open so players can rejoin when they like, I understand I will need to check the TS files to make sure nothing triggers the matchTerminate (such as from no moves detected for a certain amount of time). I’ll then setup a RPC function which will trigger matchTerminate if one of players presses “surrender” - and I will set this as the only way a match can be terminated. Does this seem like the way to go about this? Also, how do I go about having a player be able to pull up a list of their open matches they haven’t “surrendered” from so they can have the option to rejoin them? If there is a tutorial out there that has this covered that would be excellent.

  2. My other question is, if I have already created the javascript index.js file in the modules folder from my typescript files and I need to update this server code, can I just edit the index.js file? Is there any point to update the typescript files and then run npx tsc from the Terminal to create a new index.js file?

Much appreciated.

  1. You can use the match labels and the query language to look up any matches the user is in. You’d use the runtime function matchLabelUpdate to set the user IDs of participating players in its label. You’d then lookup any ongoing matches with that specific userID when attempting to rejoin using the match listing API.
    You can leave the matches running indefinitely, however this could become an issue as their respective resources will never be released so keep that in mind.
    I’d like to clarify that the matchTerminate hook is only invoked when the server receives a shut down signal, and is meant to provide a way to handle match state serialization or other tasks before the match is to be terminated.

  2. You can edit the index.js file directly and just write your code in ES5 compliant JS, however you’d lose the niceties that come from having the Nakama TS definitions (e.g.: auto-complete in your code editor) and the general benefits of a strongly typed language. Moreover, the tsc compiler options we provide ensure that the output JS is ES5 compliant and hence supported by Nakama. I’d advise you stick to editing your TS code and transpile it as recommended, but ultimately it’s up to your development personal preferences.

No worries, sounds like a plan. Thanks heaps for your help on this. Appreciate it.