Using Steamworks with UE4
Contents
Session system
In order to successfully set your game servers, you'll need to follow eXi's wiki page (How_To_Use_Sessions_In_C++) to set a basic session system in C++.
Downloading the pull request
I made a pull request on GitHub with some fixes to the engine Steam integration. You can download it here: https://github.com/EpicGames/UnrealEngine/pull/2135
Let's start
Enabling Steam Authentication
Once you have my pull request and you followed the eXi's tutorial, you can start using this system.
First you need to enable the Steam authentication. To do that, go into your gamemode class and add this in the constructor:
#if !UE_EDITOR bUseAuthentication = true; #endif
Now you should have enabled the Steam authentication into the engine code.
Setting your product name
Now you need to set the Product Name that Steam will use in the game filters. If you have a Steamworks account with an app ID, go to Edit Steamworks Settings -> Application -> Dedicated Servers and then edit the Dedicated Game Servers Information section. You can use the same value for Product Name and for Server Browser Name. When you set these parameters, click on Save, and then go to the Publish tab to publish these informations. Now on Steamworks all should be OK. Now you have to inform the Engine about the new settings. To do this, open OnlineSessionAsyncServerSteam.cpp inside Engine\Source\Runtime\Online\OnlineSubsystemSteam\Private into your UnrealEngine repository folder, then set STEAMPRODUCTNAME and STEAMGAMEDIR with the same value you entered in Steamworks, inside STEAMGAMEDESC you can enter whatever you want. Now your product name should be set. Let's go to the next step.
Registering the server on the Steam master server
To register your dedicated server on Steam, you'll need to create a session at the server launch, to do this you'll need a custom GameSession class.
Create a custom GameSession class, and then override the RegisterServer() function writing this in the header file:
virtual void RegisterServer() override;
This is an example use of the RegisterServer() function to set your server visible on Steam master server:
void AMyGameSession::RegisterServer() { IOnlineSubsystem* const OnlineSub = IOnlineSubsystem::Get(); if (OnlineSub) { IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface(); if (Sessions.IsValid()) { AMyGameMode* MyGM = Cast<AMyGameMode>(GetWorld()->GetAuthGameMode()); if (MyGM) { HostSettings = MakeShareable(new FOnlineSessionSettings(false, false, MaxPlayers)); HostSettings->Set(SETTING_GAMEMODE, FString(*MyGM->GetName()), EOnlineDataAdvertisementType::ViaOnlineService); HostSettings->Set(SETTING_MAPNAME, GetWorld()->GetMapName(), EOnlineDataAdvertisementType::ViaOnlineService); HostSettings->Set(SETTING_MATCHING_HOPPER, FString("Deathmatch"), EOnlineDataAdvertisementType::DontAdvertise); HostSettings->Set(SETTING_MATCHING_TIMEOUT, 120.0f, EOnlineDataAdvertisementType::ViaOnlineService); HostSettings->Set(SETTING_SESSION_TEMPLATE_NAME, FString("GameSession"), EOnlineDataAdvertisementType::DontAdvertise); HostSettings->bUsesPresence = false; HostSettings->bIsLANMatch = false; HostSettings->bIsDedicated = true; HostSettings->bShouldAdvertise = true; HostSettings->bAllowJoinInProgress = MyGM->bAllowJoinInProgress; HostSettings->NumPublicConnections = MaxPlayers; Sessions->CreateSession(0, GameSessionName, *HostSettings); } } } }
In this RegisterServer function, I'm getting some parameters such as GameMode or Map name from the GameMode class or from the GetWorld() function, but you can set fake parameters just to see if it works. Ok, now your server should be listed on the Steam master server, and you should be able to connect using the eXi's session system.
Custom server name
Template:Note
If you want a custom server name, simply set the GameServerName variable of the OnlineSubsystemSteam session interface, before creating the session.
For example:
Sessions->GameServerName = FString("My Server!");