This section describes the process of having friends join matchmaking sessions.
When using the friend presence library, the local station can share with friends information about the sessions it has joined and whether a session is accepting more stations. Other stations can specify the shared session information in PiaSession to join that session. There are two types of friend join-ins: joining the session of a friend playing the same game, and joining the session of a friend from the HOME Menu Friend List.
For more information about the friend presence library, see Presence Feature in the CTR Programming Manual. For more information about the join-in feature, see Joining in Using the Friend Presence Library in the Matchmaking chapter of the NEX Programming Manual: Server Services.
Friend join-in matchmaking is not supported during local communication.
Create the session after setting nn::pia::inet::SessionType_Friend to nn::pia::inet::NexCreateSessionSetting::SetSessionType().
Sessions for joining friends automatically end the join process during host migration to avoid letting players who do not have a friend relationship join after host migration.
You can share the game mode using the friend presence library. The game mode includes the session ID and other session information, in addition to a flag indicating whether the session is joinable.
Update the presence information as the game progresses.
// Game mode shared with presence.
nn::friends::GameMode gameMode; // Set the game mode to a value from 0 through 63 to link it with friend presence. gameMode.joinGameMode = FRIENDS_MATCHMAKE_GAME_MODE; // Set the matchmaking system type for the session. gameMode.matchmakeSystemType = nn::nex::MATCHMAKE_SYSTEM_TYPE_FRIEND; // Set the session ID in the group ID. gameMode.joinGroupId = nn::pia::session::Session::GetInstance()->GetSessionId(); // Get the host station instance to get the principal ID of the session host passed from NEX. nn::pia::StationId hostStationId = nn::pia::session::Session::GetInstance()->GetHostStationId(); nn::pia::transport::Station* pHostStation = nn::pia::transport::StationManager::GetInstance()->GetStation(hostStationId); // Get and set the principal ID of the session host. pHostStation->GetPrincipalId(&gameMode.ownerPrincipalId); // Set the flag that indicates whether the session is joinable. gameMode.joinAvailabilityFlag = nn::friends::JOIN_AVAILABILITY_JOINABLE; // String shared with presence. const wchar_t* DESCRIPTION = L"Available now"; // Update the presence. nn::Result result = nn::friends::UpdateGameMode(gameMode, DESCRIPTION); if (result.IsFailure()) { u32 errorCode = nn::friends::ResultToErrorCode(result); // Error handling. } |
If a friend is playing a game online, you can use friend presence to get join-in session information while running a game with the same join-in game ID.
For more information about setting the join-in game ID, see the implementation section under Joining in Using the Friend Presence Library in the Matchmaking chapter of the NEX Programming Manual: Server Services.
size_t friendsNum = 0;
nn::friends::FriendKey friendIdList[FRIENDS_LIST_MAX]; nn::friends::FriendPresence friendPresenceList[FRIENDS_LIST_MAX]; // Get the friend presence list. nn::friends::GetFriendKeyList(friendIdList, &friendsNum, 0, FRIENDS_LIST_MAX); nn::friends::GetFriendPresence(friendPresenceList, friendIdList, friendsNum); // Check whether the retrieved presence is joinable. for (size_t i = 0; i < friendsNum; i++) { if (friendPresenceList[i].isOnline && friendPresenceList[i].IsJoinable(FRIENDS_MATCHMAKE_GAME_MODE_MASK)) { // Joinable. } } |
If a friend is playing a joinable game, players can start the game that the friend is playing from the Friend List in the HOME Menu.
When a game is started from the Friend List, you can determine whether the game was started from the Friend List and the friend that was selected when the game was started. If you detect that the game was started from the Friend List, you can get the presence of the selected friend and join in that friend's session.
// Determine whether the game was started from the friend list.
isFromFriendList = false; nn::friends::FriendKey friendIdForJoinIn; nn::friends::FrinedPresence friendPresenceForJoinIn; if (nn::friends::IsFromFriendList(&friendIdForJoinIn)) { // Started from the friend list. isFromFriendList = true; // Get friend presence. nn::friends::GetFriendPresence(&friendPresenceForJoinIn, &friendIdForJoinIn); // Check whether the retrieved presence is joinable. if (friendPresenceForJoinIn.isOnline && friendPresenceForJoinIn.IsJoinable(FRIENDS_MATCHMAKE_GAME_MODE_MASK)) { // Joinable. } } |
If the presence retrieved by the friend presence library is determined to be joinable, you can join a friend's session using the game mode of the presence.
However, it might not be possible to join even if the presence is shown as joinable because the presence does not necessarily show the correct state in real time.
// Settings for joining a session.
nn::pia::inet::NexJoinSessionSetting joinSessionSetting; // Copy the join-in session ID for a joinable presence game mode to the settings for joining a session. joinSessionSetting.SetSessionId(friendPresence.gameMode.joinGroupId); // Start the asynchronous process of joining a session. result = nn::pia::session::Session::GetInstance()->JoinSessionAsync(&joinSessionSetting); if (result.IsFailure()) { // Error processing. } // If the asynchronous process has started successfully, you must call the dispatch function periodically and wait for the asynchronous process to proceed. while (nn::pia::session::Session::GetInstance()->IsCompletedJoinSession() == false) { nn::nex::Scheduler::GetInstance()->DispatchAll(); nn::pia::common::Scheduler::GetInstance()->Dispatch(); } // Check the result of the asynchronous process. result = nn::pia::session::Session::GetInstance()->GetJoinSessionResult(); if (result.IsFailure()) { // Error processing. } /* If the asynchronous process succeeds, the station will successfully join the friend's session and be able to communicate with the other stations. */ |