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
- Check the logged command value ({Cmd}) to identify which instruction has the extra '('.
- Rewrite the offending command to use flat single-level parentheses: one '(' per command, e.g. `skill(1)` not `skill(inner(1))`.
- If you intended JSON-style complex strategies, switch to a .json strategy file instead of .txt.
- 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
- Avoid nested parentheses in TXT combat scripts — the format only supports flat single-level function calls.
- For complex strategies with conditions, use the JSON strategy format instead.
- Validate scripts in an editor that highlights unbalanced parentheses.
- Watch the {Cmd} value in the log to pinpoint the exact failing command.
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.