veafWeather — Dynamic Weather and ATC Conditions¶
Module ID: WEATHER | File: veafWeather.lua
See it in game: step 17 “Weather, ATC and cockpit assistance” of the demo mission.
Purpose¶
Two distinct roles:
- Design-time: inject real-world or configured weather into a
.mizat build time, before players load the mission. Handled by.\veaf-tools.exe content inject-weather. - Runtime: players can request weather reports and ATC information via the F10 radio menu, and the mission maker can script dynamic fog changes.
Dependencies¶
veafRadio— optional weather menuveafNamedPoints— for location-based weather reports
Enable¶
veafWeather.initialize()
No parameters required.
Design-Time Weather Injection¶
Weather is injected at build time (before the mission is loaded) using veaf-tools.exe:
.\veaf-tools.exe content inject-weather mission.miz --config-file versions.yaml
The wind of weather: is the wind wanted 10 m above a reference airfield, not the editor's setting: see Weather variants — the wind.
versions.yaml example¶
position: # optional: a Syria mission here
latitude: 33.5
longitude: 35.5
timezone: "Asia/Damascus"
base_date: "2024-03-15"
versions:
- name: noon-clear
time: "12:00"
weather:
temperature: 25.0
wind_speed: 8.0
wind_direction: 270.0
visibility: 10000.0
cloud_type: "clear"
fog_enabled: false
- name: with-metar
time: "14:00"
metar: "METAR OSDI 151420Z 27015G25KT 9999 BKN025 18/12 Q1018 NOSIG"
F10 Radio Menu¶
When the WEATHER module is enabled, a "WEATHER AND ATC" submenu appears in the F10 menu:
| Entry | Available to | What it shows |
|---|---|---|
| Weather on closest point | Per group | Wind, visibility, QNH, temperature at nearest named point |
| ATC on closest airbase | Per group | Runway in use, QFE/QNH, pattern info and tower frequencies at nearest airbase |
| ATC and weather in one go | Per group | Both reports combined |
| Fog settings → ... | All (secured) | Change fog conditions (see below) |
Runtime Weather Reports¶
Get a weather report programmatically for a position (a vec3):
local report = veafWeatherData.getWeatherString(position)
veaf.outTextForUnit(unitName, report, 30)
The remaining arguments are optional: getWeatherString(vec3, dcsElementName, unitSystem, iSurfaceAltitudeMeters). Passing a DCS unit name as dcsElementName tailors the report to the aircraft type (unit system, LASTE data for the A-10).
Fog Management¶
The runtime fog system lets you change visibility conditions during a mission — useful for immersion, training scenarios, or scripted events.
⚠️ Map/DCS-version dependent: fog control uses the modern DCS API (
world.weather.setFogThickness/setFogAnimation). It is verified working on Caucasus. If fog does not change in-game on a given map, that is a DCS limitation (fog support varies by map/version), not a VEAF bug.
Pre-defined fog constants¶
Three fog families are available. Activate any constant with :activate():
Dynamic fog — recalculates density periodically based on weather conditions:
veafWeather.FOG_DYNAMIC_HEAVY:activate()
veafWeather.FOG_DYNAMIC_MEDIUM:activate()
veafWeather.FOG_DYNAMIC_SPARSE:activate()
Static fog — fixed visibility:
veafWeather.FOG_STATIC_HEAVY:activate()
veafWeather.FOG_STATIC_MEDIUM:activate()
veafWeather.FOG_STATIC_MEDIUM_LOW:activate()
veafWeather.FOG_STATIC_SPARSE:activate()
veafWeather.FOG_STATIC_SPARSE_LOW:activate()
veafWeather.FOG_STATIC_NO:activate() -- clears all fog
Animated fog — transitions smoothly to a target state over a set duration. The pattern is FOG_ANIMATED_<DURATION>M_<DENSITY>:
| Duration | Density variants |
|---|---|
1M, 5M, 10M, 15M, 30M, 60M, 90M |
HEAVY, MEDIUM, MEDIUM_LOW, SPARSE, SPARSE_LOW, NO |
Examples:
veafWeather.FOG_ANIMATED_10M_MEDIUM:activate() -- fade to medium fog over 10 minutes
veafWeather.FOG_ANIMATED_30M_NO:activate() -- clear fog over 30 minutes
veafWeather.FOG_ANIMATED_5M_HEAVY:activate() -- roll in heavy fog over 5 minutes
Activating a fog object directly¶
veafWeather.setAndActivateFog(veafWeather.FOG_STATIC_MEDIUM)
This is equivalent to calling :activate() on the constant. Any previously active fog is cancelled first.
Scripting fog changes on a trigger¶
-- On a DCS trigger "Begin Night Phase", enable heavy fog
veaf.scheduleFunction(function()
veafWeather.FOG_ANIMATED_15M_HEAVY:activate()
end, {}, timer.getTime() + 0)
The ATIS wind¶
The ATIS, the weather report and the LASTE ask DCS for the wind (atmosphere.getWind) at the point they describe: the surface wind is the one 10 m above the airfield, the wind DCS really simulates — not the editor's setting.
- Speeds are rounded, to the nearest knot or m/s: 13.9 kt reads 14 (they used to be truncated).
- Max wind 0-2000 ft: the ATIS adds a line with the strongest wind between the surface and 2,000 ft above the airfield, its direction and its height, sampled every 100 ft — what the helicopter pilots of Marteau du Golan needed (24 kt at the surface, 36 kt at 1,000 ft). The line shows only when that maximum beats the surface wind by 5 kt or more, so a calm profile does not lengthen the ATIS.
- Gusts, as an option: with
veafWeather.announceGusts = true(off by default), the ATIS samplesatmosphere.getWindWithTurbulenceon a 100 m ring around the airfield and announces the gust, the METAR way, when the peak beats the mean wind by 10 kt or more. Off by default because DCS adds a turbulence floor even with none set: an ATIS announcing gusts nobody set would be noise.
| Setting | Default | What it does |
|---|---|---|
veafWeather.MaxWindTopFeet |
2000 |
Height above the ground the max wind is looked for up to |
veafWeather.MaxWindStepFeet |
100 |
Sampling step |
veafWeather.MaxWindShowAboveSurfaceKnots |
5 |
Gap over the surface wind from which the line shows |
veafWeather.announceGusts |
false |
Announce gusts |
veafWeather.GustAboveMeanKnots |
10 |
Gap over the mean wind from which a gust is announced |
For the wind the mission sets, see Weather variants — the wind.
Chat / Remote Commands¶
These commands go through the chat window (requires veafRemote and the
server hook) — this module has no marker command. The three aliases
/weather, /atc and /atis are interchangeable; the word that follows picks the action:
| Chat command | Effect |
|---|---|
/atis (or /weather, /atc, with no argument) |
ATC + weather report at current position |
/weather weather |
Weather report only |
/atc atc |
ATIS of the nearest airbase only |
/weather fog FOG_STATIC_MEDIUM |
Activate a named fog constant |
/weather fog FOG_ANIMATED_10M_NO |
Animated fog clear over 10 minutes |
The fog name is case-insensitive. Use the exact constant names listed above (without the veafWeather. prefix).
Welcome brief on taking a slot¶
When a pilot takes a slot, a short message follows a few seconds later: the nearest airbase, the runway in service derived from the wind, and the current weather.
Welcome to Kobuleti — runway in service 13
WIND 270/10 QNH 1013 ...
Tower 262.000 UHF / 133.000 VHF / 40.800 FM — TACAN 67X
The message goes to his group only, not to the coalition: it is about his airfield, and broadcast to everyone it would become noise the moment two pilots take slots at different bases.
A few choices worth knowing:
- It is delayed by a few seconds. A pilot who has just entered his aircraft is still loading his cockpit, and a message shown at that instant is one he never reads.
- It repeats on every slot entry. A pilot who changes airfield wants the new airfield's runway, and "once per session" would withhold exactly the information that changed.
- A carrier has no runway in service — it turns into the wind, so the runway is mobile. It gives its current heading (true) instead, in the same words the carrier group's ATC uses. A helipad has neither: it gives the weather alone.
-
The full report (ATIS) stays in the radio menu. The greeting is deliberately shorter: a message that fills the screen at every slot change stops being read.
-
It ends with the tower frequencies, as the ATIS does.
To switch it off — for instance if your mission runs its own briefing:
modules:
WEATHER:
enabled: true
welcomeBrief: false
Tower frequencies¶
The welcome brief and the ATIS from the radio menu end with the line that says how to call the airfield's tower: its UHF, VHF and FM frequencies, then its TACAN. They are the ones DCS gives the airfield, the ones its card shows in the F10 view.
Tower 260.000 UHF / 131.000 VHF / 40.400 FM — TACAN 16X
The mission scripts have no way to ask DCS for these frequencies: they come from a table shipped with the scripts (veafAirfieldFrequencies.lua), captured in DCS and regenerated by veaf-build update-dcs-data --airfield-freqs.
A carrier, a FARP or an airfield missing from the table gets no line at all, rather than an empty or invented one.
When the mission's radio plan gives the airfield its own channel — an entry of the bases collection in src/presets.yaml — and that channel differs from the DCS tower, a second line gives it, under the title the pilot reads in their presets:
Tower 260.000 UHF / 131.000 VHF / 40.400 FM — TACAN 16X
Mission channel Batumi / 16X: 270.300 UHF / 130.300 VHF
The channel is tied to the airfield the way veaf-tools content airfield-channels does it: by the DCS name, or by its first word when no other airfield of the map shares it.
When it repeats the tower's frequencies it adds nothing, and the second line does not appear.
A mission that silences ATC (mission.silence_atc_on_all_airbases) leaves a tower that answers nobody: when the airfield has a mission channel, that channel is then the only line given.
When it has none — the common case — the DCS frequency is still given, as it is the only one there is.
See Also¶
- CLI Reference — every option of
veaf-tools content inject-weather - Lua API Reference — full
veafWeatherAPI