Skip to content

Town AI Vehicle Despawn Safety

rayswaynl edited this page Jun 24, 2026 · 15 revisions

Town AI Vehicle Despawn Safety

Implementation playbook for Deep-review findings DR-45, the confirmed town-AI vehicle cleanup bug in the maintained source missions.

Scope: source Chernarus Missions/[55-2hc]warfarev2_073v48co.chernarus plus maintained Vanilla Missions_Vanilla/[61-2hc]warfarev2_073v48co.takistan. Apply gameplay patches to source Chernarus first, then propagate generated missions with Tools/LoadoutManager or a deliberate maintained-Vanilla port.

Status

Field Value
Finding Confirmed bug; formal record is Deep-review findings DR-45
Backlog id town-ai-vehicle-despawn-safety
Primary file Server/FSM/server_town_ai.sqf
Risk A town-AI vehicle can be deleted while a player is aboard if that player is not the group leader.
Patch type Small server-side cleanup guard

Current Branch Matrix

B74.2 current-head follow-up town-ai-vehicle-despawn-b742-current-head-followup-2026-06-24 rechecked the maintained roots after B74.2 advanced from origin/claude/b74.2-aicom@d472da6a to origin/claude/b74.2-aicom@21b62b04. Current stable/B74.1/B74.2 still carry the tracked-vehicle crew guard in source Chernarus only; maintained Vanilla remains unsafe. The scoped d472da6a..21b62b04 town-AI file diff is empty, so the branch advance does not change DR-45 status. Docs/source, Miksuu, perf, historical release and the live AI fleet branch remain old-shape unsafe in both maintained roots. origin/claude/upstream-town-defense-diag-sync@cde1f1fc remains delegated-cleanup diagnostics evidence, not DR-45 closure.

Branch / root Evidence Status
Docs/source HEAD@ce3cf871e1e7 Chernarus and maintained Vanilla server_town_ai.sqf initializes wfbe_active_vehicles at :30, appends server-created/delegated vehicles at :161,:179, deletes tracked inactive vehicles with only !(isPlayer leader group _x) at :214, clears at :219, and does not check player crew. Checked paths are source-unchanged from 2a4020586 and 3a9ba92e (git diff --name-status 2a4020586..HEAD / 3a9ba92e..HEAD is empty for both maintained-root files). Patch-ready DR-45 still present in both maintained roots.
Current stable/B74.1 origin/master@f8a76de34 / origin/claude/b74.1-aicom@f8a76de34 Source Chernarus initializes at :41, appends at :242,:261, skips player units in town-team cleanup at :312, and deletes tracked vehicles only when ({isPlayer _x} count crew _x) == 0 at :325. Maintained Vanilla has the same activation/append line shape but still deletes units without !isPlayer at :309 and tracked vehicles with only !(isPlayer leader group _x) at :319. No checked Server_CleanupExpiredTownDefenseAssets.sqf path exists. Partial source-present candidate: Chernarus carries the DR-45 crew guard; maintained Vanilla remains patch-ready. Do not call current stable closed until Vanilla propagation and Arma smoke are done.
Current B74.2 origin/claude/b74.2-aicom@21b62b04 Source Chernarus keeps the previous B74.2 DR-45 line shape: initializes at :43, appends at :254,:273, skips player units at :324, and keeps the crew-count vehicle delete at :337. Maintained Vanilla has no checked delta from current stable and remains leader-only at :319. git diff --name-status d472da6a..origin/claude/b74.2-aicom is empty for both checked server_town_ai.sqf paths; origin/master..origin/claude/b74.2-aicom line-drifts source Chernarus only. Branch-only source Chernarus line drift over the same partial candidate; maintained Vanilla still needs the guard.
Miksuu upstream b8389e748243 Chernarus and maintained Vanilla Same tracked-vehicle cleanup shape with line drift: initialize :28, append :140,:159, delete at :195, clear at :201; no checked Server_CleanupExpiredTownDefenseAssets.sqf path. Upstream still needs the tracked-vehicle occupancy guard.
origin/perf/quick-wins@0076040f Chernarus and maintained Vanilla Same tracked-vehicle cleanup shape with line drift: initialize :30, append :166,:184, delete at :219, clear at :224; no checked persistent-defense helper. Perf branch does not rescue this safety bug.
Historical release commit a96fdda2 Chernarus and maintained Vanilla Same tracked-vehicle cleanup shape with line drift: initialize :28, append :145,:164, delete at :200, clear at :206; no checked persistent-defense helper. Current origin exposes no release/* head on 2026-06-23. Historical release evidence still needs the player-occupancy guard before release-ready safety wording.
origin/feat/aicom-fleet-improvements@cc5090bed4ad Chernarus and maintained Vanilla Same unsafe tracked-vehicle cleanup shape as the older stable-era line drift: initialize :28, append :152,:171, delete at :207, clear at :213. The live AI feature branch does not close DR-45.
origin/claude/b69@8d465fce and adjacent B74 origin/claude/b74-aicom-spend@b23f557f git diff --name-status origin/claude/b69..origin/claude/b74-aicom-spend is empty for checked server_town_ai.sqf paths. Both match current stable/B74.1 for this lane: source Chernarus preserves player units at :312 and deletes tracked vehicles only when ({isPlayer _x} count crew _x) == 0 at :325; maintained Vanilla remains unsafe at unit cleanup :309 and vehicle cleanup :319. Same Chernarus-only candidate as current stable/B74.1; maintained Vanilla and smoke remain open.
origin/claude/upstream-town-defense-diag-sync@cde1f1fc Merge-base with current stable is be2bbd084. Its diff is delegated cleanup/diagnostics work (Client_CleanupDelegatedTownAI.sqf, Common_CreateTownUnits.sqf, constants and init paths; +176/-67 across checked maintained roots), and git diff --check is clean. It does not change checked server_town_ai.sqf semantics from current stable: source Chernarus keeps the crew guard at :325; maintained Vanilla remains leader-only at :319. Branch-only delegated-cleanup diagnostics evidence, not DR-45 closure. Preserve as adjacent branch intel only.

Source Chain

File Evidence
Common/Functions/Common_CreateTownUnits.sqf Town teams are created from templates, vehicles returned by WFBE_CO_FNC_CreateTeam are appended to _town_vehicles, each server-local vehicle starts WFBE_SE_FNC_HandleEmptyVehicle, and the function returns [_town_teams, _town_vehicles].
Server/FSM/server_town_ai.sqf On activation, server-created town vehicles are appended to the town variable wfbe_active_vehicles; on inactivity, the same variable is iterated for cleanup.
Server/FSM/server_town_ai.sqf:205-219 on docs/source HEAD@ce3cf871e1e7; current stable/B74.1 Chernarus line drift :305-331; current stable/B74.1 Vanilla :305-325; current B74.2 Chernarus :317-343 Inactivity cleanup deletes town team units/groups, then town vehicles, then clears wfbe_active_vehicles.
Server/FSM/server_town_ai.sqf:214 on docs/source HEAD@ce3cf871e1e7; current stable/B74.1/current B74.2 Vanilla line drift :319 Vehicle deletion on old-shape and maintained Vanilla paths checks alive _x and !(isPlayer leader group _x), but does not inspect vehicle crew/cargo/turret occupants. Current stable/B74.1/B74.2 source Chernarus instead uses the crew-count guard at :325 / :337.
Server/Functions/Server_HandleEmptyVehicle.sqf Separate empty-vehicle cleanup loop resets its timer while {alive _x} count crew _vehicle > 0; this is not the source of the town inactivity bug.
Server/Functions/Server_OperateTownDefensesUnits.sqf Static defense removal has its own gunner/operator handling and should be validated separately from town vehicle despawn.

Failure Condition

The unsafe delete path exists when all of these are true:

Condition Source-backed reason
Town becomes inactive time - (_town getVariable "wfbe_inactivity") > WFBE_C_TOWNS_UNITS_INACTIVE.
Vehicle is still tracked The vehicle remains in _town getVariable 'wfbe_active_vehicles'.
Vehicle is alive Cleanup only enters the delete branch under if (alive _x).
Player is aboard but not leader Existing guard only checks isPlayer leader group _x.
Vehicle has a player in crew/cargo/turret Existing cleanup does not check crew _vehicle, so any non-leader player occupant can be missed.

This is a player-experience correctness bug, not a generic empty-vehicle timeout bug. Server_HandleEmptyVehicle.sqf:26-30 is already crew-aware; the unsafe delete lives in the town inactivity branch and is tracked as DR-45.

Branch-Historical Adjacent Work

Earlier 89ae9dad-era docs recorded a town-defense diagnostics / captured-defender persistence batch with Server_CleanupExpiredTownDefenseAssets.sqf. A fresh 2026-06-24 ref scan found no Server_CleanupExpiredTownDefenseAssets.sqf path in docs/source HEAD@ce3cf871e1e7, current stable/B74.1 origin/master@f8a76de34, current B74.2 origin/claude/b74.2-aicom@21b62b04, current Miksuu b8389e748243, origin/perf/quick-wins@0076040f, historical release commit a96fdda2, origin/feat/aicom-fleet-improvements@cc5090bed4ad, current B69 origin/claude/b69@8d465fce, adjacent B74 origin/claude/b74-aicom-spend@b23f557f or live origin/claude/upstream-town-defense-diag-sync@cde1f1fc.

Keep that helper evidence as historical/branch-specific until a target branch actually contains the file again. It is not a substitute for this DR-45 fix:

  • captured-defender persistence, when present on a branch, is a separate cleanup surface that also needs player-occupancy review;
  • DR-45 guards inactivity-time deletion of an already tracked wfbe_active_vehicles entry with a player aboard;
  • both cleanup surfaces should be smoke-tested together if a future branch reintroduces the persistence helper.

Historical DR-48 Capture-Persistence Cleanup

DR-48 remains useful historical evidence for 89ae9dad-era branches, even though the helper is absent from the 2026-06-13 checked heads above:

Branch / file Evidence Why it matters
89ae9dad Chernarus and maintained Vanilla Server/Init/Init_Server.sqf:55 compiles WFBE_SE_FNC_CleanupExpiredTownDefenseAssets; server_town_ai.sqf:61 calls it per town; server_town.sqf:238,241,260,324 tracks captured defender persistence through wfbe_persistent_town_defense_assets. Any branch carrying this helper has a second cleanup surface beyond the tracked inactive vehicle loop.
89ae9dad Server_CleanupExpiredTownDefenseAssets.sqf:58,62-63 in both maintained roots The GROUP path deletes every unit in the group at :58; the OBJECT path checks only isPlayer _asset and isPlayer leader group _asset before deleteVehicle _asset at :62-63. If this helper is reintroduced, audit player crew / cargo / turret occupancy for object assets and player units in group assets before release wording.

Safe Patch Shape

Use an explicit vehicle local variable so the nested crew count does not reuse the outer _x accidentally:

//--- Teams vehicles.
{
	private ["_vehicle", "_hasPlayerCrew"];
	_vehicle = _x;
	if (alive _vehicle && {local _vehicle}) then {
		_hasPlayerCrew = ({isPlayer _x} count crew _vehicle) > 0;
		if (!_hasPlayerCrew && !(isPlayer leader group _vehicle)) then {deleteVehicle _vehicle};
	};
} forEach (_town getVariable 'wfbe_active_vehicles');

The leader group guard is behavior-preserving. If a future code owner wants the simpler rule, the target behavior can become:

if (({isPlayer _x} count crew _vehicle) == 0) then {deleteVehicle _vehicle};

That simpler version is easier to reason about, but it is a behavioral change because it removes the current leader-based exception. Prefer the behavior-preserving guard first unless testing proves the exception is redundant.

Edge Cases To Check

Edge case Expected result
Empty AI-only town vehicle Deleted during town inactivity cleanup.
AI-crewed town vehicle with no player aboard Deleted during town inactivity cleanup.
Player driver Vehicle survives cleanup.
Player gunner/commander/turret occupant Vehicle survives cleanup.
Player cargo/passenger Vehicle survives cleanup.
Player group leader near but not aboard Existing leader guard may still preserve old behavior; decide whether this is desired before simplifying.
Static defense gunner Unchanged; static defenses are handled by Server_OperateTownDefensesUnits.sqf.

Validation

Gate Check
Static source check Confirm server_town_ai.sqf no longer deletes wfbe_active_vehicles without a crew player check.
In-game smoke Spawn/wake a town with vehicle templates, board a town-AI vehicle as cargo/gunner, force or wait for town inactivity, and verify the vehicle is not deleted while occupied.
Regression smoke Let the same town despawn with empty AI-only vehicles and verify cleanup still removes them.
RPT No scheduler or undefined-variable errors around town AI despawn.
Generated missions After a gameplay patch, run dotnet run from Tools/LoadoutManager in a correctly named a2waspwarfare checkout; missing 7za is packaging-only unless deployment packaging is required.

Implementation Notes For Agents

  • Use Bohemia Interactive Arma 2 OA scripting semantics; do not assume Arma 3 commands or event behavior.
  • Use -LiteralPath in PowerShell when reading or editing [55-2hc] paths.
  • Keep gameplay changes in the Chernarus source mission first.
  • Do not touch Missions_Vanilla by hand unless the LoadoutManager path is explicitly unavailable and the user approves manual propagation.
  • If adding diagnostics, keep detailed logs behind WF_Debug; a small always-on WARNING is only justified if testers need to confirm a state transition in RPT.

Related Pages

Continue Reading

Previous: HC delegation/failover | Next: Client UI/HUD/menus

Main map: Home | Fast path: Quickstart | Agent file: agent-context.json

Sidebar

Clone this wiki locally