Server authoritative unity

Hi,

So I’m having a hard time understanding the documentation regarding how to write functions server side that will dictate what clients can and must do at a given time.

I have more experience with other solutions like PUN but on a p2p level not a server authoritative like the one I’m working on right now.

The first mini game I’m trying to make is fairly simple, it’s a hyper casual 2 players game where one player has to select a number and second player has to guess if the first player has selected an odd or even number.

So basically I need to be able to do the following :

1)Server decides randomly which player starts and tells the client that they can play or wait for the other client to play

  1. Client 1 selects a number and send that information to the server

  2. Server tells client 2 they can play and client 1 they have to wait for client 2 to play

  3. Client 2 tells the server if they think client 1 number is odd or even

  4. Server compares the answer and determines if client 2 has won or not and tells it to both clients.

It adds score to client 2 if it has won or to client 1 if client 2 has lost

  1. Server starts a new round and this time client 2 starts and client 1 will bid on odd /even.

So fairly simple, but I don’t really know how to start with writing these functions server side.

Thank you for your inputs,

@atv The Nakama project template repo contains full examples in Lua, Go, and TypeScript for a server-authoritative multiplayer tic-tac-toe example. It will show you how to get players into matches, manage server-side state, control who needs to submit data next, decide winners, and even play multiple rounds in the same match.

I suggest you start there and experiment with that example. :+1:

Hi,
Thank you for your time and your answer.

I took the time to review once again the template repo that I had already seen but it’s not helpful unfortunalty.

I guess most of the things I’m looking for are in the game handler script but it does not change the fact that I don’t understand the logic lying there and that I still don’t understand exactly how to connect it with the rest of the game in unity. It’s really confusing.

Previous stages were clearer, mainly due to the fact that they were back up by videos on your youtube channel which is not the case with the part I’m struggling with at the moment.

If i were you i would start by questioning whether you really need the server to decide which player goes first, because you can likely also achieve what you want without an authoritative server which means you could just follow the fishgame tutorial videos.

opcode 1 can be for determining who goes first.
2 could be that the first player has picked a number.
and 3 could be that the second player had guessed odd or even.

for example: Have each client generate a random number between 0 and 100 and send that to the match and compare those numbers to determine the first player.

if you however decide that it’s important to have the server decide it, start by building an authoritative server, these two have a video describing the process:
Typescript: TypeScript Setup - Heroic Labs Documentation
Golang: Go Setup - Heroic Labs Documentation
or Lua (without video): Lua Setup - Heroic Labs Documentation

And once you have that create the match upon matchmaking, and already decide the first player.
https://heroiclabs.com/docs/nakama/concepts/server-authoritative-multiplayer/#matchmaker

Hi,

Yes, we need to have a server authoritative system for this game.
Now, the server is running locally using docker on a mac, but we can’t even manage to install typescript module on it despite following the documentation, all the folders and files are here as per the documentation but the server administration interface says that no javascript module is installed and it doesn’t show the “hello world” contained in the index.js in the console.

We only have that message : can’t find a suitable configuration file in this directory or any parent: not found

Are you using the dockerfile from the documentation, or made some changes to it?
And are you using Docker Compose?

because the docker compose has this line --config /nakama/data/local.yml but in the dockerfile it’s placed in . which points to /nakama/ if I’m not mistaken.
So changing that line to:

COPY local.yml /nakama/data/

might help you further.

Yes I’m using Docker Compose and the dockerfile from the documentation. BTW, what extension should the dockerfile be as it’s not indicated ?

I’ve made the change you asked in the dockerfile, but it doesn’t seem to solve the problem.

The docker compose logs shows this :
21T13:58:48.187Z","caller":"server/runtime_javascript.go:524","msg":"Initialising JavaScript runtime provider","path":"/nakama/data/modules","entrypoint":""}

{"level":"info","ts":"2021-11-21T13:58:48.188Z","caller":"server/runtime_javascript.go:1466","msg":"JavaScript runtime modules loaded"}

{"level":"info","ts":"2021-11-21T13:58:48.188Z","caller":"server/runtime_javascript.go:1469","msg":"Allocating minimum JavaScript runtime pool","count":16}

{"level":"info","ts":"2021-11-21T13:58:48.188Z","caller":"server/runtime_javascript.go:1477","msg":"Allocated minimum JavaScript runtime pool"}

{"level":"info","ts":"2021-11-21T13:58:48.188Z","caller":"server/runtime.go:610","msg":"Found runtime modules","count":0,"modules":[]}

{"level":"info","ts":"2021-11-21T13:58:48.188Z","caller":"server/leaderboard_scheduler.go:91","msg":"Leaderboard scheduler start"}

{"level":"info","ts":"2021-11-

But no sign of the Hello World message and then when we check the Nakama console, it says there is no javascript module installed.

Yeah so that means it definitely can’t find the config yaml or it isn’t passed to the container correctly, because the config file has “runtime: path:” to tell where those modules are located.

I personally am using golang and got that working, i’ll be able to check what’s wrong with the typescript one tonight.

Did you get any errors when you tried to build the docker image?
Anyhow I got the basics working quite easily but maybe this helps you find the issue:

No, I don’t get any error messages.
Should the Dockerfile be a txt file or something else?

Dockerfile doesn’t have an extension, you can try with the repo I linked, that resulted in a working situation for me.
If you want to keep your own files instead i suggest going through the files to compare and adjust your files where needed.

Tried using the dockerfile from the repo, it still says no javascript modules were found in the Nakama console and no sign of the hello world message in the server logs

try checking out that repo, and see if that starts correctly (which it does on my machine :smirk: )
because the problem can be in any of the other files too, not just the Dockerfile :sweat_smile:

Tried with the repo, now the server won’t start and gives a lot of errors when I try to launch it

So, I had to try to re-create the server from square 1 following TypeScript Setup - Heroic Labs Documentation

I did it already like 3 or 4 times since the beginning and it was “working” aside from the javascript module not found issue.

Now the server won’t even start and the terminal shows me this message when I enter docker compose up command :

[+] Running 3/3
⠿ Network nakama_default Created 0.1s
⠿ Container nakama-postgres-1 Created 0.1s
⠿ Container nakama-nakama-1 Created 0.1s
Attaching to nakama-nakama-1, nakama-postgres-1
nakama-postgres-1 |
nakama-postgres-1 | PostgreSQL Database directory appears to contain a database; Skipping initialization
nakama-postgres-1 |
nakama-postgres-1 | 2021-12-04 12:41:30.380 UTC [1] FATAL: database files are incompatible with server
nakama-postgres-1 | 2021-12-04 12:41:30.380 UTC [1] DETAIL: The data directory was initialized by PostgreSQL version 9.6, which is not compatible with this version 12.2.
nakama-postgres-1 exited with code 1
nakama-nakama-1 | + /nakama/nakama migrate up --database.address postgres:localdb@postgres:5432/nakama
nakama-nakama-1 | {“level”:“info”,“ts”:“2021-12-04T12:41:31.329Z”,“caller”:“migrate/migrate.go:181”,“msg”:“Database connection”,“dsn”:“postgres://postgres:xxxxx@postgres:5432/nakama?sslmode=prefer”}
nakama-nakama-1 | {“level”:“fatal”,“ts”:“2021-12-04T12:41:31.337Z”,“caller”:“migrate/migrate.go:195”,“msg”:“Failed to check if db exists”,“db”:“nakama”,“error”:“failed to connect to host=postgres user=postgres database=nakama: hostname resolving error (lookup postgres on 127.0.0.11:53: no such host)”}
nakama-nakama-1 exited with code 1

In your latest logs, you can see that Postgres has failed to start:

nakama-postgres-1 | 2021-12-04 12:41:30.380 UTC [1] FATAL: database files are incompatible with server

I’d suggest running:

docker-compose down -v -f <FILENAME.yml>

followed by

docker-compose up -f <FILENAME.yml>

This will remove the data directory and reset the Postgres state.

I’ve managed to solve that issue, there were some leftovers in the images and volumes.
Now, it works and even the javascript module is correctly installed and working.

I’ll try now to create rpc functions which was my main issue.

So, continuing on my trials. Like I said previously, digging inside the tic tac toe project was not a big help.

I’ve tried to create a rpc function on the server, in the main.ts .

let InitModule: nkruntime.InitModule =
    function (ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, initializer: nkruntime.Initializer)
    {
        logger.info("Hello World!");
        initializer.registerRpc('testfunction', testfunction);
    }


let testfunction: nkruntime.RpcFunction =
    function (ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, payload: string)
    {
        let json = JSON.parse(payload);

        logger.info("If this message appears, it means the client has successfully called the function");
    }

In unity, I created a test function fired by a button like this :

 public async void TestFunction()
    {
        Debug.Log("Sending to server");
        await socket.RpcAsync("testfunction");

    }

As a result, what I have is an error message in the Unity console :

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

On the server log :

15T19:03:06.807Z","caller":"server/pipeline.go:65","msg":"Received *rtapi.Envelope_Rpc message","uid":"1402bb25-a0fb-4172-be23-ed560786bbeb","sid":"95c7ca35-5dd9-11ec-a1a1-688e25b5a5ca","cid":"1","message":{"Rpc":{"id":"testfunction"}}}

nakama-nakama-1 | {"level":"debug","ts":"2021-12-15T19:03:06.808Z","caller":"server/session_ws.go:393","msg":"Sending error message","uid":"1402bb25-a0fb-4172-be23-ed560786bbeb","sid":"95c7ca35-5dd9-11ec-a1a1-688e25b5a5ca","payload":"eyJjaWQiOiIxIiwiZXJyb3IiOnsiY29kZSI6NiwibWVzc2FnZSI6IlJQQyBmdW5jdGlvbiBub3QgZm91bmQifX0="}

How are you loading your custom module into Nakama?

  • What does the server startup logs say? Does it find your module and load it up?

  • Looks like your code is in Typescript (which is fine) - but Nakama loads only JavaScript, so you need to transpile it to JS. There is a tutorial for that: TypeScript Setup - Heroic Labs Documentation

  • Make sure that the transpired JS code is in the relevant folder for Nakama to find your module.

Hum, what custom module ? I’ve loaded previously the javascript / typescript module and the hello world message appears correctly on server start up.