It feels like a pretty complicated way of testing local multiplayer, but yes, using Nakama should work!
Ahahah, It is just that I am alone at home (thank you corona virus!) and my art director and friend is in her houseā¦
To conclude on this, I can confirm that the latest update to the Websocket extension fixes this!
I also have trouble getting this example to work with my own server:
So far, nobody was able to help.
You have received a reply on the HeroicLabs forum a few hours ago: Ways to debug server code (Nakama Defold tictactoe XOXO example) - #8 by flavio - Heroic Labs
Thanks Britzl! Now it kinda works, but the bug with the default (Defold?) port for Nakama still persists. That is not fixed for me. I have the newest Defold and Nakama.
I added a PR for this change to the server. Please merge it for everyone else. Thanks!
Thanks. Iāll take a look soon.
Which bug is that?
When you run locally with the default nakama port both players win when one player wins.
I started my playtest with Nakama once again, now following this tutorial and found some issues. Here is my experience:
Nakama local server setup
Running Nakama server from Docker was flawless on Ubuntu following just this few commands (I already had docker installed, old, but enough), but the link in tutorial is not pointing directly to the page mentioned (correct link is now: Heroic Labs Documentation | Docker Compose):
$ docker --version
Docker version 20.10.24, build 297e128
$ git clone https://github.com/heroiclabs/nakama-project-template.git
Cloning into 'nakama-project-template'...
...
$ cd nakama-project-template/
$ docker compose up
You might want to need to run docker with sudo
.
Then the server is booting up and a lot is printed in console and the last message is:
backend | {"level":"info","ts":"2023-06-18T08:59:38.242Z","caller":"main.go:175","msg":"Startup done"}
If everything is ok (like it was for me) you can open server website/admin panel on any web browser at http://127.0.0.1:7351 and login with admin
and password
default credentials. It is a server you run locally, so perfect for testing.
Defold integration
Defold integration have a picture of used libraries - it would be great to put there links as well. After quick search you can find it of course, but it would be good to have them in tutorial. Newest versions are 3.1.0 and thatās what I used rn (version from tutorial is not compiling websocket native extension on this day).
Links:
https://github.com/heroiclabs/nakama-defold/archive/3.1.0.zip
https://github.com/defold/extension-websocket/archive/3.1.0.zip
Following the first few steps I have an initial code:
local defold = require "nakama.engine.defold"
-- The Nakama server configuration
local config = {}
config.host = "127.0.0.1" -- localhost, ie your own machine
config.port = 7351
config.use_ssl = (config.port == 443)
config.username = "admin" -- your Nakama server key, default is "defaultkey"
config.password = "password"
config.engine = defold -- Tell Nakama to use Defold (it can theoretically also work with other Lua based engines)
-- authentication using device id
local function device_login(client)
-- login using the token and create an account if the user
-- doesn't already exist
local result = nakama.authenticate_device(client, defold.uuid(), nil, true)
if result.token then
-- store the token and use it when communicating with the server
nakama.set_bearer_token(client, result.token)
return true
end
print("Unable to login")
return false
end
function init(self)
local client = nakama.create_client(config)
device_login(client)
end
A small issue is that 127.0.0.1
is malformed number:
So I put it as a string. I donāt know yet, if this is wrong or not, but will probably find out!
And here I am stopped at the moment, because:
Even though the extensions are fetched:
Canāt find any similar problem on forum, so I would love a help!
UPDATE 1:
Duck-debugging is always helpful, so after writing it down, I noticed in the code there is no require and nakama
is not included in the namespace like e.g. defos
is, but there is a Lua module named nakama
, so I guess this is fixing the issue (but this is the issue after following tutorial, so I have to note it down, for improvement):
local nakama = require "nakama.nakama"
Next is that Nakama must be run from within a coroutine:
UPDATE 2:
So I put it in coroutine like this:
function init(self)
local co = coroutine.create(function()
local client = nakama.create_client(config)
device_login(client)
end)
local ok, err = coroutine.resume(co)
end
And for now I am not able to log in, so will try to debug it:
But one user account is at least found in my local server admin dashboard:
But itās a system user
By printing result
I get:
So, I guess the user is not found, so canāt log in. Strange, because the call is to create the user
( @param create_bool () Register the account if the user does not already exist.
)
Not entirely true. You can either run from within a coroutine to get nice looking synchronous code as in your example, but you could also use a callback:
local id = defold.uuid()
local vars = nil
local create = true
local username_str = nil
nakama.authenticate_device(client, id, vars, create_bool, username_str, function(result)
if result.token then
-- store the token and use it when communicating with the server
nakama.set_bearer_token(client, result.token)
end
end)
Thatās strange. No idea whatās going on there!
I think you need to set the username_str
when creating the user.
Yes, this is also working, good to know! (but I just noted what is an error that is given to user when following the tutorial).
From the code I understand the config.host actually should be string, so the tutorial should be corrected imho.
It didnāt help All the time I got response:
DEBUG:SCRIPT: Logging in,
{ --[[0x7f62429e2940]]
message = "Not Found",
error = true,
code = 5
}
Socket creation
This also is problematic following the code from the tutorial, because there are simply no such functions in nakama Lua module:
local socket = nakama.create_socket(client)
local ok, err = nakama.socket_connect(socket)
Instead, I found those:
local nakama_socket = require "nakama.socket"
local socket = nakama_socket.create(client)
local ok, err = nakama_socket.connect(socket)
But it for now is not working for me, because of the previous problem, without any user, resulting in not heaving a correct bearer_token
True. Iāll see if I can update the tutorial to work with the latest version of Nakama!
I would be very thankful! I canāt dig into the issues atm, but I will try to dive in asap. For now the XOXO example is not working for me out of the box. I printed the result
from xoxo_nakama.lua:L24
under āUnable to loginā:
I can reach the dashboard from XOXO example via browser.
Hey @Pawel, Iām also messing around in Nakama and recognise some issues, so I might be able to help!
Fƶr The couroutine stuff I use the nakama.sync()
helper function which works great.
Iām using authenticate_custom() to log the player in, getting the id from Google or Appleās authentication. See comments in the code.
nakama.sync(function()
print("Authenticating Nakama.")
local custom_id = social_user_id -- Used every time when logging in.
local vars = nil
local create_bool = true
local username_str = social_user_id -- Used once when creating an account. Optional, if nil Nakama will create a unique username.
local callback = nil
local retry_policy = nil
local cancellation_token = nil
local authenticate_result = nakama.authenticate_custom(client, custom_id, vars, create_bool, username_str, callback, retry_policy, cancellation_token)
if authenticate_result.error then
print("Authentication error")
pprint(authenticate_result)
return
end
print("Authenticated.")
pprint(authenticate_result)
nakama.set_bearer_token(client, authenticate_result.token)
end)
Thank you @totebo! This works also well!
So the issue I have is that I forcefully changed the port to the same port, where I can see the Dashboard (7351) instead of the one shown in examples (7350). I can authenticate and receive a correct session when using 7350!
So for future me:
{ --[[0x7f62429e2940]]
message = "Not Found",
error = true,
code = 5
}
Might just mean you are not connecting to your server and should check the port.
Ah, glad you managed to figure it out! It would be nice with a reference to the error codes, to avoid this type of confusion.
Going on, I have this issue when trying to write anything to Storage:
local result = nakama.write_storage_objects(client, {[test] = 1}) -- even with 2nd argument being nil
pprint(Result, result)
Gives me:
DEBUG:SCRIPT: Result,
{ --[[0x7f6f2c1839f0]]
message = "proto: syntax error (line 1:12): unexpected token {",
code = 3,
error = true
}
I think youāre missing a few parameters. Check out this page where there is an example:
local objects = {
{
collection = "Favorites",
key = "Hats",
value = json.encode({ "cowboy", "alien" }),
permissionRead = 1,
permissionWrite = 1,
version = ""
}
}
local result = nakama.write_storage_objects(client, objects)
Thank you again @totebo!
Result is though:
DEBUG:SCRIPT: Result,
{ --[[0x7f2b6ac3c4b0]]
code = 3,
error = true,
message = "Value must be a JSON object."
}
Strange, but what I had to change is value to be a table of keys and pairs:
...
value = json.encode({ cowboy = 1, alien = 2}),
...
And then it works! I can store and read!
Another thing to point out in tutorial is socket connection:
Socket connect function was removed from nakama and moved to nakama.socket, so we should require it:
local realtime = require "nakama.socket"
And use function connect on created socket (create_socket is still part of nakama module):
local socket = nakama.create_socket(client)
local ok, err = realtime.connect(socket)
Buut, it still doesnāt work for me
AL lib: (EE) ALCpulsePlayback_streamStateCallback: Received stream failure!