8.5 KiB
Convoy coordination review — 27 September 2026
Findings
The latest RKS 2 logs available for this review were from 26 September. That session contains a native Defend Waypoint not provided to the node! exception in a supply-convoy escort. The existing local escort correction removes infantry Defend orders from mounted crews; it was not running in that logged game.
The supply controller also had coordination problems independent of that exception:
- Each vehicle independently drove to the same route/base destination at the same cruise speed. There was no spacing controller or leader wait for slower vehicles.
- Being within 250 metres of a base immediately counted as arrival. A shared ten-minute deadline also marked every remaining vehicle arrived regardless of location.
- Combat refreshed support and infantry waypoints every thirty seconds even when the contact had not moved, interrupting native manoeuvres.
- Native move completion and a check against the vehicle origin need different tolerances. The first new-controller test reproduced lead vehicles stopping short of a physical completion check when both used the same radius.
Current behavior
ERR_SupplyConvoyColumn owns ordinary travel. The initial lead vehicle follows the existing road route; each follower targets the preceding surviving vehicle rather than the distant base. Targets remain stable through small position changes. Followers regulate cruise speed, leave a spacing gap, and can catch up. The leader waits when a gap between neighbours exceeds 160 metres and resumes below 90 metres. After combat and at a new base leg, a stable travel order is formed from surviving vehicles’ physical distance to the next destination. This prevents restoring spawn order by sending trucks toward each other; canonical vehicle identities and combat roles remain unchanged. Released vehicles are skipped and leadership preserves route progress. A replacement leader still has to physically reach the endpoint, even if its predecessor had already completed that route.
The leader uses a 15-metre native waypoint radius and a 35-metre physical arrival check. Followers finish in sequence within 75 metres of their predecessor after it arrives. The normal 45–90 second base pause starts only after this physical column arrival. Timeouts do not advance the trip.
The troop truck waits until dismounted infantry are at least 25 metres away before withdrawing. Owned convoy vehicles slow to 8 km/h within 45 metres of their fit dismounted teams; column travel restores the cruising speed after regroup.
Travel pauses during combat and boarding; the original tactical controller retains those orders. Supply transactions retain their own control. Intentionally waiting vehicles do not accrue stuck time. During commanded travel, a missing native usable-vehicle association can be restored for the healthy original seated crew. Stock SCR_AIRemoveStuckVehicle removes that association after failed movement; a retained crew needs it to accept driving orders again. Restoration is checked when travel starts and on bounded retries, with an explicit journal event. No five-metre progress triggers a native route retry every 45 seconds; three minutes without progress releases that vehicle from the column and logs its position. Physical vehicles, surviving crew and loot remain; no teleport or replacement spawn is used.
Reboarding tracks occupied seats and the farthest remaining soldier’s distance. Thirty seconds without either kind of progress permits a retry for only that unfinished team, at most three times. The old waypoint is cancelled and its replacement waits until a subsequent tick, allowing native reservations to clear. Seated soldiers are not moved. A five-minute hard deadline retains the finite stranded-team policy; active approaches no longer lose their squad at an unconditional two-minute cutoff.
Unchanged contacts no longer recreate tactical orders. A changed contact can refresh them after the existing thirty-second limit; dismount retries and emergency abandonment retain their separate policies.
The HQ journal now records the selected lead vehicle, spacing waits/resumes, periodic neighbour-gap and supply state, route retries, stranded vehicles and departures.
Validation
tests/test_convoy_column.py executes the production controller against doubles of native entities and waypoints. It covers spacing hysteresis, stable targets, physical arrival, supply-order ownership, route-preserving leader promotion, held-time exclusion, retries and loss. It also exercises the actual unchanged-contact order policy and rejects native-test success based on movement before departure.
tests/test_supply_convoys.py verifies that expired travel deadlines and proximity to the old 250-metre base boundary no longer create arrival, and that supply/combat holds prevent departure.
The native fixture starts three production convoys (18 vehicles, 75 soldiers), checks physical cargo and seating, observes all vehicles moving, injects one labelled contact, verifies both infantry teams dismount and reboard, waits for real arrival and the normal pause, and measures truck movement from a new position captured after the next leg starts. The contact is a test input, not proof of native enemy perception. The final fixture parks its observer away from the convoy route and gives that observer a convoy-friendly native perceived faction to prevent unrelated combat from contaminating the injected-contact sequence. The fixture explicitly resets the scenario at completion; it no longer tries to kill a protected prisoner as cleanup.
Native iteration evidence is preserved under .local/analysis/convoy-coordination-2026-09-27/. The second run completed convoy movement, dismount, boarding, regroup and physical arrival, but failed obsolete player-death cleanup; its runner result remains test-failed. Its old next-leg assertion also counted earlier regroup displacement, so the final fixture requires a fresh post-departure movement sample.
The third run exposed crossed vehicle ordering after combat and also stopped on a native No suppression volume provided! exception while unrelated units were reporting the observer near the airfield. Its failed result is preserved; the suppression exception is not claimed fixed by the convoy ordering change. The isolated repeat separates that engine/ambient-combat issue from the controlled convoy sequence.
The fourth run had all 18 vehicles moving and both teams dismounted, but only 13 of 14 passengers had reboarded when the old two-minute deadline released a team. This is preserved as a failed native test and motivated the progress-aware boarding policy.
The fifth run stopped in the test-only seat logger after an infantry actor lost its AI agent during dismounted movement. The diagnostic dereference is now guarded. Vehicles moving near dismounted infantry also motivated the clearance and low-speed protection; the log does not identify a definitive damage instigator.
The sixth run reboarded all 14 passengers and formed a physical travel order, then reproduced a healthy seated troop-truck driver remaining stationary despite three waypoint retries. The three-minute watchdog correctly exposed/released it instead of inventing arrival. The subsequent change adds bounded usable-vehicle restoration and native driver/group-action diagnostics; the old failure itself does not prove which native action discarded or blocked driving.
The seventh run completed the strengthened fixture: all 18 vehicles moved, both infantry teams dismounted, all 14 passengers reboarded, all three convoys departed for another base, and the original troop truck moved twenty metres measured strictly after its next-leg departure. There were no script errors, VM exceptions or stranded-vehicle releases in that run. Native boarding emitted temporary stuck/reset warnings before completing. The runner records smoke-completed, unchanged source/external-addon hashes, and confirmed cleanup. All repository checks passed. Generic qualification still exits nonzero for existing external localization/resource and inherited-prefab keyword errors; the raw report is preserved in r7-completed/qualification.log. The successful run did not exercise missing-registration restoration, so it does not establish that as the cause of the sixth run’s stall.
Dedicated multiplayer and long-session navigation across all road layouts remain separate validation requirements. Native obstacle/pathfinding failures are recoverable only within the engine's capabilities; the controller now exposes and bounds stationary failures rather than reporting them as arrival.