- Versions: Nakama 3.21.0, (Docker), Godot 4 SDK
- Server Framework Runtime language: TS/JS
I need some help understanding how the match join works, as I observe some behavior that feels weird to me. I have this very bare bones server code in TypeScript:
const matchInit = function (
ctx: nkruntime.Context,
logger: nkruntime.Logger,
nk: nkruntime.Nakama,
params: { [key: string]: string }
): { state: nkruntime.MatchState; tickRate: number; label: string } {
logger.debug('Lobby match created');
return {
state: { Debug: true, presences: {} },
tickRate: 1,
label: ''
};
};
const matchJoinAttempt = function (
ctx: nkruntime.Context,
logger: nkruntime.Logger,
nk: nkruntime.Nakama,
dispatcher: nkruntime.MatchDispatcher,
tick: number,
state: nkruntime.MatchState,
presence: nkruntime.Presence,
metadata: { [key: string]: any }
): { state: nkruntime.MatchState; accept: boolean; rejectMessage?: string | undefined } | null {
logger.debug('%q attempted to join Lobby match', ctx.userId);
return {
state,
accept: true
};
};
const matchJoin = function (
ctx: nkruntime.Context,
logger: nkruntime.Logger,
nk: nkruntime.Nakama,
dispatcher: nkruntime.MatchDispatcher,
tick: number,
state: nkruntime.MatchState,
presences: nkruntime.Presence[]
): { state: nkruntime.MatchState } | null {
logger.debug('Presence %s', JSON.stringify(presences));
for (const presence of presences) {
state.presences[presence.userId] = presence;
logger.debug('%q joined Lobby match', presence.userId);
}
logger.debug('State %s', JSON.stringify(state));
return { state };
};
const matchLeave = function (
ctx: nkruntime.Context,
logger: nkruntime.Logger,
nk: nkruntime.Nakama,
dispatcher: nkruntime.MatchDispatcher,
tick: number,
state: nkruntime.MatchState,
presences: nkruntime.Presence[]
): { state: nkruntime.MatchState } | null {
presences.forEach(function (presence) {
state.presences[presence.userId] = presence;
logger.debug('%q left Lobby match', presence.userId);
});
return {
state
};
};
const matchLoop = function (
ctx: nkruntime.Context,
logger: nkruntime.Logger,
nk: nkruntime.Nakama,
dispatcher: nkruntime.MatchDispatcher,
tick: number,
state: nkruntime.MatchState,
messages: nkruntime.MatchMessage[]
): { state: nkruntime.MatchState } | null {
logger.debug('Lobby match loop executed');
logger.debug('State %s', JSON.stringify(state));
return { state };
};
const matchSignal = function (
ctx: nkruntime.Context,
logger: nkruntime.Logger,
nk: nkruntime.Nakama,
dispatcher: nkruntime.MatchDispatcher,
tick: number,
state: nkruntime.MatchState,
data: string
): { state: nkruntime.MatchState; data?: string } | null {
logger.debug('Lobby match signal received: ' + data);
return {
state,
data: 'Lobby match signal received: ' + data
};
};
const matchTerminate = function (
ctx: nkruntime.Context,
logger: nkruntime.Logger,
nk: nkruntime.Nakama,
dispatcher: nkruntime.MatchDispatcher,
tick: number,
state: nkruntime.MatchState,
graceSeconds: number
): { state: nkruntime.MatchState } | null {
logger.debug('Lobby match terminated');
return {
state
};
};
function matchmakerMatched(
context: nkruntime.Context,
logger: nkruntime.Logger,
nk: nkruntime.Nakama,
matches: nkruntime.MatchmakerResult[]
): string {
matches.forEach(function (match) {
logger.info("Custom Matched user '%s' named '%s'", match.presence.userId, match.presence.username);
Object.keys(match.properties).forEach(function (key) {
logger.info("Matched on '%s' value '%s'", key, match.properties[key]);
});
});
try {
const matchId = nk.matchCreate('lobby', { invited: 'test' });
return matchId;
} catch (err) {
logger.error(err as any);
throw err;
}
}
When I launch two game clients and join a match I receive the following objects on the client side from joinMatchedAsync
:
Client 1:
Match<authoritative=true, match_id=40edce82-70e5-44f2-8e50-1966ebd2b44d.nakama1, label=, presences=[], size=0, self=UserPresence<persistence=false, session_id=5436d264-1ffa-11ef-91b8-7106fdcb5b46, status=, username=Shamshiel, user_id=ea1401d5-ab1c-4ad9-9ae2-e0410c7b87b3>>
Client 2:
Match<authoritative=true, match_id=40edce82-70e5-44f2-8e50-1966ebd2b44d.nakama1, label=, presences=[UserPresence<persistence=false, session_id=5436d264-1ffa-11ef-91b8-7106fdcb5b46, status=, username=Shamshiel, user_id=ea1401d5-ab1c-4ad9-9ae2-e0410c7b87b3>], size=1, self=UserPresence<persistence=false, session_id=56b40b80-1ffa-11ef-91b8-7106fdcb5b46, status=, username=WtpzVJhcyQ, user_id=731c67bf-4794-4fc2-b604-2be4cf1168e5>>
I would have assumed that both clients receive a response with the presences in the match but for some reason only one gets both and the other one zero,
Is that normal behaviour? If yes, what would be the preferred way for both clients to get the information who is in the match so I can display details about them?