How would I setup AGameSession on a dedicated server, using ShooterGame as an example?

So, I’ve been attempting to transplant the onlinesubsystem code from ShooterGame to our fledgling prototype so that I can as a first pass find games on the LAN and list them. After much swearing I’ve given up on our code and gone back to the ShooterGame itself to try and sanity check what I’m doing.

As far as I can tell, the dedicated server never actually properly spins up an AGameSession (or in this case an AShooterGameSession) object. One gets created when BeginPlay happens (via the AGameMode::InitGame(), etc.) but nothing ever gets called to actually do anything with it as far as I can see, in particular the LAN beacon handling.

Am I missing something here - the consequence of this for me is that I can connect via a direct IP connection, but searching using the Join option in the menu never finds the game - presumably because the LAN beacon handling isn’t up and running.

Any pointers gratefully received.

Hi ,

No, you’re not missing anything. This particular flow in ShooterGame hasn’t been implemented yet. Essentially the reason the dedicated server is not advertising is that it never creates an online subsystem session (which is distinct form the AGameSession hierarchy). The Null online subsystem session is what manages the LAN beacon, so without a session there’s no way to discover the game on the LAN. A listen server should show up correctly in the join game list.

We would like to provide a sample in the future where this does work, but if you want to try setting this up yourself, the starting point would be to override RegisterServer in an AGameSession subclass and create an online subsystem session (IOnlineSession::CreateSession) there.

Thanks Ryan, that was pretty simple once I knew where to put the code. When we get some proper online subsystem documentation I think some flow charts will help a lot :slight_smile:

I have a question on this specific topic.
I override the RegisterServer() function, but it is never called.
I’ve checked the code and the RegisterServer() is called in UWorld::InitializeActorsForPlay(const FURL& InURL, bool bResetTime).
// Spawn server actors
ENetMode CurNetMode = GEngine != NULL ? GEngine->GetNetMode(this) : NM_Standalone;

		if (CurNetMode == NM_ListenServer || CurNetMode == NM_DedicatedServer)
		{
			GEngine->SpawnServerActors(this);
		}

		// Init the game mode.
		if (AuthorityGameMode && !AuthorityGameMode->bActorInitialized)
		{
			AuthorityGameMode->InitGame( FPaths::GetBaseFilename(InURL.Map), Options, Error );
		}

But this function is never called ?
Did you call explicitely RegisterServer() and where ?

D.

I’ve successfully setup a dedicated server by lifting code from AShooterGameSession::HostSession for AShooterGameSession::RegisterServer:

    const int MaxNumPlayers = 128;
    const bool bIsPresence = true;
    const bool bIsLAN = true;
    const int HostingPlayerNum = 0;
    const FString GameType = "FFA";
    const FString MapName = "Sanctuary"; //< TODO: Get actual name.
    const auto UserId = MakeShareable(new FUniqueNetIdString(FString::Printf(TEXT("%d"), HostingPlayerNum)));

    IOnlineSubsystem* const OnlineSub = IOnlineSubsystem::Get();
    if (OnlineSub)
    {
        ...
    }

AGameSession::RegisterServer only gets called when the game starts up, which, at least on the 4.8 version of ShooterGame seems to require you to run ShooterGameServer.exe with a specific map, for instance by specifying ‘/Game/Maps/Highrise’ on the command-line.

(This answer is probably too late to be useful, but I include it here to have a plug-and-play solution for ShooterGame and dedicated servers with 4.8 - this might have been resolved in the 4.9 version.)