babalae/better-genshin-impact · error · PartySetupFailedException

切换角色:未找到 {misplaced.Slot} 号位的换下按钮

Error message

切换角色:未找到 {misplaced.Slot} 号位的换下按钮

What it means

Thrown by HandlePrepareNextRole when a character currently occupies the wrong slot (a 'misplaced' slot) and the OCR-driven click of the '换下' (remove) button fails. TryClickText searches the fixed ROI Rect1080(382,994,87,51) for the literal text; a false return means the remove button could not be located, so the party teardown cannot proceed safely.

Source

Thrown at BetterGenshinImpact/GameTask/Common/Job/SwitchCharacterStateMachineTask.cs:701

            return StateHandlerResult.Success;
        }

        var misplaced = _currentTeamSlots.FirstOrDefault(slot => slot.Slot != _currentRole.Slot && _currentRole.Matches(slot.Name));
        if (misplaced != null)
        {
            if (_currentTeamSlots.Count == 1)
            {
                _logger.LogInformation("切换角色:队伍仅剩一个角色,保留该角色并从 1 号位开始通过更换重建队伍");
                StartSuffixRebuild(1);
                _currentRole = null;
                return StateHandlerResult.Wait;
            }

            ClickFixedTeamSlot(misplaced.Slot);
            await Delay(500, _ct);
            if (!TryClickText(page, "换下", Rect1080(382, 994, 87, 51)))
            {
                throw new PartySetupFailedException($"切换角色:未找到 {misplaced.Slot} 号位的换下按钮");
            }

            await WaitForRoleRemoved(misplaced.Slot, _ct);
            _expectedTeamCount--;
            _teamSnapshotDirty = true;
            _prepareSuffixRebuildAfterRemoval = true;
            _currentRole = null;
            return StateHandlerResult.Wait;
        }

        EnsureSlotIsOperable(_currentRole.Slot);
        ClickFixedTeamSlot(_currentRole.Slot);
        _workflowState = SwitchCharacterState.OpenFilterPanel;
        return StateHandlerResult.Success;
    }

    /// <summary>
    /// 打开筛选面板。

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Confirm the game is running at the 1080p-based resolution the ROIs assume (assetScale must be correct); fix the TaskContext.SystemInfo.AssetScale.
  2. Re-capture manually and inspect Rect1080(382,994,87,51): if the '换下' button moved, update the ROI constant to match the current game layout.
  3. Increase the Delay(500) before TryClickText or loop TryClickText a few times instead of throwing on the first miss, mirroring the Retry pattern used elsewhere.
  4. Verify no overlay/dialog is covering the button bar at teardown time.

Example fix

// before
ClickFixedTeamSlot(misplaced.Slot);
await Delay(500, _ct);
if (!TryClickText(page, "换下", Rect1080(382, 994, 87, 51)))
{
    throw new PartySetupFailedException($"切换角色:未找到 {misplaced.Slot} 号位的换下按钮");
}

// after
ClickFixedTeamSlot(misplaced.Slot);
await Delay(500, _ct);
if (!await NewRetry.WaitForAction(() =>
        {
            using var c = CaptureToRectArea();
            return TryClickText(page, "换下", Rect1080(382, 994, 87, 51));
        }, _ct, 3, 400))
{
    throw new PartySetupFailedException($"切换角色:未找到 {misplaced.Slot} 号位的换下按钮");
}
Defensive patterns

Strategy: try-catch

Try / catch

try { await switchTask.Start(slot1, slot2, slot3, slot4, usePhysicalSlots, ct); }
catch (PartySetupFailedException ex) when (ex.Message.Contains("换下按钮"))
{
    _logger.LogWarning(ex, "换下按钮识别失败,建议稍后重试或检查分辨率");
    // optionally retry once after re-capturing
}

Prevention

When it happens

Trigger: Inside HandlePrepareNextRole, _currentTeamSlots finds a slot whose name matches _currentRole but sits at a different slot; the team has >1 member; ClickFixedTeamSlot(misplaced.Slot) then Delay(500) runs, but TryClickText(page,"换下",...) returns false on the very first attempt (no retry within this handler — only the surrounding RetryTimeout applies on a different code path).

Common situations: Game resolution/capture scale differs from 1080p assumptions so the fixed ROI misses the button; the 500ms Delay was too short and a slot-click animation is still playing; a popup or toast covers the bottom button bar; OCR misreads '换下' due to font/color changes after a game version update; capture frame was a transitional blur.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/3784f3917ba3b451. Report an issue: GitHub.