Server authoritative unity

This is the server log :
22T07:18:29.441Z","caller":"server/pipeline.go:65","msg":"Received *rtapi.Envelope_Rpc message","uid":"1402bb25-a0fb-4172-be23-ed560786bbeb","sid":"04125abe-62f7-11ec-825f-688e25b5a5ca","cid":"20","message":{"Rpc":{"id":"customFunction","payload":"test"}}}

{"level":"debug","ts":"2021-12-22T07:18:29.441Z","caller":"server/session_ws.go:393","msg":"Sending error message","uid":"1402bb25-a0fb-4172-be23-ed560786bbeb","sid":"04125abe-62f7-11ec-825f-688e25b5a5ca","payload":"eyJjaWQiOiIyMCIsImVycm9yIjp7ImNvZGUiOjYsIm1lc3NhZ2UiOiJSUEMgZnVuY3Rpb24gbm90IGZvdW5kIn19"}

This is the error message in Unity :

WebSocketException: RPC function not found
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <695d1cc93cca45069c528c15c9fdd749>:0

@atv Do you see the function ID "customFunction" in the server startup logs? You should have a log line that looks something like this:

{"level":"info","ts":"2021-12-13T12:25:49.898Z","caller":"server/runtime.go:637","msg":"Registered Lua runtime RPC function invocation","id":"customfunction"}

No I don’t see it in the server log.

That’s where the issue is, Nakama is not actually finding/loading your custom module that contains that RPC.

And why ? The custom function is the example provided in the doc, it’s registered in the initModule in the main.ts script like I provided, the hello world message appears, why would the custom function not being registered as it’s in the main.ts file ? I tried to check in the local.yml file to see if by changing the runtime path it would solve the problem but no. The function also appears correctly in the index.js script.

Can you please zip up your project, your docker-compose and send it to me for inspection?

There were a couple of issues in the code you shared with me;

  1. Missing files in the Dockerfile:
COPY tsconfig.json .
COPY src/main.ts ./src/main.ts
COPY src/customrpcfunc.ts ./src/customrpcfunc.ts
RUN npx tsc
  1. Bad configuration between runtime path and js_entrypoint:
  path: "/nakama/data/modules/build/"   # <-- remove this line 
  js_entrypoint: "build/index.js"

Once these two changes were made, the server started with the following log lines:

...
{"msg":"Initialising JavaScript runtime provider","path":"data/modules","entrypoint":"build/index.js"}
{"msg":"Hello World! IF THIS MESSAGE APPEARS START IS CORRECT"}
{"msg":"JavaScript runtime modules loaded"}
{"msg":"Allocating minimum JavaScript runtime pool","count":16}
{"msg":"Allocated minimum JavaScript runtime pool"}
{"msg":"Found runtime modules","count":1,"modules":["index.js"]}
{"msg":"Registered JavaScript runtime RPC function invocation","id":"custom_rpc_func_id"}
...
{"level":"info","ts":"","caller":"main.go:175","msg":"Startup done"}

And finally I can see the RPC function available in the Nakama Console:

Thank you, it worked. I had not seen that I should have added the module in the docker file, makes more sense now.

Sorry to get back but still have some issues :

  1. I feel like when I make a change to a ts script, modifications are not taken into account.
    If for example I comment out a function and its initializer, it stills appears as loaded in the server log (I’m trying to change the function and it was not working) despite having compiled several times.

After some digging, I tried to copy your example of the pokeapi. At first it was not working despite doing everything right (intiliazer, dockerfile, tsconfig)

It only worked when I deleted the images and volume in Docker and recreated a new server. Is this how it is supposed to work ?

  1. When I submit a string payload to a rpc, the server returns me that error “JavaScript runtime function raised an uncaught exception”,“mode”:“rpc”,“id”:“custom_rpc_func_id”,“error”:“SyntaxError: invalid character ‘S’ looking for beginning of value at parse (native)”}
    if I try to put the same payload as the pokeapi example, “{“PokemonName”: “dragonite”}” it also returns the same error.

Yep whenever you make a code change, you need to rebuild the docker image that has your new code; To do so, run:

docker-compose up -f docker-compose.yml --build nakama

That will force rebuild the Nakama container.

Terminal shows an error : unknown shorthand flag: ‘f’ in -f.

For rpcs, I understand that there json involved but I can’t rellay wrap my head around how exactly am I suppose to send to the server a float, an int or a bool and get back from it a int, a float or a bool. I know it may sound stupid but I think I’m at a stage where I can ask stupid questions.

Sorry try:

docker-compose -f filename.yml up --build nakama

In regards to your second question, you’ll need to JSON encode your payload, and JSON decode the response:

And in Unity, you can do so with TinyJson like this:

Here’s what I’m trying to do .

In Unity :

 //We this to encode and decode json data with the server
    public class TestObjectClass
    {
        public int playerBetInt = 2;
        public bool playerBetEven = true;
    }

    public async void TestCustomFunction()
    {
        
        //Make a new object that we will send to the server in json
        TestObjectClass testObject = new TestObjectClass();
        testObject.playerBetInt = 7;
        testObject.playerBetEven = false;

        string jsonFromClient = JsonUtility.ToJson(testObject);
        Debug.Log(jsonFromClient);

        

        var payload = jsonFromClient; // Server correctly receive the informations 7 and false;
        var rpcid = "custom_rpc_func_id";
        var responseServer = await client.RpcAsync(session, rpcid,payload);
        var responseServerPayload = responseServer.Payload;


        //Decode the server return object 
        

        TestObjectClass serverObjectResponseDecoded = JsonUtility.FromJson<TestObjectClass>(responseServerPayload);

        Debug.LogFormat("Server answer is :", serverObjectResponseDecoded);
        Debug.Log(serverObjectResponseDecoded);
        Debug.Log(serverObjectResponseDecoded.playerBetInt);
        Debug.Log(serverObjectResponseDecoded.playerBetEven);

        //Information coming back is wrong as it 2 and true, the default values of the class.

    }

In the custom rpc ts:

let customFuncRpc: nkruntime.RpcFunction =
        function (ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, payload: string) {
    logger.info('payload: %q', payload);

    // "payload" is bytes sent by the client we'll JSON decode it. Works
    let json = JSON.parse(payload);

    let playerBet=json['playerBetInt'];
    let playerBetEven=json['playerBetEven'];
    let betAdditive=5;

    /*I tried several ways to get the data from the json to modify it and send it back with no success
    *The last one is just to make a serverResponse object with defined values and sent it back as a return value to the client.
    *Not working*/
    

    /*let newPlayerBet=playerBet+betAdditive;
    let newPlayerBetEven=false;*/

    
    
   


    let serverResponse=
    {
        newPlayerBet:85,
        newPlayerBetEven:false,


    }


    return JSON.stringify(serverResponse);
}

Ok, I solved the issue .

First, the playerBet in the TS needed to have the exact same name as its counterpart in Unity (logic).

But also, this :
docker-compose -f filename.yml up --build nakama
does not work, it creates new images that interfere with the code, the only way to get it working properly is to delete the container, images and volumes each time I have a code modification to make, otherwise it won’t properly work.

Hi again,

How do you write a console debug message or show a debug value for a variable ? (for functions not in nakama namespace)

When I try console.log(“Message error”) or console.log(booleanvariable) the server gives me that error :
ReferenceError: console is not defined in “name of the function where I called it”

Made sure to write console with a lowercase.

Hi @atv could you create separate posts for future questions.

You can pass the nkruntime.Logger to your methods to be able log messages outside of a Nakama function.

Thanks it worked.

1 Like