babalae/better-genshin-impact · error · PartySetupFailedException
切换角色:{logicalSlot} 号位超出当前账号可操作角色数 {_maxControlAvatarCount}
Error message
切换角色:{logicalSlot} 号位超出当前账号可操作角色数 {_maxControlAvatarCount} What it means
EnsureSlotIsOperable checks that a logical slot exists in _logicalToPhysicalSlot (the controllable-slot map built by ConfigureOperableSlots). In co-op a player only owns some physical slots, so requesting a logical slot beyond _maxControlAvatarCount (e.g. 2P asking for logical slot 3) has no physical target and is rejected.
Source
Thrown at BetterGenshinImpact/GameTask/Common/Job/SwitchCharacterStateMachineTask.cs:1272
(4, 4) => [4],
_ => throw new PartySetupFailedException(
$"切换角色:无法为 {_multiGamePlayerCount} 人联机的 {_playerIndex}P 生成可控槽位")
};
_maxControlAvatarCount = physicalSlots.Length;
_logicalToPhysicalSlot = physicalSlots
.Select((physical, index) => (Logical: index + 1, Physical: physical))
.ToDictionary(pair => pair.Logical, pair => pair.Physical);
_logger.LogInformation("切换角色:{PlayerCount} 人队伍,{PlayerIndex}P 可控物理槽位 {Slots}",
_multiGamePlayerCount, _playerIndex, string.Join(",", physicalSlots));
}
private void EnsureSlotIsOperable(int logicalSlot)
{
if (!_logicalToPhysicalSlot.ContainsKey(logicalSlot))
{
throw new PartySetupFailedException($"切换角色:{logicalSlot} 号位超出当前账号可操作角色数 {_maxControlAvatarCount}");
}
}
private void AdjustTargetsToOperableSlots()
{
int[] ignoredSlots;
if (_usePhysicalSlots)
{
var logicalByPhysicalSlot = _logicalToPhysicalSlot
.ToDictionary(pair => pair.Value, pair => pair.Key);
ignoredSlots = _targetRoles
.Where(role => !logicalByPhysicalSlot.ContainsKey(role.Slot))
.Select(role => role.Slot)
.OrderBy(slot => slot)
.ToArray();
_targetRoles = _targetRoles
.Where(role => logicalByPhysicalSlot.ContainsKey(role.Slot))View on GitHub (pinned to a7cb36712d)
Solutions
- Rely on AdjustTargetsToOperableSlots to strip/ignore slots the current player cannot operate before any click — confirm it ran and filtered the offending role.
- When scripting for co-op, only request slots within the player's controllable range (documented in Start's remarks).
- Call EnsureSlotIsOperable earlier (during BuildSwitchPlan) to fail with context before attempting UI clicks.
Defensive patterns
Strategy: validation
Validate before calling
if (!_logicalToPhysicalSlot.ContainsKey(role.Slot))
{
_logger.LogWarning("切换角色:忽略不可操作槽位 {Slot}", role.Slot);
continue;
} Type guard
bool IsOperable(int logicalSlot) => _logicalToPhysicalSlot.ContainsKey(logicalSlot);
Try / catch
try { await switchTask.Start(...); }
catch (PartySetupFailedException ex) when (ex.Message.Contains("超出当前账号可操作角色数"))
{ _logger.LogWarning(ex, "联机模式下请求了不可控槽位,已忽略"); } Prevention
- Let AdjustTargetsToOperableSlots strip inoperable slots before any click.
- In co-op, request only slots within the player's controllable range.
- Validate slot operability early in BuildSwitchPlan.
When it happens
Trigger: EnsureSlotIsOperable(logicalSlot) is called (from ClickFixedTeamSlot or HandlePrepareNextRole) with a logicalSlot not present in _logicalToPhysicalSlot, which happens when the requested target role's slot exceeds the controllable count for this player in co-op.
Common situations: usePhysicalSlots=false and a target role references a slot index beyond _maxControlAvatarCount; usePhysicalSlots=true but AdjustTargetsToOperableSlots did not filter/remap it; a co-op player issued a 4-slot command but only controls 1-2 slots.
Related errors
- 切换角色:等待单机图标、联机状态及 top_left 玩家标记超时({timeoutMilliseconds / 100
- 切换角色:无法为 {_multiGamePlayerCount} 人联机的 {_playerIndex}P 生成可控槽位
- 切换角色:角色列表队伍识别不完整,期望 {expectedTeamCount} 个,末次检测到 {lastDetecte
- 切换角色:未指定角色或同一实际角色被指定到多个槽位
- 切换角色:未找到 {misplaced.Slot} 号位的换下按钮
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/980f0dbf929455f5.
Report an issue: GitHub.