# How to link chat and match together?

**URL:** <https://forum.heroiclabs.com/t/how-to-link-chat-and-match-together/91>\
**Category:** Local Setup\
**Created:** [July 23, 2019, 8:40am UTC](https://forum.heroiclabs.com/t/how-to-link-chat-and-match-together/91 "2019-07-23T08:40:57Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![yudi-xiao](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/yudi-xiao/32/45_2.png) [@yudi-xiao](https://forum.heroiclabs.com/u/yudi-xiao)\
**Post date:** [July 23, 2019, 8:40am UTC](https://forum.heroiclabs.com/t/how-to-link-chat-and-match-together/91/1 "2019-07-23T08:40:57Z")

</div>

Is there any conventional way to link match and chat channel together?  
Or somehow to open direct chat channel along with a new or existing match?

---

<div class="post-metadata">

**Author:** ![novabyte](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/novabyte/32/1324_2.png) [@novabyte](https://forum.heroiclabs.com/u/novabyte)\
**Post date:** [July 23, 2019, 8:09pm UTC](https://forum.heroiclabs.com/t/how-to-link-chat-and-match-together/91/2 "2019-07-23T20:09:27Z")

</div>

Hi @yudi-xiao. I have a few questions about your question 🙂

> Is there any conventional way to link match and chat channel together?

1. Should these chat messages sent over the channel be persistent or only exist while the match is active?
2. Do you use the authoritative multiplayer engine or the relayed multiplayer in the server?
3. How many users will be in the chat channel? Is it the same number who’re currently connected to the match?

---

<div class="post-metadata">

**Author:** ![yudi-xiao](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/yudi-xiao/32/45_2.png) [@yudi-xiao](https://forum.heroiclabs.com/u/yudi-xiao)\
**Post date:** [July 24, 2019, 9:30am UTC](https://forum.heroiclabs.com/t/how-to-link-chat-and-match-together/91/3 "2019-07-24T09:30:27Z")

</div>

Thanks for the reply,

1. Chat message need to be persistent on the server.
2. We tried relayed multiplayer in the server (I guess by relayed multiplayer you mean [this](https://heroiclabs.com/docs/gameplay-multiplayer-realtime/) right?)
3. Currently, we only need to consider direct chat so yes the number of users should be the same.

---

<div class="post-metadata">

**Author:** ![novabyte](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/novabyte/32/1324_2.png) [@novabyte](https://forum.heroiclabs.com/u/novabyte)\
**Post date:** [July 24, 2019, 5:04pm UTC](https://forum.heroiclabs.com/t/how-to-link-chat-and-match-together/91/4 "2019-07-24T17:04:23Z")

</div>

Thanks for the details.

> 1. We tried relayed multiplayer in the server (I guess by relayed multiplayer you mean [this](https://heroiclabs.com/docs/gameplay-multiplayer-realtime/) right?)

Yep that was the feature I meant when I referred to relayed multiplayer. The reason I asked was if you had a match handler (with the authoritative multiplayer engine) and you didn’t need to persist chat messages then you could just send those messages over the match with a specific opcode.

For your use case where you need a fully persistent chat channel to run alongside the match where players are connect the simplest approach right now would be to signal the clients to join a chat room who’s name is the same as the match ID. This way all players know from the game clients which chat channel to join after they’ve successfully joined a match.

---

<div class="post-metadata">

**Author:** ![yudi-xiao](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/yudi-xiao/32/45_2.png) [@yudi-xiao](https://forum.heroiclabs.com/u/yudi-xiao)\
**Post date:** [July 26, 2019, 2:24am UTC](https://forum.heroiclabs.com/t/how-to-link-chat-and-match-together/91/5 "2019-07-26T02:24:13Z")

</div>

I’ve considered this way, but the tricky part is we want to use chat channel as the unique id, not the match id. So that each time 2(or more) users start(or continue) a chatting session, they could check if a match has been created by the server, it does then connect to the match or create a new one otherwise. Also, we need to consider when all users have disconnected from chat/match and the match become expired.  
Is there anything that can save this information in the chat channel?  
And I’m not sure if I need to write something like RPC function in the server to handle this behaviour?

---

<div class="post-metadata">

**Author:** ![zyro](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/zyro/32/14_2.png) [@zyro](https://forum.heroiclabs.com/u/zyro)\
**Post date:** [July 31, 2019, 1:36pm UTC](https://forum.heroiclabs.com/t/how-to-link-chat-and-match-together/91/6 "2019-07-31T13:36:59Z")

</div>

I’ll assume you’ve already set up a chat channel for the users, perhaps by having them join the same chat room. We can tie this channel to a match by having a “find or create match” RPC function that will either give the user an existing match ID to join, or create a new match if that channel didn’t already have one running.

This of course means you’ll want to use the [authoritative multiplayer feature](https://heroiclabs.com/docs/gameplay-multiplayer-server-multiplayer/) to maintain match state and information you can use to look up the match.

You’ll need 2 runtime scripts. A `rpc.lua`:

```auto
local nk = require("nakama")

local function list_all(context, payload)
  -- expects input to be in the format: {"channel_id": "some room name"}
  local input = nk.json_decode(payload)
  local channel_id = input["channel_id"]

  local matches = nk.match_list(1, true, channel_id)
  if #matches == 1 then
    -- already have a match running for this channel
    return matches[1]
  end

  -- match for this channel wasn't running, start one now
  return nk.match_create("match", {channel_id = channel_id})
end

```

And a match handler we’ll call `match.lua`:

```auto
local nk = require("nakama")

local M = {}

function M.match_init(context, setupstate)
  local gamestate = {
    channel_id = setupstate["channel_id"]
  }
  local tickrate = 1
  -- put the channel identifier in the match label so other players can find it
  local label = setupstate["channel_id"]
  return gamestate, tickrate, label
end

function M.match_join_attempt(context, dispatcher, tick, state, presence, metadata)
  -- check that only users in that chat channel can join the match by checking
  -- if the user attempting to join has a presence in the chat channel's stream
  local stream_id = { mode = 2, label = state.channel_id }
  local meta = nk.stream_user_get(presence.user_id, presence.session_id, stream_id)
  local accept_user = meta ~= nil
  return state, accept_user
end

function M.match_join(context, dispatcher, tick, state, presences)
  return state
end

function M.match_leave(context, dispatcher, tick, state, presences)
  return state
end

function M.match_loop(context, dispatcher, tick, state, messages)
  -- match logic here
  return state
end

function M.match_terminate(context, dispatcher, tick, state, grace_seconds)
  return nil
end

return M

```

You can learn more about streams in the advanced documentation [here](https://heroiclabs.com/docs/advanced-streams/).

---

<div class="post-metadata">

**Author:** ![yudi-xiao](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/yudi-xiao/32/45_2.png) [@yudi-xiao](https://forum.heroiclabs.com/u/yudi-xiao)\
**Post date:** [August 3, 2019, 6:35am UTC](https://forum.heroiclabs.com/t/how-to-link-chat-and-match-together/91/7 "2019-08-03T06:35:59Z")

</div>

> [@zyro](#):
>
> – match for this channel wasn’t running, start one now return nk.match\_create(“match”, {“channel\_id” = channel\_id})

Have a syntax error at ‘=’ in

```auto
return nk.match_create("match", {"channel_id" = channel_id})

```

, i assuming changing it to

```auto
return nk.match_create("match", {["channel_id"] = channel_id})

```

should fix it.

---

<div class="post-metadata">

**Author:** ![zyro](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.heroiclabs.com/zyro/32/14_2.png) [@zyro](https://forum.heroiclabs.com/u/zyro)\
**Post date:** [August 3, 2019, 11:20am UTC](https://forum.heroiclabs.com/t/how-to-link-chat-and-match-together/91/8 "2019-08-03T11:20:30Z")

</div>

Yeah that should work too, but I’ve updated the example with an alternative syntax that should be fine.
