diff --git a/Content/RWTHVRGameMode.uasset b/Content/RWTHVRGameMode.uasset
index 98183e89f709fbd7dbeb90756e70a0a14c67982d..5d31dc4d676d23d7815db315ca8d567445a51385 100644
Binary files a/Content/RWTHVRGameMode.uasset and b/Content/RWTHVRGameMode.uasset differ
diff --git a/Source/RWTHVRToolkit/Private/Core/RWTHVRGameModeBase.cpp b/Source/RWTHVRToolkit/Private/Core/RWTHVRGameModeBase.cpp
index bb25b4095a8f707d54de38852acb5dcad5ed6d9a..745b2275555f25098a56944835f59ea17afdf01a 100644
--- a/Source/RWTHVRToolkit/Private/Core/RWTHVRGameModeBase.cpp
+++ b/Source/RWTHVRToolkit/Private/Core/RWTHVRGameModeBase.cpp
@@ -4,8 +4,10 @@
 #include "Core/RWTHVRGameModeBase.h"
 
 #include "Core/RWTHVRPlayerState.h"
+#include "GameFramework/SpectatorPawn.h"
 #include "Kismet/GameplayStatics.h"
 #include "Logging/StructuredLog.h"
+#include "Utility/VirtualRealityUtilities.h"
 
 
 FString ARWTHVRGameModeBase::InitNewPlayer(APlayerController* NewPlayerController, const FUniqueNetIdRepl& UniqueId,
@@ -19,9 +21,9 @@ FString ARWTHVRGameModeBase::InitNewPlayer(APlayerController* NewPlayerControlle
 	// Check if we're using our custom PlayerState so that we can save the player type there.
 	// If not, just ingore all related args.
 	ARWTHVRPlayerState* State = Cast<ARWTHVRPlayerState>(NewPlayerController->PlayerState);
-		
+
 	if (State != nullptr)
-	{		
+	{
 		if (UGameplayStatics::HasOption(Options, PrimaryNodeIdKey))
 		{
 			const FString PrimaryNodeId = UGameplayStatics::ParseOption(Options, PrimaryNodeIdKey);
@@ -31,11 +33,53 @@ FString ARWTHVRGameModeBase::InitNewPlayer(APlayerController* NewPlayerControlle
 			const FString NodeName = UGameplayStatics::HasOption(Options, NodeNameKey)
 				                         ? UGameplayStatics::ParseOption(Options, NodeNameKey)
 				                         : PrimaryNodeId;
-			
-			const EPlayerType Type = NodeName == PrimaryNodeId ? EPlayerType::nDisplayPrimary : EPlayerType::nDisplaySecondary;			
-			State->RequestSetPlayerType(Type);		
+
+			const EPlayerType Type = NodeName == PrimaryNodeId
+				                         ? EPlayerType::nDisplayPrimary
+				                         : EPlayerType::nDisplaySecondary;
+			State->RequestSetPlayerType(Type);
+		}
+	}
+
+	return Super::InitNewPlayer(NewPlayerController, UniqueId, Options, Portal);
+}
+
+void ARWTHVRGameModeBase::PostLogin(APlayerController* NewPlayer)
+{
+	if (const ARWTHVRPlayerState* State = Cast<ARWTHVRPlayerState>(NewPlayer->PlayerState); State != nullptr)
+	{
+		// If the new player is a secondary nDisplay node, spawn it only as a Spectator
+		// Potentially we can use MustSpectate instead.
+		UClass* PawnClass;
+		if (State->GetPlayerType() == EPlayerType::nDisplaySecondary)
+		{
+			// For now, simply use the BP approach of spawning the pawn here. Can do this in a better way potentially.
+			PawnClass = SpectatorClass;
+		}
+		else
+			PawnClass = DefaultPawnClass;
+
+		FActorSpawnParameters SpawnInfo;
+		SpawnInfo.Instigator = GetInstigator();
+		SpawnInfo.ObjectFlags |= RF_Transient;
+		const AActor* StartSpot = FindPlayerStart(NewPlayer);
+
+		// If a start spot wasn't found,
+		if (StartSpot == nullptr)
+		{
+			// Check for a previously assigned spot
+			if (NewPlayer->StartSpot != nullptr)
+			{
+				StartSpot = NewPlayer->StartSpot.Get();
+				UE_LOG(Toolkit, Warning, TEXT("RestartPlayer: Player start not found, using last start spot"));
+			}
 		}
+
+		// Spawn and possess the pawn
+		APawn* ResultPawn = GetWorld()->SpawnActor<APawn>(PawnClass, StartSpot->GetTransform(), SpawnInfo);
+		NewPlayer->Possess(ResultPawn);
 	}
-	
-	return Super::InitNewPlayer(NewPlayerController, UniqueId, Options, Portal);	
+
+
+	Super::PostLogin(NewPlayer);
 }
diff --git a/Source/RWTHVRToolkit/Public/Core/RWTHVRGameModeBase.h b/Source/RWTHVRToolkit/Public/Core/RWTHVRGameModeBase.h
index 9e84c8aa895da5dbc1ec31f1cbdb0f95d1e3da42..16e0efcefd41472fe45dcd209d89935a7bca5d1f 100644
--- a/Source/RWTHVRToolkit/Public/Core/RWTHVRGameModeBase.h
+++ b/Source/RWTHVRToolkit/Public/Core/RWTHVRGameModeBase.h
@@ -17,6 +17,16 @@ class RWTHVRTOOLKIT_API ARWTHVRGameModeBase : public AGameModeBase
 	GENERATED_BODY()
 
 protected:
+	/**
+	 * Checks the connection options to see whether we're running in a cave multi user environment.
+	 * If we are, set the player types correspondingly.
+	 */
 	virtual FString InitNewPlayer(APlayerController* NewPlayerController, const FUniqueNetIdRepl& UniqueId,
 	                              const FString& Options, const FString& Portal) override;
+
+	/**
+	 * Checks the player type of the NewPlayer. If it has been set to nDisplaySecondary, spawn a spectator pawn and possess.
+	 * If not, spawn a DefaultPawnClass Pawn and Possess it (Should be BP_VirtualRealityPawn to make sense).
+	 */
+	virtual void PostLogin(APlayerController* NewPlayer) override;
 };