Greetings,
TL/DR getting “request failed validation” when trying to add a “bot” player to a lobby. Basically, the same player that created the lobby is trying to add another player that will be AI controlled.
I’ve got a pretty complete real-time, cross-platform, multiplayer card game working with NetCode for GameObjects, Lobby and Relay.
I want to add the ability for the player who created the lobby to add “bot” players.
I created the lobby via the usual means:
public static async Task CreateLobbyWithAllocation(LobbyData lobbyData)
{
try
{
// Create a relay allocation and generate a join code to share with the lobby
Debug.Log($"RelayService.Instance.CreateAllocationAsync(maxPlayers: {lobbyData.MaxPlayers});");
var a = await RelayService.Instance.CreateAllocationAsync(lobbyData.MaxPlayers);
Debug.Log($"RelayService.Instance.GetJoinCodeAsync(allocationId: {a.AllocationId});");
var joinCode = await RelayService.Instance.GetJoinCodeAsync(a.AllocationId);
// Create a lobby, adding the relay join code to the lobby data
var options = new CreateLobbyOptions
{
Player = CurrentPlayer,
Data = new Dictionary<string, DataObject>
{
{ Constants.JoinKey, new DataObject(DataObject.VisibilityOptions.Member, joinCode) },
{
Constants.GameStateKey,
new DataObject(DataObject.VisibilityOptions.Public, GameState.WaitingForPlayers.ToString())
},
{
Constants.ProtocolVersionKey,
new DataObject(DataObject.VisibilityOptions.Public, Application.version)
}
},
IsPrivate = lobbyData.Private
};
CurrentLobby = await Lobbies.Instance.CreateLobbyAsync(lobbyData.Name, lobbyData.MaxPlayers, options);
Transport.SetHostRelayData(a.RelayServer.IpV4, (ushort)a.RelayServer.Port, a.AllocationIdBytes, a.Key, a.ConnectionData);
Heartbeat();
PeriodicallyRefreshLobby();
}
catch (Exception exception)
{
Debug.LogError($"Error creating lobby {lobbyData.Name}.\n{exception}");
}
}
To add a “bot” I’m simply creating a new player object, giving it a name and a portrait index and appending an integer to its client id:
static Player CreateBotPlayer()
{
var botIndex = CurrentLobby.GetRandomBotIndex();
var playerName = PlayerExtensions.BotNames[botIndex];
var clientId = $"{NetworkManager.Singleton.LocalClientId.ToString()}-{botIndex:smile:2}";
return new Player(
$"BotPlayer{botIndex}",
null,
new Dictionary<string, PlayerDataObject>
{
{Constants.ClientIdKey, new PlayerDataObject(PlayerDataObject.VisibilityOptions.Public, clientId)},
{Constants.PlayerNameKey, new PlayerDataObject(PlayerDataObject.VisibilityOptions.Public, playerName)},
{Constants.PlayerPortraitKey, new PlayerDataObject(PlayerDataObject.VisibilityOptions.Public, botIndex.ToString())}
});
}
And adding it to the lobby as follows:
public static async Task AddBotPlayer()
{
try
{
await Lobbies.Instance.JoinLobbyByIdAsync(CurrentLobby.Id, new JoinLobbyByIdOptions
{
Player = CreateBotPlayer()
});
}
catch (Exception e)
{
Debug.LogError($"Failed to add bot player {CurrentLobby?.Name}: {e}");
}
}
This is failing with the following (not very informative) error:
Failed to add bot player Duncan’s game: Unity.Services.Lobbies.LobbyServiceException: request failed validation —> Unity.Services.Lobbies.Http.HttpException1[Unity.Services.Lobbies.Models.ErrorStatus]: HTTP/1.1 400 Bad Request at Unity.Services.Lobbies.Http.ResponseHandler.HandleAsyncResponse (Unity.Services.Lobbies.Http.HttpClientResponse response, System.Collections.Generic.Dictionary
2[TKey,TValue] statusCodeToTypeMap) [0x0007b] in F:\dev\Unity Projects\Highland Panic Root\ios_release\Library\PackageCache\com.unity.services.lobby@1.0.3\Runtime\Http\ResponseHandler.cs:95
at Unity.Services.Lobbies.Http.ResponseHandler.HandleAsyncResponse[T] (Unity.Services.Lobbies.Http.HttpClientResponse response, System.Collections.Generic.Dictionary2[TKey,TValue] statusCodeToTypeMap) [0x00001] in F:\dev\Unity Projects\Highland Panic Root\ios_release\Library\PackageCache\com.unity.services.lobby@1.0.3\Runtime\Http\ResponseHandler.cs:186 at Unity.Services.Lobbies.Apis.Lobby.LobbyApiClient.JoinLobbyByIdAsync (Unity.Services.Lobbies.Lobby.JoinLobbyByIdRequest request, Unity.Services.Lobbies.Configuration operationConfiguration) [0x001bb] in F:\dev\Unity Projects\Highland Panic Root\ios_release\Library\PackageCache\com.unity.services.lobby@1.0.3\Runtime\Apis\LobbyApi.cs:396 at Unity.Services.Lobbies.Internal.WrappedLobbyService.TryCatchRequest[TRequest,TReturn] (System.Func
3[T1,T2,TResult] func, TRequest request) [0x00046] in F:\dev\Unity Projects\Highland Panic Root\ios_release\Library\PackageCache\com.unity.services.lobby@1.0.3\Runtime\SDK\WrappedLobbyService.cs:355
— End of inner exception stack trace —
at Unity.Services.Lobbies.Internal.WrappedLobbyService.ResolveErrorWrapping (Unity.Services.Lobbies.LobbyExceptionReason reason, System.Exception exception) [0x000a1] in F:\dev\Unity Projects\Highland Panic Root\ios_release\Library\PackageCache\com.unity.services.lobby@1.0.3\Runtime\SDK\WrappedLobbyService.cs:411
at Unity.Services.Lobbies.Internal.WrappedLobbyService.TryCatchRequest[TRequest,TReturn] (System.Func`3[T1,T2,TResult] func, TRequest request) [0x000c3] in F:\dev\Unity Projects\Highland Panic Root\ios_release\Library\PackageCache\com.unity.services.lobby@1.0.3\Runtime\SDK\WrappedLobbyService.cs:359
at Unity.Services.Lobbies.Internal.WrappedLobbyService.JoinLobbyByIdAsync (System.String lobbyId, Unity.Services.Lobbies.JoinLobbyByIdOptions options) [0x000a3] in F:\dev\Unity Projects\Highland Panic Root\ios_release\Library\PackageCache\com.unity.services.lobby@1.0.3\Runtime\SDK\WrappedLobbyService.cs:165
at Unity.Services.Lobbies.Internal.WrappedLobbyService.JoinLobbyByIdAsync (System.String lobbyId, Unity.Services.Lobbies.JoinLobbyByIdOptions options) [0x00234] in F:\dev\Unity Projects\Highland Panic Root\ios_release\Library\PackageCache\com.unity.services.lobby@1.0.3\Runtime\SDK\WrappedLobbyService.cs:179
at MatchmakingService.AddBotPlayer () [0x00043] in F:\dev\Unity Projects\Highland Panic Root\ios_release\Assets_highlandPanic\Lobby\Scripts\MatchmakingService.cs:167
UnityEngine.Debug:LogError (object)