Improve AI garrisons, player recovery and mission administration

This commit is contained in:
2026-09-24 22:12:45 +02:00
parent 1b1a8b5173
commit 2551d171b3
115 changed files with 3622 additions and 547 deletions
+11 -7
View File
@@ -6,22 +6,22 @@ Implemented 2026-09-23 in the combined Core addon. These are server-owned missio
Only a fresh BODY report delivered to HQ identifies a body for aggression. The identity is the immutable formation SourceId plus original roster slot. A status-known death can subsequently be identified once; multiple observers, repeat deliveries and status reports cannot inflate this counter. Missing or silent units do not count.
`ERR_HQWatchRules.Aggression(bodies)` is `clamp(floor(bodies / 3), 0, 30)`. `Hunters(level)` is `ceil(level / 2)`, capped at 15:
`ERR_HQWatchRules.Aggression(bodies)` is `clamp(floor(bodies / 3), 0, 30)`. `Hunters(level)` is `3 + ceil(clamp(level, 0, 30) × 12 / 30)`, capped at 15:
| Identified bodies | Aggression | Cumulative UAZ allowance |
|---:|---:|---:|
| 0–2 | 0 | 0 |
| 3–8 | 1–2 | 1 |
| 9–14 | 3–4 | 2 |
| 45 | 15 | 8 |
| 0–2 | 0 | 3 |
| 3–8 | 1–2 | 4 |
| 9–14 | 3–4 | 5 |
| 45 | 15 | 9 |
| 87–89 | 29 | 15 |
| 90+ | 30 | 15 |
The existing confirmed-loss infantry response budget remains independent. The new allowance creates **additional hunter UAZ-PKM vehicles**, separate from supply convoys, each with the selected primary enemy faction's driver and gunner. There are at most 15 deployments per round, not an endless replacement pool. Destroyed, captured or failed vehicles consume their deployment; surviving entities and loot remain physical. Surviving AI crew retain their HQ registration and skill profile when a driving task ends; capture releases the mission binding. The status string distinguishes active vehicles from the cumulative allowance.
Deployment waits until the prison is unlocked and checks friendly-site road access, terrain, collision, the force-ledger cap and a 400 m player exclusion radius. A blocked candidate is retried after 30 seconds; native crew readiness has a 30-second deadline. Vehicles are registered only with their actual original native agents and seat occupants. Faction selection, inventory, radio fitting and body/intel ownership use existing mission services.
Deployment waits until the prison is unlocked. Three initial UAZs are planned around the opening player centroid (prison position if no player exists), on actual roads at least 90 degrees apart and at least 600 m from that center. The bounded survey tries up to 64 candidates in four rings (800–2150 m), eight queries per HQ second, and retains three clear positions before spawning at most one vehicle per second. Every spawn rechecks terrain/collision, the force ledger and a 400 m exclusion around every player. Unsafe placement is withheld and logged. Additional aggression deployments use friendly-site roads and 30-second spacing. Native crew readiness has a 30-second deadline. Vehicles are registered only with their actual original native agents and seat occupants. Faction selection, inventory, radio fitting and body/intel ownership use existing mission services.
Without delivered sightings, hunters patrol roads between friendly objectives. With fresh actionable HQ memory, they intercept a road near the last reported/predicted position. Destination selection does not query live player positions. Orders must traverse the existing physical radio network. Loss of communications prevents new orders; it does not magically reveal a player or cancel the last received order.
Each hunter crew requests one physical manpack through the existing finite radio-fitting service; destroyed or looted radios are not replenished. Without delivered sightings, hunters patrol roads between friendly objectives. With fresh actionable HQ memory, they intercept a road near the last reported/predicted position. A fresh delivered contact bypasses the 30-second patrol cooldown and cancels a pending patrol downlink. An interception already in radio transit is allowed to complete; updates are limited to one attempt per five seconds. The destination is a road within 250 m of the delivered belief. Destination selection does not query live player positions. Orders must traverse the existing physical radio network. Loss of communications prevents new orders; it does not magically reveal a player or cancel the last received order.
## Objective crews
@@ -57,3 +57,7 @@ The complete HQ journal is `$logs:rereintroduced-hq.log` (existing filename reta
Production-method policy tests cover body/status deduplication, three-body thresholds, 30/15 caps, reset, authority/capture boundaries, maximum skill binding/restoration, regular aim-error selection and native perception fallback. The native `aggression` fixture exercises actual body intake, a physical UAZ with seated crew, radio delivery and movement, objective reservations, medical-stash reinforcement admission and teardown. This is local native Workbench validation, not a dedicated-server multiplayer or full 15-UAZ performance benchmark.
Final local run: `/tmp/erri-aggression-native7/logs/logs_2026-09-23_15-01-06`. All 14 native assertions and the completion marker passed: full medical defence at terrain height, seated driver/gunner, real radio delivery, driving over 30 m, bounded deployment and surviving-crew profile after release. Source stayed unchanged during the run. The runner reported a transient empty-argv Wine `enfMain` during cleanup; a subsequent explicit private-prefix idle check passed. Existing external localization/resource messages remain in the native log; this is not a clean-log claim. `python tools/check.py` passed, and the final hunter lifecycle and affected skill/body/registration policy tests passed separately.
Opening-patrol regressions: `test_hunter_opening.py` executes the actual geometry and order-selection methods, covering angular separation, insufficient candidates, first-contact preemption, in-flight order preservation, lost radio and retry throttling. `test_hq_watch.py` checks the three-to-fifteen allowance across all aggression levels.
2026-09-23 opening-patrol validation: `/tmp/erri-opening-hunters-native2/logs/logs_2026-09-23_17-32-18` completed all 16 native assertions. Three physical UAZs with seated two-man crews and manpacks were confirmed at mutually separated road starts before any fixture body reports. Three distinct delivered body reports then raised allowance to four. The test observed real HQ radio orders and over 30 m of native driving, preserved objective security, and verified survivor handling. Source/addon fingerprints remained unchanged and cleanup was confirmed. Existing external resource errors remain; multiplayer and an actual patrol sighting through the complete uplink were not tested. First-contact preemption is covered by the production-method regression with radio adapters.
+3 -6
View File
@@ -11,15 +11,12 @@ Adapted from independently authored, user-authorized AI code. Original files rem
| `escapists-ai/Scripts/Game/EscapistsAI/EAI_AIResponseSystem.c` | `b3e1263e986837744a70fbaedaa6e57afae7f2981a21211d3a2066e2c63ac84d` | First combat-component section's Expert skill clamp and native reset handling only; no convoy spawning, original faction/group hooks or other sections imported |
| `escapists-ai/Scripts/Game/EscapistsAI/EAI_AIConfig.c` | `8c320d3163d443b43e50547734702484c8ad51f2cffe88cf6dfd33aaf339ec01` | `stingerChanceOneIn`, default 15 and valid range 0..10000 |
The successor HQ owns `ERR_EnemyEquipment`. Registration supplies exact physical groups; two seconds after group registration, at most five scans discover initialized members. Entries retain exact actor/group identity, with 128 group and 2048 actor limits. Per-actor inventory submission is finite. Accepted pending operations are never repeated; unresolved completion at the fifth check ends processing permanently for that actor. Explicit failure may retry before the fifth check. A success callback ends issuance even if the item was dropped before it could be observed. A late callback after Stop cannot restart this service, although native accepted insertion itself is not cancellable through this API.
The successor HQ owns `ERR_EnemyEquipment`. Registration supplies exact physical groups; five startup scans discover initialized members. Entries retain exact actor/group identity, with 256 group and 2048 actor limits. Inventory grants are finite. Accepted pending operations are never repeated; a late callback after Stop cannot restart issuance. See the current loadout policy below for launcher and mine checks.
The exact allowed launcher is `{3DF204EEE0534EF2}Prefabs/Weapons/Launchers/FIM92_Stinger/Launcher_FIM92_Stinger.et`, owned by WCS Armaments. The successor requests insertion into `PURPOSE_WEAPON_PROXY`, preserving native slot constraints and other equipment. It creates no loose ammunition or replenishment; actual prefab loadout and operational AI firing need native validation.
Expert minimum binds only after initialization to an eligible, living, nonplayer member of a registered military enemy group in the active successor mission. Native SetAISkill and ResetAISkill enforce that scoped floor; higher skills are preserved. No perception/target knowledge is changed. Unregistration or Stop clears the binding and restores the skill captured at first binding. Convoy-gunner Cylon specialization is not implemented here because no production convoy-gunner registration exists yet.
The original fixed-FIM and one-in-N policy has been superseded by [percentage-based faction loadouts](enemy-loadouts.md). FIM-92 remains the fallback. Native slot constraints, mission ownership and finite grants remain enforced.
Settings migrate through the existing additive-default reader and import helper. Existing valid ten-key/six-key files preserve their values and obtain 15 for missing `stingerChanceOneIn`; explicitly present malformed values remain invalid. `/esc hq stinger show|set N` changes only actors that have not rolled yet: 0 disables, 1 selects every eligible actor, 2..10000 selects one in N. The existing ten native menu fields are preserved; this extra key is available through text commands. Unsupported convoy/simulation/start keys are still reported as deferred by the importer, never exposed as working settings.
`tests/test_enemy_equipment.py` executes actual eligibility, callback, insertion, scoped skill and coordinator bodies against native API doubles. It covers pending nonduplication, success after item removal, finite rejected/failed requests, timeout quarantine, capture, absence, wrong mode/faction/player/client/editor, native resets, higher skills, restoration, delayed group membership, registration dedupe, terminal stop and bounded scans. These are policy regressions, not native inventory or multiplayer proof. Expanded external runtime qualification remains separate.
Old `stingerChanceOneIn` settings migrate to the nearest integer percentage; 15 becomes 7%, 1 becomes 100%, and 0 stays off. The HQ page exposes both anti-air and AP-mine percentages. `/esc hq stinger` remains an alias but now accepts a percentage.
## Magnified optics
+40 -8
View File
@@ -19,6 +19,7 @@ Open the normal game chat and enter a command. Core provides:
| `/esc status` | Server administrator | Current objective or startup failure cause; adds HQ status when Chat is loaded |
| `/esc killais` | Server administrator | Kill AI characters within 1,000 m of your living character; preserve players and vehicles |
| `/esc settings` | Server administrator | Current shared settings and values |
| `/esc mission keepweapon set 0` / `1` | Server administrator | Disable/enable retaining the held firearm while unconscious and equipping it after revival; applies from the next knockout |
| `/esc mission radio show` | Server administrator | Radio defence duration in seconds |
| `/esc mission radio set N` | Server administrator | Save a whole-number duration from 30 to 1800 seconds |
| `/esc mission time show` | Server administrator | Current clock and saved next-round time/speed |
@@ -39,8 +40,9 @@ Additional AI commands:
| Command | Effect |
| --- | --- |
| `/esc hq memory` | Show bounded delivered-report beliefs, confidence, uncertainty and travel estimates |
| `/esc hq stinger show` | Show the saved one-in-N initial equipment chance |
| `/esc hq stinger set N` | Set 0 to disable, 1 for every eligible actor, or 2–10000 for one in N; affects actors that have not rolled yet |
| `/esc hq aa show` / `/esc hq aa set N` | Enemy MANPADS grant chance, 0–100% or Random; default 7% |
| `/esc hq mines show` / `/esc hq mines set N` | Enemy AP-mine grant chance, 0–100% or Random; default 60%, up to two carried mines |
| `/esc hq stinger show` / `/esc hq stinger set N` | Legacy alias for anti-air percentage, now 0–100 rather than one-in-N |
| `/esc hq convoy show` | Show the finite deployment task, retained vehicles, native cargo insertion results and stop reason |
| `/esc hq convoy start` | Deploy the next unused slot in this round’s configured convoy allowance after physical force admission |
| `/esc convoys show` | Show the saved count and active fleet |
@@ -60,33 +62,57 @@ Core also provides `/esc mission abandon`: an administrator-only explicit defeat
## Mission menu
**Esc → Escapists Reintroduced** opens one administrator menu. Its top navigation
**Esc → Co10 Escape Reintroduced** opens one administrator menu. Its top navigation
stays visible on every page:
| Page | Controls |
| --- | --- |
| Mission | Radio defence duration and next-round convoy count |
| Mission | Radio defence duration, next-round convoy count and unconscious weapon retention |
| World | Start time, Random day, time speed, date and weather |
| Factions | Escapists, enemy and independent faction choices; Random all |
| Mods | Content pack and individual faction switches |
| HQ | Report interval, support squad limit and response radius |
| HQ | Report interval, support squad limit, response radius, anti-air percentage and AP-mine percentage |
| Intel | Document frequency, exact-reveal chance, summary and reroll |
| Status | Scrollable live mission and service status |
| Journal | Scrollable HQ activity, pause/resume and jump to latest |
| Journal | Readable HQ activity, technical-detail toggle, pause/resume and jump to latest |
Changing pages preserves drafts and never applies them. Escape returns to Mission;
a second Escape closes the menu (an active text edit consumes Escape first).
Server authorization and capability checks still control every mutation.
Each of the thirteen value fields includes a short explanation of its effect
and when it applies. Equipment percentages affect newly equipped soldiers; time,
weather and convoy settings apply next round. The faction page distinguishes your
faction, the enemy that controls HQ, and the other hostile faction.
**Keep weapon when unconscious** has explicit Enabled/Disabled buttons on Mission. It defaults to Enabled and applies from each player’s next knockout. With it enabled, the same gun is retained and re-equipped after revival; Disabled restores the normal ground drop. Unconscious and dead spectators use **Left/Right arrows** to change teammates.
The Journal normally shows sentences with real server-local clock time
(`HH:MM:SS`), event numbers and radio message numbers. Timestamps are captured
when events occur and stay unchanged when history is opened or resumed. It distinguishes local sightings, reports awaiting transmission,
received reports and delivered orders. **Show technical details** also displays
the original records, including elapsed seconds, coordinates, identifiers and diagnostic fields;
switching views preserves history and the live cursor. The server journal file
contains each readable summary followed by its unchanged technical record.
Status labels explicitly identify mortar readiness, identified-body aggression
and the total UAZ deployment allowance.
Validated on 2026-09-23 with the complete repository checks and the isolated native
`prisoner-kit` fixture (359 assertions, no script/runtime failures). Native checks
cover all thirteen description bounds using DPI-correct measurements, eight-page
navigation and the readable/technical journal toggle without cursor/history loss.
The fixture still reports existing installed-content resource/keyword errors;
this is local Workbench validation, not a dedicated-server multiplayer test.
## Optional content
Use **Esc → Escapists Reintroduced → Mods** for server-admin RHS and individual faction switches.
Use **Esc → Co10 Escape Reintroduced → Mods** for server-admin RHS and individual faction switches.
Selections apply after mission restart, while Workshop dependencies remain loaded.
See [content packs and the modder registry](content-packs.md).
## Random settings
Every editable setting on **Mission**, **World**, **HQ** and **Intel** has a
The numeric and world settings on **Mission**, **World**, **HQ** and **Intel** have a
**Random** button. It selects the draft; press **Apply** to save it. You can still
enter a fixed value. The start-time row also offers **Random day**.
@@ -154,3 +180,9 @@ Everon also sets `ScoutCount 10` in its scenario definition. This creates ten fi
Search helicopter: `heliTimerMinutes` defaults to 15 minutes after prison escape
and after aircraft loss. Use `/esc hq heli show`, `/esc hq heli timer set 15`,
or `/esc hq heli return`. See [search-helicopter.md](search-helicopter.md).
Enemy equipment percentages affect soldiers whose initial loadout has not yet been rolled. They do not replace authored equipment or replenish dropped/looted items. Mines are carried, not automatically planted. See [enemy loadouts](enemy-loadouts.md) for faction launcher selection and fallback.
**Factions → Random all** immediately saves Random for all three roles; no second Apply is needed. Random remains saved after closing the menu and is resolved afresh at each round startup. Current factions stay unchanged until the next round. Individual dropdown edits still use **Apply factions**.
The 2026-09-23 native `prisoner-kit` fixture verified that Random all saves via the authenticated owner RPC, survives a fresh settings load and menu reopen without Apply, and preserves current-round faction roles. It completed 357 assertions without script/runtime failures; installed external resource errors still make the engine report non-clean. Regression coverage is in `test_faction_menu.py` and `test_faction_selection.py`.
+3 -1
View File
@@ -1,6 +1,6 @@
# Mission content packs and factions
Administrators open **Esc → Escapists Reintroduced → Mods** (also available in `/esc menu`). RHS
Administrators open **Esc → Co10 Escape Reintroduced → Mods** (also available in `/esc menu`). RHS
and its US Marines, Russian Armed Forces and ION factions default to enabled.
Each faction can be disabled independently. Disabling the parent pack excludes
all its factions and the mission's optional RHS optics, while retaining child
@@ -131,3 +131,5 @@ replication acceptance. No Workshop publishing was performed.
Faction hostility follows the native
[SCR_FactionManager API](https://community.bistudio.com/wikidata/external-data/arma-reforger/ArmaReforgerScriptAPIPublic/interfaceSCR__FactionManager.html),
with both directions validated before preparation can finish.
Faction entries may optionally specify `AntiAirLauncher` for a loaded MANPADS prefab. The HQ anti-air percentage uses that override, otherwise searches the native faction item catalog and falls back to FIM-92 when necessary. See [enemy loadouts](enemy-loadouts.md) for supported naming, compatibility checks and finite grants.
+68
View File
@@ -0,0 +1,68 @@
# Enemy infantry loadouts
**Esc → Co10 Escape Reintroduced → HQ** has two percentage settings, each accepting
0–100 or Random:
| Setting | Default | Effect |
| --- | --- | --- |
| Anti-air launchers | 7% | One initially loaded faction MANPADS, with FIM-92 fallback |
| Anti-personnel mines | 60% | Up to two carried PMN-4 mines, subject to inventory space |
These are independent per-soldier grant probabilities, not exact population quotas.
They apply to eligible living, nonplayer military members of mission-owned hostile
groups, including hostile independent factions. Existing authored equipment is
preserved. Specialist loadouts that bypass ordinary fitting remain unchanged.
Changing a value affects soldiers whose initial roll has not happened yet; it does
not reroll existing soldiers. Mines are inventory loot, not automatically planted.
Commands are `/esc hq aa show|set N|set random` and
`/esc hq mines show|set N|set random`. The old `/esc hq stinger set N` alias now
means a percentage. Server authentication and the existing settings save/validation
path apply. Canonical keys are `antiAirChancePercent` and
`antiPersonnelMineChancePercent`. Old `stingerChanceOneIn` files migrate to the
nearest integer percentage: 0 → 0%, 1 → 100%, 15 → 7%, 37 → 3%.
Very small probabilities can round to zero. The canonical key takes precedence.
Missing settings default to 7% and 60%.
## Faction launchers and modder overrides
An `ERR_ContentOption` can specify `AntiAirLauncher` as a prefab ResourceName.
The lookup matches `NativeFactionKey` in `Configs/ERR/ContentRegistry.conf`.
Otherwise, enabled entries in that faction's native ITEM catalog are checked for
MANPADS prefab names (Stinger/FIM92, Igla, Strela or MANPAD under Launchers).
Catalog inspection is bounded to 4,096 entries. Unrecognized naming requires an
explicit override. USSR/FIA use the installed WCS Igla when no catalog candidate
exists. Other factions, unavailable resources and confirmed insertion failures
fall back to the WCS FIM-92; no additional mod dependency was added.
The runtime verifies that the replacement physically occupies a weapon slot,
is a rocket launcher, and has a chambered round or loaded magazine. A newly
issued unusable replacement is removed only while still in that soldier's
inventory, with confirmed deletion before the FIM request. Authored equipment
is never deleted to make room. This verifies equipment and ammunition, not the
mod's targeting/lock-on behavior in combat.
Inventory operations have finite startup checks. Pending operations are not
repeated or replaced while their result is unknown. Dropping, firing or looting a
granted launcher does not earn a new one; mine allowance is likewise finite.
No loose items are spawned when inventory capacity is unavailable.
`AA PROFILE`, `AA EQUIPMENT`, `AA FALLBACK` and `MINE EQUIPMENT` journal entries
record selection, grants and failure reasons.
## Verification
`test_enemy_loadout.py` executes production grant methods with native API doubles:
all percentage boundaries, preferred success, fallback, exact-item removal,
pending-operation quarantine, missing/looted items, capture, authored mines and
finite mine grants. Existing coordinator, admin/menu and settings migration tests
cover integration. `--project core --smoke enemy-loadout` is a Workbench-only
fixture for physical inventory, loaded weapons and HQ menu capture.
The 2026-09-23 local Workbench fixture completed four assertions with no script
or runtime failures: persisted percentage settings, a physical test group, loaded
WCS Igla and fallback FIM-92 plus two carried AP mines, and HQ navigation.
The native checker still reports installed RHS/WCS localization/resource and
external prefab-field errors; this is not a clean whole-mod engine report.
Multiplayer replication and actual missile targeting/firing were not tested.
Final local fixture logs: `/tmp/erri-loadouts-native2/logs/logs_2026-09-23_15-29-59`. Source and external-addon fingerprints remained unchanged; runner cleanup was confirmed. Native menu navigation passed, but the engine screenshot omitted the overlay and the separate display capture failed, so visual layout acceptance remains unverified.
+5
View File
@@ -135,6 +135,11 @@
"guid": "9ADD554959C09197",
"addon": "65930CB4CD0237B2",
"verification": "Exact installed owning resourceDatabase.rdb path/type/GUID and inspected native prefab/scripts, 2026-09-22."
},
"Prefabs/Weapons/Launchers/9K38_IGLA/Launcher_9K38_IGLA.et": {
"guid": "962C400354E4BD6C",
"addon": "629B2BA37EFFD577",
"verification": "Installed WCS USSR AA character references this exact prefab; inspected launcher has infrared guidance and a loaded disposable muzzle, 2026-09-23."
}
}
}
+37
View File
@@ -0,0 +1,37 @@
# Random field hospitals and camps
Everon now has **three field hospitals and five field camps**. This replaces the old medical stash and eastern outpost and adds six locations. Their positions and headings are chosen again at round start. The prison, radio, four mortars and existing supply/extraction objectives remain separate.
Each field site has four permanent defenders and a separate two-person mobile team, drawn from the selected enemy faction's group roster. Both groups are created once, registered with the force ledger, and receive the existing AI skill, equipment, intel and reporting systems. HQ reserves the defenders against hunting, support, courier and logistics assignments. The mobile team is eligible for delivered HQ hunting orders and otherwise defends its home assembly area. Its standing home waypoint remains available after a temporary HQ assignment ends. Losing mobile soldiers does not turn the permanent guards into replacements. Guards still fight locally and can be killed; the existing objective-defence system permits one finite relief squad after a garrison is lost.
Hospitals have a vanilla medical tent with red-cross markings, a table, sandbags, and a finite cache of dressings, saline, morphine and radio documents. The first camp also retains the existing finite twelve-shell mortar depot, with courier duty assigned to its mobile team. The loose supplies can be carried away and used for treatment; no endless item replenishment was added. Camps have two tents, sandbag cover, a table and finite rifles, magazines, binoculars and dressings. New scenery requests a native navigation rebuild.
The original medical clue route remains marked after prison escape. The other field sites are hidden until seen nearby or revealed through existing intel. Partial clues use an approximate question mark; identified hospitals use the medical icon and camps use the outpost icon. Intel carried by AI can refer to these sites, and corpse inspection therefore feeds their compromise into the existing HQ security response.
## Placement and authoring
Edit `addons/core/Configs/ERR/EveronSites.conf`. `GuardCount` selects the permanent roster size (1–8, or zero for the full faction group). `ResponseCount` selects a separate mobile roster (0–8). `GuardOffset` and `ResponseOffset` are rotated with the composition. Do not put a roaming `Patrol` on a permanent garrison; use its separate response team instead. The selected profile must provide usable infantry members.
`RandomClear` supports hospitals, outposts and depots as well as the existing generated objectives. Each new field site is at least 600 metres from other committed locations; unresolved fallback seeds do not reserve ground. The survey checks water, terrain variation, physical obstacles, the composition footprint, and both squad assembly areas. Each site has a bounded 12,000-candidate/30-second search and a validated authored fallback. Invalid terrain is never accepted just to satisfy a requested count; preparation reports the site's ID if placement fails. Custom scenery still needs to fit the surveyed footprint (ten metres either side of its centre).
Scenario bounds are 32 sites, 24 initial groups including mobile teams, 512 stock items and 128 scenery props. The default field sites total 32 fixed defenders and 16 mobile soldiers, in addition to other mission forces. These finite limits are not performance measurements.
## Original investigation
The installed original was inspected read-only. Its location preparer chooses weighted types at random-location holders, randomly enables static hospitals, and attaches existing static buildings as compositions. Its location character manager creates local defenders independently of its patrol manager. The successor uses newly authored vanilla-resource layouts and its existing terrain sampler and HQ rather than importing the original's compositions or lifecycle code. This is a field-hospital/camp implementation, not full parity with every original city, checkpoint, depot or hideout.
Reference SHA-256 values:
- `ESCT_LocationPreparer.c`: `71b32259306b4a5794283d31485a5c4533a3e95364218fcb0e3e46998df89df6`
- `ESCT_LocationCharacterManagerComponent.c`: `15090d0a7a5a1f972db4a46d9dc027d6fd45b3f4e1f00b6620a05419c7918694`
- `ESCT_LocationPatrolManagerComponent.c`: `5da0ed5d50ec7bee4496d8e9007255c400c059cb54ff7efd6a2428aebaa4ddcd`
The medical tent's GUID was verified through the installed vanilla foundation variant referencing `Prefabs/Structures/Military/Camps/TentUS_01/TentUSMedical_01.et`. No additional Workshop dependency is introduced.
## Validation
`tests/test_field_sites.py` executes actual roster selection and placement-separation code. The HQ registration regression checks that groups sharing a home receive different permanent/mobile eligibility. The `site-garrisons` Workbench scenario uses the production randomized configuration and checks physical squads, finite inventories, marker discovery, generated spacing and role separation before/after prison escape. It does not fabricate enemy reports or claim a dedicated multiplayer hunting test.
The final local Workbench run on 24 September completed with **106 passing assertions and no script/runtime failures**. It verified all eight randomized sites, exact direct stock (including the separate mortar shells and excluding nested rifle attachments), 32 permanent defenders, 16 eligible mobile soldiers, map discovery and role separation across live HQ ticks after unlocking the prison. The complete repository checks also passed.
Local evidence is retained in `.local/analysis/field-sites-2026-09-24/`. The runner reported a transient process-classification failure during immediate shutdown verification; a separate follow-up confirmed the disposable prefix was idle and the addon source hash unchanged. The original runner result is preserved. Existing RHS/WCS resource/keyword engine errors remain in the native report. This is not dedicated multiplayer, manual interaction, sustained hunting/navigation or performance qualification. No Workshop publication or live-server update was performed.
+27
View File
@@ -0,0 +1,27 @@
# Gameplay recovery after the 23 September RKS #2 session
The session analysis and deployed source snapshot are in `.local/analysis/rks2-2026-09-23-gameplay/analysis.md` (local evidence, not a published asset).
- Mortar initialization receives 90 seconds from its first eligible poll. Waiting in prison does not spend that deadline. Failed/stopped mortar preparation no longer prevents independent supply-convoy admission; other outstanding group admissions still block it.
- Hunter UAZs activate their native agents before checking seated readiness and allow up to 120 seconds for startup. Losing the gunner does not invalidate a seated, conscious original driver. Incapacitation/dismount suspends driving without deleting the delivered destination; the original driver receives native boarding tasks. A surviving original crew member may take over a vacant driver seat. Occupied seats are never forcibly cleared, including seats containing casualties.
- Hunter movement reports include source ID, position, speed, destination, combat state, time without progress and route retries. A vehicle without movement for 60 seconds outside combat gets at most three native route retries until it moves again. Destroyed/captured vehicles and groups without living original crew are released. No replacement actors, repaired vehicles or teleport-based unsticking are introduced.
- Body-search jobs log their job ID, team/body positions and remaining distance. Outside combat, 120 seconds without closing by ten metres triggers another approach. After three failed route attempts, a job may select another team, up to twice, within the existing finite team budget. Physical proximity and inspection are still required before missing intel becomes known.
- Compromised-site messages distinguish waiting for an eligible team/radio route from a queued dispatch. They no longer say reinforcement was requested when no team was assigned.
- Parachute placement checks up to 72 candidates: twelve bearings, three distances (300/500/700 metres) and two corridor orientations. Every candidate retains the existing ground, water and descent-clearance checks. Logs summarize rejected candidates and distinguish a successful corridor from no safe corridor. Failed attempts retain the existing 15-second retry delay; the eight-minute committed-drop cooldown is unchanged.
- The radio has an explicit interaction point attached to the radio mesh, an omnidirectional three-metre context, and its existing eight-second action. Server authorization remains unchanged.
Automated checks include `tests/test_gameplay_session_regressions.py`, the existing policy suites, the native `radio-interaction` fixture, and the delayed-prison `mortar-station` fixture. The radio fixture uses native client context collection rather than injecting actions into the handler. Its final action execution is scripted; this does not claim human input or dedicated-client replication coverage.
Native radio comparison: the deployed prefab failed `GetTransformationWorld()` for its interaction context. With the authored point, `/tmp/erri-radio-context-fixed/logs/logs_2026-09-23_21-43-16` passed all seven assertions, including actual native client selection in the furnished tent and transition into radio defence. The runner recorded unchanged sources and confirmed cleanup. Existing RHS/WCS resource/keyword errors still make the aggregate engine-error report nonzero; no script/runtime failures were recorded in this successful fixture.
The native `mortar-station` fixture held the prison closed for 110 seconds before releasing it. The one battery in that fixture initialized, seated its gunner, retained its crew against competing orders, and released survivors only after destruction. Evidence: `/tmp/erri-behavior-mortar-station/logs/logs_2026-09-23_21-44-58`. This is not a four-battery or dedicated-server test. Its smoke completed, but the runner could not classify a process during immediate cleanup verification; that PID was subsequently confirmed absent and the next run passed prefix preflight.
The extended native UAZ fixture also exposed a separate equipment-coordinator bug: temporary unconsciousness permanently stopped an actor's skill entry. Ownership now remains valid for living unconscious AI, while equipment/skill work requires consciousness. The existing entry and completed grant state survive recovery; death, capture, faction change and unregister remain terminal. Policy tests exercise both temporary suspension and permanent release.
One intermediate UAZ test (`/tmp/erri-behavior-aggression-fixed/logs/logs_2026-09-23_21-55-15`) stopped on an engine behavior-tree `NodeError` for `supply-convoy-1-vehicle-3`: failed movement from `<5924.18,210.115,7040.86>` to `<5880.83,211.208,7023.45>`. This was not a compile error or a hunter recovery assertion. Cleanup and unchanged-source verification passed. That supply-convoy navigation case remains unresolved; the hunter recovery changes do not guarantee every native road/path request succeeds.
Route retries reuse the physical waypoint's last delivered destination, even when a newer HQ order has already been queued. An executable policy regression checks this boundary, the three-retry limit, reset after movement and suspension during combat.
Final native hunter validation: `/tmp/erri-behavior-aggression-final/logs/logs_2026-09-23_21-58-13` completed with 19 passing assertions and no script/runtime failures. It verified three separated opening UAZs, a delivered HQ order and more than 30 metres of physical movement, gunner death without losing the patrol, temporary driver unconsciousness, native dismount/reboarding with the same actors, and the surviving driver's enhanced skill after driving-task release. Source hashes remained unchanged and runner cleanup was confirmed. Existing external resource/keyword engine errors still produce a nonzero aggregate CLI exit. This is local Workbench coverage, not a dedicated multiplayer playtest.
`python tools/check.py` passed after the recovery/ownership changes; the delivered-route retry regression and hunter lifecycle checks were rerun after the final route adjustment. No Workshop publication, Git push or live-server change was performed for these fixes.
+1 -1
View File
@@ -19,7 +19,7 @@ The first release remains vanilla Everon, prison start and twelve players. Alter
| Radio objectives, tasks and discovery | partial (first-release) | 21 | Independent radio defence and native task-detail refresh are implemented. Validate visible task/map usability, simultaneous real clients, discovery replication and complete manual objective route. |
| Physical equipment, storage and scavenging | partial (first-release) | 23 | Two independent clue caches and optional medical/outpost stock are authored. Manual access, route balance, medical treatment, destruction and network ownership remain unverified; finite stock replaces refill systems. |
| Usable vehicles, locks, alarms and navigation | partial (first-release) | 17 | Finite optional vanilla ground transport passes native parking, seats, engine, fuel depletion and loss checks. Manual driving/access, route navigation, repair, alarms and remote vehicle ownership remain validation/integration work. |
| Locations, compositions and population ownership | partial (first-release) | 32 | Seven sites and bounded proximity/discovery events are implemented. Expand towns/checkpoints and turret population, validate authored static cover, loss retention, manual access and multiplayer cleanup. |
| Locations, compositions and population ownership | partial (first-release) | 32 | Sixteen sites now include three randomized field hospitals and five camps with separate permanent defenders and mobile teams; see [field sites](field-sites.md). Towns/checkpoints, turret population, manual access, loss retention and multiplayer cleanup remain to be qualified. |
| Player identity, spawning and reconnect | partial (first-release) | 14 | Native local slot reservations, final-assignment guards and owned pending cleanup pass. Active admission now counts blocked geometry and missing prerequisites toward its bounded retry budget; the actual-method regression passes. Real dedicated-server concurrent joins, preload races, reconnects, connection-ID reuse, spent lives, late arrivals and spectator streaming remain. |
| Mission setup, configuration and administration | partial (first-release) | 16 | Core administration/settings and saved environment changes pass local native checks, including two restart rounds. Ordinary local startup/admission passes for loose Chat and an exact archived packed Core candidate; the latter predates current mortar edits and does not qualify packaging. Verify current-source startup, remote authorization, player-facing pre-round setup and difficulty choices. |
| Mission state, restart and base framework | partial (first-release) | 7 | Separate remaining objective/lifecycle policies, test mission failure reporting and multiplayer restart/cleanup. |
+24
View File
@@ -1,9 +1,31 @@
# Player lifecycle and pending admission
Admitted prisoners now survive lethal damage as treatable unconscious casualties.
If everyone is unconscious and neither treatment nor recovery progresses for 30
seconds, the round ends in defeat. See [recovery rules](recovery.md) for medical
behavior and reconnect reservations. The death/spectator paths below remain as
fallbacks for deleted bodies and administrative/native lifecycle events.
## Unconscious teammate camera
An admitted player who becomes unconscious now gets a local third-person spectator camera without losing possession of the injured body. Teammates can continue treatment, including the existing epinephrine recovery path. Native healing restores the player's own camera automatically; the round's all-unconscious failure timer is unchanged.
The server selects conscious, friendly players whose controlled bodies belong to the current round. It excludes the unconscious observer's own body, unfinished admissions and stale/replaced bodies. If the target becomes unavailable, it selects another valid teammate. With no conscious teammate, the camera remains near the casualty's own body. Press **Left/Right arrow** to cycle teammates without administrator rights; holding an arrow does not repeatedly switch targets, and open menus suppress cycling. `/esc spectate next` and `/esc spectate previous` remain available as chat alternatives. Native manual-camera look and zoom controls orbit the target at a bounded distance; there is no free-flight or target possession. The follow view also handles teammates in vehicles and traces camera clearance against terrain and objects. Default screen effects hide while a manual camera is active and return with the normal player camera.
Existing dead/late-join spectator reasons retain their prior eligibility and wording. The new unconscious reason explains treatment and recovery rather than telling a living player to wait for the next round. Closing the round clears the selected target and the existing forced target/vehicle streaming leases.
The owner's original `ESCT_SpectatorComponent`, `ESCT_OrbitPlayerManualCameraComponent`, and `ESCT_OrbitDistanceManualCameraComponent` were inspected read-only. The successor extends its existing observer instead of importing the original editor mode, fade dependencies or epinephrine-based camera exclusion. Their SHA-256 values are respectively `543891977028488a149498ab777477b4cc415e35d54d63d239a9358ae08393be`, `f11166bc01dc63b5503f74f40d7901f683c004b2f92b913fbdf8104d923e8c9b`, and `6245587ac6fad9819bd3098d14cb2f000539557cb4f0781f25611ad10be26354`.
The successor keeps one round-owned life record per authenticated account. A connection number is only the current binding to that record. A new life can enter during prison, radio search or radio defence; extraction and terminal phases refuse new admission. Successful initial assignment spends the life. Cancelling an unassigned preload never restores or spends a life.
Native reconnect reservation and handoff remain separate from new-character admission. A returning account may reclaim its surviving reserved actor through Reforger's reconnect system. A dead actor remains a spent life; unconsciousness is not death. Reserved living actors remain participants while their connections are absent. These policies are implemented, but real remote reconnect and reservation-expiry acceptance remains unfinished.
## Weapon retention on unconsciousness
**Esc → Co10 Escape Reintroduced → Mission → Keep weapon when unconscious** offers Enabled/Disabled buttons. Enabled is the default, including for older settings files. Administrators can also use `/esc mission keepweapon set 1` or `0`. The preference persists in the server profile and is captured at each knockout; changing it does not alter a casualty already being treated.
Enabled retains the actual held firearm, including its magazine and attachments, and selects it again after revival. It never creates a replacement or takes a gun acquired by another inventory. Disabled allows the normal ground drop. Grenades, gadgets and mounted weapons are excluded. The native test verifies inventory retention and the same rifle in hand after waking; it does not qualify the unconscious ragdoll's hand pose. Revival inside a vehicle leaves the gun in inventory rather than forcing an equip animation.
## Placement
Prison placement searches a 4×4 lattice with axis coordinates -4.5, -1.5, 1.5 and 4.5m relative to the authored center. The four inner positions are checked first, then eight edge positions, then four corners. Neighboring centers are 3m apart and remain 1.5m inside walls positioned at ±6m. The inner and edge positions are within 5m of the prison center. Terrain height and slope, physical scene/character occupancy, and pending reservations can reject a slot. Connection IDs 1 and 13 receive no special or shared position. Disconnected physical bodies still obstruct the native query.
@@ -31,3 +53,5 @@ The native lifecycle fixture in [050403](evidence/native-2026-09-19-050403/repor
`tests/test_participant_selection.py` executes the actual `CurrentActor`, `SpawnPosition` and server observer-selection methods with engine enumeration, geometry and streaming represented by adapters. It covers unregistered and pending actors, missing identity, disconnect, mismatched connection/body, recycled IDs, dead/foreign bodies, accepted canonical targets, cycling, loss of a previously selected target, unconscious following and unchanged prison/geometry fallback. This closes a source-proven membership omission; it does not establish native possession or multiplayer streaming behavior for the revision.
`tests/test_spawn_retry_budget.py` executes the actual `DoSpawn_S` method with native controller, respawn, geometry and scheduler adapters. It covers persistent blocked positions, missing prerequisites, thirty-attempt exhaustion, temporary recovery, request rejection, preparation waiting, spent/late life refusal and unchanged pending requests. The counter change has source-local regression evidence only until the next native integration run; this does not qualify slow remote clients or real multiplayer admission.
The combined unconscious-camera/weapon revision passed eighteen native Workbench assertions on 24 September 2026: real player incapacitation, current manual camera activation, unchanged possession/living body, no-target fallback, physical-target tracking and movement, native FullHeal recovery, restoration of the player camera, repeated knockout, default-enabled retention of the exact rifle, the same rifle equipped after revival, and normal ground drop with retention disabled. There were no script/runtime failures, and runner cleanup and unchanged-source verification succeeded. Existing RHS/WCS and vanilla resource errors remain in the log, so this is not an error-free engine log. A WORKBENCH-only target stand-in exercises camera tracking because this runner has one real player; it does not establish remote multiplayer streaming. The actual server selection/client policy regressions cover self-exclusion, conscious teammates, canonical identity, target loss, recovery, inactive rounds and delayed unconscious metadata. Arrow input edge/hold/menu behavior and firearm categories have source-policy tests; the new menu controls have structural and command-route checks. The complete repository checks passed. Evidence is in `.local/analysis/unconscious-weapon-2026-09-24`.
+35 -6
View File
@@ -1,11 +1,40 @@
# Incapacitated survivors and administrator abandonment
# Revivable players and all-unconscious mission failure
Core observes the controlled, living bodies of participants who have already used their life. A conscious participant can help; an incapacitated participant remains a survivor. A disconnected or temporarily unpossessed living body remains reserved and is not counted as an available rescuer. Dead bodies and spectators do not count. This observation does not change health, consume another life, advance a phase or end a round.
Admitted player bodies receive server-owned casualty protection. Ordinary damage
still causes wounds and bleeding. Damage to physical, overall-health and blood
hitzones is limited above their configured destruction threshold; an otherwise
lethal hit knocks the prisoner unconscious. Resilience can still reach zero, and
healing damage is passed through unchanged. Further hits and bleeding cannot
finish the casualty. AI retain their normal damage rules. Protection stays with
the original body across reconnects and does not grant a new life or respawn.
When no controlled survivor is conscious and at least one is incapacitated, the replicated mission status and native objective description explain that recovery remains possible and an administrator may abandon the round. Reconnection is mentioned when a living reserved body exists. The message clears when the condition changes; identical samples do not emit duplicate events. No additional death timer is imposed. Blood loss may still require treatment: the message is not a promise that every casualty will wake unaided.
The round fails after **30 uninterrupted seconds** with every remaining prisoner
unconscious, no conscious reserved prisoner available to reconnect, and no
ongoing treatment or observed blood/resilience recovery. Waking up, a treatment
in progress, or increasing blood/resilience resets that timer. A passive recovery
effect that is present but makes no progress does not prevent failure. An empty
server does not start this timer. Mission status explains whether recovery is
continuing or the team is in the failure grace period.
`/esc mission abandon` is restricted to the existing server-validated administrator command channel. It accepts only the exact command during an active mission, records a specific result reason and enters the ordinary defeat/cleanup/restart path. Unauthorized, malformed, preparation and repeated terminal requests do not change the round. This gives administrators an explicit way to end a hopeless round while preserving recoverable and reconnecting survivors.
Treatment uses the existing medical system. Bandaging and saline remain relevant;
ACE Medical epinephrine heals resilience and is not blocked by casualty protection.
ACE's own treatment prerequisites still apply (including stopping bleeding and
restoring sufficient health). Installing this mission does not itself install
ACE Medical or add an unlimited epinephrine action.
The `recovery` WORKBENCH fixture exercises actual controller incapacitation, the shared status, observer event deduplication, survival beyond the ordinary 30-second all-dead grace, restoration without replacing the actor, unauthorized/malformed requests and authorized abandonment. Controller state changes in that fixture establish mission policy only. The separate `medical` fixture tests actual blood loss and native treatment recovery without directly restoring consciousness. Neither fixture establishes remote-client replication, manual treatment actions or multiplayer acceptance.
`/esc mission abandon` remains an administrator-only way to end a round explicitly.
The all-dead/missing-body fallback and exhausted-admission handling also remain,
for deleted bodies and administrative/native paths outside ordinary damage.
Native run `native-2026-09-19-064406` passed all 54 combined assertions with zero engine errors. The fixture restored consciousness once, then tested authorized abandonment during a second active all-incapacitated warning. Terminal cleanup removed the status and counts. This is local policy evidence; multiplayer replication and manual treatment remain unqualified.
The isolated `recovery` Workbench fixture exercises damage exceeding full health
on health, blood and head hitzones, continued survival while treatment is flagged
active, restoration by native resilience healing, and the actual all-unconscious
failure timer. This is separate from remote-client/manual treatment acceptance.
Validation on 2026-09-23: all repository checks passed after updating the existing
ServerTick test adapters. The isolated `recovery` run at
`/tmp/erri-revivable-native2/logs/logs_2026-09-23_20-02-04` completed 66 assertions
with no script/runtime failures, unchanged source and verified cleanup. Existing
RHS/WCS resource and inherited prefab-keyword errors remain in that engine log.
The recovery effect was a native timed resilience-healing effect; an actual ACE
injector action and remote multiplayer treatment were not exercised by this run.
+1 -1
View File
@@ -1,7 +1,7 @@
# Single Workshop mod
All five owned modules are now one project: `addons/core/addon.gproj`, titled
**Escapists Reintroduced**, with the existing Core GUID `2528466DE220D91C`.
**Co10 Escape Reintroduced**, with the existing Core GUID `2528466DE220D91C`.
There are no separate AI, Intel, Map or Chat project descriptors to publish.
The project ID `ERR_Core` is retained; it now identifies the complete mod.
+21
View File
@@ -0,0 +1,21 @@
# Town garrisons
After the prison opens, approaching within 700 metres horizontally of a native named town, city, village or settlement activates its population attempt. Each settlement rolls **3–10 enemy soldiers once per round**, using the selected enemy faction's infantry roster. Duplicate map descriptors within 50 metres share the same entry.
The squad must fit on clear, navigable ground within 200 metres of the settlement's map centre. Every soldier's actual spawn point must be **at least 700 metres from every controlled player**, including unconscious teammates. Placement leaves a small extra margin. If another player is inside the town, the terrain is unsuitable, navigation is still loading, or the mission force budget is full, the town waits. It never relaxes the distance to fill its quota. A rapid approach can therefore leave a town empty until a safe approach becomes possible.
The owner first plans the whole formation and loads the faction resources, then rechecks player positions immediately before each synchronous character creation. The group has no queued native roster slots, so a delayed expansion cannot create additional soldiers beside an approaching player. A native creation/admission failure cancels that attempt rather than repeatedly replenishing part of a squad.
All members enter the existing force ledger, intel, equipment and VirtualHQ systems. Each squad requests a physical HQ manpack through the existing equipment service. Initially it guards its assembly area; all members are available for delivered HQ hunting/investigation orders. Town proximity itself does not reveal player positions to HQ: normal AI observations and radio delivery still apply. These squads are distinct from the permanently reserved hospital/camp guards.
Town soldiers are not replaced after casualties and are not despawned/recreated as players cross the activation boundary. One squad at most is admitted per two-second update, with round-robin attempts for towns approached by separated teammates. The existing finite force budget applies. The owner and its pending work are stopped with HQ at round teardown.
The 700-metre rule here applies to these new town formations. Existing mission preparation and other reinforcement systems retain their separate lifecycle rules.
## Diagnostics and validation
Look for `TOWN GARRISON` in the HQ log. Admission records include the settlement name/identifier, map position, squad size, minimum player distance measured during creation, and HQ role. Deferred attempts explain why they cannot spawn; repeated waiting messages are limited to one per minute per town. The usual `SPAWN GROUP`/`SPAWN MEMBER` events retain individual identities.
`tests/test_town_garrisons.py` executes the actual distance/activation policy with exact boundaries, split players, empty/invalid observations and a player crossing the exclusion distance. `tests/test_intel_registration.py` checks the actual HQ registration method's town radio selection and unrestricted order eligibility. The isolated `town-garrisons` Workbench fixture exercises native map descriptors, navigation, three- and ten-member physical squads, blocked placement with a second observer in town, HQ binding and no replacement after elimination. It is not a live dedicated-server playtest.
The 24 September 2026 local Workbench test completed with **12 passing assertions and no script/runtime failures**. Minimum player distances at creation were 718 m for the three-man squad and 720 m for the ten-man squad. Repository checks passed. Existing RHS/WCS localization and vanilla resource keyword errors remain in the native log. The runner hit a transient exiting-process classification error during cleanup; a separate read-only follow-up confirmed that its private prefix was idle and addon sources were unchanged. Original runner results are preserved alongside the follow-up in `.local/analysis/town-garrisons-2026-09-24`.
+2
View File
@@ -102,6 +102,7 @@
"Prefabs/Structures/BuildingParts/Doors/Door_Metal_A_RIGHT_EXT_COV_B.et": "67F17696FF278AE0",
"Prefabs/Structures/Military/Camps/TentSmallUS_01/TentSmallUS_01.et": "01AE5FD77A9A4C21",
"Prefabs/Structures/Military/Camps/TentUSSR_01/TentUSSR_01_base.et": "BE5D5CFA90224646",
"Prefabs/Structures/Military/Camps/TentUS_01/TentUSMedical_01.et": "F8427C3EFC52644E",
"Prefabs/Structures/Walls/Concrete/ConcreteWall_01/ConcreteWall_01_3m.et": "60E5729BEA18F875",
"Prefabs/Systems/Radio/RadioManager.et": "B8E09FAB91C4ECCD",
"Prefabs/Tasks/BaseTask.et": "1D0F815858EE24AD",
@@ -116,6 +117,7 @@
"Prefabs/Weapons/Attachments/Optics/Optic_4x20/Optic_4x20.et": "BD496EE1B40DC510",
"Prefabs/Weapons/Attachments/Optics/Optic_ARTII/Optic_ARTII.et": "D2018EDB1BBF4C88",
"Prefabs/Weapons/Attachments/Optics/Optic_PSO1/Optic_PSO1.et": "C850A33226B8F9C1",
"Prefabs/Weapons/Explosives/Mine_PMN4/Mine_PMN4.et": "B05A816C0BF50802",
"Prefabs/Weapons/Handguns/PM/Handgun_PM.et": "C0F7DD85A86B2900",
"Prefabs/Weapons/Magazines/Magazine_545x39_AK_30rnd_Ball.et": "BBB50A815A2F916B",
"Prefabs/Weapons/Magazines/Magazine_762x51_M14_20rnd_SpecialBall.et": "627255315038152A",