Nakama official client

I couldn’t find Lua reference to create a Match (not a matchmaker) , i used the javascript api as refence .
To Create Match in js you have to use

var response = await socket.createMatch();
console.log("Created match with ID:", response.match.match_id);

You can share the match id with other players to join .
i want to do the same thing using Defold and Lua .
if i am not mistaken , the same should be in Lua :

local match_create_message = {
        match_create = {} -- empty , no arguments		
}
		
local match_result = nakama.socket_send(socket, match_create_message,callback)

This caused the server to disconnect with :

{"level":"warn","ts":"2021-01-04T11:23:32.727Z","msg":"Received malformed payload","uid":"51fc50d1-da4e-4f4c-b74a-ea60e75bad37","sid":"71335a58-9d9d-4d72-8cd4-3942df576269","data":"eyJjaWQiOiIxIiwibWF0Y2hfY3JlYXRlIjpbXX0="}

after decoding the data

{"cid":"1","match_create":[]}

Please have a look here: Nakama official client

I have checked the Official defold client , i couldn’t find a way through making a custom Match(not a match maker) , similar to Realtime Multiplayer - Nakama server (heroiclabs.com)

The error seems to be this

{"cid":"1","match_create":[]}

It should be

{"cid":"1","match_create":{}}

Edit.
I have tested and this is the problem.

To fix it, you to have to patch nakama.engine.defold.lua
You properly have to copy manually the nakama modules to your project.

Change function M.socket_send to be

function M.socket_send(socket, message, callback)
	assert(socket and socket.ws, "You must provide a socket")
	assert(message, "You must provide a message to send")
	socket.cid = socket.cid + 1
	message.cid = tostring(socket.cid)

	socket.requests[message.cid] = callback
	local data = json.encode(message)
	local clean_data = string.gsub(data, "%[%]", "{}")
	pprint("Todo remove", clean_data)
	socket.ws:send(clean_data) 
end

Please create a ticket in the Nakama repo and I’ll make sure to fix it! It should be solved in the Nakama client.

I don’t know if it’s a bug. It come down to how to encode lua’s {} to json. Should it be encoded as “{}” or “[]”.

So this instead of sending a json empty object it sent an empty array .

I have already created a ticket about this topic

Creating a Match in Defold · Issue #17 · heroiclabs/nakama-defold (github.com)

1 Like

Yes, that is the issue. I will properly create a pull request.
Talking of which the nakama API seems to have changed, For example in the authenticate_email callback, it does not return result.error but result.code.

Edit.
I have created a pull request in github.

2 Likes

@kiprono
What if actually we meant to send an empty array for example , this will force all [ ] to be { } without exceptions .
e.g :

local match_data = {
    match_data_send = {
        match_id = match.match.match_id,
        op_code = 1337,
        data = {
            players = {} -- i want to receive it as an empty array
        }
    }
}

if i am not mistaken, in this case the players will be converted to Json object instead of an empty array of players

Yep, this is a problem with json encoding an empty table from Lua since you can’t tell if it is supposed to be an empty array or an empty object. I don’t have a good solution for it.

1 Like
    local data = json.encode(message)
    local message
    local is_match_create = string.find(data,"match_create")
    if is_match_create ~= nil then -- match_create message
        message = string.gsub(data, "%[%]", "{}") -- array to json object
    end
	
    socket.ws:send(message)

based on @kiprono solution
this works in case a user send a match_create message , i guess this type of message is the only one that’s being sent without params

Hey guys, first of all I want to say that Nakama is AWESOME. Being able to write server code in lua has enabled me to set up a simple realtime multiplayer game quickly. This is so much fun.

I bumped into a small problem when attempting to join a match. Sending this from the client:

local metadata = {}
metadata.equipped_weapon_type = 1
local metadata_json = json.encode(metadata) -- {"equipped_weapon_type":1}
local message = nakama.create_match_join_message(match_id, token, metadata_json)

--[[
-- message:
{ 
  match_join = { --[[0x120d6fe00]]
    match_id = "9b8d2c60-25e5-4ddb-8e26-d0717d47dfb4.nakama-node-1",
    metadata = "{"equipped_weapon_type":1}"
  }
}
--]]

local result = nakama.socket_send(socket, message) -- This call fails

Results in this server error:

{"level":"debug","ts":"2021-03-12T14:29:54.210Z","msg":"Error reading message from client","uid":"4b4b9e18-8c26-4a62-a857-9f97f994ac7c","sid":"66a02717-d678-4b5a-9855-7f030c5136c1","error":"websocket: close 1006 (abnormal closure): unexpected EOF"}

If the metadata parameter is nil everything works as it should. I haven’t found any documentation about how the metadata should be formatted, hence this post. Any ideas?

3 Likes

What if you don’t json.encode the metadata and instead send it as a table?

I tried that first by mistake actually! It produces a different error:

{"level":"warn","ts":"2021-03-12T15:01:19.829Z","msg":"Received malformed payload","uid":"c5922789-ae72-4c54-8ec1-b475b3aa4358","sid":"d5101fde-45ce-4ac5-86e2-97b7d8076624","data":"eyJjaWQiOiIyIiwibWF0Y2hfam9pbiI6eyJtZXRhZGF0YSI6eyJ3ZWFwb25fdHlwZSI6MX0sIm1hdGNoX2lkIjoiZWNjMDFkYjAtZjE0MC00MDk0LTk0YzYtNmJlOWUxYzU1ODMyLm5ha2FtYS1ub2RlLTEifX0="}

Hmm, perhaps @novabyte sees and can help us out. Otherwise I’d recommend posting on the Nakama forum to get help.

1 Like

Posted on the Nakama forum too.

1 Like

Solved! The metadata has to be a table containing only strings as values. Like this:

local metadata = {}
metadata.equipped_weapon_type = "1"
local message = nakama.create_match_join_message(match_id, token, metadata)

More info on Nakama’s forums.

5 Likes

I can’t find the method to validate in-app purchases from both Google and iOS as mentioned here:
https://heroiclabs.com/docs/in-app-purchase-validation/#recovering-purchases

Are they absent from the current Nakama defold integration?