Files
EscapistsReintroduced/docs/architecture.md
T
jakub 6a667d8deb Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
2026-10-13 22:52:53 +02:00

16 KiB

Architecture

Dependencies

One project, addons/core/addon.gproj (ERR_Core, 2528466DE220D91C), contains Core, AI, Intel, Map and Chat modules. It directly depends on vanilla Reforger, RHS: Status Quo, WCS Armaments and WCS BMP-1; the external closure is recorded in external-addons.json. The numbered script folders preserve extension order. tools/check.py validates the single identity, dependency graph, unique resource GUIDs and exact authored/vanilla/authorized external resource references. See single-mod setup.

Core owns ERR_GameMode, mission rules, native spawn lifecycle integration, settings, the location registry, the vanilla faction catalog and authored scenario construction. ERR_Phase transitions are checked centrally. ERR_LocationComponent registers stable location IDs and replicates discovery. Mission phase, discovery and persistent settings mutations are server-owned.

The mode exposes OnPhaseChanged, OnGroup, OnTick, OnStop and server-side OnLocationDiscovered events. ERR_CommandService is the response-coordinator interface. AI supplies its implementation through CreateCommandService. Core owns ERR_DiscoveryService, recovering physical documents and remembering consumed folder identities, and presents discovered objective markers. Intel subscribes to group and mission ticks only to distribute optional extra documents to enemies. Map supplies its shared field-map item through the scenario resource hook. Chat sends authenticated owner RPCs to mutate validated settings or read HQ status. Scenario placement, radio defence, extraction and mission transitions are separate services; native player assignment uses an identity-bound admission gate, with a restricted standalone alternative described below. AI owns finite mortar support and the western-cache courier through the same HQ and physical-radio authority; broader convoy and aircraft support remain migration work.

HQ information flow

Physical group members observe through vanilla AI perception. ERR_HQObservation requires fresh visual observations; ERR_HQReport snapshots the available information. The radio graph uses living, correctly affiliated actors actually carrying radios. Reports traverse bounded physical routes, with delay and inventory/affiliation checks at each hop. The delivered contact registry expires stale reports. Orders return through the radio graph before an existing eligible group receives a native search waypoint.

The coordinator is the sole source of strategic response orders. Individual units retain vanilla tactical combat. It does not spawn reinforcements when alerted. Initial physical forces are authored by the scenario. No distant-unit virtual simulation is implemented.

The 092237 native fixture verifies real guard perception, immutable report delivery through uplink/HQ/downlink, and movement by another original physical infantry group without adding forces. The 095513 courier fixture verifies a finite physical delivery, HQ reservation release and restoration of the original patrol. These are arranged local integration tests: the perception fixture places and temporarily protects its real player, while the courier fixture physically sequesters the original 27 shells to trigger depletion. They do not establish manual encounter quality, multiplayer behavior or improved FPS. Operational supporting aircraft, broader logistics/convoy parity and distant virtual simulation remain incomplete; aircraft availability helpers and isolated flight experiments are not an operational controller.

Bounded work and ownership

HQ bounds group/contact registries and staggers report checks; routes have hop limits and timeouts. Intel has a bounded insertion queue. Core remembers physical folders already consumed, so handing a folder to another player cannot rediscover a location. The journal buffers and rotates output. Spawn retries are bounded and server-authored tickets constrain spawn resources and positions.

Stop events cancel service timers, remove HQ waypoints and despawn owned AI groups through the native group lifecycle. Composition walls have explicit hierarchy ownership. Two scripted round completions across restart are recorded, but full entity-count and memory soak tests are still required. The engine destroys the world during a scenario restart; merely clearing an owner array is not evidence of complete entity cleanup.

Round player lifecycle

ERR_PlayerRoster owns network life records by backend identity; the sole genuine standalone local controller can use the pinned round-local key described below. Transient connection IDs are only lookup keys. Spawn, disconnect and rebind publish OnChanged. The native reconnect component retains the same physical character for voluntary as well as involuntary departures during its configured reservation interval. Reservation expiry does not restore a spent life. The defeat check includes reserved living characters. A server with no connected players pauses defeat and clears the radio defence timer.

First-time arrivals may spawn during prison, search or defence. Prison placement checks a bounded grid against physical obstacles and pending reservations; a full grid waits without spending the failure budget. Late spawn positions are checked beside conscious, on-foot survivors, with the same prison grid as fallback. Native preloads receive account/controller/request/data/actor-bound tickets. Final assignment rechecks current life, phase, connection and placement; stop, disconnect and closed-admission phases cancel owned pending actors and callbacks. See player lifecycle. New arrivals during extraction observe until the next round. Dead players cannot request another life. Unconscious characters remain survivors and retain their own camera; they do not hold the radio objective.

The server selects a living friendly survivor for each spectator and replicates only its replication ID and fallback position. A local camera follows that survivor; owner RPCs allow /esc spectate next and /esc spectate previous. Only the selected survivor and occupied vehicle are pinned for streaming to that spectator. Loss, target changes and mission stop release pins. Reconnect, remote streaming and multi-client camera behavior still require multiplayer tests.

Base objective presentation

ERR_Objectives subscribes to phase and tick events and publishes one native SCR_Task per active phase, completing the previous task or failing it on defeat. The independent radio service emits start/completion events; Core mission rules alone advance phases. Native task replication carries current instructions to joining players; task markers remain list-only because the discovery registry owns map disclosure. Radio descriptions update on five-second boundaries and show interruptions. These APIs compile against installed vanilla scripts; actual task UI presentation and remote-client delivery still require gameplay validation.

Authored sites and finite scavenging

Core reads ERR_ScenarioDefinition from Configs/ERR/EveronSites.conf. ERR_SiteService owns the resulting locations, guards, containers and stock. The scenario component handles pending/ready/failed preparation separately from mission progression. Location IDs are supplied by configuration and replicated; templates carry no fixed scenario identity. Initial inventory items are created once, and retries move the same entities into the container. Readiness requires observed physical inventory contents. A completed service never refills stock or replaces destroyed sites.

ERR_DocumentComponent binds each mandatory physical clue to a radio location. Core recovery applies it only to that destination; optional generic enemy intel retains its broader discovery behavior. Definition validation requires a starting map and, for Everon, two separate guaranteed clue sources at least 100 metres apart. Each has enough documents to identify the radio independently. Optional supply/outpost locations use bounded five-second conscious-participant visibility scans. Radio identification also permits an eight-metre clear-view approach to the physical station, preserving progress if every finite document is lost. Prison and extraction locations do not gain proximity disclosure. Location names and discovery state replicate to the map, while actual knowledge transitions publish the server-side discovery event. Native tests mutate separate definition instances to verify invalid inputs are rejected. Authoring details and current stock.

Base configuration and administration

ERR_FactionCatalog is authored in Configs/ERR/VanillaFactions.conf and injected through the game mode resource. The scenario chooses guard groups from it; spawning, spawn authorization and spectator filtering use its player faction; HQ and support use its enemy faction. Startup rejects missing, identical or non-hostile faction keys, and site preparation rejects guard groups with mismatched affiliation. Shared intel and waypoint resources belong to ERR_Resources, not a faction selector. A new catalog alone does not provide new factions or suitable support compositions.

Core owns the /esc command registration, owner RPC, server-derived admin authorization, rate limit and command service. /esc status, settings and mission radio show|set N work without companion addons. Spectator cycling is available to players through its existing owner RPC. Chat extends the service with existing HQ/Intel aliases and HQ journal output; it does not install a second command transport. Native service fixtures test parsing and rejected mutations, not remote RPC identity enforcement.

Preparation failure is retained in replicated state. Spawning remains disabled, local guidance can explain failure before a character exists, and administrators can request the detailed cause. Waiting for site preparation does not consume a player's bounded spawn-attempt budget. The failure path stops services instead of silently leaving their timers running. Remote and visible pre-spawn presentation remain runtime acceptance work.

Extraction and personal results

ERR_ExtractionService owns the exact pickup point, prisoner smoke validation, friendly transport/escort dispatch, all-survivor boarding hold and immutable account-identity escape snapshot. Aircraft are allocated after the smoke signal, not during preparation. The friendly flight subclass reuses the server flight controller and native AI gunners without registering with hostile VirtualHQ. Transport loss remains terminal; see extraction.

The native end-data connection ID list is retained only as a framework adapter. Core publishes an account-derived personal result on each player's controller, keyed to the current mission replication ID and reset at round startup/audit. Binding/rebinding republishes the result. The successor victory content ignores stale end-data winner IDs and refreshes if personal-result replication arrives after the end screen opens. Local widget tests and real network reconnect acceptance are distinct.

ERR_TimeService configures the native world clock once before the prison phase. Core administration saves start time and progression for the next round while showing the current applied values separately. The native manager advances and replicates time; there is no per-tick clock reset. See mission time and extraction.

Radio defence service and objective details

ERR_RadioDefenceService owns tune authorization, eligible conscious defenders, continuous occupancy and one-time completion. GameMode consumes its events to advance phases and expose extraction; native tasks carry instructions to clients. The service requires current connected life records and the configured player faction, so unregistered actors, disconnected bodies and hostile characters cannot hold transmission. Empty-server sampling resets progress before mission work pauses. See radio defence for exact boundaries and test scope.

ERR_ObjectiveText supplies hints and native task descriptions from the same mission state. Radio identification can update local guidance within the search phase, and extraction instructions use the replicated pickup stage. ERR_ObjectiveDetails subscribes open successor task details directly to native display-data changes; it removes that subscription on task switch and widget detach. Detach also removes native global task-event callbacks, and pending overflow work is cancelled before assignee labels are deleted. Other task types retain their native behavior. See objective widget lifecycle.

Optional ground transport belongs to the existing site definition/service and its rollback path. It has bounded parking checks, actual native fuel and compartments, and no replacement/refill loop. See ground transport.

Standalone admission and finite mortar orders

ERR_LocalAdmission supplies a round-local roster key only for the sole genuine local controller in native RplMode.None. It is selected through normal audited spawn admission, pinned to that controller/context and closed on invalidation. It is not an account identity and never replaces native identity handling in Listen, Dedicated or Client modes. Design and evidence.

HQ owns each finite mortar battery, its readiness, delivered order and exact shell transactions. Initial expansion and inventory callbacks must resolve to the actual original crew and 27 distinct HE shells. Resupply moves one exact existing shell; acceptance alone is not readiness. Re-aim validation recomputes native ballistics against the immutable original command while retaining the original report's expiry. The per-battery report ledger prevents a cancelled/completed radio observation from becoming another order; only newly delivered observations can authorize new attempts. Operations, aim renewal, report deduplication.

An active order can accept a strictly newer same-target observation only after its own real HQ downlink. Each report keeps its original observation time and 60-second freshness bound; updates preserve the original order/activity, eight-round limit and 120-second deadline. If the barrel already has a command, the original native solver must prove equivalent geometry before adopting the update; an already committed shell retains its previous report until its actual projectile callback. The 111915 refresh attempt emitted eight real projectiles but failed the required natural-completion gate and remains failed evidence, not a qualified complete salvo or impact test. The subsequent event-latch correction captures vanilla completion/failure on the exact activity and order before deselection can overwrite its state, then consumes that event on the HQ tick. Cleanup detaches before its own Complete call and cannot manufacture a completion observation. The subsequent 112900 native rerun passes this handoff and the complete refreshed salvo; its evidence is described below. See report refresh.

ERR_MortarLogistics inserts twelve distinct depot shells once into the existing western clue cache and uses its original physical patrol as courier. A genuine low-ammunition status reaches HQ through the battery's RTO; HQ alone reserves the patrol and sends the delivery downlink. Transport authorization retains that status's original time with a 180-second bound, separately from firing-contact freshness. Native waypoints move the bearer and exact inventory transactions move surviving shells; there is no teleport, replenishment or replacement crew/vehicle. Cancellation releases owned orders while surviving stock remains physical, and unresolved live-item transfers cannot be retried. This is one finite walking route, not complete logistics parity. Courier contract and native evidence.

The subsequent 112900 native refresh regression passes the exact activity-event handoff, all eight fresh physical shots, 19 remaining original shells and 25-second replay refusal with 55 assertions and zero captured errors. The earlier completion failure remains historical evidence.