From VEAF Mission Editor
How to author VEAF DCS missions correctly through the veaf-mission-mcp server — the reserved naming conventions, the combat-zone vs QRA group models, when to use VEAF aliases /
How this skill is triggered — by the user, by Claude, or both
Slash command
/veaf-mission-editor:veaf-mission-authoringThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You edit a Mission Maker's DCS mission through the `veaf-mission-mcp` server. This skill is the
veaf-mission-mcpYou edit a Mission Maker's DCS mission through the veaf-mission-mcp server. This skill is the
reasoning half; the server provides the actions. The user gives intent ("a combat zone
with two armor groups"); you derive the concrete unit types, group names and config — do not
ask the user for mechanical details you can decide correctly yourself.
Before naming a group, picking a unit type, or configuring a module, call the read-only oracle actions. They read VEAF's canonical, always-current data — your training memory of DCS types or VEAF conventions may be stale or wrong.
list_unit_types — real DCS unit type ids (filter by category / name).list_shortcuts — VEAF spawn aliases. Three families: units (shilka, sa8), groups
(composite SAM/convoy groups), and commands — the #command shortcuts (-samLR, -samSR,
-armor, random convoys, …). This is the authoritative source for the -<alias> you put in a
combat-zone #command — never guess an alias from memory (there is no -lrsam; it is -samLR).describe_naming_conventions — the reserved naming patterns (below).describe_module — is a module real? its doc page? enabled in this mission?For an action's exact parameters, call describe_action(name).
These oracle actions plus this skill are the authoritative source for VEAF-framework facts —
naming conventions, spawn aliases, marker/#command/#veafInterpreter formats, module config.
For those specifically, don't consult other tools/agents or read the VEAF framework's Lua
source (a mission maker's machine has neither): if a fact seems missing, re-query the oracle
(describe_naming_conventions, describe_action, list_shortcuts) or state the gap plainly rather
than sourcing it elsewhere or guessing. This scoping is only about VEAF-framework knowledge —
keep using your other tools normally for everything else (geocoding, reading/writing files,
building, etc.).
mission.yaml. Durable: survives a rebuild. Prefer it for configuration..miz. Direct, no rebuild, but overwritten on the next build from the recipe.Every write is backed up first. State which world you are editing when you report back.
Prefer to express intent and let add_group name the group for you (for_combat_zone,
late_activation, as_spawn_template) — it applies these rules and returns warnings. To check a
name yourself, call validate_group_name (or describe_naming_conventions for the full list).
The dangerous ones:
veafSpawn-<name> → auto-registered as a spawnable-aircraft template.OnDemand-<name> → CAP-mission template (late activation).#veafInterpreter["<cmd>"] in a name → the unit is destroyed and the command runs at start.#command=, #spawngroup=, #spawnradius=, #spawncount=, #spawnchance=,
#spawndelay= → tune combat-zone spawn behaviour.[ or - are read as commands, not group names.When a list_shortcuts alias covers what's asked (a SAM, AAA, infantry, armor, artillery, a
convoy…), use the alias, not hand-placed literal DCS units — whether as a #command fake-unit
(combat-zone content) or a #veafInterpreter carrier (permanent asset). list_shortcuts gives each
command a category (SAM / AAA / infantry / armor / artillery / naval / transport / …), so look
there first to find the right alias. Fall back to literal units only when no alias fits — a
specific airframe/type or an exact placement the alias can't express. Example: asked for a
long-range SAM, place a #veafInterpreter["-samLR"] carrier, not a literal Patriot battery.
Combat zone — groups are found by geometry (inside the trigger zone), coalition is
ignored for capture (VEAF despawns then respawns any group inside, whatever its side), and
membership also keys off the zone-name prefix. So: create the trigger zone, then create groups
named <ZoneName>-... placed inside it. To have the zone spawn VEAF assets rather than hand-placed
units, use a fake unit carrying #command="-<alias> ..." (an alias from list_shortcuts) — set it
as that unit's name (the units entry takes an optional name; the runtime reads
#command/#spawn* off the unit name). Prefer this #command fake-unit for combat-zone
content over hand-placing literal units.
Coalition rule: a #command fake-unit spawns in its own coalition — a blue fake-unit →
a blue SAM (-samLR is not inherently red; its "random" is the battery type). So for a blue SAM
site, make the fake-unit blue — don't fall back to literal units just for a colour. (The
"coalition is ignored" above only governs which real groups the zone captures by geometry.)
Permanent asset vs combat-zone asset — two spawn markers, don't confuse them:
#veafInterpreter["<alias …>"] on a unit's name → spawned at mission start and
permanent (the carrier unit is destroyed). Use it — in preference to a literal unit — for
always-there assets, e.g. a fixed SAM site: a blue unit named #veafInterpreter["-samLR"] →
a blue long-range SAM at that spot on start. Same alias vocabulary as list_shortcuts; same
coalition rule (follows the carrier).#command="-<alias> …" on a fake-unit inside a combat-zone → spawned when the zone is
activated (dynamic), and despawned/respawned with the zone.list_shortcuts and spawn in the carrier's coalition. Pick
#veafInterpreter for a standing site, #command for zone-driven content.add_group targeting the mission
folder (it writes src/mission/, so it survives a rebuild) — not a .miz (that's the built
world, overwritten on the next build). add_group's result has durable: true for a folder.QRA — interceptor groups are referenced by exact name, coalition matters, and they must be Late Activation (VEAF scrambles them). So: create the trigger zone, create the late-activation interceptor group with a coherent name, set its coalition, and list that exact name in the QRA definition.
An airfield's coalition is not set by placing a unit near it — it lives in the mission's
warehouses table. When the user says "make Mezzeh blue", call set_airbase_coalition (name +
coalition) on the mission folder. It colours the airfield durably and turns on its Dynamic Spawn
slots at the same time; the build then stocks the base's warehouse with that coalition's dynamic
templates. So a base the user assigns becomes both the right colour and playable (dynamic slots)
without extra steps.
CZ-North). Add two
groups named CZ-North-armor-1 / CZ-North-armor-2 inside it — as fake-unit groups carrying
#command="-armor ..." (alias from list_shortcuts, preferred), or, only if no alias fits,
concrete armor unit types from list_unit_types. Add the COMBATZONE block referencing CZ-North.list_unit_types. Create
a Late-Activation group (coherent name, correct coalition), a trigger zone, and a QRA
definition referencing the group name verbatim. The user did not give names — you did.If the user wants a mission but has only an empty folder (no mission.yaml, no src/mission/),
start with scaffold_mission — it downloads the VEAF tools from GitHub, installs them into the
folder, and runs prepare. Ask which template first and pass it as the template parameter —
never guess it:
minimal — infrastructure + core modules;standard — the everyday set (a good default);full — everything, advanced config as commented examples.(custom is not available through the MCP.) Also ask which theatre (map) the mission is on and
pass it as theatre: scaffold_mission then lays down a synthetic blank mission for that map in
src/mission/, so the folder is ready for the composites with no DCS round-trip. Omit theatre
only if the user will supply their own .miz. Once the folder exists, use the composites below to
fill it.
When the user asks for a whole feature ("create a combat zone / a QRA / a CAP mission"), reach
for the one-pass composite (create_combat_zone / create_qra / create_cap_mission) on a
mission folder — it edits both worlds (source src/mission/ + mission.yaml) durably in one
call. Drop to the primitives (add_trigger_zone, add_group, set_mission_module) only for
partial or one-off edits, or when there's no folder (a lone .miz).
Placement actions take DCS local x/y. To orient, call describe_map (theatre, bullseyes,
existing zones/groups as anchors). If the user gives a lat/long, use resolve_coordinates to get
the x/y for the mission's theatre, then place. Real place names ("near Batumi", "north of
Kobuleti") resolve through the geocoder (geocode action) when available — always surface the
resolved point so the user can sanity-check it (DCS terrain approximates the real world).
When the mission is authored, close the loop without leaving the tools: run validate_mission on
the folder first (fix any error it reports), then build_mission to produce the playable .miz.
Surface build errors to the user rather than claiming success. This completes the empty-folder →
scaffold → edit → validate → build → play flow.
Tell the user which world you edited, the names/types you chose and why, and surface any convention warning the actions returned so they can veto before you proceed with irreversible or large changes.
npx claudepluginhub veaf/veaf-mission-creation-tools --plugin veaf-mission-editorGuides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.
Forks private projects, strips secrets/internal references, verifies cleanliness, and packages them with CLAUDE.md, README, and setup.sh for safe public release.