Electronic Attack (EA)¶
AEGIS models electronic attack as physics-based jamming from opposing coalition aircraft. EA aircraft use the EA- naming prefix and suppress the IADS through two layers: EW contact filtering (per-contact angular masking at the EW antenna) and SAM binary suppression (jammed EMCON cycling). AI jammers auto-discover at mission start. Player jammers discover via S_EVENT_BIRTH. On by default (eaEnabled = true).
v0.8.4-beta Changes
This page documents v0.8.3 EA mechanics. The v0.8.4-beta includes changes to burn-through formulas, JAMMER_DB entries, and default tuning values. Beta-specific changes are called out in admonition blocks throughout this page.
Singleplayer EA Setup
EA in singleplayer requires v0.8.2+. Your EA aircraft exists at mission start and AEGIS initially registers it as AI — the script automatically upgrades it to player-controlled when you spawn in.
Slotting behavior: DCS singleplayer slot-change events are unreliable. If the F10 EA menu or GUI doesn't appear on your first slot-in, slot out to a non-EA aircraft and then slot back into the EA jet. This forces a clean S_EVENT_BIRTH cycle. Once connected, it stays connected for the session.
EA GUI overlay requires one additional step: desanitize require and package in your MissionScripting.lua (same edit needed for SRS/DCS-gRPC). Without this, the mission-side UDP socket can't load and the GUI won't connect.
-- In DCS World/Scripts/MissionScripting.lua, comment out these two lines:
--_G['require'] = nil
--_G['package'] = nil
DCS updates may overwrite MissionScripting.lua — check after every patch.
Theory of Operations¶
The AEGIS EA model operates at two processing layers because of a fundamental DCS constraint: we have full per-contact control at the EW radar feed, but only binary on/off control at the SAM level. DCS AI handles SAM target selection when the radar is on — there is no ignoreTarget() API.
Layer 1 — EW Contact Filtering¶
When a jammer is active within range of an EW radar, AEGIS filters the EW's contact feed before passing it downstream to sector SAMs. This is where directional geometry lives.
_GetEWJamState(ew)computes all jam effects on a specific EW — one effect record per jammer (bearing, burn-through distance, pie width).- For each contact in the EW's
getDetectedTargets()return,_IsContactJammed(ew, contactPos, effects)checks:- Is the contact inside any jammer's angular "pie" (as seen from the EW)?
- If yes: apply cosine gradient from boresight to pie edge, compute effective burn-through at that angle.
- Contact closer than burn-through passes (radar power wins). Contact farther is masked (jammer noise wins).
- Masked contacts are dropped before they ever reach the SAM activation logic. The SAM never gets cued, never goes ALERT, DCS AI never engages.
Even omni jamming creates directional masking because the EW antenna only receives strongly from one bearing at a time. Pie width scales with power density at the EW — more focused beam = more power = wider shadow. OMNI creates a narrow pie (±25°), WIDE presets scale from ±30° (W90) to ±45° (W50), and DIR creates the widest pie (±60°) with deepest suppression. Contacts outside the pie pass completely unaffected.
Range-dependent pie narrowing (v0.8.4-beta2): The masking pie shrinks linearly with distance beyond ewPieRefDist (default 45 NM). A jammer at 90 NM masks half the angular width of one at 30 NM. Formula: effectivePie = basePie × min(1.0, 45/dist).
The C2 Path — Sector Jam Warning¶
When an EW detects a jammer (noise floor rise), it sets sector.jammed = true and sector.jamBearing. This warning flows down the same C2 channel that feeds contacts and HARM warnings. DARK and AWARE SAMs in the jammed sector start EMCON cycling — the same autonomous behavior as if the EW were killed. The EW is still alive and still feeding contacts that survive the jam filter, but the degraded picture triggers SAM autonomy.
This is the core SOJ tradeoff: you blind the EW, but you wake up the SAMs. They start peeking independently with randomized timing, making the ingress corridor unpredictable. When the jammer leaves, the next EW poll cycle restores the feed, sector.jammed clears, and SAMs return to network-integrated behavior.
Layer 2 — SAM Binary Suppression¶
Any SAM that peeks (emits radar) while a jammer is within range gets checked by _IsJammed(sam). If jammed, after a 1-3s crew detection delay, the SAM enters jammed EMCON cycling — a separate timer chain from normal EMCON (jammedEmconGen vs emconGen):
- On-phase: Brief radar peek. During this window,
_JammedEmconOnPhasechecks if any contact is inside burn-through range. If yes, SAM stays ALERT and engages (burn-through kill). If no, goes dark. - Off-phase: Radar off, hiding from jammer. Then the cycle repeats.
samTrackingBias = 1.5 makes SAM tracking radars harder to suppress than EW search radars. An SA-10 (WEZ 39 NM) only loses the outer ~21% of its engagement envelope to omni jamming at max jammer range. Contacts at 20 NM burn through easily.
v0.8.4-beta Changes
The global samTrackingBias default changes from 1.5 to 1.0. Per-system bias is now set via the trackingBias field in SYSTEM_DB, allowing differentiated resistance (e.g., SA-10 harder to jam than SA-6) without a single global knob.
Priority Chain¶
1. HARM cooldown (harmCooldownUntil) — highest, never overridden
2. Jammed EMCON (jammedEmconActive) — jammer in range
3. Normal state machine — poll evaluation
Jammed EMCON uses its own generation counter (jammedEmconGen), independent of normal EMCON (emconGen). _StopEMCON() is called before starting jammed EMCON to prevent timer conflicts.
DCS Scripting Constraints
Several design decisions are bounded by what the DCS scripting API allows. Understanding these explains why the architecture works the way it does.
No per-contact SAM engagement control. DCS ground AI ROE is binary: shoot everything (OPEN_FIRE) or shoot nothing (WEAPON_HOLD). There is no ignoreTarget() — when a SAM's radar is on, DCS AI picks targets autonomously. This is why EA has two layers: we have per-contact control at the EW feed (filter before the SAM ever sees it), but only on/off at the SAM itself.
No passive track injection. Real HOJ means the SAM passively tracks the jammer's noise source. DCS has no API to create bearing-only tracks or direct a SAM to engage a specific contact. HOJ is modeled as a jam immunity window — suppression lifts, the SAM goes weapons-free, and DCS AI handles targeting. The jammer dies because the jam stopped protecting it, not because the SAM homed on the signal. The gameplay effect is identical.
No jammer pod state. DCS has no flyable ECM aircraft and the scripting API doesn't expose pod state. We can't detect whether a player's jammer is physically on. Activation is manual (F10 menu or GUI), and jammer capability comes from the group naming convention — any airframe can fly the EA role.
Separate Lua VMs on dedicated server. The standard net.dostring_in("mission", ...) hook-to-mission bridge accesses a different Lua VM from trigger-loaded scripts on dedicated servers. AEGIS mission globals are invisible to hooks. The EA GUI works around this with a mission-side UDP socket in the same VM as AEGIS, which is why it requires MissionScripting.lua desanitization for LuaSocket access.
SP vs MP slot lifecycle. In multiplayer, client aircraft don't exist until a player joins — event-driven discovery works cleanly. In singleplayer, the aircraft pre-exists at mission start and gets registered as AI before the player spawns in. The script auto-upgrades on spawn, but DCS singleplayer doesn't fire onPlayerChangeSlot, making the handoff less reliable than MP.
Jammer Modes¶
| Mode | Pods | Coverage | Gain | Use Case |
|---|---|---|---|---|
| OMNI | 2 barrage | Full sphere | 0.40x | Area denial, strike escort |
| WIDE | 1 cone + 1 directional | Configurable cone | 0.61-0.80x | Focused area + targeted |
| 2xDIR | 2 directional | 2 independent targets | 2.00x | Precision suppression |
| OFF | — | ESM only (passive) | — | Threat detection without jamming |
AI jammers default to OMNI. Player jammers default to OFF — the WSO manages modes and pod assignments via F10 menu or the EA GUI overlay.
WIDE Presets¶
WIDE mode uses one pod as a configurable cone and the other as a focused directional beam. Presets trade coverage for penetration:
| Preset | Cone | Gain | EW Pie Mask | Coverage |
|---|---|---|---|---|
| W90 | ±45° | 0.61x | ±30° | Maximum area, weakest power per EW |
| W70 | ±35° | 0.68x | ±37° | Default balance |
| W50 | ±25° | 0.80x | ±45° | Tightest beam, strongest power per EW |
The WSO types a relative bearing (0-359° off nose) and sends SET to lock the WIDE cone direction. Gain is derived from beam half-angle: 0.4 / (1 - cos(θ))^0.29. Narrower beam = more concentrated power.
Burn-Through Physics¶
Burn-through range determines where radar power overcomes jammer noise. The formula:
| Term | Source | Effect |
|---|---|---|
burnRange |
SAM's WEZ or EW detection range | Bigger SAM = harder to suppress at range |
ratio |
burnThroughRatio (0.35) |
Baseline: 35% of reference range |
gainMult |
_BeamGain(halfAngle) |
Narrow beam = lower spread = deeper penetration |
mult |
JAMMER_DB per-type (Growler 1.0, Prowler 0.8, etc.) |
Platform effectiveness |
dist / effectRange |
Jammer-to-target distance | Closer jammer = stronger suppression |
exponent |
burnExponent (0.5 = √R) |
Physics-based distance falloff |
SAM tracking radars are harder to jam: samTrackingBias = 1.5 scales burn range up. EW search radars are softer targets: ewScanPenalty = 0.5 scales burn range down.
Practical effect: An SA-10 (WEZ 39 NM) only loses the outer ~21% of its engagement envelope to omni jamming at max jammer range. Contacts at 20 NM burn through easily.
v0.8.4-beta Changes
The EW layer burn-through formula changes to BT = ewBeta / (gainMult * mult) * sqrt(dist) with ewBeta = 1.8. The old ewScanPenalty and ewBurnExponent parameters are removed. The SAM layer formula is unchanged except that the global samTrackingBias is replaced by per-system trackingBias values in SYSTEM_DB.
Jammed EMCON Cycle¶
When a SAM detects jamming, it enters a suppression cycle:
SAM emitting (ALERT, EMCON_OFF, or EMCON_ENGAGED)
-> Jammer in range detects emission (1-3s delay)
-> Crew recognizes jamming -> shuts down (DARK)
-> Enters jammed EMCON cycling:
-> Off-phase: hiding from jammer
-> On-phase: brief radar peek
-> During jam detection window (1-3s): targets inside burn-through range engageable
-> Burn-through contact found -> SAM stays ALERT (monitored every 5s)
-> Contacts leave burn-through range -> back to off-phase
-> No burn-through -> jammer catches emission -> crew goes dark again
-> Jammer leaves/dies -> next on-cycle, no jam detected -> exit jammed EMCON
-> Poll restores normal state (EW alive -> ALERT, EW dead -> normal EMCON)
Differentiated Timing¶
SAMs behave differently under jamming based on capability:
| Capability | On-Phase (Peek) | Off-Phase (Hide) | Behavior |
|---|---|---|---|
| HOJ-capable (SA-10, SA-11, SA-17, SA-20, SA-21, SA-23, PATRIOT) | 12-25s | 20-45s | Aggressive — seeking HOJ lock |
| Standard (SA-2, SA-3, SA-5, SA-6, SA-8, SA-15, TOR) | 5-10s | 60-150s | Cautious — survival mode |
HOJ-capable SAMs peek longer and more often because each peek has tactical value — they might burn through or trigger HOJ. Standard SAMs peek briefly because exposure just invites HARMs.
Home-on-Jam (HOJ)¶
Modern SAMs with homeOnJam = true in SYSTEM_DB can break through jamming using passive tracking. Each jammed EMCON peek, the SAM rolls for HOJ:
- 7% base probability, escalating +7% per consecutive peek (#1=7%, #2=14%, #3=21%...)
- On success: 75-120s jam immunity window —
_IsJammed()returns false, SAM goes weapons-free - After window expires: 60s cooldown before re-roll eligible
- Peek count resets on re-entry to jammed EMCON
HOJ-capable systems: SA-10, SA-10B, SA-11, SA-12, SA-17, SA-20A, SA-20B, SA-21, SA-23, PATRIOT
Risk Curve for EA Pilots¶
- SOJ (50+ NM): Few peeks reach the jammer, low probability per peek. Relatively safe but weaker suppression.
- SIJ (15-25 NM): More frequent peeks (shorter hide time at close range), higher cumulative HOJ probability. Stronger suppression but you might eat an SA-10 missile.
- The skill expression: Managing standoff distance vs suppression effectiveness.
Disable with hojEnabled = false.
Passive ESM¶
The ESM receiver is independent of jammer transmit state — the emitter list populates in all modes including OFF. This enables an ESM-first workflow: observe threats before committing to a jam mode.
Each emitter displays:
- NATO radar name — from
SYSTEM_DB.srLabel(e.g., SA-2 = "Fan Song", SA-6 = "Straight Flush", SA-10 = "Big Bird"). PD/SHORAD without distinctive radar show system designator (SA-8, SA-15). EW radars show "EW". - Signal strength — 5-bar scale based on distance and emitter power:
|||||(closest) to|....(farthest) - Relative bearing — off the nose (0° = dead ahead). GUI respects ABS/REL mode toggle.
- Range estimate (v0.8.4-beta2) — builds over time via non-deterministic per-cycle rolls weighted by proximity. NONE → LOW (±20 NM band, e.g.,
40-80) → MED (±10 NM band, e.g.,40-60) → HIGH (~5 NM, e.g.,~48). Stale emitters show?suffix and decay one confidence level per 150s. - Pod assignment — P1/P2 if assigned
DIR pod bearing (v0.8.4-beta2): Pod assignment labels show bearing to target in F10 STATUS, GUI panel, and map markers. Bearing is position-based — stays live even when target stops emitting.
Stale emitters: ~~~~~ replaces bars when a radar goes silent. Last-known bearing updates as the jammer orbits. Persists for eaEmitterMemory seconds (default 60). Destroyed emitters drop immediately.
EA GUI Overlay (Optional)¶
An optional clickable panel replaces the nested F10 menu workflow for EA pilots — one-click mode switching, pod assignment, emitter tracking, and bearing input without pausing to navigate menus. Completely optional — players without it use F10 menus with no loss of functionality.
- Server auto-discovery — SRS-style chat message auto-connect
- Copilot/WSO support — slot-based lookup resolves non-pilot crew seats
- F10 and GUI stay in sync — either interface can control the jammer
- Toggle with Ctrl+Shift+J (configurable)
See the EA GUI Overlay page for installation, configuration, and troubleshooting. Download files from the Downloads page.
Mission Maker Reference¶
Setup¶
EA works out of the box with eaEnabled = true (the default). Name your EA aircraft on the opposing coalition using the EA- prefix:
EA-GROWLER-1 Growler, auto-discovers at mission start
EA-PROWLER-SOUTH-2 Prowler in SOUTH sector
EA-SPARKVARK-3 Tornado ECR
EA-GENERIC-NORTH Generic jammer
AI EA aircraft auto-discover. Player EA aircraft discover when the player spawns.
v0.8.4-beta Changes
v0.8.4-beta adds the HERC type for C-130 Compass Call: EA-HERC-NORTH-1.
JAMMER_DB¶
Each jammer type has a platform effectiveness multiplier:
| Type | mult | Notes |
|---|---|---|
| GROWLER | 1.0 | Baseline — EA-18G |
| PROWLER | 0.8 | EA-6B, slightly less effective |
| SPARKVARK | 0.7 | Tornado ECR |
| GENERIC | 0.5 | Any unknown type |
| UNKNOWN | 0.5 | Fallback for unrecognized names |
v0.8.4-beta Changes
v0.8.4-beta simplifies JAMMER_DB to two types: GROWLER (mult 1.0) and HERC (mult 1.3, C-130 Compass Call). PROWLER, SPARKVARK, and GENERIC are removed. Names using removed types fall back to UNKNOWN (mult 0.5).
JAMMER_BASELINE Overrides¶
All physics parameters are tunable via jammerBaseline = { ... } table merge in AEGIS:New(). Only specify fields you want to change — partial overrides are supported:
local iads = AEGIS:New({
jammerBaseline = {
effectRange = 60, -- default 55 NM
burnThroughRatio = 0.40, -- default 0.35
samTrackingBias = 1.8, -- default 1.5
}
})
Key fields: effectRange, burnThroughRatio, burnExponent, directionalRangeMult, samTrackingBias, ewScanPenalty
v0.8.4-beta Changes
Removed parameters: ewScanPenalty, ewBurnExponent. New parameter: ewBeta = 1.8 (EW layer burn-through coefficient). samTrackingBias default changes from 1.5 to 1.0 (per-system override via trackingBias field in SYSTEM_DB).
Configuration Summary¶
Key config knobs for EA behavior:
| Parameter | Default | Description |
|---|---|---|
eaEnabled |
true |
Master EA toggle |
eaDebugLabels |
false |
Show full emitter names (debug) |
eaEmitterMemory |
60 |
Stale emitter retention (seconds) |
jamDetectionDelayMin/Max |
1/3 |
Crew jam detection delay (seconds) |
jamEmconOnMinHOJ/MaxHOJ |
12/25 |
HOJ SAM peek duration (seconds) |
jamEmconOffMinHOJ/MaxHOJ |
20/45 |
HOJ SAM hide duration (seconds) |
jamEmconOnMinStd/MaxStd |
5/10 |
Standard SAM peek duration (seconds) |
jamEmconOffMinStd/MaxStd |
60/150 |
Standard SAM hide duration (seconds) |
hojEnabled |
true |
Home-on-Jam toggle |
hojBasePct |
0.07 |
HOJ base probability per peek |
ewPieRefDist |
45 |
NM: full pie width inside this range, linear falloff beyond |
esmRevealChance |
0.10 |
Base probability per cycle to advance range confidence |
esmRevealRefDist |
45 |
NM: range reveal at full chance inside this distance |
esmDecayInterval |
150 |
Seconds per confidence level lost while stale |
See the Tuning Guide for full parameter reference and behavioral effects.