OSSv2 and Steam Invite to Play

When using OSSv2, I’m unclear what is triggering FLobbiesEOSGS::HandleJoinLobbyAccepted, when a steam invite is accepted.

It appears that the steam FOnlineAsyncTaskManagerSteam::OnInviteAccepted is getting called, but it effectively does nothing (the search never succesfully runs or correctly terminate). Even still it doesn’t look like it matters, because EOS_Lobby_AddNotifyJoinLobbyAccepted gets called, I assume from within the EOS SDK?

It seems to have the correct information for the lobby, but how does this work? Where is the data coming from since the steam invite looks like it only has steam relevant data

I ask because want to support a proprietary OSS InviteToPlay flow, but I don’t see how they mapped the steam invite to an invite that the LobbiesEOSGS callback can use

[Attachment Removed]

Actually, just to back it up one more step, how does steam lobby presence get updated with OSSv2?

Is there documentation somewhere I can reference? It looks like it is connected to the FCreateLobby::Params.bPresenceEnabled

but I can’t find how it actually does the presence update

[Attachment Removed]

Hey, with native platform integration, when a Steam invite is accepted the EOS SDK will call the function bound in EOS_Lobby_AddNotifyJoinLobbyAccepted (or EOS_Sessions_AddNotifyJoinSessionAccepted if sessions are used). The native platform integration will also handle EOS presence mirroring to the base platform (Steam) for you. I recommend reading over the features provided by our native platform integration here.

[Attachment Removed]

I tried to look through that documentation but it didn’t really talk about how it does these things for Steam. For example, we have these settings in our ini

[OnlineServices]
DefaultServices=Epic
PlatformServices=Steam
 
[EOSSDK]
bEnablePlatformIntegration=true
bEnableOverlayIntegration=true
+IntegratedPlatformManagementFlags=LibraryManagedByApplication
 
[OnlineServices.OSSAdapter]
+Services=(Service="Steam",ConfigName="Steam",OnlineSubsystem="Steam",Priority=1000)

Can you expand on what bEnablePlatformIntegration itself does?

It looks like it is necessary to get things like a steam overlay to function, but how does it initialize steam?

When I set it (and only it) to false, the steam init code still gets run, but suddenly the steam overlay doesn’t work anymore, I don’t see why that would happen.

If I have a new custom service, how would the EOSSDK call the custom platform’s initialization functions?

How would it mirror presence?

For instance, w/ OSSv1, I would have to use EOSPlus which would then call the base interface, and the platform interface, but I don’t see any kind of equivalent for OSSv2 where I could implement a custom OSS behaviour

[Attachment Removed]

Looking around some more, I see that there is custom UE_WITH_EOS_STEAM_INTEGRATION for the EOS SDK.

Is that handling the custom integration with steam?

If I want to support a custom windows based platform integration, is there any documentation I can look at to know what delegates/functions I need to support?

For example, if I wanted to mirror presence for this new platform, I don’t see any callback or function to implement to do that

[Attachment Removed]

bEnablePlatformIntegration and the IntegratedPlatformManagementFlags control whether or not the SDK will natively integrated with Steam. We don’t have much documentation on the inner workings, but we do have an explanation of what each of the flags do in the header eos_integratedplatform_types.h. You can find this header in Engine\Source\ThirdParty\EOSSDK\SDK\Include.

The UE_WITH_EOS_STEAM_INTEGRATION is present to load the SteamShared module when native platform integration is available, ensuring the correct ordering of module load on startup and unload on shutdown.

The Steam overlay issue you described is unexpected. I’d expect the Steam overlay to work regardless of native platform integration. Can you share the logs for when the overlay works and when it doesn’t?

The SDK will call Steam APIs to mirror specific features, such as presence and invites. If you want to mirror to another platform, you can bind EOS_Lobby_AddNotifyJoinLobbyAccepted (or EOS_Sessions_AddNotifyJoinSessionAccepted if sessions are used) for invites, and EOS_Presence_AddNotifyOnPresenceChanged for presence.

[Attachment Removed]

Overlay

[Attachment Removed]

NoOverlay

[Attachment Removed]

The SDK will call Steam APIs to mirror specific features, such as presence and invites. If you want to mirror to another platform, you can bind EOS_Lobby_AddNotifyJoinLobbyAccepted (or EOS_Sessions_AddNotifyJoinSessionAccepted if sessions are used) for invites, and EOS_Presence_AddNotifyOnPresenceChanged for presence.Isn’t this only part of the answer?

For steam, I can’t tell where, but my understanding is that the EOS SDK natively listens for OnInviteAccepted, effectively does this line:

STEAM_CALLBACK(FOnlineAsyncTaskManagerSteam, OnInviteAccepted, GameRichPresenceJoinRequested_t, OnInviteAcceptedCallback);

but done in the EOS SDK somewhere. Then, it maps the callback data to an EOS Lobby ID which it passes back up to the notifyLobbyInviteAccepted data.

If we were to make a custom Platform Integration, I would think that I need to do my own delegate binding to our version of InviteAccepted, and then somehow trigger the NotifyLobbyInviteAccepted so that the existing listener EOS_Lobby_AddNotifyLobbyInviteAccepted can be triggered. That, then triggers the EOS lobby to be joined, and then finally we can mirror the join onto the custom platform integration.

Is that correct? We would need create a custom function for our InviteAccepted (which maps the platforms invite data to some EOS Lobby data), and also a custom function to mirror the join onto the platform lobby

[Attachment Removed]

The EOS SDK listens to the Steam SDK callback GameRichPresenceJoinRequested_t, not the UE STEAM_CALLBACK. I’m not sure if this is what was meant by “effectively does this line”.

You can’t trigger the EOS SDK NotifyLobbyInviteAccepted, it will get done automatically when GameRichPresenceJoinRequested_t fires within the SDK. You can’t instead use the EOS SDK NotifyLobbyInviteAccepted for your custom platform integration? That callback fires the UE OSSv2 event OnUILobbyJoinRequested.

If you can share a bit more about your custom platform integration and the end result, I might be able to offer some options. Thanks!

[Attachment Removed]

I think we’re saying the same thing for the first portion. In OnlineAsyncTaskManagerSteam.h

STEAM_CALLBACK(FOnlineAsyncTaskManagerSteam, OnInviteAccepted, GameRichPresenceJoinRequested_t, OnInviteAcceptedCallback);coupled with

OnInviteAcceptedCallback(this, &FOnlineAsyncTaskManagerSteam::OnInviteAccepted),

binds onto Steam’s events (the one that creates the data inside of GameRichPresenceJoinRequested_t).

My understanding is that with OSSv1, OnlineAsyncTaskManagerSteam handles binding to that callback inside the Unreal Engine. It creates FOnlineAsyncEventSteamInviteAccepted, which searches for the friend session, which eventually returns back to EOSPlus which maps that found session to the EOSSessionID

I wanted verification that with OSSv2, the EOS SDK handles that steam event internally, and it maps the data in

struct GameRichPresenceJoinRequested_t
{
	enum { k_iCallback = k_iSteamFriendsCallbacks + 37 };
	CSteamID m_steamIDFriend;		// the friend they did the join via (will be invalid if not directly via a friend)
	char m_rgchConnect[k_cchMaxRichPresenceValueLength];
};

to an EOSLobbyID, and then triggers NotifyLobbyInviteAccepted.

If that was true, does that meant we have to replicate that functionality with our custom platform OSS?

The effect we’re trying to replicate is:

Player1 and Player2 are playing our game in seperate lobbies (or not in a lobby at all)

Player1 uses the custom platform UI to invite Player2 to play.

This triggers an EOS lobby and a mirrored Platform lobby (done proprietarily) to be created

After that is done, custom platform library sends event from Player1 to Player2 with proprietary platform lobby data

Custom platform library on Player2 triggers the event: OnInvited(Player1’s PlatformLobbyData)

This is the point where we’re at now, but Player2 cannot join the game yet, because they don’t have the EOS lobby.

They would first have to map that Player1 Lobby data to the EOS lobby, and then somehow trigger NotifyLobbyInviteAccepted (which it sounds like we can’t so we’d have to call the same OnLobbyInviteAccepted) so they can join that.

I wanted to get confirmation on the above^

[Attachment Removed]

Hey, I can’t share EOS SDK code, but the flow in the SDK is that when GameRichPresenceJoinRequested_t fires, the SDK checks the connection string stored in m_rgchConnect. The connection string consists of:

  • -EOSInvite
  • 3 characters that indicate version and whether the invite is for a lobby, a session, or a custom invite
  • The sessionId OR LobbyId OR custom invite payload.

For a lobby, the connection string passed via GameRichPresenceJoinRequested_t would be -EOSInvite=01L{LobbyId}. The SDK then triggers the correct callback, EOS_Lobby_AddNotifyJoinLobbyAccepted for lobbies. You can retrieve the lobby ID via EOS_Lobby_CopyLobbyDetailsHandleByUiEventId and EOS_LobbyDetails_CopyInfo.

For your custom platform, I wonder if you can also listen to GameRichPresenceJoinRequested_t? I’m not sure if we can guarantee the m_rgchConnect value will remain the same across SDK versions, but that is something I can ask the developers.

[Attachment Removed]

yah, that makes sense. Just for clarification, our custom OSS would be replacing Steam in our scenario. So we would be using an EOS lobby and our base custom platform. The platforms invite will have to mimic steam’s invite flow but instead of relying on the EOS SDK to handle, we will have to ensure the invite contains the correct lobbyID information (similar to the steam invite)

[Attachment Removed]