Skip to content

ai-battle: support team assignment (--teams) and establish team start-pacts - #1957

Merged
Flamefire merged 7 commits into
Return-To-The-Roots:masterfrom
FlexApex:ai-battle-teams
Oct 4, 2026
Merged

Flamefire merged 7 commits into
Return-To-The-Roots:masterfrom
FlexApex:ai-battle-teams

Conversation

@FlexApex

Copy link
Copy Markdown
Contributor

ai-battle: support team assignment (--teams) and establish team start-pacts

Builds on #1949 (uses its HeadlessGame). Two commits:

1. --teams option for team assignment

Adds a --teams option to the headless ai-battle harness so the AI can be
verified under real team rules instead of a free-for-all:

ai-battle -m Map.swd --ai aijh --ai aijh --ai aijh --ai aijh --teams "0,1;2,3"

Groups are separated by ;, player indices by ,. The first group becomes
Team1, the second Team2, and so on; unlisted players stay teamless. The
assignment is threaded through HeadlessGame into GeneratePlayerInfo, which
sets PlayerInfo::team.

2. Establish team start-pacts in HeadlessGame to match GameClient (avoid desyncs in replays)

GameClient::StartGame calls GamePlayer::MakeStartPacts() for every player on
a fresh map, creating the ally + non-aggression pacts that bind a team together.
HeadlessGame never did this, so a recorded ai-battle with teams had no pacts:
GamePlayer::IsAttackable() returned true for teammates and the AIs attacked
their own team. On replay GameClient does set up the pacts, so the recorded
inter-team attack commands hit allied players and were resolved differently —
producing an object-count divergence (replay desync) without any RANDOM
divergence.

MakeStartPacts() early-returns for Team::None, so the call is a no-op until
players are actually assigned to teams via --teams. Together with the
MapLoader::SetupResources() call already in HeadlessGame, this makes the
headless world setup match the GameClient replay path.

Note

Comment thread extras/ai-battle/main.cpp Outdated
Comment thread extras/ai-battle/main.cpp Outdated
FlexApex and others added 5 commits October 4, 2026 12:22
Adds a --teams option (e.g. "0,1;2,3" for a 2v2) that assigns players to
teams in the headless harness, so the AI can be verified under real team
rules instead of a free-for-all. Player indices map to Team1, Team2, ...
in the order the groups are given; unlisted players stay teamless.

The assignment is threaded through HeadlessGame into GeneratePlayerInfo,
which sets PlayerInfo::team. Establishing the actual alliances follows in
the next commit.
…ient

GameClient::StartGame calls GamePlayer::MakeStartPacts() for every player
on a fresh map, creating the ally + non-aggression pacts that bind a team
together. HeadlessGame never did this, so in a recorded ai-battle with
teams the teammates had no pacts and GamePlayer::IsAttackable() returned
true for them: the AIs attacked their own team. On replay GameClient
*does* set up the pacts, so the recorded inter-team attack commands hit
allied players and were resolved differently, producing an object-count
divergence (and replay desync) without any RANDOM divergence.

MakeStartPacts() early-returns for Team::None, so this is a no-op until
players are actually assigned to teams via --teams.
…skipping

Silently skipping unparseable or unknown [addons] entries hid exactly the
mistakes the settings file is meant to catch (a mistyped key/value or an
accidental section name went unnoticed while the user's intent was not applied).
Make loadAddonsFromIni strict:
- an entry that doesn't parse -> hard error naming the entry,
- an unknown/unsupported addon id (getAddon(id) == null) -> hard error,
- a missing [addons] section -> hard error, except for a fully empty file.
Move from explicit type-templates and `count` checks to a struct passing members by reference to Boost.ProgramOptions.
Flamefire
Flamefire previously approved these changes Oct 4, 2026

@Flamefire Flamefire left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased and fixed conflict

@Flamefire
Flamefire enabled auto-merge October 4, 2026 11:01
@Flamefire
Flamefire merged commit 59327b2 into Return-To-The-Roots:master Oct 4, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants