Opcode not getting received by the matchLoop


I am using the Lobby guide that you guys created recently, but when I send a message to the backend with an opcode then it won’t get noticed by the matchLoop and I have no clue why. It only receives the Envelope_MatchDataSend but I cannot use that in the loop.


Server version: 3.13.1+2000e4b8
@heroiclabs/nakama-js: 2.4.1

Frontend code

socket.sendMatchState(matchId, 2, "test");

Backend code

export const matchLoop: nkruntime.MatchLoopFunction = (_ctx, logger, _nk, dispatcher, _tick, state, messages) => {
  logger.info("----------------- MATCH LOOP -----------------");

  messages.forEach((message) => {
    logger.debug("------ MESSAGE ------");

    // If the message is a Ready message, update the player's isReady status and broadcast it to other players
    if (message.opCode === 2) {
      state.players[message.sender.userId].isReady = true;
      dispatcher.broadcastMessage(2, JSON.stringify({ userId: message.sender.userId }));

      // Check to see if all players are now ready
      const allReady = !Object.keys(state.players).find((userId) => !state.players[userId].isReady);

      // If all players are ready, broadcast the game starting event
      if (allReady && Object.keys(state.players).length === state.settings.requiredPlayerCount) {

  return {


[backend] {"level":"info","ts":"2022-10-20T11:14:55.813Z","caller":"server/runtime_javascript_logger.go:74","msg":"----------------- MATCH LOOP -----------------","mid":"73fc85cf-3f9d-48e1-af2e-564bbd654ff0"}
// The messages object
[backend] {"level":"debug","ts":"2022-10-20T11:14:55.814Z","caller":"server/runtime_javascript_logger.go:104","msg":"[]","mid":"73fc85cf-3f9d-48e1-af2e-564bbd654ff0"}
// The received opcode as envelope
[backend] {"level":"debug","ts":"2022-10-20T11:14:56.785Z","caller":"server/pipeline.go:65","msg":"Received *rtapi.Envelope_MatchDataSend message","uid":"a1f2c9a8-b1c9-448d-bda2-a56a44aecd5b","sid":"67112cbc-5068-11ed-92ad-006100a0eb06","message":{"MatchDataSend":{"match_id":"73fc85cf-3f9d-48e1-af2e-564bbd654ff0.nakama","op_code":1,"data":"dGVzdA=="}}}
// But sadly still no pickup of the message received, empty messages object
[backend] {"level":"info","ts":"2022-10-
20T11:14:56.813Z","caller":"server/runtime_javascript_logger.go:74","msg":"----------------- MATCH LOOP -----------------","mid":"73fc85cf-3f9d-48e1-af2e-564bbd654ff0"}
[backend] {"level":"debug","ts":"2022-10-20T11:14:56.814Z","caller":"server/runtime_javascript_logger.go:104","msg":"[]","mid":"73fc85cf-3f9d-48e1-af2e-564bbd654ff0"}

So it only receives the envelope but nothing gets picked up in the matchLoop so I can intercept it.
What am I doing wrong here? :sweat_smile:

@nick Can you double-check if you’ve correctly wired the join match step? Without it your client can send messages, but the match would never receive them.

Hi @zyro, well that’s another funny thing. With this code:

socket.onchannelpresence = async (presence) => {
  console.log({ presence });

socket.onmatchmakermatched = async (matched) => {
  matched.users.forEach((user) => {

  if (matched.match_id) await joinMatch(matched.match_id);

The onmatchmakermatched gets triggered and I can add the players to my local state, and the game starts with the players in it. But oddly enough the onchannelpresence never gets triggered.

If I log the state.presences in the matchLoop, I see all players there so I don’t know it that’s what you mean with correctly wired the join match step? Is there another way to test it? The AddPresences method in the article is just an example, right?

@nick I think you may have deviated from the Lobby Guide in a way I don’t quite follow.

socket.onchannelpresence is not expected to trigger for matches, only for chat channels. What you want is socket.onmatchpresence.

The Lobby Guide MatchInit does not have a state.presences field, so I’m not entirely sure how or where you’re using that. I can’t say what you should expect its value to be unless I know that.

Either way, what I’m talking about is the Lobby Guide’s “Joining the match” section. After matchmaking the client is expected to join the match by calling:

match = await socket.JoinMatchAsync(matchId);

Or equivalent if you’re not using the Nakama C# SDK.