Session -no override available for virtual member function from base 'UGameInstance'; function is hidden- problem

I followed eXi’s How To Use Sessions In C++ Wiki Tutorial to implement the online session system in my game but it gives me this error, it compiles but I don’t know where is the error coming from

log file

the LobbyGameMode includes the WaveGameInstance so the problem must be there

here is my WaveGameInstance code

.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Engine/GameInstance.h"
#include "WaveGameInstance.generated.h"

/**
 * 
 */

USTRUCT(BlueprintType)
struct FSessionDisplayInfo
{
	GENERATED_BODY()

		//Always make USTRUCT variables into UPROPERTY()
		//    any non-UPROPERTY() struct vars are not replicated

		// So to simplify your life for later debugging, always use UPROPERTY()
		UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SessionDisplay)
		int32 SessionIndex;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SessionDisplay)
		FText SessionName;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SessionDisplay)
		int32 CurrentPlayers;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SessionDisplay)
		int32 MaxPlayers;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = SessionDisplay)
		int32 Ping;

	//Constructor
	FSessionDisplayInfo()
	{
		//Always initialize your USTRUCT variables!
		//   exception is if you know the variable type has its own default constructor

		SessionIndex = 0;
		CurrentPlayers = 0;
		MaxPlayers = 0;
		Ping = 0;

	}
};

UCLASS()
class WAVE_API UWaveGameInstance : public UGameInstance
{
	GENERATED_BODY()
	


		UWaveGameInstance(const FObjectInitializer& ObjectInitializer);

		/**
		*  Function to host a game!
		*
		*  @Param    UserID      User that started the request
		*  @Param    SessionName    Name of the Session
		*  @Param    bIsLAN      Is this is LAN Game?
		*  @Param    bIsPresence    "Is the Session to create a presence Session"
		*  @Param    MaxNumPlayers          Number of Maximum allowed players on this "Session" (Server)
		*/
		bool HostSession(TSharedPtr<const FUniqueNetId> UserId, FName SessionName, bool bIsLAN, bool bIsPresence, int32 MaxNumPlayers);

		/* Delegate called when session created */
		FOnCreateSessionCompleteDelegate OnCreateSessionCompleteDelegate;
		/* Delegate called when session started */
		FOnStartSessionCompleteDelegate OnStartSessionCompleteDelegate;
		/** Handles to registered delegates for creating/starting a session */
		FDelegateHandle OnCreateSessionCompleteDelegateHandle;
		FDelegateHandle OnStartSessionCompleteDelegateHandle;

		/**
		*  Function fired when a session create request has completed
		*
		*  @param SessionName the name of the session this callback is for
		*  @param bWasSuccessful true if the async action completed without error, false if there was an error
		*/
		virtual void OnCreateSessionComplete(FName SessionName, bool bWasSuccessful);
		/**
		*  Function fired when a session start request has completed
		*
		*  @param SessionName the name of the session this callback is for
		*  @param bWasSuccessful true if the async action completed without error, false if there was an error
		*/
		void OnStartOnlineGameComplete(FName SessionName, bool bWasSuccessful);

		/**
		*	Find an online session
		*
		*	@param UserId user that initiated the request
		*	@param SessionName name of session this search will generate
		*	@param bIsLAN are we searching LAN matches
		*	@param bIsPresence are we searching presence sessions
		*/
		virtual void FindSessions(TSharedPtr<const FUniqueNetId> UserId, FName SessionName, bool bIsLAN, bool bIsPresence);

		/** Delegate for searching for sessions */
		FOnFindSessionsCompleteDelegate OnFindSessionsCompleteDelegate;

		/** Handle to registered delegate for searching a session */
		FDelegateHandle OnFindSessionsCompleteDelegateHandle;

		/**
		*	Delegate fired when a session search query has completed
		*
		*	@param bWasSuccessful true if the async action completed without error, false if there was an error
		*/
		void OnFindSessionsComplete(bool bWasSuccessful);

		/**
		*	Joins a session via a search result
		*
		*	@param SessionName name of session
		*	@param SearchResult Session to join
		*
		*	@return bool true if successful, false otherwise
		*/
		bool JoinSession(TSharedPtr<const FUniqueNetId> UserId, FName SessionName, const FOnlineSessionSearchResult& SearchResult);

		/** Delegate for joining a session */
		FOnJoinSessionCompleteDelegate OnJoinSessionCompleteDelegate;

		/** Handle to registered delegate for joining a session */
		FDelegateHandle OnJoinSessionCompleteDelegateHandle;

		/**
		*	Delegate fired when a session join request has completed
		*
		*	@param SessionName the name of the session this callback is for
		*	@param bWasSuccessful true if the async action completed without error, false if there was an error
		*/
		void OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result);

		/** Delegate for destroying a session */
		FOnDestroySessionCompleteDelegate OnDestroySessionCompleteDelegate;

		/** Handle to registered delegate for destroying a session */
		FDelegateHandle OnDestroySessionCompleteDelegateHandle;

		/**
		*	Delegate fired when a destroying an online session has completed
		*
		*	@param SessionName the name of the session this callback is for
		*	@param bWasSuccessful true if the async action completed without error, false if there was an error
		*/
		virtual void OnDestroySessionComplete(FName SessionName, bool bWasSuccessful);

public:

		UFUNCTION(BlueprintCallable, Category = "Network|Test")
		void StartOnlineGame(bool bIsLanMatch, int32 MaxPlayers);

		UFUNCTION(BlueprintCallable, Category = "Network|Test")
		void  FindOnlineGames(bool bIsLanMatch);

		UFUNCTION(BlueprintCallable, Category = "Network|Test")
		void JoinOnlineGame(int32 SessionIndex);

		UFUNCTION(BlueprintCallable, Category = "Network|Test")
		void DestroySessionAndLeaveGame();

		UFUNCTION(BlueprintImplementableEvent, Category = "Network|Test")
		void UpdateServerList();

		UFUNCTION(BlueprintCallable, Category = "Network|Test")
		FORCEINLINE TArray<FSessionDisplayInfo> GetSessionsDisplayInfo() { return SessionUMGDiplayInfo; }

		UFUNCTION(BlueprintCallable, Category = "Network|Test")
		void SetPlayerNickname(FString Nickname);

		FORCEINLINE FString GetPlayerNickname() { return PlayerNickname; }


private:

		TSharedPtr<class FOnlineSessionSettings> SessionSettings;
	
		TSharedPtr<class FOnlineSessionSearch> SessionSearch;

		UPROPERTY(EditDefaultsOnly)
		FName MainMenuMapName;

		UPROPERTY(EditDefaultsOnly)
		FName LobbyMapName;

		TArray<FSessionDisplayInfo> SessionUMGDiplayInfo;

		FString PlayerNickname;

		//UPROPERTY(EditDefaultsOnly)
		//uint32 bIsLanMatch : 1;
};

.cpp

// Fill out your copyright notice in the Description page of Project Settings.

#include "Wave.h"
#include "WaveGameInstance.h"

UWaveGameInstance::UWaveGameInstance(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	/** Bind function for CREATING a Session */
	OnCreateSessionCompleteDelegate = FOnCreateSessionCompleteDelegate::CreateUObject(this, &UWaveGameInstance::OnCreateSessionComplete);
	OnStartSessionCompleteDelegate = FOnStartSessionCompleteDelegate::CreateUObject(this, &UWaveGameInstance::OnStartOnlineGameComplete);

	/** Bind function for FINDING a Session */
	OnFindSessionsCompleteDelegate = FOnFindSessionsCompleteDelegate::CreateUObject(this, &UWaveGameInstance::OnFindSessionsComplete);

	/** Bind function for JOINING a Session */
	OnJoinSessionCompleteDelegate = FOnJoinSessionCompleteDelegate::CreateUObject(this, &UWaveGameInstance::OnJoinSessionComplete);

	/** Bind function for DESTROYING a Session */
	OnDestroySessionCompleteDelegate = FOnDestroySessionCompleteDelegate::CreateUObject(this, &UWaveGameInstance::OnDestroySessionComplete);

	MainMenuMapName = "MainMenu";

	LobbyMapName = "Lobby";

	PlayerNickname = TEXT("Player");

	//bIsLanMatch = true;
}

bool UWaveGameInstance::HostSession(TSharedPtr<const FUniqueNetId> UserId, FName SessionName, bool bIsLAN, bool bIsPresence, int32 MaxNumPlayers)
{
	// Get the Online Subsystem to work with
	IOnlineSubsystem* const OnlineSub = IOnlineSubsystem::Get();

	if (OnlineSub)
	{
		// Get the Session Interface, so we can call the "CreateSession" function on it
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();

		if (Sessions.IsValid() && UserId.IsValid())
		{
			/*
			Fill in all the Session Settings that we want to use.

			There are more with SessionSettings.Set(...);
			For example the Map or the GameMode/Type.
			*/
			SessionSettings = MakeShareable(new FOnlineSessionSettings());

			SessionSettings->bIsLANMatch = bIsLAN;
			SessionSettings->bUsesPresence = bIsPresence;
			SessionSettings->NumPublicConnections = MaxNumPlayers;
			SessionSettings->NumPrivateConnections = 0;
			SessionSettings->bAllowInvites = true;
			SessionSettings->bAllowJoinInProgress = true;
			SessionSettings->bShouldAdvertise = true;
			SessionSettings->bAllowJoinViaPresence = true;
			SessionSettings->bAllowJoinViaPresenceFriendsOnly = false;

			//SessionSettings->Set(SETTING_MAPNAME, FString("NewMap"), EOnlineDataAdvertisementType::ViaOnlineService);

			//SessionSettings->Set(SETTING_MAPNAME, LobbyMapName, EOnlineDataAdvertisementType::ViaOnlineService);

			// Set the delegate to the Handle of the SessionInterface
			OnCreateSessionCompleteDelegateHandle = Sessions->AddOnCreateSessionCompleteDelegate_Handle(OnCreateSessionCompleteDelegate);

			// Our delegate should get called when this is complete (doesn't need to be successful!)
			return Sessions->CreateSession(*UserId, SessionName, *SessionSettings);
		}
	}
	else
	{
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("No OnlineSubsytem found!"));
	}

	return false;
}

void UWaveGameInstance::OnCreateSessionComplete(FName SessionName, bool bWasSuccessful)
{
	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("OnCreateSessionComplete %s, %d"), *SessionName.ToString(), bWasSuccessful));

	// Get the OnlineSubsystem so we can get the Session Interface
	IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
	if (OnlineSub)
	{
		// Get the Session Interface to call the StartSession function
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();

		if (Sessions.IsValid())
		{
			// Clear the SessionComplete delegate handle, since we finished this call
			Sessions->ClearOnCreateSessionCompleteDelegate_Handle(OnCreateSessionCompleteDelegateHandle);
			if (bWasSuccessful)
			{
				// Set the StartSession delegate handle
				OnStartSessionCompleteDelegateHandle = Sessions->AddOnStartSessionCompleteDelegate_Handle(OnStartSessionCompleteDelegate);

				// Our StartSessionComplete delegate should get called after this
				Sessions->StartSession(SessionName);
			}
		}

	}
}

void UWaveGameInstance::OnStartOnlineGameComplete(FName SessionName, bool bWasSuccessful)
{
	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("OnStartSessionComplete %s, %d"), *SessionName.ToString(), bWasSuccessful));

	// Get the Online Subsystem so we can get the Session Interface
	IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
	if (OnlineSub)
	{
		// Get the Session Interface to clear the Delegate
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();
		if (Sessions.IsValid())
		{
			// Clear the delegate, since we are done with this call
			Sessions->ClearOnStartSessionCompleteDelegate_Handle(OnStartSessionCompleteDelegateHandle);
		}
	}

	// If the start was successful, we can open a NewMap if we want. Make sure to use "listen" as a parameter!
	if (bWasSuccessful)
	{
		//UGameplayStatics::OpenLevel(GetWorld(), "NewMap", true, "listen");
		UGameplayStatics::OpenLevel(GetWorld(), LobbyMapName, true, "listen");
	}
}

void UWaveGameInstance::FindSessions(TSharedPtr<const FUniqueNetId> UserId, FName SessionName, bool bIsLAN, bool bIsPresence)
{

	// Get the OnlineSubsystem we want to work with
	IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();

	if (OnlineSub)
	{
		// Get the SessionInterface from our OnlineSubsystem
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();

		if (Sessions.IsValid() && UserId.IsValid())
		{
			/*
			Fill in all the SearchSettings, like if we are searching for a LAN game and how many results we want to have!
			*/
			SessionSearch = MakeShareable(new FOnlineSessionSearch());

			SessionSearch->bIsLanQuery = bIsLAN;
			SessionSearch->MaxSearchResults = 20;
			SessionSearch->PingBucketSize = 50;

			// We only want to set this Query Setting if "bIsPresence" is true
			if (bIsPresence)
			{
				SessionSearch->QuerySettings.Set(SEARCH_PRESENCE, bIsPresence, EOnlineComparisonOp::Equals);
			}

			TSharedRef<FOnlineSessionSearch> SearchSettingsRef = SessionSearch.ToSharedRef();

			// Set the Delegate to the Delegate Handle of the FindSession function
			OnFindSessionsCompleteDelegateHandle = Sessions->AddOnFindSessionsCompleteDelegate_Handle(OnFindSessionsCompleteDelegate);

			// Finally call the SessionInterface function. The Delegate gets called once this is finished
			Sessions->FindSessions(*UserId, SearchSettingsRef);
		}
	}
	else
	{
		// If something goes wrong, just call the Delegate Function directly with "false".
		OnFindSessionsComplete(false);
	}

}

void UWaveGameInstance::OnFindSessionsComplete(bool bWasSuccessful)
{
	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("OFindSessionsComplete bSuccess: %d"), bWasSuccessful));

	// Get OnlineSubsystem we want to work with
	IOnlineSubsystem* const OnlineSub = IOnlineSubsystem::Get();
	if (OnlineSub)
	{
		// Get SessionInterface of the OnlineSubsystem
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();
		if (Sessions.IsValid())
		{
			// Clear the Delegate handle, since we finished this call
			Sessions->ClearOnFindSessionsCompleteDelegate_Handle(OnFindSessionsCompleteDelegateHandle);

			// Just debugging the Number of Search results. Can be displayed in UMG or something later on
			GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Num Search Results: %d"), SessionSearch->SearchResults.Num()));

			// If we have found at least 1 session, we just going to debug them. You could add them to a list of UMG Widgets, like it is done in the BP version!
			if (SessionSearch->SearchResults.Num() > 0)
			{
				// "SessionSearch->SearchResults" is an Array that contains all the information. You can access the Session in this and get a lot of information.
				// This can be customized later on with your own classes to add more information that can be set and displayed
				for (int32 SearchIdx = 0; SearchIdx < SessionSearch->SearchResults.Num(); SearchIdx++)
				{
					// OwningUserName is just the SessionName for now. I guess you can create your own Host Settings class and GameSession Class and add a proper GameServer Name here.
					// This is something you can't do in Blueprint for example!
					GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Session Number: %d | Sessionname: %s "), SearchIdx + 1, *(SessionSearch->SearchResults[SearchIdx].Session.OwningUserName)));
					
					FSessionDisplayInfo DisplayInfo;
					//FText SessionDisplayName = 

					DisplayInfo.SessionIndex = SearchIdx;
					DisplayInfo.SessionName = FText::FromString(SessionSearch->SearchResults[SearchIdx].Session.OwningUserName);
					DisplayInfo.CurrentPlayers = SessionSearch->SearchResults[SearchIdx].Session.SessionSettings.NumPublicConnections - SessionSearch->SearchResults[SearchIdx].Session.NumOpenPublicConnections;
					DisplayInfo.MaxPlayers = SessionSearch->SearchResults[SearchIdx].Session.SessionSettings.NumPublicConnections;
					DisplayInfo.Ping = SessionSearch->SearchResults[SearchIdx].PingInMs;

					SessionUMGDiplayInfo.Add(DisplayInfo);
				}
			}
		}
	}
	UpdateServerList();
}

bool UWaveGameInstance::JoinSession(TSharedPtr<const FUniqueNetId> UserId, FName SessionName, const FOnlineSessionSearchResult& SearchResult)
{
	// Return bool
	bool bSuccessful = false;

	// Get OnlineSubsystem we want to work with
	IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();

	if (OnlineSub)
	{
		// Get SessionInterface from the OnlineSubsystem
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();

		if (Sessions.IsValid() && UserId.IsValid())
		{
			// Set the Handle again
			OnJoinSessionCompleteDelegateHandle = Sessions->AddOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegate);

			// Call the "JoinSession" Function with the passed "SearchResult". The "SessionSearch->SearchResults" can be used to get such a
			// "FOnlineSessionSearchResult" and pass it. Pretty straight forward!
			bSuccessful = Sessions->JoinSession(*UserId, SessionName, SearchResult);
		}
	}

	return bSuccessful;
}

void UWaveGameInstance::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
{
	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("OnJoinSessionComplete %s, %d"), *SessionName.ToString(), static_cast<int32>(Result)));

	// Get the OnlineSubsystem we want to work with
	IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
	if (OnlineSub)
	{
		// Get SessionInterface from the OnlineSubsystem
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();

		if (Sessions.IsValid())
		{
			// Clear the Delegate again
			Sessions->ClearOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegateHandle);

			// Get the first local PlayerController, so we can call "ClientTravel" to get to the Server Map
			// This is something the Blueprint Node "Join Session" does automatically!
			APlayerController * const PlayerController = GetFirstLocalPlayerController();

			// We need a FString to use ClientTravel and we can let the SessionInterface contruct such a
			// String for us by giving him the SessionName and an empty String. We want to do this, because
			// Every OnlineSubsystem uses different TravelURLs
			FString TravelURL;

			if (PlayerController && Sessions->GetResolvedConnectString(SessionName, TravelURL))
			{
				// Finally call the ClienTravel. If you want, you could print the TravelURL to see
				// how it really looks like
				PlayerController->ClientTravel(TravelURL, ETravelType::TRAVEL_Absolute);
			}
		}
	}
}

void UWaveGameInstance::OnDestroySessionComplete(FName SessionName, bool bWasSuccessful)
{
	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("OnDestroySessionComplete %s, %d"), *SessionName.ToString(), bWasSuccessful));

	// Get the OnlineSubsystem we want to work with
	IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
	if (OnlineSub)
	{
		// Get the SessionInterface from the OnlineSubsystem
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();

		if (Sessions.IsValid())
		{
			// Clear the Delegate
			Sessions->ClearOnDestroySessionCompleteDelegate_Handle(OnDestroySessionCompleteDelegateHandle);

			// If it was successful, we just load another level (could be a MainMenu!)
			if (bWasSuccessful)
			{
				UGameplayStatics::OpenLevel(GetWorld(), MainMenuMapName, true);
			}
		}
	}
}

void UWaveGameInstance::StartOnlineGame(bool bIsLanMatch, int32 MaxPlayers)
{
	// Creating a local player where we can get the UserID from
	ULocalPlayer* const Player = GetFirstGamePlayer();

	// Call our custom HostSession function. GameSessionName is a GameInstance variable
	HostSession(Player->GetPreferredUniqueNetId(), GameSessionName, bIsLanMatch, true, MaxPlayers);
}

void UWaveGameInstance::FindOnlineGames(bool bIsLanMatch)
{
	SessionUMGDiplayInfo.Empty();

	ULocalPlayer* const Player = GetFirstGamePlayer();

	FindSessions(Player->GetPreferredUniqueNetId(), GameSessionName, bIsLanMatch, true);

}

void UWaveGameInstance::JoinOnlineGame(int32 SessionIndex)
{
	ULocalPlayer* const Player = GetFirstGamePlayer();

	// Just a SearchResult where we can save the one we want to use, for the case we find more than one!
	FOnlineSessionSearchResult SearchResult;

	// If the Array is not empty, we can go through it
	if (SessionSearch->SearchResults.Num() > 0)
	{
		/*
		for (int32 i = 0; i < SessionSearch->SearchResults.Num(); i++)
		{
			// To avoid something crazy, we filter sessions from ourself
			//if (SessionSearch->SearchResults[i].Session.OwningUserId != Player->GetPreferredUniqueNetId())
			{
				SearchResult = SessionSearch->SearchResults[i];

				// Once we found sounce a Session that is not ours, just join it. Instead of using a for loop, you could
				// use a widget where you click on and have a reference for the GameSession it represents which you can use
				// here
				JoinSession(Player->GetPreferredUniqueNetId(), GameSessionName, SearchResult);
				break;
			}
		}*/

		SearchResult = SessionSearch->SearchResults[SessionIndex];

		JoinSession(Player->GetPreferredUniqueNetId(), GameSessionName, SearchResult);

	}
}

void UWaveGameInstance::DestroySessionAndLeaveGame()
{
	IOnlineSubsystem* OnlineSub = IOnlineSubsystem::Get();
	if (OnlineSub)
	{
		IOnlineSessionPtr Sessions = OnlineSub->GetSessionInterface();

		if (Sessions.IsValid())
		{
			Sessions->AddOnDestroySessionCompleteDelegate_Handle(OnDestroySessionCompleteDelegate);

			Sessions->DestroySession(GameSessionName);
		}
	}
}

void UWaveGameInstance::SetPlayerNickname(FString Nickname)
{
	PlayerNickname = Nickname;
}

Header line 53. Change that to GENERATED_UCLASS_BODY. Remove line 57.

The difference between generated body and generated u class body are as follows:

  • uclass body does not automatically generated a constructor for you. It does generate line 57 for you automatically.
  • uclass body sets proceeding data to public.
  • generated body expects a parameterless constructor.

I did that but I still get the same problem

CompilerResultsLog:Error: Error c:\users\nada\documents\unreal projects\wave\source\wave\WaveGameInstance.h(121) : warning C4263: 'bool UWaveGameInstance::JoinSession(TSharedPtr<const FUniqueNetId,0>,FName,const FOnlineSessionSearchResult &)': member function does not override any base class virtual member function
CompilerResultsLog:Error: Error c:\users\nada\documents\unreal projects\wave\source\wave\WaveGameInstance.h(197) : warning C4264: 'bool UGameInstance::JoinSession(ULocalPlayer *,const FOnlineSessionSearchResult &)': no override available for virtual member function from base 'UGameInstance'; function is hidden
CompilerResultsLog:Error: Error c:\program files\epic games\4.12\engine\source\runtime\engine\classes\engine\GameInstance.h(123) : note: see declaration of 'UGameInstance::JoinSession'
CompilerResultsLog:Error: Error C:\Program Files\Epic Games\4.12\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Engine\GameplayStatics.generated.h(48) : note: see declaration of 'UGameInstance'
CompilerResultsLog:Error: Error c:\users\nada\documents\unreal projects\wave\source\wave\WaveGameInstance.h(197) : warning C4264: 'bool UGameInstance::JoinSession(ULocalPlayer *,int32)': no override available for virtual member function from base 'UGameInstance'; function is hidden
CompilerResultsLog:Error: Error c:\program files\epic games\4.12\engine\source\runtime\engine\classes\engine\GameInstance.h(122) : note: see declaration of 'UGameInstance::JoinSession'
CompilerResultsLog:Error: Error C:\Program Files\Epic Games\4.12\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Engine\GameplayStatics.generated.h(48) : note: see declaration of 'UGameInstance'

Take a look at the signature of UGameInstance::JoinSession. It is as follows (it says this on line 2):

bool UGameInstance::JoinSession(ULocalPlayer *,const FOnlineSessionSearchResult &)

Now take a look at your UWaveGameInstance::JoinSession signature (line 1)

bool UWaveGameInstance::JoinSession(TSharedPtr<const FUniqueNetId,0>,FName,const FOnlineSessionSearchResult &)

They do not match. When you override a method its signature must match the parent’s method signature.

all this pain because of this, I thought that it was just a problem because of the different versions, everything worked when I changed the function name, thank you, that mistake was very stupid.

Just wanted to point out, it seems it is a version thing, I had 2 versions of the same project, the old one didn’t have any problem, as to the GameInstance.h from it didn’t have a function already made as JoinSession. While the new one gave me this problem, verified the new ones GameInstance.h and it has the function… it seems it was updated at some point.