VEAF Lua Modules - Complete API Reference¶
Version: generated for 6.36.0
Last Updated: November 2026
Project: VEAF Mission Creation Tools
Table of Contents¶
- Introduction
- Module Architecture
- Core Infrastructure
- veaf.lua - Core utilities and logger
- veafEventHandler.lua - Event management
- veafMarkers.lua - Map marker system
- veafCommands.lua - Central command dispatcher
- veafInterpreter.lua - Command parsing
- Unit & Group Management
- veafSpawnParser.lua - Spawn command text parser
- veafSpawn.lua - Dynamic spawning
- veafUnits.lua - Unit definitions
- veafAssets.lua - Asset tracking
- Mission Systems
- veafCombatMission.lua - Combat missions
- veafCasMission.lua - CAS missions
- Infrastructure & Services
- veafAirbases.lua - Airbase data
- veafCarrierOperations.lua - Carrier ops
- Communication & Control
- veafRadio.lua - Radio menus
- Support Systems
- veafWeather.lua - Weather system
- veafTime.lua - Time management
- Data & Database
- dcsUnits.lua - DCS unit database
- dcsDataExport.lua - Data export
- Appendix
Introduction¶
The VEAF (Virtual European Air Force) Lua modules provide a comprehensive framework for creating dynamic DCS World missions. This API reference documents all public functions, classes, and constants available to mission creators.
Key Features¶
- 33+ Lua modules providing runtime functionality
- Event-driven architecture using DCS World event system
- Modular design allowing selective module usage
- Extensive logging with configurable log levels
- Security system for controlled access
- Radio menu integration via F10 menu
- Marker-based commands using map markers
Module Loading Order¶
Modules must be loaded in dependency order:
1. veaf.lua (core - must be first)
2. veafEventHandler.lua
3. veafMarkers.lua
4. Other modules (any order)
Conventions Used¶
Parameter Types:
string- Text stringnumber- Numeric valueboolean- true/falsetable- Lua table/arrayvec3- 3D vector:{x=number, y=number, z=number}function- Callback functioncoalition- Coalition ID: 0=neutral, 1=red, 2=blue (coalition.side.REDis 1 — see the note below)
coalition.side is RED=1, BLUE=2
coalition.side = { NEUTRAL = 0, RED = 1, BLUE = 2 }
An inversion of these values is caught by nothing: code written from a wrong mapping compiles, runs, and quietly targets the other side.
Return Values:
- Functions return
nilon failure unless otherwise specified - Boolean returns indicate success/failure
Module Architecture¶
Standard Module Structure¶
All VEAF modules follow this pattern:
-- Module declaration
veafModuleName = veafModuleName or {}
-- Module metadata
veafModuleName.Id = "MODULE_ID"
veafModuleName.LogLevel = "info" -- or "debug", "trace"
-- Logger initialization
veafModuleName.logger = veaf.loggers.new(veafModuleName.Id, veafModuleName.LogLevel)
-- Initialization function
function veafModuleName.initialize()
veafModuleName.logger:info("Initializing module")
-- Initialization code
end
-- Start function (if applicable)
function veafModuleName.start()
veafModuleName.logger:info("Starting module")
-- Start monitoring/services
end
Logging Levels¶
All modules use standardized logging:
| Level | Value | Usage |
|---|---|---|
error |
1 | Critical errors only |
warning |
2 | Warnings and errors |
info |
3 | Normal operations (default) |
debug |
4 | Detailed debugging |
trace |
5 | Very verbose tracing |
Setting Log Levels:
veafModuleName.LogLevel = "debug"
veaf.loggers.setBaseLevel("info") -- Global default
Core Infrastructure¶
veaf.lua¶
Module ID: VEAF
Purpose: Root library providing core utilities, constants, and logger system
Constants¶
veaf.BuildVersion = "6.7.x+<sha>" -- build stamp (package version + git sha) injected at build time; "dev" when unbuilt
veaf.Development = false -- Enable development features
veaf.HideNamesFromSpawnedGroups = true -- hides the zone and the type in spawned group names; set per mission with `mission.hide_names_from_spawned_groups`
veaf.BaseLogLevel = 3 -- Default log level (info); acts as a cap for module log levels
veaf.DEFAULT_GROUND_SPEED_KPH = 30
veaf.DEFAULT_GROUND_SPEED_KTS = 16.2
veaf.DEFAULT_SPEED_KTS = 350
Localization (i18n) & pilot feedback¶
In-game pilot-facing messages are localized (FR/EN). The active language is veaf.config.language (set from mission.language, else the tools' resolved language at build time, whose final fallback is en); logs always stay in English.
veaf.t(key, ...)¶
Returns the localized string for key from veaf.i18nCatalog (populated by veafI18n.lua), with string.format interpolation. Fallback: requested language → French → the key itself (a missing entry never crashes).
trigger.action.outText(veaf.t("spawn.group_spawned", group.description, country), 5)
veaf.reportToPilot(message, duration, coalition)¶
Shows message in-game. With a coalition it uses outTextForCoalition; otherwise (or nil) it shows it to everyone (outText). Use it for command feedback addressed to the requester.
veaf.nearestMatch(word, candidates, maxDistance)¶
Returns the closest string in candidates within maxDistance Levenshtein edits (or nil). Used for the "did you mean …?" spawn-parameter hint.
veaf.getRequesterCoalition(event)¶
The coalition that issued a command (marker placer / interpreter unit), normalized to coalition.side.RED/.BLUE, or nil when unknown/all. Use it for pilot feedback — not for deciding the side of spawned units.
veaf.getOppositeCoalition(side)¶
The opposing coalition — the default side of units spawned from a marker (RED↔BLUE; neutral/all → RED). Pass an explicit side/country parameter to override.
JSON Functions¶
veaf.json.stringify(obj, as_key)¶
Convert Lua object to JSON string.
Parameters:
obj(any) - Lua object to serializeas_key(boolean, optional) - Format as JSON key
Returns: string - JSON representation
Example:
local data = {name = "Strike", type = "mission"}
local json = veaf.json.stringify(data)
-- Result: '{"name":"Strike","type":"mission"}'
veaf.json.parse(str, pos, end_delim)¶
Parse JSON string to Lua object.
Parameters:
str(string) - JSON stringpos(number, optional) - Starting position (default: 1)end_delim(string, optional) - End delimiter
Returns: table - Parsed Lua object
Example:
local json = '{"name":"Strike","type":"mission"}'
local data = veaf.json.parse(json)
-- Result: {name = "Strike", type = "mission"}
String Utilities¶
veaf.trim(s)¶
Remove leading and trailing whitespace.
Parameters:
s(string) - String to trim
Returns: string - Trimmed string
Example:
local trimmed = veaf.trim(" hello ")
-- Result: "hello"
veaf.split(str, sep)¶
Split string by separator into array.
Parameters:
str(string) - String to splitsep(string) - Separator character/string
Returns: table - Array of substrings
Example:
local parts = veaf.split("red,blue,green", ",")
-- Result: {"red", "blue", "green"}
veaf.splitWithPattern(str, pat)¶
Split string using regex pattern.
Parameters:
str(string) - String to splitpat(string) - Lua pattern
Returns: table - Array of substrings
veaf.breakString(str, sep)¶
Break string around separator (returns 2 parts).
Parameters:
str(string) - String to breaksep(string) - Separator
Returns: string, string - Two parts (before and after separator)
Example:
local before, after = veaf.breakString("key=value", "=")
-- Result: before="key", after="value"
veaf.escapeRegex(stringToEscape)¶
Escape special regex characters.
Parameters:
stringToEscape(string) - String to escape
Returns: string - Escaped string
Table/Array Utilities¶
veaf.length(T)¶
Get table length (handles non-sequential keys).
Parameters:
T(table) - Table to measure
Returns: number - Number of elements
Example:
local t = {a=1, b=2, c=3}
local len = veaf.length(t)
-- Result: 3
veaf.arrayRemoveWhen(t, fnKeep)¶
Remove elements from array based on condition.
Parameters:
t(table) - Array to filterfnKeep(function) - Keep function:function(element) return boolean end
Returns: table - Modified array
Example:
local numbers = {1, 2, 3, 4, 5}
veaf.arrayRemoveWhen(numbers, function(n) return n > 3 end)
-- Result: {1, 2, 3}
veaf.shuffle(tbl)¶
Randomly shuffle array elements in place.
Parameters:
tbl(table) - Array to shuffle
Returns: table - Shuffled array (same reference)
veaf.tableContains(table, element)¶
Check if table contains element.
Parameters:
table(table) - Table to searchelement(any) - Element to find
Returns: boolean - True if found
veaf.randomlyChooseFrom(aTable, bias)¶
Choose random element from table with optional bias.
Parameters:
aTable(table) - Table to choose frombias(number, optional) - Bias factor (default: 1.0)
Returns: any - Random element
Example:
local colors = {"red", "blue", "green"}
local color = veaf.randomlyChooseFrom(colors)
Vector & Coordinate Functions¶
veaf.vecToString(vec)¶
Convert 3D vector to human-readable string.
Parameters:
vec(vec3) - Vector{x, y, z}
Returns: string - Formatted string
Example:
local pos = {x=1000, y=50, z=2000}
local str = veaf.vecToString(pos)
-- Result: "x=1000, y=50, z=2000"
veaf.findPointInZone(spawnSpot, dispersion, isShip)¶
Find random spawn point within zone with dispersion.
Parameters:
spawnSpot(vec3) - Center positiondispersion(number) - Radius in metersisShip(boolean, optional) - Find water location
Returns: vec3 - Random point within zone
veaf.placePointOnLand(vec3)¶
Place point on land surface (adjusts Y altitude).
Parameters:
vec3(vec3) - Position to adjust
Returns: vec3 - Position on land surface
veaf.findSpawnPoint(vec3, radius, safeRadius)¶
Searches for an acceptable ground spawn point near a centre. Where placePointOnLand moves a
point vertically, this one searches for one.
The search degrades in three bounded tiers:
- Every criterion, clearance from scenery included - through the
DispositionDCS singleton, which returns points clear of buildings and forests. - Every criterion except that clearance - validated random draws within the radius.
- Failure - returns
nil; the caller reports it and aborts the spawn.
Parameters:
vec3(vec3) - Centre of the searchradius(number) - Search radius in metres, used by the random tiersafeRadius(number, optional) - Required clearance (defaultveaf.DEFAULT_SPAWN_CLEARANCE)
Returns: vec3 placed on land, or nil when no acceptable point was found
Settings:
veaf.SPAWN_SEARCH_ATTEMPTS(default 10) - candidates examined per tierveaf.DEFAULT_SPAWN_CLEARANCE(default 100) - requested clearance, in metresveaf.doNotAvoidScenery(defaultfalse) - whentrue, skips tier 1
Note:
Dispositionis a native but undocumented DCS API, absent fromdcs-world-schema. The call is guarded andpcall-wrapped: if the singleton is missing on this DCS version or map, the search falls through to tier 2 instead of failing.
veafUnits.settleGroup(units, honourDeclaredPosition)¶
Moves the whole group, as one rigid body, into a clearing wide enough to hold it.
veaf.findSpawnPoint only places the group's centre; veafUnits.placeGroup then spreads the
vehicles around that centre without looking at the scenery, so a battery standing in the open can
still have half its pieces in the trees.
Every vehicle gets the same offset, so the distances between them do not change: the formation is preserved. A vehicle-by-vehicle nudge cannot work — a battery's natural spacing is 20 to 27 m, while the closest free point DCS can propose is 52 m away.
How it searches: it sweeps rings of growing radius around the group, closest first, and keeps the
first offset where every vehicle stands on drivable terrain and passes the small scenery probe
(Disposition.getSimpleZones asked about one point: 5 m free within 20 m). It never asks
Disposition to propose a clearing: that query is not deterministic and returns nothing where a
group most needs moving (measured 2026-09-26).
Parameters:
units- the unit list, asveafUnits.placeGroupfilled it inhonourDeclaredPosition- whentrue, the caller states that it owns the placement and nothing moves. Same contract asVeafGroupSpawn:honouringDeclaredPosition(), and explicit for the same reason: a zero radius is this codebase's default, not a statement. Measured 2026-09-25 on GermanyCW-v6, 100 of the 118 spawn commands of one launch passradius 0- that is to say every battery this lot has to move.
Returns: the distance the group was moved by, 0 when it stayed put.
Never moves: a group holding an air unit, a naval unit or a naval static; a convoy; a caller that
set honourDeclaredPosition; a mission that set veaf.doNotAvoidScenery to true; and Mission
Editor content, which goes through VeafGroupSpawn:honouringDeclaredPosition() and never reaches
here.
Settings:
veafUnits.SETTLE_MAX_TRANSLATION(default 300) - acceptable translation distance, in metres, and how far the sweep looks. Beyond it the group stays where it is.veafUnits.SETTLE_SWEEP_STEP(default 20) - spacing between two rings of the sweep, and between two offsets on one ring, in metres.veafUnits.SETTLE_SWEEP_PROBE_BUDGET(default 1000) - most probes spent on one group. It all runs in the spawn's frame, so this is the hitch a group with no way out costs on every activation (one probe ≈ 0.38 ms, measured 2026-09-26).
veaf.getLandHeight(vec3)¶
Get terrain height at coordinates.
Parameters:
vec3(vec3) - Position
Returns: number - Terrain altitude in meters
veaf.headingBetweenPoints(point1, point2)¶
Calculate heading from point1 to point2.
Parameters:
point1(vec3) - Starting pointpoint2(vec3) - Destination point
Returns: number - Heading in degrees (0-360)
veaf.getBearingAndRangeFromTo(fromPoint, toPoint)¶
Calculate bearing and range between two points.
Parameters:
fromPoint(vec3) - Starting pointtoPoint(vec3) - Destination point
Returns: number, number - Bearing (degrees), Range (meters)
Example:
local bearing, range = veaf.getBearingAndRangeFromTo(pos1, pos2)
veaf.logger:info("Target at %d° for %.0f meters", bearing, range)
veaf.computeLLFromString(value)¶
Parse latitude/longitude from string.
Parameters:
value(string) - Lat/Lon string (various formats supported)
Returns: table - {lat=number, lon=number} or nil
Supported Formats:
- DMS:
N 43°15'30" E 005°45'20" - Decimal:
43.258333, 5.755556 - MGRS: (via conversion)
veaf.computeCoordinatesOffsetFromRoute(startingPoint, destinationPoint, distanceFromStartingPoint, offset)¶
Calculate position offset from a route.
Parameters:
startingPoint(vec3) - Route startdestinationPoint(vec3) - Route enddistanceFromStartingPoint(number) - Distance along route (meters)offset(number) - Perpendicular offset (meters, positive = right)
Returns: vec3 - Offset position
Unit & Group Functions¶
veaf.addUnit(group, spawnSpot, dispersion, unitType, unitName, skill)¶
Add unit to group definition.
Parameters:
group(table) - Group definition tablespawnSpot(vec3) - Spawn positiondispersion(number) - Dispersion radius (meters)unitType(string) - DCS unit type nameunitName(string) - Unit nameskill(string) - Skill level: "Average", "Good", "High", "Excellent", "Random"
Returns: table - Modified group table
veaf.getAveragePosition(group)¶
Get center position of group.
Parameters:
group(table or DCS Group) - Group object or table
Returns: vec3 - Average position
veaf.getAvgGroupPos(groupName)¶
Get average position of group by name.
Parameters:
groupName(string) - Group name
Returns: vec3 - Average position or nil
veaf.moveGroupAt(groupName, leadUnitName, heading, speed, timeInSeconds, endPosition, pMiddlePointDistance)¶
Move group in specific direction and speed.
Parameters:
groupName(string) - Group to moveleadUnitName(string) - Lead unit nameheading(number) - Direction in degreesspeed(number) - Speed in m/stimeInSeconds(number) - Duration of movementendPosition(vec3, optional) - Final positionpMiddlePointDistance(number, optional) - Intermediate waypoint distance
Returns: boolean - Success flag
veaf.moveGroupTo(groupName, pos, speed, altitude)¶
Move group to position.
Parameters:
groupName(string) - Group namepos(vec3) - Destinationspeed(number, optional) - Speed in m/s (default: 30 kph)altitude(number, optional) - Altitude override
Returns: boolean - Success
veaf.readyForCombat(group, alarm, disperseTime)¶
Prepare ground group for combat.
Parameters:
group(DCS Group or string) - Group or group namealarm(boolean, optional) - Alarm state (default: false)disperseTime(number, optional) - Time to disperse in seconds
Returns: None
Description: Sets group to combat ready state, optionally disperses units.
veaf.getGroupsOfCoalition(coa)¶
Get all groups of coalition.
Parameters:
coa(coalition, optional) - Coalition filter (default: all)
Returns: table - Array of DCS Group objects
veaf.getUnitsOfCoalition(includeStatics, coa)¶
Get all units of coalition.
Parameters:
includeStatics(boolean) - Include static objectscoa(coalition, optional) - Coalition filter
Returns: table - Array of unit/static objects
veaf.findUnitsInCircle(center, radius, includeStatics, onlyTheseUnits)¶
Find units in circular area.
Parameters:
center(vec3) - Circle centerradius(number) - Radius in metersincludeStatics(boolean, optional) - Include staticsonlyTheseUnits(table, optional) - Filter to these units only
Returns: table - Array of units/statics
Example:
local targetPos = {x=1000, y=0, z=2000}
local enemyUnits = veaf.findUnitsInCircle(targetPos, 500, false)
veaf.logger:info("Found %d enemy units", #enemyUnits)
veaf.isUnitInZone(unitOrName, zoneOrName)¶
Check if unit is inside trigger zone.
Parameters:
unitOrName(DCS Unit or string) - Unit or unit namezoneOrName(DCS Zone or string) - Zone or zone name
Returns: boolean - True if inside zone
veaf.isUnitAlive(unit)¶
Check if unit is alive.
Parameters:
unit(DCS Unit or string) - Unit or unit name
Returns: boolean - True if alive
veaf.getUnitLifeRelative(unit)¶
Get unit health as percentage.
Parameters:
unit(DCS Unit or string) - Unit or unit name
Returns: number - Health percentage (0-100)
veaf.fixUnitsTable(unitsOrNames)¶
Convert unit names to unit objects.
Parameters:
unitsOrNames(table) - Array of units or unit names
Returns: table - Array of unit objects
Route Generation¶
veaf.generateVehiclesRoute(startPoint, destination, onRoad, speed, groupName)¶
Generate vehicle movement route.
Parameters:
startPoint(vec3) - Starting positiondestination(vec3) - Destination positiononRoad(boolean) - Use roads when possiblespeed(number) - Speed in m/sgroupName(string, optional) - Group name for logging
Returns: table - Route table
Route Table Structure:
{
[1] = {
x = number,
y = number,
action = "On Road" or "Off Road",
speed = number,
type = "Turning Point"
},
-- ... more waypoints
}
veaf.PatrolWatchdog(groupName, patrolRoute, speed, firstPass)¶
Monitor patrol route and repeat.
Parameters:
groupName(string) - Group namepatrolRoute(table) - Route tablespeed(number) - Speed in m/sfirstPass(boolean) - Is first iteration
Returns: None (schedules itself)
Information Functions¶
veaf.getTankerData(tankerGroupName)¶
Get tanker information.
Parameters:
tankerGroupName(string) - Tanker group name
Returns: table - Tanker data structure
Tanker Data Structure:
{
name = "Texaco-1",
type = "KC-135",
TACANchannel = "61X",
TACANfrequency = "1088 MHz",
TACANmorse = "\u2013\u2022 \u2022\u2022\u2022\u2022 \u2013\u2022\u2022",
RadioFrequency = "251.0 MHz",
RadioModulation = "AM",
callsign = "Texaco 1-1",
position = vec3
}
veaf.getCarrierATCdata(carrierGroupName, carrierUnitName)¶
Get carrier ATC information.
Parameters:
carrierGroupName(string) - Carrier group namecarrierUnitName(string, optional) - Specific unit name
Returns: table - ATC data
ATC Data Structure:
{
name = "CVN-73",
callsign = "Mother",
RadioFrequency = "127.5 MHz",
RadioModulation = "AM",
TACANchannel = "73X",
TACANfrequency = "1205 MHz",
TACANmorse = "\u2013\u2022\u2022\u2022 \u2022\u2022\u2022\u2013 \u2013\u2022\u2022",
ICLS = "13",
position = vec3,
heading = number
}
veaf.getGroupData(groupIdent)¶
Get raw DCS group data.
Parameters:
groupIdent(string or number) - Group name or ID
Returns: table - DCS group data table
veafWeatherData.getWeatherString(vec3, dcsElementName, unitSystem, iSurfaceAltitudeMeters)¶
Generate a weather report string for a position. The unit system and LASTE inclusion are derived from the supplied DCS element (e.g. an A-10 enables LASTE automatically).
Parameters:
vec3(vec3) - Position for reportdcsElementName(string, optional) - Name of a DCS element (unit/airbase) used to derive the unit system and LASTEunitSystem(string, optional) - Unit system; defaults based on the elementiSurfaceAltitudeMeters(number, optional) - Surface altitude in metres
Returns: string - Weather report text
Example Output:
Weather at position:
QNH: 29.92 inHg (1013 hPa)
Temperature: 15°C (59°F)
Wind: 270° at 10 kts
Output Functions¶
veaf.outTextForUnit(unitName, message, duration, forAllGroup)¶
Display text message to unit.
Parameters:
unitName(string) - Target unit namemessage(string) - Message textduration(number, optional) - Display duration in seconds (default: 5)forAllGroup(boolean, optional) - Show to all group members
Returns: None
Example:
veaf.outTextForUnit("Viper 1-1", "Target destroyed!", 10, true)
veaf.outTextForGroup(unitName, message, duration)¶
Display text to entire group.
Parameters:
unitName(string) - Any unit in groupmessage(string) - Message textduration(number, optional) - Duration in seconds
Returns: None
Conversion Functions¶
veaf.convertMachSpeed(mach, altitude, temperature)¶
Convert Mach number to true airspeed.
Parameters:
mach(number) - Mach numberaltitude(number) - Altitude in meterstemperature(number, optional) - Temperature offset in °C
Returns: number - True airspeed in knots
veaf.convertTrueAirSpeed(ktas, altitude, temperature)¶
Convert true airspeed to Mach.
Parameters:
ktas(number) - True airspeed in knotsaltitude(number) - Altitude in meterstemperature(number, optional) - Temperature offset
Returns: number - Mach number
veaf.convertSpeeds(mach, kias, ktas, altitude, temperature, pressure)¶
Convert between speed formats.
Parameters:
mach(number, optional) - Mach numberkias(number, optional) - Indicated airspeed (knots)ktas(number, optional) - True airspeed (knots)altitude(number) - Altitude in meterstemperature(number, optional) - Temperature offsetpressure(number, optional) - Pressure in hPa
Returns: table - {mach, kias, ktas}
Example:
local speeds = veaf.convertSpeeds(0.9, nil, nil, 10000)
-- Result: {mach=0.9, kias=calculated, ktas=calculated}
veaf.getMagneticDeclination()¶
Get magnetic declination for current theater.
Returns: number - Declination in degrees
veaf.getWind(point)¶
Get wind at position.
Parameters:
point(vec3) - Position
Returns: table - {direction=number, strength=number}
Math & Utility Functions¶
veaf.round(num, numDecimalPlaces)¶
Round number to decimal places.
Parameters:
num(number) - Number to roundnumDecimalPlaces(number, optional) - Decimal places (default: 0)
Returns: number - Rounded number
veaf.getRandomizableNumeric(val)¶
Parse randomizable numeric value.
Parameters:
val(string or number) - Value like "2-6" or "5"
Returns: number - Random value in range
Example:
local size = veaf.getRandomizableNumeric("3-7")
-- Result: Random number between 3 and 7
veaf.invertHeading(heading)¶
Get opposite heading.
Parameters:
heading(number) - Heading in degrees
Returns: number - Opposite heading (0-360)
veaf.laserCodeToDigit(code)¶
Convert laser code to digit.
Parameters:
code(number) - Laser code (e.g., 1688)
Returns: number - Digit representation
Country & Coalition Functions¶
veaf.getCountryId(countryName)¶
Get DCS country ID from name.
Parameters:
countryName(string) - Country name (e.g., "USA", "Russia")
Returns: number - Country ID or nil
veaf.getCountryName(countryId)¶
Get country name from ID.
Parameters:
countryId(number) - DCS country ID
Returns: string - Country name
veaf.getCountryForCoalition(coalition)¶
Get default country for coalition.
Parameters:
coalition(coalition) - Coalition ID
Returns: number - Country ID
Default Mapping:
- Blue → USA (2)
- Red → Russia (0)
veaf.getCoalitionForCountry(countryName, asNumber)¶
Get coalition for country.
Parameters:
countryName(string) - Country nameasNumber(boolean, optional) - Return as number instead of coalition object
Returns: coalition or number - Coalition
veaf.getAirbaseForCoalition(airbase_name, coa)¶
Get airbase object for coalition.
Parameters:
airbase_name(string) - Airbase namecoa(coalition) - Coalition
Returns: DCS Airbase - Airbase object or nil
Airbase Functions¶
veaf.findDcsAirbase(name)¶
Find DCS airbase by name (case-insensitive).
Parameters:
name(string) - Airbase name
Returns: DCS Airbase - Airbase object or nil
veaf.silenceAtcOnAllAirbases()¶
Disable ATC on all airbases.
Returns: None
Description: Useful for immersion or to prevent ATC conflicts.
veaf.loadAirbasesLife0()¶
Load airbase initial health data.
Returns: None
Description: Must be called before using veaf.getAirbaseLife().
veaf.getAirbaseLife(airbase_name, percentage, loading)¶
Get airbase health/damage.
Parameters:
airbase_name(string) - Airbase namepercentage(boolean, optional) - Return as percentageloading(boolean, optional) - Loading initial data
Returns: number - Health value (0-1 or 0-100 if percentage)
veaf.getPolygonFromUnits(unitNames)¶
Create polygon from unit positions.
Parameters:
unitNames(table) - Array of unit names
Returns: table - Array of vec3 positions
Trigger Zone Functions¶
veaf.getTriggerZone(zoneName)¶
Get trigger zone by name.
Parameters:
zoneName(string) - Zone name
Returns: DCS Zone - Zone object or nil
veaf.getZoneProperty(zoneName, key)¶
Reads a trigger-zone property, as typed by the mission maker in the editor.
DCS stores these as an array of pairs { key = "…", value = "…" }, never a map, and every
value is a string. These three accessors replace the linear scan and the tonumber every
caller would otherwise write.
Parameters:
zoneName(string) - Zone namekey(string) - Property name
Returns: string - or nil when the zone, its properties or the key are missing
veaf.getZonePropertyBoolean(zoneName, key, default)¶
Reads a property as a boolean. Accepts true/false in any case; anything else is a failed
read and yields default - so a typo cannot silently read as false.
Parameters:
zoneName(string) - Zone namekey(string) - Property namedefault(boolean) - Value returned when absent or unparseable
Returns: boolean
veaf.getZonePropertyNumber(zoneName, key, default, min, max)¶
Reads a property as a number, clamped into an optional range. Clamps rather than rejects: a mission maker who types an absurd value gets the bound, not a dead module.
Parameters:
zoneName(string) - Zone namekey(string) - Property namedefault(number) - Value returned when absent or not a numbermin(number, optional) - Lower boundmax(number, optional) - Upper bound
Returns: number
Mission Control Functions¶
veaf.endMissionAt(endTimeHour, endTimeMinute, checkIntervalInSeconds, checkMessage, ...)¶
Schedule mission end at specific time.
Parameters:
endTimeHour(number) - Hour (0-23)endTimeMinute(number) - Minute (0-59)checkIntervalInSeconds(number) - Check frequencycheckMessage(string, optional) - Message to display- Additional parameters for message formatting
Returns: None
Example:
-- End mission at 14:30 (2:30 PM)
veaf.endMissionAt(14, 30, 60, "Mission ends at %s")
veaf.getDcsTypeName(dcsElementName)¶
Get DCS type name from element name.
Parameters:
dcsElementName(string) - DCS element name
Returns: string - Type name
Serialization Functions¶
veaf.p(o, level, skip, includeMeta, dontRecurse)¶
Pretty-print/serialize object.
Parameters:
o(any) - Object to serializelevel(number, optional) - Indentation levelskip(table, optional) - Keys to skipincludeMeta(boolean, optional) - Include metatablesdontRecurse(table, optional) - Objects not to recurse
Returns: string - Serialized representation
Example:
local data = {name = "Strike", units = {1, 2, 3}}
local str = veaf.p(data)
print(str)
-- Output:
-- {
-- name = "Strike",
-- units = {
-- [1] = 1,
-- [2] = 2,
-- [3] = 3
-- }
-- }
veaf.serialize(name, value, level)¶
Serialize value to Lua code string.
Parameters:
name(string) - Variable namevalue(any) - Value to serializelevel(number, optional) - Indentation level
Returns: string - Lua code string
veaf.exportAsJson(data, name, jsonify, filename, export_path)¶
Export data to JSON file.
Parameters:
data(any) - Data to exportname(string) - Variable namejsonify(boolean) - Convert to JSON (vs Lua)filename(string, optional) - Output filenameexport_path(string, optional) - Export directory path
Returns: boolean - Success flag
Example:
local missions = {
{name = "CAP Alpha", type = "air"},
{name = "Strike Bravo", type = "ground"}
}
veaf.exportAsJson(missions, "missions", true, "missions.json")
Logger Class¶
The veaf.Logger class provides structured logging with levels.
Creating Loggers¶
-- Global loggers
veaf.loggers.setBaseLevel("info") -- Set default level
local logger = veaf.loggers.new("MYMODULE", "debug") -- Create logger
local existingLogger = veaf.loggers.get("MYMODULE") -- Get existing
-- Instance loggers
local myLogger = veaf.Logger:new("MYMODULE", "info")
Logger Methods¶
logger:setName(value)
Set logger name.
logger:setLevel(value, force)
Set logging level.
Parameters:
value(string or number) - Level: "error", "warning", "info", "debug", "trace"force(boolean, optional) - Force override base level
logger:error(text, ...)
Log error message (level 1).
Parameters:
text(string) - Message with format placeholders...- Format arguments
Example:
logger:error("Failed to spawn %s at position %s", groupName, veaf.vecToString(pos))
logger:warn(text, ...)
Log warning message (level 2).
logger:info(text, ...)
Log info message (level 3).
logger:debug(text, ...)
Log debug message (level 4).
logger:trace(text, ...)
Log trace message (level 5).
logger:wouldLogDebug()
Check if debug logging enabled.
Returns: boolean
logger:wouldLogTrace()
Check if trace logging enabled.
Returns: boolean
Usage:
if logger:wouldLogTrace() then
-- Expensive trace logging
logger:trace("Complex data: %s", veaf.p(largeTable))
end
Map Marker Logging¶
logger:marker(id, header, message, position, markersTable, radius, fillColor)
Add map marker for debugging.
Parameters:
id(number) - Marker IDheader(string) - Marker header textmessage(string) - Marker messageposition(vec3) - Marker positionmarkersTable(table, optional) - Track markers in tableradius(number, optional) - Circle radiusfillColor(table, optional) - Fill color{r, g, b, a}
Returns: None
logger:markerArrow(id, header, message, positionStart, positionEnd, markersTable, lineType, fillColor)
Add arrow marker.
Parameters:
id(number) - Marker IDheader(string) - Header textmessage(string) - MessagepositionStart(vec3) - Arrow startpositionEnd(vec3) - Arrow endmarkersTable(table, optional) - Track markerslineType(number, optional) - Line typefillColor(table, optional) - Color
logger:markerQuad(id, header, message, points, markersTable, lineType, fillColor)
Add quadrilateral marker.
Parameters:
id(number) - Marker IDheader(string) - Headermessage(string) - Messagepoints(table) - Array of 4 vec3 pointsmarkersTable(table, optional) - Track markerslineType(number, optional) - Line typefillColor(table, optional) - Color
veafEventHandler.lua¶
Module ID: EVENTS
Purpose: DCS World event handling and callback management
Constants¶
Event Types¶
veafEventHandler.EVENTS = {
[0] = "S_EVENT_INVALID",
[1] = "S_EVENT_SHOT",
[2] = "S_EVENT_HIT",
[3] = "S_EVENT_TAKEOFF",
[4] = "S_EVENT_LAND",
[5] = "S_EVENT_CRASH",
[6] = "S_EVENT_EJECTION",
[7] = "S_EVENT_REFUELING",
[8] = "S_EVENT_DEAD",
[9] = "S_EVENT_PILOT_DEAD",
[10] = "S_EVENT_BASE_CAPTURED",
[11] = "S_EVENT_MISSION_START",
[12] = "S_EVENT_MISSION_END",
[13] = "S_EVENT_TOOK_CONTROL",
[14] = "S_EVENT_REFUELING_STOP",
[15] = "S_EVENT_BIRTH",
[16] = "S_EVENT_HUMAN_FAILURE",
[17] = "S_EVENT_DETAILED_FAILURE",
[18] = "S_EVENT_ENGINE_STARTUP",
[19] = "S_EVENT_ENGINE_SHUTDOWN",
[20] = "S_EVENT_PLAYER_ENTER_UNIT",
[21] = "S_EVENT_PLAYER_LEAVE_UNIT",
[22] = "S_EVENT_PLAYER_COMMENT",
[23] = "S_EVENT_SHOOTING_START",
[24] = "S_EVENT_SHOOTING_END",
[25] = "S_EVENT_MARK_ADDED",
[26] = "S_EVENT_MARK_CHANGE",
[27] = "S_EVENT_MARK_REMOVED",
[28] = "S_EVENT_KILL",
[29] = "S_EVENT_SCORE",
[30] = "S_EVENT_UNIT_LOST",
[31] = "S_EVENT_LANDING_AFTER_EJECTION",
[32] = "S_EVENT_PARATROOPER_LENDING",
[33] = "S_EVENT_DISCARD_CHAIR_AFTER_EJECTION",
[34] = "S_EVENT_WEAPON_ADD",
[35] = "S_EVENT_TRIGGER_ZONE",
-- ... up to event 61
}
Callback Delay¶
veafEventHandler.CALLBACK_DELAY = 0.5 -- seconds
Functions¶
veafEventHandler.addCallback(name, events, callback)¶
Register event callback function.
Parameters:
name(string) - Unique callback nameevents(table or nil) - Array of event IDs/names, or nil for all eventscallback(function) - Callback function
Callback Signature:
function callback(transformedEvent)
-- transformedEvent is enhanced event table
end
Returns: boolean - True if registered successfully
Example:
-- Listen to all events
veafEventHandler.addCallback("myHandler", nil, function(event)
veaf.logger:info("Event: %s", event.type.name)
end)
-- Listen to specific events
veafEventHandler.addCallback("birthHandler",
{"S_EVENT_BIRTH", "S_EVENT_PLAYER_ENTER_UNIT"},
function(event)
if event.initiator then
veaf.logger:info("Unit spawned: %s", event.initiator.unitName)
end
end
)
-- Listen by event ID
veafEventHandler.addCallback("shotHandler", {1, 23}, function(event)
-- Handle S_EVENT_SHOT and S_EVENT_SHOOTING_START
end)
veafEventHandler.completeUnit(unit)¶
Get complete unit information from DCS unit.
Parameters:
unit(DCS Unit) - Unit object
Returns: table - Unit info table
Unit Info Structure:
{
unitName = "Viper 1-1",
unitCallsign = "Viper11",
unitType = "F-16C_50",
unitGroupName = "Viper Flight",
unitGroupId = 123,
unitCoalition = coalition.side.BLUE,
unitCategory = Unit.Category.AIRPLANE,
unitPilotName = "Player Name", -- if human
unitPilotUcid = "abc123...", -- if human with SRS
unitLifePercent = 100.0
}
veafEventHandler.completeUnitFromName(unitName)¶
Get unit information from unit name.
Parameters:
unitName(string) - Unit name
Returns: table - Unit info table (same as completeUnit)
Example:
local unitInfo = veafEventHandler.completeUnitFromName("Viper 1-1")
if unitInfo then
veaf.logger:info("Unit %s is at %.0f%% health",
unitInfo.unitName, unitInfo.unitLifePercent)
end
veafEventHandler.checkEventKnown(eventNameOrId, warnOnly)¶
Validate event is recognized by DCS.
Parameters:
eventNameOrId(string or number) - Event name or IDwarnOnly(boolean, optional) - Only warn, don't error
Returns: boolean - True if event is known
veafEventHandler.setEventEnabled(eventNameOrId, enabled)¶
Enable or disable event processing.
Parameters:
eventNameOrId(string or number) - Event to controlenabled(boolean) - Enable flag
Returns: None
Example:
-- Disable shooting events for performance
veafEventHandler.setEventEnabled("S_EVENT_SHOOTING_START", false)
veafEventHandler.setEventEnabled("S_EVENT_SHOOTING_END", false)
veafEventHandler.isEventEnabled(eventNameOrId)¶
Check if event processing is enabled.
Parameters:
eventNameOrId(string or number) - Event to check
Returns: boolean - True if enabled
veafEventHandler.isEventDelayedCallback(eventNameOrId)¶
Check if event uses delayed callback.
Parameters:
eventNameOrId(string or number) - Event to check
Returns: boolean - True if delayed
Description: Some events like BIRTH need delayed callbacks to allow DCS to fully initialize objects.
veafEventHandler.initialize()¶
Initialize event handler system.
Returns: None
Description: Called automatically by VEAF initialization. Registers DCS world event handler.
Transformed Event Structure¶
Events passed to callbacks are enhanced with additional fields:
{
-- Original DCS event fields
id = number, -- DCS event ID
time = number, -- Mission time
initiator = DCS_Unit, -- Unit that triggered event
target = DCS_Unit, -- Target unit (if applicable)
weapon = DCS_Weapon, -- Weapon object (if applicable)
place = DCS_Airbase, -- Airbase (for takeoff/land)
-- VEAF enhancements
type = { -- Event type info
id = number,
name = "S_EVENT_XXX",
definition = event_definition
},
idx = number, -- Event index
coordinates = vec3, -- Event position
text = string, -- Marker text (for marker events)
coalition = coalition, -- Coalition ID
groupId = number, -- Group ID
-- Enhanced unit info (if initiator exists)
initiator = {
unitName = string,
unitCallsign = string,
unitType = string,
unitGroupName = string,
unitGroupId = number,
unitCoalition = coalition,
unitCategory = category,
unitPilotName = string, -- if human
unitPilotUcid = string, -- if human
unitLifePercent = number
},
-- Enhanced target info (if target exists)
target = {
-- same structure as initiator
},
-- Weapon info (if weapon fired/hit)
weaponName = string, -- Weapon type name
-- Marker event fields
comment = string -- Marker comment text
}
Event Handling Best Practices¶
Performance:
- Disable unused events to reduce overhead
- Use delayed callbacks for expensive operations
- Filter events by type when registering callbacks
Event Timing:
- BIRTH events fire before units fully initialized
- Use delayed callbacks for BIRTH if accessing unit properties
- PLAYER_ENTER_UNIT fires after player fully loaded
Example: Complete Event Handler:
-- Track player kills
local playerKills = {}
veafEventHandler.addCallback("killTracker", {"S_EVENT_KILL"}, function(event)
if event.initiator and event.initiator.unitPilotName then
-- Human player got a kill
local playerName = event.initiator.unitPilotName
playerKills[playerName] = (playerKills[playerName] or 0) + 1
local targetName = "unknown"
if event.target and event.target.unitName then
targetName = event.target.unitName
end
veaf.outTextForUnit(event.initiator.unitName,
string.format("Kill confirmed! Total: %d", playerKills[playerName]),
10, false)
veaf.logger:info("%s killed %s (total kills: %d)",
playerName, targetName, playerKills[playerName])
end
end)
veafMarkers.lua¶
Module ID: MARKERS
Purpose: Listen to map marker events and execute handlers
Constants¶
veafMarkers.MarkerAdd = 1 -- Marker added event
veafMarkers.MarkerChange = 2 -- Marker changed event
veafMarkers.MarkerRemove = 3 -- Marker removed event
veafMarkers.DCSbugfixed = true -- DCS marker bug status
Functions¶
veafMarkers.registerEventHandler(eventType, eventHandler)¶
Register handler for marker events.
Parameters:
eventType(number) - Event type:MarkerAdd,MarkerChange, orMarkerRemoveeventHandler(function) - Handler function
Handler Signature:
function eventHandler(vec3_position, event)
-- vec3_position: marker position
-- event: DCS event table
end
Returns: number - Handler ID for unregistering
Example:
-- Listen for marker additions
local handlerId = veafMarkers.registerEventHandler(
veafMarkers.MarkerAdd,
function(pos, event)
local text = event.text or ""
if text:match("^_spawn") then
-- Handle spawn command
veaf.logger:info("Spawn marker at %s", veaf.vecToString(pos))
end
end
)
veafMarkers.unregisterEventHandler(id)¶
Remove marker event handler.
Parameters:
id(number) - Handler ID from registerEventHandler
Returns: boolean - True if unregistered successfully
Example:
local handlerId = veafMarkers.registerEventHandler(veafMarkers.MarkerAdd, myHandler)
-- Later...
veafMarkers.unregisterEventHandler(handlerId)
Marker Event Structure¶
Marker events received by handlers contain:
{
id = number, -- Marker ID
time = number, -- Mission time
initiator = DCS_Unit, -- Unit that created marker (if applicable)
coalition = coalition, -- Coalition (-1 for all, 0=neutral, 1=red, 2=blue)
groupID = number, -- Group ID
text = string, -- Marker text
pos = vec3 -- Marker position
}
Usage Patterns¶
Command Pattern:
Modules register a handler with veafCommands which routes all F10 marker commands centrally:
-- In a module's initialize() function:
veafCommands.registerCommandHandler(function(pos, event, bypass, fromMarker, groups, route)
local text = event.text or ""
if not text:lower():match("^_mycommand") then
return false -- not our command
end
-- handle the command...
return true -- consumed
end, veafCommands.PRIORITY_SPAWN)
All handlers are called in priority order until one returns true.
The central dispatcher (veafCommands.dispatchMarker) handles the mark removal automatically.
Security Pattern:
Check coalition before executing:
veafMarkers.registerEventHandler(veafMarkers.MarkerAdd, function(pos, event)
-- Only allow blue coalition markers
if event.coalition == coalition.side.BLUE then
processCommand(pos, event.text)
else
veaf.logger:warn("Unauthorized marker from coalition %d", event.coalition)
end
end)
Cleanup Pattern:
Remove markers after processing:
veafMarkers.registerEventHandler(veafMarkers.MarkerChange, function(pos, event)
if processMarkerCommand(pos, event.text) then
-- Remove marker after successful processing
trigger.action.removeMark(event.id)
end
end)
veafCommands.lua¶
Module ID: COMMANDS
Init order: 15 (after veafMarkers, before all command modules)
Purpose: Central registry and dispatcher for all text commands (F10 markers and interpreter)
Constants¶
veafCommands.PRIORITY_SHORTCUTS = 10
veafCommands.PRIORITY_SPAWN = 20
veafCommands.PRIORITY_NAMEDPOINTS = 30
veafCommands.PRIORITY_CASMISSION = 40
veafCommands.PRIORITY_SECURITY = 50
veafCommands.PRIORITY_MOVE = 60
veafCommands.PRIORITY_RADIO = 70
veafCommands.PRIORITY_REMOTE = 80
Functions¶
veafCommands.registerCommandHandler(fn, priority)¶
Register a command handler function. Handlers are called in ascending priority order.
Parameters:
fn(function) - Handler with signature(pos, event, bypass, fromMarker, groups, route) → booleanpriority(number) - Execution order (lower = earlier); use thePRIORITY_*constants
veafCommands.execute(pos, text, coalition, groups, route)¶
Execute a command from the interpreter path (unit names). The coalition is used as-is.
Parameters:
pos(vec3) - Execution positiontext(string) - Command textcoalition(number) - Coalition numbergroups(table, optional) - Table to receive spawned group namesroute(table, optional) - Route definition
Returns: boolean — true if a handler consumed the command
veafCommands.dispatchMarker(eventPos, event)¶
Handle a marker change event. Inverts coalition (marker events report the placer's side, not the target's), calls all registered handlers in priority order, and removes the mark on success.
Parameters:
eventPos(vec3) - Marker positionevent(table) - Marker event object
veafInterpreter.lua¶
Module ID: INTERPRETER
Purpose: Interpret and execute commands from unit names and markers
Constants¶
veafInterpreter.Starter = "#veafInterpreter[\"" -- Unit name command prefix
veafInterpreter.Trailer = "\"]" -- Unit name command suffix
veafInterpreter.DelayForStartup = 1 -- Startup delay (seconds)
Functions¶
veafInterpreter.interpret(text)¶
Extract command from text string.
Parameters:
text(string) - Text containing command (unit name or marker text)
Returns: string - Extracted command or nil
Example:
local unitName = "#veafInterpreter[\"_spawn, name F-16C, group 2\"]"
local command = veafInterpreter.interpret(unitName)
-- Result: "_spawn, name F-16C, group 2"
veafInterpreter.execute(command, position, coalition, route, spawnedGroups)¶
Execute VEAF command. Delegates to veafCommands.execute() — all registered handlers are tried in priority order.
Parameters:
command(string) - Command stringposition(vec3) - Command execution positioncoalition(coalition, optional) - Coalition executing commandroute(table, optional) - Route definition for spawned groupsspawnedGroups(table, optional) - Table to receive spawned group names
Returns: boolean - True if command executed successfully
Note: Command routing is handled by veafCommands. Modules register themselves via veafCommands.registerCommandHandler().
Example:
local pos = {x=1000, y=50, z=2000}
local success = veafInterpreter.execute("_spawn, name F-16C, group 2", pos, coalition.side.BLUE)
if success then
veaf.logger:info("Command executed successfully")
end
veafInterpreter.executeCommandOnUnit(unitName, command)¶
Execute command from unit's position.
Parameters:
unitName(string) - Unit or static namecommand(string) - Command to execute
Returns: None
Description:
- Finds unit or static object by name
- Executes command at unit's position
- Destroys unit/static after successful execution
- Useful for pre-placed trigger units
Example:
-- In mission editor, create unit named: "#veafInterpreter[\"_spawn, name SA-6\"]"
-- Or execute via script:
veafInterpreter.executeCommandOnUnit("TriggerUnit1", "_spawn, name SA-6")
veafInterpreter.initialize()¶
Initialize interpreter module.
Returns: None
Description:
- Called automatically during VEAF initialization
- Scans for units with interpreter commands in names
- Executes commands after delay
Command Execution Flow¶
1. Command received (unit name or marker)
↓
2. veafInterpreter.interpret() extracts command
↓
3. Check veafShortcuts for shorthand
↓
4. Try module-specific handlers in order:
- veafSpawn (spawn commands)
- veafNamedPoints (named locations)
- veafCasMission (CAS missions)
- veafSecurity (security commands)
- veafMove (movement)
- veafRadio (radio/comms)
- veafRemote (remote API)
↓
5. Return success/failure
Unit Name Command Pattern¶
Mission Editor Usage:
1. Create unit (any type, even static)
2. Name unit: #veafInterpreter["COMMAND HERE"]
3. Unit will execute command on mission start and self-destruct
Example Use Cases:
-- Spawn CAP on mission start
Unit name: #veafInterpreter["_spawn, name CAP-2, alt 25000, hdg 090, speed 450"]
-- Create CAS target area
Unit name: #veafInterpreter["_cas, size 5, defense 3, armor 2"]
-- Spawn convoy on road
Unit name: #veafInterpreter["_spawn, convoy, name convoy1, dest marker1, speed 50"]
Unit & Group Management¶
veafSpawnParser.lua¶
Purpose: Parse spawn command text into options tables. Extracted sub-module of veafSpawn.
Functions¶
veafSpawn.markTextAnalysis(text)¶
Parse marker text for spawn parameters. Defined in veafSpawnParser.lua, available on the veafSpawn table.
Parameters:
text(string) - Marker text to parse
Returns: table — options table with parsed key/value pairs
veafSpawn.convertLaserToFreq(laser)¶
Convert a laser code to a TACAN/radio frequency string.
Parameters:
laser(number) - Laser code (1111–1788)
Returns: string — frequency label, or nil if not found
veafSpawn.lua¶
Module ID: SPAWN
Purpose: Dynamic spawning system for units, groups, convoys, and effects
Constants¶
Keyphrases¶
veafSpawn.SpawnKeyphrase = "_spawn"
veafSpawn.DestroyKeyphrase = "_destroy"
veafSpawn.TeleportKeyphrase = "_teleport"
veafSpawn.DrawingKeyphrase = "_drawing"
veafSpawn.MissionMasterKeyphrase = "_mm"
Configuration¶
veafSpawn.IlluminationFlareAglAltitude = 1000 -- meters
veafSpawn.LogisticUnitType = "FARP Ammo Dump Coating"
veafSpawn.CAP_WATCHDOG_DELAY = 10 -- seconds
veafSpawn.AFAC.maximumAmount = 8 -- max simultaneous AFACs
Main Functions¶
veafSpawn.executeCommand(eventPos, eventText, coalition, markId, bypassSecurity, spawnedGroups, repeatCount, repeatDelay, route, allowStartDelay, requesterCoalition)¶
Execute spawn command from marker or script.
Parameters:
eventPos(vec3) - Spawn positioneventText(string) - Command textcoalition(coalition, optional) - CoalitionmarkId(number, optional) - Marker ID to removebypassSecurity(boolean, optional) - Skip security checkspawnedGroups(table, optional) - Receive spawned group namesrepeatCount(number, optional) - Number of repetitionsrepeatDelay(number, optional) - Delay between spawns (seconds)route(table, optional) - Route for spawned groupsallowStartDelay(boolean, optional) - Allow delayed startrequesterCoalition(coalition, optional) - Requester coalition
Returns: boolean - Success flag
Example:
local pos = {x=1000, y=0, z=2000}
veafSpawn.executeCommand(pos, "_spawn, name F-16C, group 2, hdg 270", coalition.side.BLUE)
veafSpawn.markTextAnalysis(text)¶
Parse marker text for spawn parameters.
Parameters:
text(string) - Marker text
Returns: table - Parsed options
Returned Table Fields:
{
name = string, -- Unit/group name
unitName = string, -- Specific unit name
groupName = string, -- Override group name
alias = string, -- Name alias
group = number, -- Group count
country = string, -- Country name
alt = number, -- Altitude (feet)
altitude = number, -- Altitude (feet)
hdg = number, -- Heading (degrees)
heading = number, -- Heading (degrees)
speed = number, -- Speed (knots)
dist = number, -- Distance
spacing = number, -- Unit spacing (meters)
side = coalition, -- Coalition
defense = number, -- Defense level (0-5)
armor = number, -- Armor level (0-5)
size = number, -- Size (0-5)
shells = number, -- Shell count
power = number, -- Explosion power
radius = number, -- Dispersion radius
color = string, -- Smoke color
smoke = boolean, -- Add smoke
type = string, -- Type specification
skill = string, -- Skill level
password = string, -- Security password
silent = boolean, -- Suppress messages
-- Specific spawn types
convoy = boolean,
dest = vec3, -- Destination
patrol = boolean,
offroad = boolean,
-- Air units
cap = boolean, -- CAP mission
capRadius = number, -- CAP radius
afac = boolean, -- AFAC unit
immortal = boolean, -- Invulnerable
-- Effects
bomb = boolean,
smoke = boolean,
flare = boolean,
illumination = boolean,
-- FARP/FOB
farp = boolean,
fob = boolean,
farptype = string,
fobtype = string,
-- Advanced
code = number, -- Laser/TACAN code
freq = number, -- Frequency
mod = string, -- Modulation
role = string, -- Unit role
static = boolean, -- Spawn as static
hidden = boolean -- Hide from MFD
}
Unit Spawning Functions¶
veafSpawn.spawnUnit(spawnPosition, radius, name, czName, country, alt, hdg, unitName, role, static, code, freq, mod, silent, hiddenOnMFD)¶
Spawn single unit.
Parameters:
spawnPosition(vec3) - Spawn positionradius(number) - Dispersion radius (meters)name(string) - Unit type name (DCS type or alias)czName(string, optional) - Combat zone namecountry(number, optional) - Country IDalt(number, optional) - Altitude (feet)hdg(number, optional) - Heading (degrees)unitName(string, optional) - Override unit namerole(string, optional) - Unit rolestatic(boolean, optional) - Spawn as static objectcode(number, optional) - Laser/TACAN codefreq(number, optional) - Radio frequencymod(string, optional) - Radio modulationsilent(boolean, optional) - Suppress messageshiddenOnMFD(boolean, optional) - Hide from MFD
Returns: table - Spawned group info
Example:
-- Spawn F-16C at position
local pos = {x=1000, y=0, z=2000}
veafSpawn.spawnUnit(pos, 50, "F-16C", nil, nil, 5000, 270)
-- Spawn JTAC with laser code
veafSpawn.spawnUnit(pos, 0, "JTAC", nil, nil, nil, nil, "JTAC-1", "forward_observer", false, 1688)
-- Spawn tanker with TACAN
veafSpawn.spawnUnit(pos, 100, "KC-135", nil, nil, 25000, 270, "Texaco", nil, false, 61, 251.0, "AM")
veafSpawn.spawnGroup(spawnSpot, radius, name, czName, country, alt, hdg, spacing, groupName, silent, hasDest, hiddenOnMFD)¶
Spawn predefined group.
Parameters:
spawnSpot(vec3) - Spawn positionradius(number) - Dispersion radiusname(string) - Group template nameczName(string, optional) - Combat zonecountry(number, optional) - Countryalt(number, optional) - Altitudehdg(number, optional) - Headingspacing(number, optional) - Unit spacinggroupName(string, optional) - Override group namesilent(boolean, optional) - Suppress messageshasDest(vec3, optional) - Destination for movementhiddenOnMFD(boolean, optional) - Hide from MFD
Returns: table - Group info
Example:
-- Spawn armor platoon from template
veafSpawn.spawnGroup(pos, 100, "Soviet Armor Platoon", nil, nil, nil, 180, 50)
Ground Force Spawning¶
veafSpawn.spawnInfantryGroup(spawnSpot, radius, czName, country, side, heading, spacing, defense, armor, size, silent, hiddenOnMFD)¶
Spawn infantry group with parameters.
Parameters:
spawnSpot(vec3) - Spawn positionradius(number) - Dispersion radiusczName(string, optional) - Combat zonecountry(number, optional) - Countryside(coalition) - Coalitionheading(number, optional) - Formation headingspacing(number) - Unit spacing (meters)defense(number) - Defense level 0-5armor(number) - Armor level 0-5size(number) - Size 0-5 (affects unit count)silent(boolean, optional) - Suppress messageshiddenOnMFD(boolean, optional) - Hide from MFD
Returns: table - Group info
Example:
-- Spawn small infantry squad
veafSpawn.spawnInfantryGroup(pos, 50, nil, nil, coalition.side.RED, 0, 10, 0, 0, 1, false)
veafSpawn.spawnArmoredPlatoon(spawnSpot, radius, czName, country, side, heading, spacing, defense, armor, size, silent, hasDest, hiddenOnMFD)¶
Spawn armored platoon.
Parameters: Same as infantry + hasDest for movement
Returns: table - Group info
Example:
-- Spawn medium tank platoon
veafSpawn.spawnArmoredPlatoon(pos, 100, nil, nil, coalition.side.BLUE, 90, 50, 2, 3, 3, false)
veafSpawn.spawnAirDefenseBattery(spawnSpot, radius, czName, country, side, heading, spacing, defense, silent, hasDest, hiddenOnMFD)¶
Spawn SAM/AAA battery.
Parameters: Similar to armor platoon
Returns: table - Group info
Example:
-- Spawn SA-6 battery
veafSpawn.spawnAirDefenseBattery(pos, 200, nil, nil, coalition.side.RED, 0, 75, 4, false)
veafSpawn.spawnTransportCompany(spawnSpot, radius, czName, country, side, heading, spacing, defense, size, silent, hasDest, hiddenOnMFD)¶
Spawn transport company (trucks).
Returns: table - Group info
veafSpawn.spawnFullCombatGroup(spawnSpot, radius, czName, country, side, heading, spacing, defense, armor, size, silent, hiddenOnMFD)¶
Spawn combined arms group (infantry + armor + transport).
Returns: table - Multiple group info
Convoy System¶
veafSpawn.spawnConvoy(spawnSpot, name, czName, radius, country, side, heading, spacing, speed, patrol, offroad, destination, defense, size, armor, silent, hiddenOnMFD)¶
Spawn vehicle convoy with waypoints.
Parameters:
spawnSpot(vec3) - Starting positionname(string) - Convoy nameczName(string, optional) - Combat zoneradius(number) - Dispersioncountry(number, optional) - Countryside(coalition) - Coalitionheading(number, optional) - Initial headingspacing(number) - Vehicle spacingspeed(number) - Speed (km/h)patrol(boolean) - Patrol mode (return to start)offroad(boolean) - Allow offroad movementdestination(vec3) - Destination positiondefense(number) - Defense level 0-5size(number) - Size 0-5armor(number) - Armor level 0-5silent(boolean, optional) - Suppress messageshiddenOnMFD(boolean, optional) - Hide from MFD
Returns: table - Convoy info
Example:
local start = {x=1000, y=0, z=2000}
local dest = {x=5000, y=0, z=6000}
veafSpawn.spawnConvoy(start, "Convoy1", nil, 50, nil, coalition.side.RED,
nil, 25, 40, false, false, dest, 2, 3, 2, false)
Convoy Control Functions¶
veafSpawn.stopClosestConvoy(unitName)
Stop nearest convoy to unit.
veafSpawn.moveClosestConvoy(unitName)
Resume nearest convoy movement.
veafSpawn.markClosestConvoyWithSmoke(unitName)
Mark nearest convoy with smoke.
veafSpawn.markClosestConvoyRouteWithSmoke(unitName)
Mark convoy route with smoke markers.
veafSpawn.infoOnAllConvoys(unitName)
Display info on all active convoys.
veafSpawn.cleanupAllConvoys()
Destroy all active convoys.
Aircraft Spawning¶
veafSpawn.spawnCombatAirPatrol(spawnSpot, radius, name, country, altitude, altitudeDelta, hdg, distance, speed, capRadius, skill, silent, hiddenOnMFD)¶
Spawn CAP flight with patrol orbit.
Parameters:
spawnSpot(vec3) - Spawn positionradius(number) - Dispersionname(string) - Aircraft typecountry(number, optional) - Countryaltitude(number) - Patrol altitude (feet)altitudeDelta(number, optional) - Altitude randomizationhdg(number) - Orbit headingdistance(number) - Length of the race-track leg (nautical miles, 20 by default)speed(number) - Speed (knots)capRadius(number) - Radius of the defended zone, centred on the middle of the leg (nautical miles, 60 by default)skill(string) - Skill levelsilent(boolean, optional) - Suppress messageshiddenOnMFD(boolean, optional) - Hide from MFD
Returns: table - CAP flight info
Description:
- Spawns aircraft at position
- Creates racetrack orbit at specified location
- Starts watchdog to monitor and engage targets
Example:
-- Spawn F-15C CAP
local pos = {x=0, y=0, z=0}
veafSpawn.spawnCombatAirPatrol(pos, 100, "F-15C", nil, 25000, 2000,
90, 50000, 450, 20000, "Good", false)
veafSpawn.spawnAFAC(spawnSpot, name, country, altitude, speed, hdg, frequency, mod, code, immortal, silent, hiddenOnMFD)¶
Spawn Airborne Forward Air Controller (AFAC).
Parameters:
spawnSpot(vec3) - Spawn positionname(string) - Aircraft typecountry(number, optional) - Countryaltitude(number) - Orbit altitude (feet)speed(number) - Speed (knots)hdg(number) - Orbit headingfrequency(number) - Radio frequency (MHz)mod(string) - "AM" or "FM"code(number) - Laser code (e.g., 1688)immortal(boolean) - Invulnerable flagsilent(boolean, optional) - Suppress messageshiddenOnMFD(boolean, optional) - Hide from MFD
Returns: table - AFAC info
Example:
-- Spawn A-10C AFAC
veafSpawn.spawnAFAC(pos, "A-10C", nil, 15000, 250, 0, 133.0, "AM", 1688, true, false)
veafSpawn.startCapWatchdog(capGroupName, capCoalition, capZone, pTargetsList, pEngagedTargetIds)¶
Start CAP engagement watchdog.
Parameters:
capGroupName(string) - CAP group namecapCoalition(coalition) - CoalitioncapZone(table) - Zone definitionpTargetsList(table, optional) - Targets tracked, from the previous passpEngagedTargetIds(table, optional) - Targets that already have anEngageUnit, from the previous pass
Returns: None
Description: Monitors area and tasks CAP to engage enemy aircraft.
Targets are ranked by type, distance and aspect; a cold target past veafSpawn.CAP_COLD_CUTOFF (40,000 m) is not engaged.
Facing several targets, each aircraft is given its own on its own controller (veafSpawn.spreadCapTargets).
veafSpawn.targetAspect(targetPosition, targetVelocity, capPosition)¶
Returns "hot", "flanking" or "cold" from the angle between the target's track and the target → CAP line, on the horizontal plane: up to veafSpawn.CAP_ASPECT_HOT_MAX (60°) hot, from veafSpawn.CAP_ASPECT_COLD_MIN (120°) cold.
With no readable velocity, "flanking".
Also returns the angle in degrees (nil with no velocity).
veafSpawn.spreadCapTargets(unitNames, targets)¶
Spreads the targets (sorted, most important first) over the CAP's aircraft, round-robin. Returns a table aircraft name → target id, empty with one target or one aircraft.
Cargo & Logistics¶
veafSpawn.spawnCargo(spawnSpot, radius, cargoType, country, weightBias, cargoSmoke, unitName, silent, hiddenOnMFD)¶
Spawn CTLD cargo.
Parameters:
spawnSpot(vec3) - Spawn positionradius(number) - DispersioncargoType(string) - Cargo type: "container", "barrels", "ammo", "fuel"country(number, optional) - CountryweightBias(number, optional) - Weight preference (0-1)cargoSmoke(boolean) - Add smoke markerunitName(string, optional) - Cargo namesilent(boolean, optional) - Suppress messageshiddenOnMFD(boolean, optional) - Hide from MFD
Returns: table - Cargo info
Example:
-- Spawn fuel containers
veafSpawn.spawnCargo(pos, 10, "fuel", nil, 0.5, true, "Fuel-1", false)
veafSpawn.spawnLogistic(spawnSpot, radius, country, silent, hiddenOnMFD)¶
Spawn CTLD logistic unit.
Returns: table - Logistic unit info
FARP & FOB¶
veafSpawn.spawnFarp(spawnSpot, radius, name, country, farptype, side, hdg, spacing, silent, hiddenOnMFD, noFarpMarkers, code, freq, mod)¶
Spawn Forward Arming and Refueling Point (FARP).
Parameters:
spawnSpot(vec3) - Positionradius(number) - Dispersionname(string) - FARP namecountry(number, optional) - Countryfarptype(string, optional) - FARP configuration typeside(coalition) - Coalitionhdg(number, optional) - Headingspacing(number) - Unit spacingsilent(boolean, optional) - Suppress messageshiddenOnMFD(boolean, optional) - Hide from MFDnoFarpMarkers(boolean, optional) - Don't create markerscode(number, optional) - TACAN codefreq(number, optional) - Radio frequencymod(string, optional) - Modulation
Returns: string|nil - the FARP name, or nil when it is refused for want of clear ground for its escort (nothing is created then)
Example:
-- Spawn basic FARP
veafSpawn.spawnFarp(pos, 100, "FARP Alpha", nil, nil, coalition.side.BLUE,
0, 50, false, false, false, 71, 251.0, "AM")
veafSpawn.spawnFob(spawnSpot, radius, name, country, fobtype, side, hdg, spacing, silent, hiddenOnMFD)¶
Spawn Forward Operating Base (FOB).
Parameters: Similar to FARP
Returns: table - FOB info
Effects & Markers¶
veafSpawn.spawnBomb(spawnSpot, radius, shells, power, altitude, altitudedelta, password)¶
Create explosion effect.
Parameters:
spawnSpot(vec3) - Explosion positionradius(number) - Dispersionshells(number) - Number of explosionspower(number) - Explosion power (kg TNT equivalent)altitude(number, optional) - Altitude offsetaltitudedelta(number, optional) - Altitude randomizationpassword(string, optional) - Security password
Returns: None
Example:
-- Create 5x 500kg explosions
veafSpawn.spawnBomb(pos, 50, 5, 500, 0, 0)
veafSpawn.spawnSmoke(spawnSpot, color, radius, shells)¶
Add smoke markers.
Parameters:
spawnSpot(vec3) - Positioncolor(string) - "Green", "Red", "White", "Orange", "Blue"radius(number) - Dispersionshells(number) - Number of smoke markers
Returns: None
Example:
-- Mark position with red smoke
veafSpawn.spawnSmoke(pos, "Red", 0, 1)
veafSpawn.spawnSignalFlare(spawnSpot, radius, shells, color)¶
Fire signal flare(s).
Parameters:
spawnSpot(vec3) - Positionradius(number) - Dispersionshells(number) - Number of flarescolor(string) - Flare color
Returns: None
veafSpawn.spawnIlluminationFlare(spawnSpot, radius, steps, power, height, heading, distance, speed)¶
Create illumination flare pattern.
Parameters:
spawnSpot(vec3) - Positionradius(number) - Dispersionsteps(number) - Number of flares in linepower(number) - Flare powerheight(number, optional) - Altitude AGLheading(number, optional) - Line headingdistance(number, optional) - Distance between flaresspeed(number, optional) - Drop speed
Returns: None
Example:
-- Create illumination line
veafSpawn.spawnIlluminationFlare(pos, 0, 5, 1000000, 1000, 90, 500, 0)
Drawing Functions¶
veafSpawn.drawCircle(point, name, radius, color, fillColor, lineType)¶
Draw circle on map.
Parameters:
point(vec3) - Center positionname(string) - Drawing nameradius(number) - Circle radius (meters)color(table, optional) - Line color{r, g, b, a}(0-1 range)fillColor(table, optional) - Fill colorlineType(number, optional) - Line type
Returns: None
Example:
-- Draw red circle
veafSpawn.drawCircle(pos, "Zone1", 5000, {1, 0, 0, 1}, {1, 0, 0, 0.3})
veafSpawn.drawSquare(point, name, side, color, fillColor, lineType)¶
Draw square on map.
Parameters:
point(vec3) - Centername(string) - Drawing nameside(number) - Side length (meters)color(table, optional) - Line colorfillColor(table, optional) - Fill colorlineType(number, optional) - Line type
Returns: None
veafSpawn.eraseDrawing(name)¶
Remove drawing from map.
Parameters:
name(string) - Drawing name
Returns: None
Destruction & Teleport¶
veafSpawn.destroy(spawnSpot, radius, unitName)¶
Destroy units in area or specific unit.
Parameters:
spawnSpot(vec3) - Positionradius(number) - Search radius (0 for specific unit)unitName(string, optional) - Specific unit name
Returns: None
Example:
-- Destroy all units in 500m radius
veafSpawn.destroy(pos, 500)
-- Destroy specific unit
veafSpawn.destroy(pos, 0, "Tank-1")
veafSpawn.teleport(spawnSpot, name, silent)¶
Teleport group to position.
Parameters:
spawnSpot(vec3) - Destinationname(string) - Group namesilent(boolean, optional) - Suppress messages
Returns: None
Example:
-- Teleport player group to position
veafSpawn.teleport(newPos, "Viper Flight", false)
JTAC Functions¶
veafSpawn.JTACAutoLase(groupName, laserCode, radioData)¶
Setup auto-lasing JTAC.
Parameters:
groupName(string) - JTAC group namelaserCode(number) - Laser code (e.g., 1688)radioData(table, optional) - Radio configuration
Returns: None
Example:
veafSpawn.JTACAutoLase("JTAC-1", 1688, {freq=133.0, mod="AM"})
veafSpawn.convertLaserToFreq(laser)¶
Convert laser code to radio frequency.
Parameters:
laser(number) - Laser code
Returns: number - Frequency in MHz
Mission Master Functions¶
Mission Master provides scriptable mission control.
veafSpawn.missionMasterSetMessagingMode(silent, toGroupId)¶
Set message output mode.
Parameters:
silent(boolean) - Silent modetoGroupId(number, optional) - Target group ID
Returns: None
veafSpawn.missionMasterOutText(message)¶
Output Mission Master message.
Parameters:
message(string) - Message text
Returns: None
veafSpawn.missionMasterAddRunnable(name, code, parameters)¶
Add executable command.
Parameters:
name(string) - Command namecode(string) - Lua code to executeparameters(table, optional) - Parameters
Returns: None
veafSpawn.missionMasterRun(name)¶
Run Mission Master command.
Parameters:
name(string) - Command name
Returns: None
veafSpawn.missionMasterSetFlag(name, value)¶
Set Mission Master flag.
Parameters:
name(string) - Flag namevalue(any) - Flag value
Returns: None
veafSpawn.missionMasterGetFlag(name)¶
Get flag value.
Parameters:
name(string) - Flag name
Returns: any - Flag value
veafSpawn.missionMasterAddValueToFlag(name, increment)¶
Modify flag value.
Parameters:
name(string) - Flag nameincrement(number) - Value to add
Returns: None
Utility Functions¶
veafSpawn.listAllCAP(unitName)¶
Display list of all active CAP flights.
Parameters:
unitName(string) - Requesting unit name
Returns: None
veafSpawn.dumpSpawnablePlanesList(export_path)¶
Export spawnable aircraft list to file.
Parameters:
export_path(string, optional) - Export directory
Returns: None
veafSpawn.buildRadioMenu()¶
Build spawn radio menu.
Returns: None
veafSpawn.initialize()¶
Initialize spawn module.
Returns: None
veafUnits.lua¶
Module ID: UNITS
Purpose: Unit/group definitions and utilities
Constants¶
veafUnits.DefaultCellWidth = 10 -- meters
veafUnits.DefaultCellHeight = 10 -- meters
veafUnits.DefaultPathfindingUnitType = "TZ-22_KrAZ"
veafUnits.delayBeforePathfindingFix = 5 -- seconds
Functions¶
veafUnits.findDcsUnit(unitType)¶
Find DCS unit by type name (case-insensitive).
Parameters:
unitType(string) - Unit type (e.g., "F-16C", "M-1 Abrams")
Returns: table - Unit definition or nil
Example:
local f16 = veafUnits.findDcsUnit("F-16C_50")
if f16 then
veaf.logger:info("Found: %s", f16.displayName)
end
veafUnits.countInfantryAndVehicles(groupname)¶
Count infantry and vehicle units in group.
Parameters:
groupname(string) - Group name
Returns: number, number - Vehicle count, Infantry count
veafUnits.processGroup(group)¶
Process and validate group definition.
Parameters:
group(table) - Group definition table
Returns: table - Processed group
Description: Handles unit positioning, spacing, formation.
veafAssets.lua¶
Module ID: ASSETS
Purpose: Manage and track mission assets (tankers, AWACS, carriers)
Data Structures¶
Asset Definition¶
{
name = "Tanker-1", -- Group name
description = "KC-135 Texaco", -- Display name
information = "TACAN 61X", -- Optional info
disposable = false, -- Can be destroyed
jtac = 1688, -- Optional JTAC laser code
linked = {"AWACS-1"} -- Respawn these groups too
}
Functions¶
veafAssets.respawn(name)¶
Respawn asset group.
Parameters:
name(string) - Asset name
Returns: None
Description:
- Respawns asset group
- Respawns all linked groups
- Repairs its escort's
Escorttask — the group named<name> escort, if there is one. DCS invalidates that task as soon as the escorted group is recreated, and the escort then leaves to land after about ten minutes. See Escorting an asset - Starts JTAC if configured
Example:
veafAssets.respawn("Tanker-1")
veafAssets.dispose(name)¶
Destroy asset.
Parameters:
name(string) - Asset name
Returns: None
Example:
veafAssets.dispose("AWACS-1")
veafAssets.info(parameters)¶
Get asset information.
Parameters:
parameters(table) -{name=string, unitName=string}
Returns: string - Asset info text
Example:
local info = veafAssets.info({name="Tanker-1", unitName="Viper 1-1"})
-- Displays tanker position, TACAN, frequency
veafAssets.get(assetName)¶
Get asset definition.
Parameters:
assetName(string) - Asset name
Returns: table - Asset definition
veafAssets.help(unitName)¶
Display help text.
Parameters:
unitName(string) - Unit to receive help
Returns: None
veafAssets.buildRadioMenu()¶
Build assets radio menu.
Returns: None
veafAssets.buildAssetsDatabase()¶
Build asset lookup tables.
Returns: None
veafAssets.initialize()¶
Initialize assets module.
Returns: None
Description:
- Builds asset database
- Creates radio menus
- Must be called after assets defined
Mission Systems¶
veafCombatMission.lua¶
Module ID: COMBATMISSION
Purpose: Create and manage combat missions with objectives
Constants¶
veafCombatMission.SecondsBetweenWatchdogChecks = 30
veafCombatMission.RadioMenuName = "MISSIONS"
veafCombatMission.MinimumSpacingBetweenClones = 300 -- meters
Classes¶
VeafCombatMissionObjective¶
Mission objective definition.
Fields:
name(string) - Objective namedescription(string) - Description textmessage(string) - Completion messageparameters(table) - Objective parametersonStartupFunction(function) - Called when mission startsonCheckFunction(function) - Called periodically to check completion
States:
VeafCombatMissionObjective.FAILED = -1
VeafCombatMissionObjective.SUCCESS = 1
VeafCombatMissionObjective.NOTHING = 0
Methods:
obj = VeafCombatMissionObjective:new()
obj:setName(value)
obj:getName()
obj:setDescription(value)
obj:getDescription()
obj:setMessage(value)
obj:getMessage()
obj:setParameters(value)
obj:getParameters()
obj:setOnStartup(value)
obj:getOnStartup()
obj:setOnCheck(value)
obj:getOnCheck()
obj:onStartup(mission)
obj:onCheck(mission)
obj:configureAsTimedObjective(timeInSeconds)
obj:configureAsKillEnemiesObjective(nbKillsToWin, whatsInAKill)
obj:configureAsPreventDestructionOfSceneryObjectsInZone(zones, objects)
Example:
local objective = VeafCombatMissionObjective:new()
objective:setName("Destroy Armor")
objective:setDescription("Destroy all enemy tanks")
objective:setOnStartup(function(mission)
-- Spawn enemy tanks
end)
objective:setOnCheck(function(mission)
-- Check if tanks destroyed
if allTanksDestroyed() then
return VeafCombatMissionObjective.SUCCESS
end
return VeafCombatMissionObjective.NOTHING
end)
VeafCombatMission¶
Complete mission definition.
Fields:
name(string) - Mission name (technical)friendlyName(string) - Human-friendly mission namebriefing(string) - Full briefing textsecured(boolean) - Requires security clearanceradioMenuEnabled(boolean) - Show in F10 menuobjectives(table) - Array of objectiveselements(table) - Elements defined in the missionspawnedGroups(table) - Spawned DCS groupsactive(boolean) - Mission is activetraining(boolean) - Training missionhidden(boolean) - No message on activation/deactivationsilent(boolean) - Same ashidden, but for a single activation
Methods:
mission = VeafCombatMission:new()
mission:setName(value)
mission:getName()
mission:setFriendlyName(value)
mission:getFriendlyName()
mission:setBriefing(value)
mission:getBriefing()
mission:setSecured(value)
mission:isSecured()
mission:setRadioMenuEnabled(value)
mission:isRadioMenuEnabled()
mission:setActive(value)
mission:isActive()
mission:setTraining(value)
mission:isTraining()
mission:setHidden(value)
mission:isHidden()
mission:setSilent(value)
mission:isSilent()
mission:addObjective(objective)
mission:getObjectives()
mission:addElement(value)
mission:addSpawnedGroup(group)
mission:addDefaultObjectives()
mission:getRemainingEnemies(whatsInAKill)
mission:getInformation()
mission:initialize()
mission:activate(silent)
mission:desactivate()
Example:
local mission = VeafCombatMission:new()
mission:setName("Strike Alpha")
mission:setFriendlyName("Strike Alpha")
mission:setBriefing("Enemy armor advancing on friendly position. Destroy all tanks.")
mission:addObjective(destroyTanksObjective)
mission:addObjective(rtbObjective)
veafCombatMission.AddMission(mission)
Functions¶
veafCombatMission.AddMission(mission)¶
Register mission.
Parameters:
mission(VeafCombatMission) - Mission object
Returns: None
veafCombatMission.AddMissionsWithSkillAndScale(mission, includeOriginal, skills, scales)¶
Add mission variants with different skill/scale.
Parameters:
mission(VeafCombatMission) - Base missionincludeOriginal(boolean) - Include originalskills(table) - Skill levels:{"Average", "Good", "High"}scales(table) - Scale factors:{0.5, 1.0, 1.5}
Returns: None
Description: Creates multiple variants (e.g., "Strike Alpha - Good - 1.0x")
Example:
veafCombatMission.AddMissionsWithSkillAndScale(
baseMission,
false,
{"Average", "Good", "High", "Excellent"},
{0.5, 1.0, 1.5, 2.0}
)
-- Creates 16 mission variants (4 skills × 4 scales)
veafCombatMission.GetMission(name)¶
Get mission by name.
Parameters:
name(string) - Mission name
Returns: VeafCombatMission - Mission object or nil
veafCombatMission.GetMissionNumber(number)¶
Get mission by index.
Parameters:
number(number) - Mission index (1-based)
Returns: VeafCombatMission - Mission object
veafCombatMission.ActivateMission(name, silent, unitName)¶
Activate mission.
Parameters:
name(string) - Mission namesilent(boolean, optional) - Suppress messagesunitName(string, optional) - Unit to receive messages
Returns: None
Description:
- Executes all objective startup functions
- Spawns mission elements
- Starts watchdog timer
- Displays briefing
Example:
veafCombatMission.ActivateMission("Strike Alpha", false, "Viper 1-1")
veafCombatMission.ActivateMissionNumber(number, silent)¶
Activate mission by index.
Parameters:
number(number) - Mission indexsilent(boolean, optional) - Suppress messages
Returns: None
veafCombatMission.DesactivateMission(name, silent, unitName)¶
Deactivate mission.
Parameters:
name(string) - Mission namesilent(boolean, optional) - Suppress messagesunitName(string, optional) - Unit to receive messages
Returns: None
Description:
- Stops mission watchdog
- Destroys spawned groups
- Clears objectives
veafCombatMission.DesactivateMissionNumber(number, silent)¶
Deactivate mission by index.
Returns: None
veafCombatMission.GetInformationOnMission(parameters)¶
Get mission status.
Parameters:
parameters(table) -{name=string, unitName=string}
Returns: string - Mission status text
Example:
local status = veafCombatMission.GetInformationOnMission({
name = "Strike Alpha",
unitName = "Viper 1-1"
})
veafCombatMission.CompletionCheck(name)¶
Check mission completion status.
Parameters:
name(string) - Mission name
Returns: number - Status: FAILED (-1), SUCCESS (1), NOTHING (0)
Description: Calls all objective check functions and aggregates results.
veafCombatMission.addCapMission(missionName, missionDescription, missionBriefing, secured, radioMenuEnabled, skills, scales, spawnRadius)¶
Create CAP mission helper.
Parameters:
missionName(string) - Mission namemissionDescription(string) - DescriptionmissionBriefing(string) - Briefingsecured(boolean) - Security requiredradioMenuEnabled(boolean) - Show in menuskills(table) - Skill levelsscales(table) - Scale factorsspawnRadius(number) - Spawn dispersion
Returns: VeafCombatMission - Mission object
Description: Helper for creating CAP missions with standard objectives.
veafCombatMission.listAvailableMissions(unitName)¶
Display mission list to player.
Parameters:
unitName(string) - Unit to receive list
Returns: None
veafCombatMission.listActiveMissions()¶
Show active missions.
Returns: None
veafCombatMission.help(unitName)¶
Display help text.
Parameters:
unitName(string) - Unit to receive help
Returns: None
veafCombatMission.buildRadioMenu()¶
Build missions radio menu.
Returns: None
veafCombatMission.executeCommandFromRemote(parameters)¶
Execute command from remote API.
Parameters:
parameters(table) - Remote command parameters
Returns: None
veafCombatMission.dumpMissionsList(export_path)¶
Export missions to file.
Parameters:
export_path(string, optional) - Export directory
Returns: None
veafCombatMission.initialize()¶
Initialize module.
Returns: None
veafCasMission.lua¶
Module ID: CASMISSION
Purpose: Create close air support training missions
Constants¶
veafCasMission.Keyphrase = "_cas"
veafCasMission.SecondsBetweenWatchdogChecks = 15
veafCasMission.SecondsBetweenSmokeRequests = 180
veafCasMission.SecondsBetweenFlareRequests = 120
veafCasMission.RedCasGroupName = "Red CAS Group"
veafCasMission.BlueCasGroupName = "Blue CAS Group"
veafCasMission.RadioMenuName = "CAS MISSION"
Unit Type Tables¶
Units are categorized by coalition, era, and defense level:
TRANSPORT_TYPES[coalition][era][defense] = {unit_types}
ARMOR_TYPES[coalition][era][defense] = {unit_types}
DEFENSE_TYPES[coalition][era][defense] = {unit_types}
Coalition: "blue", "red"
Era: "cold", "modern"
Defense: 0-5 (0=none, 5=heavy)
Functions¶
veafCasMission.executeCommand(eventPos, eventText, coalition, markId, bypassSecurity)¶
Execute CAS mission command.
Parameters:
eventPos(vec3) - Spawn positioneventText(string) - Command textcoalition(coalition, optional) - CoalitionmarkId(number, optional) - Marker IDbypassSecurity(boolean, optional) - Skip security
Returns: boolean - Success flag
veafCasMission.markTextAnalysis(text)¶
Parse CAS marker text.
Parameters:
text(string) - Marker text
Returns: table - Parsed options
Options:
{
size = 0-5, -- Force size
defense = 0-5, -- Defense level
armor = 0-5, -- Armor level
spacing = number, -- Unit spacing (meters)
disperseOnAttack = boolean, -- Units disperse when attacked
side = coalition -- Coalition
}
veafCasMission.generateCasMission(spawnSpot, size, defense, armor, spacing, disperseOnAttack, side)¶
Generate complete CAS mission.
Parameters:
spawnSpot(vec3) - Spawn positionsize(number) - Size 0-5defense(number) - Defense 0-5armor(number) - Armor 0-5spacing(number) - Unit spacing (meters)disperseOnAttack(boolean) - Disperse on attackside(coalition) - Coalition
Returns: table - Generated group info
Description:
- Spawns infantry, armor, transport, and air defense
- Groups react to player attacks
- Provides smoke/flare marking
Example:
-- Generate medium difficulty CAS mission
local pos = {x=1000, y=0, z=2000}
veafCasMission.generateCasMission(pos, 3, 3, 3, 50, true, coalition.side.RED)
veafCasMission.smokeCasTargetGroup()¶
Add smoke to current CAS target.
Returns: None
Description: Limited by SecondsBetweenSmokeRequests timer.
veafCasMission.flareCasTargetGroup()¶
Add flare to current CAS target.
Returns: None
veafCasMission.smokeReset()¶
Reset smoke request timer.
Returns: None
veafCasMission.flareReset()¶
Reset flare request timer.
Returns: None
veafCasMission.skipCasTarget()¶
Skip current target group (destroy without score).
Returns: None
veafCasMission.reportTargetInformation(unitName)¶
Get CAS target info.
Parameters:
unitName(string) - Unit to receive report
Returns: None
veafCasMission.help(unitName)¶
Display CAS help text.
Parameters:
unitName(string) - Unit to receive help
Returns: None
veafCasMission.buildRadioMenu()¶
Build CAS radio menu.
Returns: None
veafCasMission.initialize()¶
Initialize CAS module.
Returns: None
Infrastructure & Services¶
veafAirbases.lua¶
Module ID: AIRBASES
Purpose: Normalized airbase and runway information
Classes¶
veafAirbase¶
Airbase descriptor holding normalized information about a DCS airbase.
Fields:
Name(string) - Airbase nameDisplayName(string) - Normalized display nameCategory(number) - DCS category (AIRDROME,HELIPAD,SHIP)DcsAirbase(DCS Airbase) - Underlying DCS airbase objectRunways(table) - Array ofveafAirbaseRunwayobjects
Methods:
airbase = veafAirbase:create(dcsAirbase)
airbase:getRunwayInService(iWindDirectionTrue) -- Best runway end facing the wind
airbase:getRunwayInServiceString(iWindDirectionTrue) -- In-service runway number ("02")
airbase:toString()
veafAirbaseRunway¶
Runway descriptor holding normalized information about a DCS airbase runway.
Each object is an indexed table of the two runway ends ([1] and [2]), each having:
Number(number) - Runway number (1-36)Heading(number) - True heading of the end (degrees)
Methods:
runway = veafAirbaseRunway:create(dcsAirbase, dcsRunway, iReportOrder)
runway:toString()
Functions¶
veafAirbases.initialize(bReset)¶
Initialize airbase database.
Parameters:
bReset(boolean, optional) - Force rebuild database
Returns: None
veafAirbases.getAirbaseByName(sAirbaseName)¶
Get airbase by name.
Parameters:
sAirbaseName(string) - Airbase name
Returns: veafAirbase - Airbase object or nil
Example:
local kutaisi = veafAirbases.getAirbaseByName("Kutaisi")
if kutaisi then
veaf.loggers.get("AIRBASES"):info("Kutaisi has %d runways", #kutaisi.Runways)
veaf.loggers.get("AIRBASES"):info("Airbase: %s", kutaisi:toString())
end
veafAirbases.getAirbaseFromDcsAirbase(dcsAirbase)¶
Convert DCS airbase to veafAirbase object.
Parameters:
dcsAirbase(DCS Airbase) - DCS airbase object
Returns: veafAirbase - VEAF airbase object
veafAirbases.getNearestAirbaseList(dcsUnit, iCount)¶
Get nearest airbases to unit.
Parameters:
dcsUnit(DCS Unit) - Unit objectiCount(number) - Number of results
Returns: table - Array of {veafAirbase, distance} pairs sorted by ascending distance
Example:
local unit = Unit.getByName("Viper 1-1")
local nearestBases = veafAirbases.getNearestAirbaseList(unit, 3)
for i, pair in ipairs(nearestBases) do
local airbase = pair[1]
local distance = pair[2]
veaf.loggers.get("AIRBASES"):info("%d. %s (%dm)", i, airbase.Name, distance)
end
veafAirbases.getNearestAirbase(dcsUnit)¶
Get single nearest airbase.
Parameters:
dcsUnit(DCS Unit) - Unit object
Returns: veafAirbase - Nearest airbase
Example:
local unit = Unit.getByName("Viper 1-1")
local nearest = veafAirbases.getNearestAirbase(unit)
veaf.outTextForUnit("Viper 1-1",
string.format("Nearest airbase: %s", nearest.Name), 10)
veafAirbases.getAtcFrequencies(veafAirbase)¶
Tower frequencies (MHz) and TACAN DCS gives the airfield, read from veafAirfieldFrequencies (a table shipped with the scripts, since the mission scripts have no API to ask DCS for them).
Parameters:
veafAirbase(veafAirbase) - Airbase
Returns: table|nil - { uhf?, vhf?, fm?, tacan? }, or nil for a carrier, a FARP or an airfield the table lacks
veafAirbases.getMissionChannel(veafAirbase)¶
The channel the mission's radio plan gives the airfield (bases collection of src/presets.yaml), written by the build into veaf-config.lua.
Parameters:
veafAirbase(veafAirbase) - Airbase
Returns: table|nil - { alias, title, uhf?, vhf?, fm? }, or nil when the mission has none
veafCarrierOperations.lua¶
Module ID: CARRIER
Purpose: Manage aircraft carrier operations
Functions¶
veafCarrierOperations.startCarrierOperations(parameters)¶
Start carrier recovery operations.
Parameters:
parameters(table) -{carrierGroupName=string, userUnitName=string}
Returns: None
Description:
- Turns carrier into wind
- Maintains position for recovery
- Reports wind direction and ATC info
Example:
veafCarrierOperations.startCarrierOperations({
carrierGroupName = "CVN-73",
userUnitName = "Hornet 1-1"
})
veafCarrierOperations.continueCarrierOperations(groupName, userUnitName)¶
Continue carrier operations.
Parameters:
groupName(string) - Carrier group nameuserUnitName(string, optional) - User unit
Returns: None
veafCarrierOperations.stopCarrierOperations(parameters)¶
Stop carrier operations.
Parameters:
parameters(table) -{carrierGroupName=string}
Returns: None
Description: Returns carrier to normal navigation.
veafCarrierOperations.getAtcForCarrierOperations(groupName, skipNavigationData)¶
Get carrier ATC data.
Parameters:
groupName(string) - Carrier group nameskipNavigationData(boolean, optional) - Skip nav info
Returns: string - ATC information text
Example Output:
CVN-73 Washington
Callsign: Mother
Position: N 42°15' E 041°45'
Heading: 270°
Wind: 285° at 25 kts
Radio: 127.5 MHz AM
TACAN: 73X (1205 MHz)
ICLS: 13
veafCarrierOperations.atcForCarrierOperations(parameters)¶
Get ATC for carrier (with output).
Parameters:
parameters(table) -{carrierGroupName=string, userUnitName=string}
Returns: None
veafCarrierOperations.listAvailableCarriers(forGroup)¶
Display available carriers.
Parameters:
forGroup(string, optional) - Group name to receive list
Returns: None
veafCarrierOperations.executeCommandFromRemote(parameters)¶
Execute from remote API.
Parameters:
parameters(table) - Remote command parameters
Returns: None
veafCarrierOperations.initializeCarrierGroups()¶
Initialize carrier groups.
Returns: None
veafCarrierOperations.buildRadioMenu()¶
Build carrier radio menu.
Returns: None
veafCarrierOperations.initialize()¶
Initialize carrier operations module.
Returns: None
Communication & Control¶
veafRadio.lua¶
Module ID: RADIO
Purpose: Manage F10 radio menus and communications
Constants¶
veafRadio.RadioMenuName = "VEAF"
veafRadio.Keyphrase = "_radio"
veafRadio.BEACONS_SCHEDULE = 5 -- seconds
veafRadio.USAGE_ForAll = 0
veafRadio.USAGE_ForGroup = 1
veafRadio.USAGE_ForUnit = 2
Functions¶
veafRadio.addSubMenu(title, parentMenu, coalitionSide)¶
Add submenu to radio.
Parameters:
title(string) - Submenu titleparentMenu(menu, optional) - Parent menu (nil = root VEAF menu)coalitionSide(number, optional) -coalition.side.RED/coalition.side.BLUE: the submenu and everything under it is only shown to that coalition (nil= everyone). The side is inherited by child submenus, commands and pagination pages; aUSAGE_ForGroupcommand is only attached for groups of that side.
Returns: menu - Submenu object
Example:
local assetsMenu = veafRadio.addSubMenu("Assets")
local tankersMenu = veafRadio.addSubMenu("Tankers", assetsMenu)
veafRadio.addCommandToSubmenu(text, menu, callback, parameters, usage)¶
Add command to submenu.
Parameters:
text(string) - Command textmenu(menu) - Target menucallback(function) - Callback functionparameters(any, optional) - Parameters passed to callbackusage(number, optional) - Usage type:USAGE_ForAll,USAGE_ForGroup,USAGE_ForUnit
Returns: None
Callback Signature:
function callback(parameters)
-- parameters: value passed to addCommandToSubmenu
end
Example:
local menu = veafRadio.addSubMenu("Test")
veafRadio.addCommandToSubmenu("Say Hello", menu, function(params)
veaf.logger:info("Hello from %s!", params.unitName)
end, {unitName = "Player"}, veafRadio.USAGE_ForAll)
veafRadio.addSecuredCommandToSubmenu(text, menu, callback, parameters, usage)¶
Add security-protected command.
Parameters: Same as addCommandToSubmenu
Returns: None
Description: Command only appears if user has security clearance.
veafRadio.executeCommand(eventPos, eventText, eventCoalition, bypassSecurity)¶
Execute radio command from marker.
Parameters:
eventPos(vec3) - Command positioneventText(string) - Command texteventCoalition(coalition) - CoalitionbypassSecurity(boolean, optional) - Skip security check
Returns: boolean - Success flag
Supported Commands:
transmit- Transmit via SRSplaymp3- Play MP3 via SRS
veafRadio.markTextAnalysis(text)¶
Parse radio marker text.
Parameters:
text(string) - Marker text
Returns: table - Parsed options
Options:
{
transmit = boolean, -- Transmit message
playmp3 = boolean, -- Play MP3 file
message = string, -- Message text
frequencies = table, -- Array of frequencies (MHz)
modulations = table, -- Array of "AM"/"FM"
name = string, -- Transmission name
path = string, -- MP3 file path
quiet = boolean -- Suppress confirmation
}
veafRadio.transmitMessage(message, frequencies, modulations, name, coalition, position, quiet)¶
Transmit message via SRS.
Parameters:
message(string) - Message text (TTS)frequencies(table) - Array of frequenciesmodulations(table) - Array of modulationsname(string) - Transmission name/callsigncoalition(coalition, optional) - Coalitionposition(vec3, optional) - Transmission originquiet(boolean, optional) - Suppress confirmation
Returns: None
Example:
veafRadio.transmitMessage(
"All aircraft, return to base",
{251.0, 305.0},
{"AM", "AM"},
"Tower",
coalition.side.BLUE,
airbasePos,
false
)
veafRadio.playToRadio(path, frequencies, modulations, name, coalition, position, quiet)¶
Play MP3 file via SRS.
Parameters:
path(string) - MP3 file path- Other parameters same as
transmitMessage
Returns: None
Example:
veafRadio.playToRadio(
"D:\\Sounds\\airraid.mp3",
{305.0},
{"AM"},
"Alert",
coalition.side.BLUE,
nil,
false
)
veafRadio.refreshRadioMenu()¶
Rebuild radio menu (delayed).
Returns: None
Description: Schedules menu rebuild after delay to prevent conflicts.
The rebuild only touches what changed in DCS: an unchanged entry keeps its place, a new entry is added at the end of its menu.
DCS gives a removed entry's id to the next one created, and a player whose F10 menu stayed open would fire that one (f10-menu-entry-id-is-recycled in the DCS runtime traps).
veafRadio.addPaginatedRadioElements(menu, buildFunction, elements, sortKey, sortField)¶
Add paginated elements to menu.
Parameters:
menu(menu) - Target menubuildFunction(function) - Function to build each elementelements(table) - Array of elementssortKey(string, optional) - Sort keysortField(string, optional) - Sort field
Returns: None
Description: Creates pages of 10 items with next/previous navigation.
veafRadio.onBirthEvent(event)¶
Handle unit birth (add to radio menu).
Parameters:
event(table) - Birth event
Returns: None
Description: Automatically adds human units to radio menu.
veafRadio.initialize()¶
Initialize radio module.
Returns: None
Support Systems¶
veafWeather.lua¶
Module ID: WEATHER
Version: (varies)
Purpose: Dynamic weather system
Functions¶
veafWeatherData.getWeatherString(vec3, dcsElementName, unitSystem, iSurfaceAltitudeMeters)¶
Builds the full textual weather report at a given position.
Parameters:
vec3(vec3) - PositiondcsElementName(string) - DCS element name (used to infer the default unit system)unitSystem(optional) - Unit system (defaults to the one inferred from the element type)iSurfaceAltitudeMeters(number, optional) - Surface altitude in meters
Returns: string - The weather report
veafWeather.getWind(vec3, iAltitudeMeters, bTurbulence)¶
Computes the wind at a position and altitude.
Parameters:
vec3(vec3) - PositioniAltitudeMeters(number) - Altitude in metersbTurbulence(boolean, optional) - Include turbulence (defaults tofalse)
Returns: number, number - Direction (degrees, "where the wind comes from", [1, 360]) and speed (m/s)
veafWeather.messageWeatherAtClosestPoint(unitName, forUnit)¶
Displays the weather report for the named point closest to the unit.
Parameters:
unitName(string) - Unit nameforUnit(boolean) - Iftrue, displays to the pilot only; otherwise to the group
veafWeather.messageAtcClosestAirbase(unitName, forUnit)¶
Displays the ATC (ATIS) report for the airbase closest to the unit.
Parameters:
unitName(string) - Unit nameforUnit(boolean) - Iftrue, displays to the pilot only; otherwise to the group
veafWeather.messageAtcAndWeather(unitName, forUnit)¶
Displays the ATC report followed by the weather report.
Parameters:
unitName(string) - Unit nameforUnit(boolean) - Iftrue, displays to the pilot only; otherwise to the group
veafWeather.createStaticFog(name, thickness, visibility)¶
Creates a static fog object.
Parameters:
name(string) - Fog namethickness(number) - Thickness (meters)visibility(number) - Visibility (meters)
Returns: A fog object
veafWeather.createDynamicFog(name, baseFactor, notAnimated)¶
Creates a dynamic fog object.
Parameters:
name(string) - Fog namebaseFactor(number) - Dynamic fog base factornotAnimated(boolean, optional) - Iftrue, the fog is not animated
Returns: A fog object
veafWeather.createAnimatedFog(name, minutes, thickness, visibility)¶
Creates a fog object animated over a given duration.
Parameters:
name(string) - Fog nameminutes(number) - Animation duration (minutes)thickness(number) - Thickness (meters)visibility(number) - Visibility (meters)
Returns: A fog object
veafWeather.setAndActivateFog(fogObject)¶
Disables the existing fog (if any) then activates the supplied fog object.
Parameters:
fogObject- A fog object (created via thecreate*Fogfunctions or aveafWeather.FOG_*constant)
Returns: The activated fog object
Predefined fog constants: veafWeather.FOG_DYNAMIC_HEAVY, FOG_DYNAMIC_MEDIUM, FOG_DYNAMIC_SPARSE, FOG_STATIC_HEAVY, FOG_STATIC_MEDIUM, FOG_STATIC_MEDIUM_LOW, FOG_STATIC_SPARSE, FOG_STATIC_SPARSE_LOW, FOG_STATIC_NO.
veafTime.lua¶
Module ID: TIME
Version: (varies)
Purpose: Mission time management
Read-only module: it computes date and time information from the mission time, it never sets the mission time or date.
Functions¶
veafTime.getMissionDateTime(iAbsTime)¶
Computes the mission date and time matching an absolute time (handles day, month and year rollover).
Parameters:
iAbsTime(number, optional) - Absolute time (defaults totimer.getAbsTime())
Returns: table - { year, month, day, yday, hour, min, sec }
veafTime.absTimeToStringTime(iAbsTime, bWithSeconds)¶
Formats an absolute time into a time string.
Parameters:
iAbsTime(number) - Absolute timebWithSeconds(boolean, optional) - Include seconds
Returns: string
veafTime.toZulu(dateTime, nOffsetHours)¶
Converts a local date/time to Zulu time (UTC).
Parameters:
dateTime(table) - Date/time (format ofgetMissionDateTime)nOffsetHours(number, optional) - Timezone offset (defaults to the one inferred fromgetTimezone)
Returns: table - Date/time in Zulu
veafTime.getSunTimesZulu(vec3, iAbsTime)¶
Computes the sunrise and sunset times (in Zulu) for a position.
Parameters:
vec3(vec3) - PositioniAbsTime(number) - Absolute time
Returns: The sunrise and sunset times
veafTime.determineSeason(month, latitude)¶
Determines the season from the month and latitude (handles both hemispheres).
Parameters:
month(number) - Month (1-12)latitude(number, optional) - Latitude (northern hemisphere ifnilor>= 0)
Returns: string - Season ("spring", "summer", "autumn", "winter")
Other available functions:
getMissionAbsTime,absTimeToDateTime,toStringDate/absTimeToStringDate,toStringTime,toStringDateTime/absTimeToStringDateTime,getTimezone,toLocal,getSunTimesLocal,isAeronauticalNight.
Data & Database¶
dcsUnits.lua¶
Module ID: DCSUNITS
Version: datamine-dc7d15e8
Purpose: Complete DCS unit database
This module exposes no functions: it only provides data tables.
Data Structures¶
dcsUnits.DcsUnitsDatabase¶
Raw DCS units database, keyed by DCS type id.
Schema of each entry:
{
type = ".Ammunition depot", -- DCS type id (table key)
name = "Ammunition depot", -- Human-readable name
kind = "static", -- Kind ("static", "vehicle", "plane", etc.)
category = "Warehouse", -- DCS category
description = "Ammunition depot", -- Description
attribute = {}, -- DCS attributes table
}
dcsUnits.NavalStatics¶
Set (table of booleans) of static names considered naval:
dcsUnits.NavalStatics = {
["Gas platform"] = true,
["M1 barrage balloon"] = true,
["Oil platform"] = true,
["Oil rig"] = true,
["Orca"] = true,
["offshore WindTurbine"] = true,
["offshore WindTurbine2"] = true,
}
See also dcs-data.md for the detailed schema description.
dcsDataExport.lua¶
Module ID: DCSEXPORT
Purpose: DCS data export script, to be run in the mission editor
Description¶
This is not a library: the script exposes no public function. It is meant to
be loaded (dofile) at the end of DCS World\MissionEditor\modules\me_mission.lua.
On load it defines the global DcsDataExport table (internal logging and
serialization helpers) then immediately runs the export: it writes the units
database (db.Units.lua) and calls browseUnits(...) for each unit category
(Animal, Cargo, Vehicle, Effect, Fortification, GrassAirfield, GroundObject,
Helicopter, Heliport, Personnel, Plane, Ship, Warehouse).
The output directory is set by the local export_path variable (defaults to .\,
the current directory).
Returns: None
Appendix¶
Common Patterns¶
Creating a Spawn Command¶
-- Via marker
local pos = {x=1000, y=0, z=2000}
veafSpawn.executeCommand(pos, "_spawn, name F-16C, group 2, hdg 270", coalition.side.BLUE)
-- Via interpreter (in unit name)
veafInterpreter.executeCommandOnUnit("SpawnTrigger1", "_spawn, name F-16C, group 2")
-- Programmatically
veafSpawn.spawnUnit(pos, 50, "F-16C", nil, nil, 5000, 270)
Listening to Events¶
-- Register callback
veafEventHandler.addCallback("myHandler", {"S_EVENT_TAKEOFF", "S_EVENT_LAND"},
function(event)
if event.initiator then
veaf.logger:info("%s - %s", event.type.name, event.initiator.unitName)
end
end
)
Creating a Mission¶
-- Define objective
local objective = VeafCombatMissionObjective:new()
objective:setName("Destroy Tanks")
objective:setOnStartup(function(mission)
-- Spawn tanks
local spawnPos = veafGeo.zoneToVec3("TargetZone")
veafSpawn.spawnArmoredPlatoon(spawnPos, 100, nil, nil,
coalition.side.RED, 0, 50, 2, 3, 3, true)
end)
objective:setOnCheck(function(mission)
-- Check completion
if allTanksDestroyed() then
return VeafCombatMissionObjective.SUCCESS
end
return VeafCombatMissionObjective.NOTHING
end)
-- Define mission
local mission = VeafCombatMission:new()
mission:setName("Tank Hunt")
mission:setFriendlyName("Tank Hunt")
mission:setBriefing("Destroy enemy armor")
mission:addObjective(objective)
-- Register
veafCombatMission.AddMission(mission)
Building Radio Menus¶
-- Create submenu
local myMenu = veafRadio.addSubMenu("My Commands")
-- Add command
veafRadio.addCommandToSubmenu("Do Something", myMenu, function(params)
veaf.logger:info("Command executed!")
veaf.outTextForUnit(params.unitName, "Done!", 5)
end, {unitName = "Viper 1-1"}, veafRadio.USAGE_ForAll)
Security Best Practices¶
- Use veafSecurity for sensitive commands
- Validate coalition before spawning
- Use bypassSecurity only when necessary
- Check user permissions via radio menus
Performance Optimization¶
- Disable unused events:
veafEventHandler.setEventEnabled("S_EVENT_SHOOTING_START", false) - Use delayed callbacks for expensive operations
- Limit spawn counts and areas
- Clean up inactive groups regularly
Debugging Tips¶
- Enable trace logging:
veafModuleName.LogLevel = "trace" - Use logger markers:
logger:marker(id, "Debug", "Position", pos) - Export data for analysis:
veaf.exportAsJson(data, "debug", true, "debug.json") - Check event handlers: Verify callbacks registered correctly
Version History¶
- v1.57.0 (veaf.lua) - Latest core utilities
- v1.59.3 (veafSpawn.lua) - Latest spawn system
- v2.2.1 (veafCombatMission.lua) - Latest mission system
- v1.15.3 (veafCasMission.lua) - Latest CAS system
Credits¶
VEAF Project: https://www.veaf.org
Repository: https://github.com/VEAF/VEAF-Mission-Creation-Tools
Documentation: https://veaf.github.io/documentation/
Lead Developer: Zip (davidp57)
Document Version: 1.0
Last Updated: November 2026
Generated for: VEAF Mission Creation Tools v6.36.0