Tactical Air Defense Controller with Automated Logistics
TADC (Tactical Air Defense Controller) is an automated air defense system for DCS missions that creates realistic, dynamic fighter aircraft responses to airborne threats. Think of it as an AI commander that:
The TADC system consists of three main scripts that work together:
Moose_TADC_SquadronConfigs_Load1st.lua)Purpose: Define all fighter squadrons for RED and BLUE coalitions
Contains: Aircraft templates, airbases, patrol parameters, zone assignments
Load Order: FIRST (must load before main TADC script)
Moose_TADC_Load2nd.lua)Purpose: Core threat detection and interceptor management
Contains: Threat scanning, squadron selection, intercept logic, F10 menus
Load Order: SECOND (after squadron config)
Moose_TADC_CargoDispatcher.lua)Purpose: Automated squadron resupply through cargo aircraft
Contains: Squadron monitoring, cargo spawning, delivery tracking
Load Order: THIRD (optional, only if using resupply system)
Before setting up TADC, you need:
RED_CAP_Kilpyavr_MiG29)Moose_TADC_SquadronConfigs_Load1st.luaMoose_TADC_Load2nd.luaMoose_TADC_CargoDispatcher.lua1. MOOSE.lua
2. Moose_TADC_SquadronConfigs_Load1st.lua
3. Moose_TADC_Load2nd.lua
4. Moose_TADC_CargoDispatcher.lua (optional)
Open Moose_TADC_SquadronConfigs_Load1st.lua and find the squadron configuration sections.
{
templateName = "RED_CAP_Kilpyavr_MiG29", -- Must match mission editor template name
displayName = "Kilpyavr CAP MiG-29A", -- Human-readable name for logs/messages
airbaseName = "Kilpyavr", -- Exact airbase name from DCS
aircraft = 12, -- Maximum aircraft in squadron
skill = AI.Skill.EXCELLENT, -- AI pilot skill level
altitude = 20000, -- Patrol altitude (feet)
speed = 350, -- Patrol speed (knots)
patrolTime = 30, -- Time on station (minutes)
type = "FIGHTER" -- Aircraft role
}
| Parameter | Description | Example Values |
|---|---|---|
| templateName | Group name from mission editor (EXACT match) | "RED_CAP_Base_F15" |
| displayName | Friendly name shown in messages | "Kilpyavr CAP Squadron" |
| airbaseName | DCS airbase name (case sensitive) | "Kilpyavr", "Nellis AFB" |
| aircraft | Max squadron size | 8, 12, 16 |
| skill | AI difficulty | AI.Skill.AVERAGE, GOOD, HIGH, EXCELLENT, ACE |
| altitude | CAP patrol altitude | 15000 (feet) |
| speed | CAP patrol speed | 300 (knots) |
| patrolTime | Minutes on station before RTB | 20, 30, 40 |
| type | Aircraft role | "FIGHTER" |
Kola Peninsula (Example Map):
"Kilpyavr", "Severomorsk-1", "Severomorsk-3", "Murmansk International""Luostari Pechenga", "Ivalo", "Alakurtti"Nevada:
"Nellis AFB", "McCarran International", "Creech AFB", "Tonopah Test Range"Caucasus:
"Batumi", "Gudauta", "Senaki-Kolkhi", "Kobuleti", "Kutaisi"You can add as many squadrons as you want. Just copy the squadron block and modify the values:
RED_SQUADRON_CONFIG = {
-- First Squadron
{
templateName = "RED_CAP_Base1_MiG29",
displayName = "Base 1 CAP",
airbaseName = "Kilpyavr",
aircraft = 12,
skill = AI.Skill.EXCELLENT,
altitude = 20000,
speed = 350,
patrolTime = 30,
type = "FIGHTER"
},
-- Second Squadron (different base)
{
templateName = "RED_CAP_Base2_SU27",
displayName = "Base 2 CAP",
airbaseName = "Severomorsk-1",
aircraft = 16,
skill = AI.Skill.ACE,
altitude = 25000,
speed = 380,
patrolTime = 25,
type = "FIGHTER"
},
-- Add more squadrons here...
}
BLUE_SQUADRON_CONFIG section.
Zones allow squadrons to have specific areas of responsibility, creating realistic layered defense.
Each squadron can have up to 3 zone types:
"RED BORDER")Mission Editor:
- Helicopter Group: "RED BORDER" with waypoints forming a polygon
- Helicopter Group: "BLUE BORDER" with waypoints forming a polygon
- Helicopter Group: "CONTESTED ZONE" with waypoints forming a polygon
Add zone configuration to your squadron:
{
templateName = "RED_CAP_Kilpyavr_MiG29",
displayName = "Kilpyavr CAP",
airbaseName = "Kilpyavr",
aircraft = 12,
skill = AI.Skill.EXCELLENT,
altitude = 20000,
speed = 350,
patrolTime = 30,
type = "FIGHTER",
-- Zone Configuration
primaryZone = "RED BORDER", -- Main responsibility area
secondaryZone = "CONTESTED ZONE", -- Backup coverage
tertiaryZone = nil, -- No tertiary zone
-- Optional: Customize zone behavior
zoneConfig = {
primaryResponse = 1.0, -- Full response in primary zone
secondaryResponse = 0.6, -- 60% response in secondary
tertiaryResponse = 1.4, -- 140% response in tertiary
enableFallback = false, -- Don't auto-switch to tertiary
fallbackThreshold = 0.3, -- Switch when <30% aircraft remain
secondaryLowPriorityFilter = true, -- Ignore small threats in secondary
secondaryLowPriorityThreshold = 2 -- "Small threat" = 2 or fewer aircraft
}
}
primaryZone = "RED BORDER", -- Patrols the border
secondaryZone = "INTERIOR", -- Helps with interior threats if needed
tertiaryZone = nil -- No fallback
primaryZone = "NORTHERN SECTOR", -- Main patrol area
secondaryZone = nil, -- No secondary
tertiaryZone = "BASE PERIMETER", -- Falls back to defend base when weakened
enableFallback = true, -- Auto-switch to tertiary when low
fallbackThreshold = 0.4 -- Switch at 40% strength
-- Squadron A: Outer layer
primaryZone = "OUTER PERIMETER"
-- Squadron B: Middle layer
primaryZone = "MIDDLE PERIMETER"
-- Squadron C: Inner/base defense
primaryZone = "BASE DEFENSE"
If you DON'T want zone restrictions, simply leave all zones as nil:
{
templateName = "RED_CAP_Base_MiG29",
displayName = "Global Response CAP",
airbaseName = "Kilpyavr",
aircraft = 12,
skill = AI.Skill.EXCELLENT,
altitude = 20000,
speed = 350,
patrolTime = 30,
type = "FIGHTER",
-- No zones = responds to threats anywhere on the map
primaryZone = nil,
secondaryZone = nil,
tertiaryZone = nil
}
The cargo system automatically replenishes squadrons by spawning transport aircraft that fly supplies to airbases.
The system detects cargo by aircraft name patterns:
CARGOTRANSPORTC130 or C-130AN26 or AN-26Delivery Methods:
Edit Moose_TADC_CargoDispatcher.lua and find CARGO_SUPPLY_CONFIG:
local CARGO_SUPPLY_CONFIG = {
red = {
cargoTemplate = "CARGO_RED_AN26_TEMPLATE", -- Template name from mission editor
supplyAirfields = {"Airbase1", "Airbase2"}, -- List of supply bases
replenishAmount = 4, -- Aircraft added per delivery
threshold = 0.90 -- Trigger at 90% capacity
},
blue = {
cargoTemplate = "CARGO_BLUE_C130_TEMPLATE",
supplyAirfields = {"Airbase3", "Airbase4"},
replenishAmount = 4,
threshold = 0.90
}
}
CARGO_RED_AN26_TEMPLATE or CARGO_BLUE_C130_TEMPLATEcargoTemplate fieldsupplyAirfields arrayreplenishAmount)Choose rear/safe airbases for supplies:
red = {
cargoTemplate = "CARGO_RED_AN26_TEMPLATE",
supplyAirfields = {
"Rear_Base_1", -- Far from frontline, safe
"Rear_Base_2", -- Alternate supply source
"Central_Logistics_Hub" -- Main supply depot
},
replenishAmount = 4,
threshold = 0.90
}
Tips:
If you don't want automated resupply:
Moose_TADC_CargoDispatcher.luaThe system includes built-in validation. Check the DCS log file after mission start for:
[Universal TADC] ═══════════════════════════════════════
[Universal TADC] Configuration Validation Results:
[Universal TADC] ✓ All templates exist
[Universal TADC] ✓ All airbases valid
[Universal TADC] ✓ All zones found
[Universal TADC] Configuration is VALID
[Universal TADC] ═══════════════════════════════════════
Press F10 in-game to access TADC utilities:
Cause: Template name in config doesn't match mission editor
Solution:
Cause: Airbase name wrong or captured by enemy
Solution:
_G.TDAC_CheckAirbase("AirbaseName") in DCS consoleCheck:
Check:
Cause: Parking spots occupied or insufficient space
Solution:
Open DCS Lua console (F12 or scripting console) and run:
-- Check all supply airbase ownership
_G.TDAC_CheckAirbaseOwnership()
-- Check specific airbase
_G.TDAC_CheckAirbase("Kilpyavr")
-- Validate dispatcher configuration
_G.TDAC_RunConfigCheck()
-- Check airbase parking availability
_G.TDAC_LogAirbaseParking("Kilpyavr")
-- Test cargo spawn (debugging)
_G.TDAC_CargoDispatcher_TestSpawn("CARGO_RED_AN26_TEMPLATE", "SupplyBase", "DestinationBase")
The interceptRatio setting controls how many fighters launch per enemy aircraft.
In Moose_TADC_Load2nd.lua:
local TADC_SETTINGS = {
red = {
interceptRatio = 0.8, -- RED launches 0.8 fighters per threat
maxActiveCAP = 8, -- Max 8 groups in air simultaneously
defaultCooldown = 300, -- 5-minute cooldown after engagement
},
blue = {
interceptRatio = 1.2, -- BLUE launches 1.2 fighters per threat
maxActiveCAP = 10, -- Max 10 groups in air simultaneously
defaultCooldown = 300,
}
}
| Ratio | 1 Enemy | 4 Enemies | 8 Enemies | Effect |
|---|---|---|---|---|
| 0.5 | 1 fighter | 2 fighters | 4 fighters | Conservative response |
| 0.8 | 1 fighter | 4 fighters | 7 fighters | Balanced (default) |
| 1.0 | 1 fighter | 4 fighters | 8 fighters | 1:1 parity |
| 1.4 | 2 fighters | 6 fighters | 12 fighters | Strong response |
| 2.0 | 2 fighters | 8 fighters | 16 fighters | Overwhelming force |
Tactical Effects:
Asymmetric Scenarios:
-- RED advantage
red = { interceptRatio = 1.4 },
blue = { interceptRatio = 0.8 }
-- BLUE advantage
red = { interceptRatio = 0.8 },
blue = { interceptRatio = 1.4 }
Control how far squadrons will chase threats:
{
templateName = "RED_CAP_Base_MiG29",
displayName = "Base Defense",
airbaseName = "Kilpyavr",
aircraft = 12,
-- ... other settings ...
zoneConfig = {
maxEngagementRange = 50000, -- Won't engage threats >50km from base
primaryResponse = 1.0,
secondaryResponse = 0.6
}
}
After launching interceptors, squadrons go on cooldown to prevent spam:
local TADC_SETTINGS = {
red = {
defaultCooldown = 300, -- 5 minutes between launches
-- ... other settings ...
}
}
Per-Squadron Cooldown (optional):
{
templateName = "RED_CAP_Base_MiG29",
cooldownOverride = 600, -- This squadron: 10-minute cooldown
-- ... other settings ...
}
Adjust AI difficulty per squadron:
skill = AI.Skill.AVERAGE -- Easiest, good for training
skill = AI.Skill.GOOD -- Below average
skill = AI.Skill.HIGH -- Average pilots
skill = AI.Skill.EXCELLENT -- Above average (recommended)
skill = AI.Skill.ACE -- Hardest, expert pilots
Mixed Difficulty Example:
RED_SQUADRON_CONFIG = {
{
displayName = "Elite Squadron",
skill = AI.Skill.ACE, -- Best pilots
aircraft = 8,
-- ...
},
{
displayName = "Regular Squadron",
skill = AI.Skill.GOOD, -- Average pilots
aircraft = 12,
-- ...
}
}
Goal: RED defends northern border, BLUE defends southern border
-- RED Configuration
RED_SQUADRON_CONFIG = {
{
templateName = "RED_CAP_North_MiG29",
displayName = "Northern Border CAP",
airbaseName = "Northern_Base",
aircraft = 12,
skill = AI.Skill.EXCELLENT,
altitude = 20000,
speed = 350,
patrolTime = 30,
type = "FIGHTER",
primaryZone = "RED BORDER"
}
}
-- BLUE Configuration
BLUE_SQUADRON_CONFIG = {
{
templateName = "BLUE_CAP_South_F16",
displayName = "Southern Border CAP",
airbaseName = "Southern_Base",
aircraft = 12,
skill = AI.Skill.EXCELLENT,
altitude = 20000,
speed = 350,
patrolTime = 30,
type = "FIGHTER",
primaryZone = "BLUE BORDER"
}
}
Goal: Multiple squadrons covering overlapping zones with different priorities
RED_SQUADRON_CONFIG = {
-- Outer Layer: Long-range interceptors
{
templateName = "RED_LONG_RANGE_MiG31",
displayName = "Long Range Interceptors",
airbaseName = "Forward_Base",
aircraft = 8,
skill = AI.Skill.EXCELLENT,
altitude = 35000,
speed = 450,
patrolTime = 20,
type = "FIGHTER",
primaryZone = "OUTER PERIMETER"
},
-- Middle Layer: General defense
{
templateName = "RED_CAP_MiG29",
displayName = "Middle Defense CAP",
airbaseName = "Central_Base",
aircraft = 12,
skill = AI.Skill.EXCELLENT,
altitude = 25000,
speed = 350,
patrolTime = 30,
type = "FIGHTER",
primaryZone = "MIDDLE PERIMETER",
secondaryZone = "OUTER PERIMETER"
},
-- Inner Layer: Point defense
{
templateName = "RED_BASE_DEFENSE_SU27",
displayName = "Base Defense",
airbaseName = "Main_Base",
aircraft = 16,
skill = AI.Skill.ACE,
altitude = 20000,
speed = 320,
patrolTime = 40,
type = "FIGHTER",
primaryZone = "BASE PERIMETER",
tertiaryZone = "BASE PERIMETER",
zoneConfig = {
enableFallback = true,
fallbackThreshold = 0.3
}
}
}
Goal: Long mission with automated squadron replenishment
RED_SQUADRON_CONFIG = {
{
templateName = "RED_CAP_Frontline_MiG29",
displayName = "Frontline CAP",
airbaseName = "Frontline_Base",
aircraft = 12, -- Will be resupplied
skill = AI.Skill.EXCELLENT,
altitude = 20000,
speed = 350,
patrolTime = 30,
type = "FIGHTER",
primaryZone = "COMBAT ZONE"
}
}
Moose_TADC_CargoDispatcher.lua):local CARGO_SUPPLY_CONFIG = {
red = {
cargoTemplate = "CARGO_RED_AN26",
supplyAirfields = {
"Rear_Base_1", -- Safe logistics hub
"Rear_Base_2", -- Backup supply source
"Central_Depot" -- Main supply depot
},
replenishAmount = 4, -- +4 aircraft per delivery
threshold = 0.75 -- Trigger at 75% (9/12 aircraft)
}
}
Goal: RED has numerical superiority, BLUE has quality advantage
-- RED: More squadrons, lower skill
local TADC_SETTINGS = {
red = {
interceptRatio = 0.8, -- Conservative response
maxActiveCAP = 12, -- More groups allowed
}
}
RED_SQUADRON_CONFIG = {
{
templateName = "RED_CAP_1",
airbaseName = "Base_1",
aircraft = 16, -- Large squadron
skill = AI.Skill.GOOD, -- Average skill
-- ...
},
{
templateName = "RED_CAP_2",
airbaseName = "Base_2",
aircraft = 16,
skill = AI.Skill.GOOD,
-- ...
},
{
templateName = "RED_CAP_3",
airbaseName = "Base_3",
aircraft = 16,
skill = AI.Skill.GOOD,
-- ...
}
}
-- BLUE: Fewer squadrons, higher skill
local TADC_SETTINGS = {
blue = {
interceptRatio = 1.2, -- Aggressive response
maxActiveCAP = 8, -- Fewer groups
}
}
BLUE_SQUADRON_CONFIG = {
{
templateName = "BLUE_CAP_1",
airbaseName = "Base_1",
aircraft = 10, -- Smaller squadron
skill = AI.Skill.ACE, -- Elite pilots
-- ...
},
{
templateName = "BLUE_CAP_2",
airbaseName = "Base_2",
aircraft = 10,
skill = AI.Skill.ACE,
-- ...
}
}
Small Airbase: 6-8 aircraft per squadron
Medium Airbase: 10-12 aircraft per squadron
Large Airbase: 14-18 aircraft per squadron
Balance across map: If RED has 40 total aircraft, BLUE should have similar unless asymmetric
maxActiveCAP to prevent FPS dropsThe Universal TADC system provides mission makers with powerful, automated air defense capabilities that create dynamic, realistic air combat scenarios. By following this guide, even new mission makers can create sophisticated missions with minimal scripting knowledge.
If you encounter issues:
Happy mission making! 🚁✈️