Skip to content

Commander Vote And Reassignment Playbook

rayswaynl edited this page Jun 25, 2026 · 16 revisions

Commander Vote And Reassignment Playbook

Source-backed implementation playbook for commander election, no-commander vote semantics, manual reassignment and the nearby commander-authority boundary.

Status: docs only; current stable origin/master@f8a76de34 / origin/claude/b74.1-aicom@f8a76de34, B74.2 origin/claude/b74.2-aicom@21b62b04, current B69 origin/claude/b69@8d465fce and adjacent B74 origin/claude/b74-aicom-spend@b23f557f have the server-side DR-47 tautology removed in both maintained roots, but vote UI preview/policy smoke remains open and older checked refs still carry the old comparison.

Scope: Arma 2 Operation Arrowhead 1.64 mission behavior. Gameplay patches should start in Missions/[55-2hc]warfarev2_073v48co.chernarus, then propagate maintained Vanilla through LoadoutManager.

Use this page with Commander/HQ lifecycle, Commander reassignment call shape, Server authority map, Hardening roadmap, Feature status, Client UI systems and Testing workflow.

How To Use This Page

Need Go here
Decide commander vote / no-commander policy Use Current Branch Scope, then Current Vote Behavior and Patch Order.
Patch manual reassignment helper shape Use Commander reassignment call shape; this page keeps only the adjacent smoke and ordering context.
Separate requester/server authority from vote semantics Use Server authority map for RequestCommanderVote / RequestNewCommander validation.
Debug HQ/MHQ lifecycle after commander changes Use Commander/HQ lifecycle.
Clean vote UI refresh loops, row colors or menu cadence Use Client UI systems.
Review AI commander stop/start implications Use AI commander autonomy audit.

Current Branch Scope

Checked again on 2026-06-23 after git fetch --all --prune. Current stable origin/master@f8a76de34, the same commit as origin/claude/b74.1-aicom@f8a76de34, B74.2 origin/claude/b74.2-aicom@21b62b04, current B69 origin/claude/b69@8d465fce and adjacent B74 origin/claude/b74-aicom-spend@b23f557f differ from the older 8c3942d2 / cf2a6d6a branch evidence: the vote worker no longer uses the old >= || <= tautology. The scoped 0139a3468609..origin/master, origin/master..origin/claude/b74.2-aicom, d472da6a..origin/claude/b74.2-aicom and origin/claude/b69..origin/claude/b74-aicom-spend diffs are empty for the checked maintained-root Server_VoteForCommander.sqf, GUI_VoteMenu.sqf, RequestNewCommander.sqf, Server_AssignNewCommander.sqf and GUI_Commander_VoteMenu.sqf paths. Miksuu b8389e748243, origin/perf/quick-wins@0076040f, historical release commit a96fdda2, historical AI-commander commit c20ce153 and docs/source HEAD@e0d82714 still keep the old vote comparison. Current origin exposes no release/* or reassignment rescue head on 2026-06-23; origin/claude/trello-vote-para-guards@92101abe is branch-only vote-worker random tie-break plus paratrooper-guard context, not current stable/B74.2 closure.

Surface Current branch truth Route
Commander vote AI/no-commander outcome Current stable origin/master@f8a76de34 / B74.1, B74.2 origin/claude/b74.2-aicom@21b62b04, current B69 origin/claude/b69@8d465fce and adjacent B74 origin/claude/b74-aicom-spend@b23f557f Chernarus and maintained Vanilla still count wfbe_vote == -1 into _aiVotes (Server_VoteForCommander.sqf:18,26-27) but now select a player commander only when !_tie, _highestTeam != -1 and _highest >= _aiVotes (:43). Chernarus blame points to cbc2294c4; maintained Vanilla propagation points to 91dc6a75; the checked 0139a3468609..f8a76de34, current-stable..B74.2, d472da6a..21b62b04 and B69..B74 vote-worker/preview diffs are empty. The client preview still treats row 0 or no strict majority as AI/no commander (GUI_VoteMenu.sqf:88), so UI/policy smoke remains open. Docs/source HEAD@e0d82714, Miksuu b8389e748243, perf 0076040f, historical a96fdda2 and historical c20ce153 still use the old `>=
PR #80 random tied-player candidate Open draft PR #80 / origin/claude/trello-vote-para-guards@92101abe9f7b83bd7f658d03e4160d5f030aa3c7 is one clean commit on current stable base f8a76de34, with maintained-root vote/support payload. In both source Chernarus and maintained Vanilla, Server_VoteForCommander.sqf:17 adds _tiedTeams; :43-51 collects every tied team whose vote count equals _highest, selects one with floor (random (count _tiedTeams)), clears _tie, and then the existing grant line at :59 can assign that randomly selected player team when _highest >= _aiVotes. Checked current stable, current B74.2, B69, adjacent B74, Miksuu and perf refs have no _tiedTeams hits in the maintained roots. Branch-only commander vote candidate. Smoke player-candidate ties that beat/equal AI/no-commander votes, clear winners, zero-vote/AI-majority rounds, repeated runs for random variation, UI preview wording, JIP vote state and maintained Vanilla parity before promotion. Paratrooper cap from the same PR is owned by Support specials.
B74.5 primitive vote-roster display fallback origin/claude/b745@b996bcb3 adds source-Chernarus-only primitive rows for late joiners before live wfbe_teams group objects arrive. GUI_VoteMenu.sqf:10-35 and GUI_Commander_VoteMenu.sqf:10-32 render names from WFBE_JIP_ROSTER_PRIMS with row value -1; GUI_VoteMenu.sqf:75-99,119-125 and GUI_Commander_VoteMenu.sqf:69-91 suppress live prune/update loops while primitives are displayed and rebuild once player-led live groups arrive. The server/JIP producer is documented on Player join/disconnect; UI ownership is on Client UI systems. No matching primitive-roster symbols were found in current stable, current B74.2, Miksuu master or maintained Vanilla Takistan checked paths. Branch-only display/JIP fallback, not a vote outcome-policy change and not current stable/Vanilla behavior. Smoke must prove primitive rows stay visible without blank names/RPT spam, then hand over to live team-index rows before treating a selected player candidate as a normal castable/reassignable row.
Manual reassignment helper shape Current stable origin/master@f8a76de34 / B74.1, B74.2 origin/claude/b74.2-aicom@21b62b04, current B69 origin/claude/b69@8d465fce and adjacent B74 origin/claude/b74-aicom-spend@b23f557f Chernarus and maintained Vanilla unpack _side = _this select 0 / _commander = _this select 1 at Server_AssignNewCommander.sqf:4-5, while RequestNewCommander.sqf:13-14 still spawns the helper and also sends new-commander-assigned. Duplicate senders remain at helper :10 plus caller RequestNewCommander.sqf:14; the UI identity edge remains open. Docs/source HEAD@60c35c05 still carries _side = _this in both maintained roots. Commander reassignment call shape
Reassignment UI identity Every checked root still stores team indexes with lnbSetValue (GUI_Commander_VoteMenu.sqf:13,63) but resolves the selected commander by visible leader-name text at :33,37. Keep this smoke tied to DR-15; broader UI loop cleanup routes to Client UI systems.
Requester authority RequestCommanderVote and RequestNewCommander remain payload-side/requester-light flows; this pass did not patch sender authentication or authority validation. Server authority map
Objective Ping / old town tasks Current docs head, Miksuu and perf still keep the commander-menu SetTask sends commented (GUI_Menu_Command.sqf:335,337,343) while registering SetTask; stable and release send targeted Objective Ping tasks at GUI_Menu_Command.sqf:336,344 in both maintained roots. The old town TaskSystem remains commented in all checked roots. Client UI systems

What It Covers

Area Finding Current status
Commander vote resolution DR-47 server tautology is fixed on current stable origin/master@f8a76de34 / B74.1, B74.2 origin/claude/b74.2-aicom@21b62b04, current B69 origin/claude/b69@8d465fce and adjacent B74 origin/claude/b74-aicom-spend@b23f557f: player candidate assignment now requires _highest >= _aiVotes. Older checked refs still use `>=
Vote UI preview Client preview can still show AI/no commander for a distribution the current stable/B74.1/B69/B74 server resolves to a player, because GUI_VoteMenu.sqf:88 uses row 0 / strict-majority preview logic rather than the server _highest >= _aiVotes rule. Confirmed remaining mismatch risk.
Manual reassignment helper DR-15 helper unpacking is source-present on current stable origin/master@f8a76de34 / B74.1, current B69 origin/claude/b69@8d465fce and adjacent B74 origin/claude/b74-aicom-spend@b23f557f, but duplicate new-commander-assigned senders and UI visible-name targeting remain open. Partial source-present; dedicated page owns exact patch/smoke shape.
Reassignment UI identity UI stores team ids in rows but resolves selected commander by visible leader name text. Confirmed UI correctness debt in every checked root.
Requester authority Vote/reassign PVFs use payload side/name/candidate. Separate hardening pass; do not mix with vote semantics.

Not covered here: AI commander autonomy, HQ killed scoring, MHQ repair authority and construction authority. Route those through the owning pages linked above.

Source Chain

All source refs below are from the Chernarus source mission unless the path starts with Missions_Vanilla.

Flow Evidence What it means
Vote worker starts Server/Functions/Server_VoteForCommander.sqf:9-14 sets _side, reads the side logic vote timer and broadcasts wfbe_votetime. Server owns the countdown and final commander assignment.
Vote counting Server/Functions/Server_VoteForCommander.sqf:17-29 counts wfbe_vote == -1 as _aiVotes; all other values increment a player-team vote bucket. Row value -1 represents AI/no commander in the worker.
Winner selection Current stable/B74.1/B74.2/current B69/B74 Server/Functions/Server_VoteForCommander.sqf:31-43 finds _highest, _highestTeam and _tie, then assigns a player commander only when _highest >= _aiVotes and the top player candidate is not tied. Older docs/source/Miksuu/perf/historical release/AI refs still use _highest >= _aiVotes OR _highest <= _aiVotes at :43. Current stable/B74.1/B74.2/B69/B74 removed the tautology; old-branch code can still select any non-tied player candidate regardless of no-commander votes.
Final assignment Current stable/current B69/B74 Server/Functions/Server_VoteForCommander.sqf:49,54,57,61 applies the AI-commander lock override, writes wfbe_commander, broadcasts commander-vote, and stops AI commander state if a player commander wins. Vote semantics affect commander, UI and AI handoff state.
Vote menu rows Client/GUI/GUI_VoteMenu.sqf:7-14 adds a No Commander row with value -1 and player rows with team indexes. Client row ids match the server's wfbe_vote value model.
B74.5 primitive rows Branch-only origin/claude/b745 source Chernarus adds primitive name rows from WFBE_JIP_ROSTER_PRIMS with value -1 at GUI_VoteMenu.sqf:28-35 and GUI_Commander_VoteMenu.sqf:26-32; both menus suppress live prune/update loops until live player-led groups arrive. Primitive rows are display placeholders. Do not infer final vote semantics from them; normal row identity resumes only after live team-index rows are rebuilt.
Vote preview Client/GUI/GUI_VoteMenu.sqf:42-49,87-89 offsets wfbe_vote + 1, then previews AI/no commander when row 0 wins or no option has more than half the player count. UI preview and server resolver can disagree.
Commander assign UI Client/GUI/GUI_Commander_VoteMenu.sqf:8-14,33-46 stores row team indexes but resolves the target by visible leader-name text before sending RequestNewCommander. Duplicate or changed names can point the reassignment at the wrong team.
Vote restart PVF Server/PVFunctions/RequestCommanderVote.sqf:3-22 trusts payload side/name, resets votes, seeds the current commander vote and spawns VoteForCommander. Useful recovery path, but requester identity hardening is separate from vote resolution.
Manual reassign PVF Server/PVFunctions/RequestNewCommander.sqf:3-14 reads side/candidate, writes wfbe_commander, spawns [_side, _assigned_commander] into the helper and sends new-commander-assigned. The caller already mutates commander state before the helper runs.
Assign helper Current stable/B74.1/current B69/B74 Server/Functions/Server_AssignNewCommander.sqf:4-5,10 unpacks _side / _commander correctly, then sends another new-commander-assigned. RequestNewCommander.sqf:13-14 still spawns the helper and sends the caller notification too. DR-15 helper shape is source-present on current stable/B74.1/B69/B74, but duplicate notification ownership must still be decided.
Vanilla parity Maintained Vanilla matches the named Chernarus current-stable/B69/B74 vote shape: the server comparison is source-present, while UI preview logic and old-branch vote comparison remain as documented above. Manual reassignment helper branch status stays on Commander reassignment call shape. Use the reassignment owner page before claiming the broader commander lane fixed.

Current Vote Behavior

On current stable origin/master@f8a76de34 / B74.1, B74.2 origin/claude/b74.2-aicom@21b62b04, current B69 origin/claude/b69@8d465fce and adjacent B74 origin/claude/b74-aicom-spend@b23f557f, the server tracks no-commander votes and now lets _aiVotes block a player candidate when the AI/no-commander count is greater than the highest player-candidate count. A player candidate can still win on equality because the current comparison is _highest >= _aiVotes. The branch-only origin/claude/trello-vote-para-guards@92101abe changes player-candidate ties that beat/equal AI votes into a random tied-team pick, but that is not current stable/B74.2 behavior.

The client vote menu can still suggest a different rule. It previews AI/no commander when the leading row is the No Commander row or when no row has more than half of the counted player slots. That creates a remaining player-facing mismatch: the UI can imply no commander while the current stable/B74.1/B69/B74 server assigns a human commander under the _highest >= _aiVotes rule.

Older checked refs still carry the worse server comparison. On Miksuu b8389e74, origin/perf/quick-wins 0076040f, historical release commit a96fdda2 and historical AI-commander commit c20ce153, _highest >= _aiVotes || _highest <= _aiVotes is true for any pair of numeric counts, so any non-tied player candidate can win if at least one player candidate exists.

Before patching, choose the rule explicitly:

Candidate rule Consequence
Plurality winner Highest vote count wins, including no-commander as a real candidate; ties produce no commander or previous commander by policy.
Strict majority A player commander wins only with more than half of eligible/team voters; otherwise no commander or revote.
AI/no commander as veto No-commander wins whenever _aiVotes >= _highest, otherwise highest non-tied player wins.
Preserve player preference Player candidate wins any non-tied player plurality; update UI text to match the legacy behavior.

Do not let the patch pick a policy accidentally by changing only the tautological comparison.

Manual Reassignment Boundary

Manual reassignment is a separate flow from the vote result, but the fixes are adjacent:

  1. RequestNewCommander.sqf already writes wfbe_commander.
  2. It then spawns Server_AssignNewCommander.sqf with [_side, _assigned_commander].
  3. Old-shape targets read _side = _this, so side-logic routing receives an array instead of a side.
  4. Current stable/current B69/B74 maintained roots unpack the helper side correctly, so both caller and helper can send new-commander-assigned.

Patch or port the DR-15 helper call shape with Commander reassignment call shape on old-shape targets. Current stable, current B69, adjacent B74, Miksuu, perf, historical release and historical AI-commander already fix helper unpacking in both maintained roots, but still need one notification owner or clients can receive duplicate commander messages.

Patch the UI identity edge in the same implementation branch if possible. GUI_Commander_VoteMenu.sqf should use the row value/team index already stored in the listbox instead of comparing visible leader names.

Patch Order

Step Action Validation gate
1 Decide vote semantics and write the expected outcome matrix before editing SQF. Owner decision recorded in Pending owner decisions.
2 Patch Server_VoteForCommander.sqf so no-commander/tie/player-candidate outcomes match the chosen rule. Dedicated or hosted smoke for player-majority, no-commander-majority, equal-vote and player-candidate tie cases.
3 Align GUI_VoteMenu.sqf preview text and leading-row logic with the server rule. Client preview matches server broadcast after countdown.
4 Preserve or port Server_AssignNewCommander.sqf payload unpacking per DR-15; current stable/B74.1/current B69/B74 maintained roots already use _this select 0, while docs/source and modded full forks still need old-shape handling. Manual reassignment affects the intended side on every claimed target root.
5 Choose one new-commander-assigned sender after the helper works. Clients receive exactly one reassignment message.
6 Use row value/team identity in GUI_Commander_VoteMenu.sqf. Duplicate/similar leader names cannot redirect reassignment.
7 Propagate maintained Vanilla and inspect generated diffs. Chernarus and maintained Vanilla share the same behavior.
8 Treat RequestCommanderVote and RequestNewCommander requester validation as a separate server-authority branch if not handled in the same owner-approved scope. Wrong-side/non-authorized request smoke is recorded separately.

Smoke Matrix

Scenario Expected evidence
One player candidate has chosen-rule majority Server sets wfbe_commander to that team, clients receive the matching commander-vote message, UI preview agrees.
No Commander row wins under chosen rule Server leaves commander null or AI/no-commander state as documented, UI preview agrees.
No Commander and player candidate tie Tie result matches owner policy and does not accidentally assign due to comparison fall-through.
Two player candidates tie Tie result matches owner policy and no stale previous candidate leaks through.
Vote restart after wfbe_votetime <= 0 RequestCommanderVote starts exactly one new vote for the intended side.
Manual reassignment to another player team wfbe_commander changes on the intended side and clients get exactly one notification.
Duplicate or similar leader names Commander assign UI targets the stored team row value, not visible text.
B74.5 primitive roster late join Primitive names appear when live wfbe_teams is missing/broken, no primitive row blanks or RPT spam occur, and the menu rebuilds to live team-index rows once live groups arrive.
JIP after vote/reassign Late client sees current commander state and does not replay stale preview text as truth.
Maintained Vanilla parity Same source defects are patched or explicitly left unpatched in Missions_Vanilla/[61-2hc]warfarev2_073v48co.takistan.

Agent Notes

  • Treat DR-47 vote semantics, DR-15 reassignment call shape and commander requester-authority hardening as related but separate claims.
  • Do not claim "commander voting fixed" if only the helper call shape is patched.
  • Do not claim "commander authority fixed" if only the vote comparison is patched.
  • Do not use stable/release DR-15 helper unpacking as evidence that vote semantics, duplicate notification ownership or UI identity are fixed.
  • Keep all source refs relative to Chernarus first and update the Vanilla parity note after LoadoutManager propagation.
  • Use Arma 2 OA-safe SQF only; do not import Arma 3 event/remoteExec assumptions.

Continue Reading

Previous: Commander/HQ lifecycle | Next: Commander reassignment call shape

Sidebar

Clone this wiki locally