babalae/better-genshin-impact · error · Exception

战斗脚本格式错误,指令括号无法配对

Error message

战斗脚本格式错误,指令括号无法配对

What it means

Thrown by CombatScriptParser.ParseLinePart when merging comma-separated script fragments reveals more than one '(' in a single command token. The TXT combat script parser splits commands by comma, then re-merges fragments whose '(' has no matching ')'. During merge, if the accumulated command contains more than one '(', the parser concludes the parentheses are unbalanced/uncloseable and aborts. This means nested or malformed parenthesis structures are not supported in the legacy TXT script format.

Source

Thrown at BetterGenshinImpact/GameTask/AutoFight/Script/CombatScriptParser.cs:246

        for (var i = 0; i < commandArray.Length; i++)
        {
            var command = commandArray[i];
            if (string.IsNullOrEmpty(command))
            {
                continue;
            }

            if (command.Contains('(') && !command.Contains(')'))
            {
                var j = i + 1;
                // 括号被逗号分隔,需要合并
                while (j < commandArray.Length)
                {
                    command += "," + commandArray[j];
                    if (command.Count("(".Contains) > 1)
                    {
                        Logger.LogError("战斗脚本格式错误,指令 {Cmd} 括号无法配对", command);
                        throw new Exception("战斗脚本格式错误,指令括号无法配对");
                    }

                    if (command.Contains(')'))
                    {
                        i = j;
                        break;
                    }

                    j++;
                }

                if (!(command.Contains('(') && command.Contains(')')))
                {
                    Logger.LogError("战斗脚本格式错误,指令 {Cmd} 括号不完整", command);
                    throw new Exception("战斗脚本格式错误,指令括号不完整");
                }
            }

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Check the logged command value ({Cmd}) to identify which instruction has the extra '('.
  2. Rewrite the offending command to use flat single-level parentheses: one '(' per command, e.g. `skill(1)` not `skill(inner(1))`.
  3. If you intended JSON-style complex strategies, switch to a .json strategy file instead of .txt.
  4. Remove any stray or duplicated parentheses in the script line.

Example fix

// before (broken — nested parens across commas)
// 香菱 skill(long(1),e(2))

// after (flat single-level)
// 香菱 skill(1),e(2)
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate a combat script line for balanced single-level parens
static bool HasBalancedParens(string line)
{
    // Each comma-separated command should have at most one '(' and matching ')'
    var parts = line.Split([','], StringSplitOptions.RemoveEmptyEntries);
    int openPending = 0;
    foreach (var part in parts)
    {
        openPending += part.Count(c => c == '(');
        openPending -= part.Count(c => c == ')');
        if (openPending < 0) return false;
    }
    return openPending == 0;
}

// Before parsing:
if (!HasBalancedParens(scriptLine))
    Log.LogWarning("Script line has unbalanced parens: {Line}", scriptLine);

Try / catch

// Wrap ParseContext in try-catch for user-facing script loading
try
{
    var script = CombatScriptParser.ParseContext(text);
}
catch (Exception e) when (e.Message.Contains("括号无法配对"))
{
    Logger.LogWarning("战斗脚本括号配对失败,请检查嵌套括号:{Msg}", e.Message);
    // Provide user with the specific failing line from logs
}

Prevention

When it happens

Trigger: A TXT combat script line where a command token has an opening '(' that spans across commas, and after merging fragments the command contains two or more '(' characters. For example: `skill(long_attack(1)` split as `skill(long_attack(` and `1)` — the merge produces two '(' and triggers the guard. Also any typo adding an extra '(' like `e((1))`.

Common situations: User writes nested parentheses in a TXT combat script (e.g. copying JSON-style syntax into a .txt file), or has a stray extra '(' from manual editing. Also occurs when Chinese full-width '(' is mixed and only partially converted (the parser converts '(' to '(' at line 75 but double-conversion or partial conversion can leave stray parens).

Related errors


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