Christmas Crunch
A Cahotic Party Game

A Cahotic Party Game

Christmas Crunch is a chaotic, festive mix and match inspired by the frantic gameplay of Overcooked.


Device Management and Multiplayer Plugin

Unreal Engine’s native local multiplayer management lacks the flexibility to handle dynamic controller connections and disconnections and the rapid reassignment of players to gameplay entities (e.g., team management, slot reassignment). The goal was to create a centralized system that could be reused across projects without duplicating code in GameMode or PlayerController.

Technical Approach & Architecture


DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerConnected, FPlatformUserId, Platform);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerDeConnected, FPlatformUserId, Platform);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerReConnected, FPlatformUserId, Platform);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerRemoved, FPlatformUserId, Platform);

void UCMSubsystem::OnConnectionChange(EInputDeviceConnectionState NewConnectionState, FPlatformUserId PlatformUserID,
                                      FInputDeviceId InputDeviceID)
{
    switch (NewConnectionState) {
        case EInputDeviceConnectionState::Connected:
		//Verifie si le joueur existe deja
		if (ConnectedPlayers.Contains(PlatformUserID))
		{
			//Si le joueur existe, update l'identifant des controles
			auto& Data = ConnectedPlayers[PlatformUserID].DeviceIds;
			if (!Data.Contains(InputDeviceID))
			{
				Data.Add(InputDeviceID);
			}
			OnPlayerConnected.Broadcast(PlatformUserID);
		}
		else
		{
			//Verifie si un local player existe deja
			if (APlayerController* PC = UGameplayStatics::GetPlayerControllerFromPlatformUser(GetWorld(), PlatformUserID))
			{
				//Ajoute dans la liste
				FControllerData Data;
				Data.DeviceIds.Add(InputDeviceID);
				Data.Player = PC->GetLocalPlayer();
				ConnectedPlayers.Add(PlatformUserID, Data);
				//Restat le playe si pas de pawn si in game
			}
			else
			{
				//verifie si joueur max n'est pas atteind
				if (ConnectedPlayers.Num() < UControllersSettings::Get()->MaxPlayer)
				{
					FControllerData Data;
					Data.DeviceIds.Add(InputDeviceID);
					ConnectedPlayers.Add(PlatformUserID, Data);
					
					OnPlayerConnected.Broadcast(PlatformUserID);
					break;
				}
			}
		}
		break;
	}
}