DCS Mission Editing Tools and Discussion

My [DCS mission creation/editing/scripting] life got a little easier when I realized I needed to keep things really, really, simple. ‘They’ are very limited.

This is a complex beast, DCS. Time is the enemy.

I feel you see problems with things like Moose (and my system) not because of the third party but due to the underlying DCS AI code. There appear to be a lot of ‘dependencies’ that are not published, requiring either a lot of time to uncover or constant micro-management.

I treat them as simple ‘drones’.

One of my original goals for an AI flight was:

  • Start engines at a specific time
  • fly a route (a series of 3D points, with speeds)
  • Get gas on the way if needed
  • At a specific time attack a specific target.
  • RTB

Sounds easy enough. There were issues that had to be resolved with every one of those bullets from

  • how long does it take them to start taxing once they turn the key (~2 minutes)
  • how long will it take them to reach the runway
  • will they reach the runway, without blocking/colliding into each other
  • how long will it take them to refuel in the air (turns out too long)
  • what altitudes do I give them, based on weight and such
    …and I haven’t even gotten to the target yet…

And, because having only one flight is not very realistic, how do we throw multiple ones into the mix, and have it all ‘just work’?

My conclusion: DCS was not designed with AI in mind. Because, likely, this takes a lot of work, time, and processing cycles. Cycles that are in competition with ‘other things’. If you want something even slightly complex you have to manage it all, yourself.

The best I can hope for is that, given enough simple objects moving about the appearance of something intentional will be achieved. Make up a ‘story’ about what is happening and let the player’s imagination fill in the blanks - tie it all together themselves.

4 Likes

I’ve not had issues in that regard, however, recent tests show that when I start (the mission start time of each group) them all 1 second apart the DCS ‘deck handler’ (my term) does a better job. At least towards getting them to utilize all catapults (this is with Tomcats & hornets, up to 12, counting the player flight of 2). When I started them all at time = 0 they all tried to hog cat’s 1 & 2, ignoring 3 & 4.

Basically, the start time affects things. You can use a value smaller than one second (ie; 0.25) though I’ve not seen the need.

Also, with DCS it feels like a coin toss when you use ‘unsupported’ modules. I hate that! But, I’ve seen screwy things happen (see ‘dependencies’ above) that were resolved by removing all mods. I use only 1, the Community A-4, but I don’t use it for AI. FWIW. And haven’t used it in a while so maybe that has borked things recently? Takes too long the check every aircraft under multiple conditions; when a combo works I tend to avoid using some other.

Question for everyone here. What do you use these days to make plans and kneeboards for DCS? Years ago I used combatflyte but it seems to be abandoned and not working well, as well as not supporting the latest in DCS. I found fragorders but the features I’m looking for are unfortunately paywalled behind a SaaS subscription (I’m fine with paying/buying, but not with subscribing). Then there’s the DCS web planner but it’s missing a little bit of flexibility and options that I was looking for. What else is out there, does anyone know?

That’s exactly what I want to test with my mod: The interplay of it and related mods in a somewhat meaningful context. I almost entirely test the aircraft, ships and buildings in isolation and usually only a single aspect of them. To see if they still work in a mission context is quite valuable.

So I need Vietnam War Vessels, VSN F-4B, VSN A-6A, A-4E-C at least :smiley: As I reckon these modules will be popular with the Enterprise '66.

But of course it’s fully adverse to robustness of the overall mission. Like in dcs.log I now see a zillion traces of shiptrail.lua lacking some definitions. But what is shiptrail.lua and where should it sit, btw? :smiley:

1 Like

After getting the Vietnam War Vessels showcase halfway stable, I looked into a related subject: What to do with the ASW Helicopters aboard the Destroyers and Frigates accompanying the carrier.

I pondered different ideas and went then with what seemed achievable - hijack the rescue helicopter code from MOOSE that translates into a follow instruction to the helicopter with an offset to the ship.

Now where should the ASW Helos be placed? I’ve decided to go with a half circle in front of the task force/flotilla, with equi-distant spacing between the helicopters. With my math being pretty rusty, I tasked chatGPT to give me some code for enclosing my task force with a circle. I then place the helicopters with 1.5 * radius distance from the flagship. Unfortunately I could not figure out yet how to calculate the offset from the individual ASW escorts, so I went for the easy way to center them around the flagship, via air start.

It’s far from perfect, but at least some helicopters fly ahead of the task force!
Code is at https://tetet.de/dcs/missions/asw-vanilla-demo.lua and a mission for vanilla assets at https://tetet.de/dcs/missions/moose-vanilla-asw-001.miz

There’s still a lot to do for the mission, but it’s good enough as a proof of concept for me for now.

Cheers,
TeTeT

1 Like

Oh well, discovered that it worked well when the Task Force sails south westerly direction. In other directions, particularly to the north east, not so much.

I guess that was the price for copy/pasting from ChatGPT without much reflection - the code calculated the off-set for the ASW helicopters in relation to the flagship’s direction. Of course this makes no sense, as the off-set is always ahead of the task force, no matter which direction that is. Reminds me of the hey-day of Stack Overflow when folks copy/pasted half baked stuff without any idea of what they are doing - something I often snickered about. Now I was prey to the same behaviour … lol.

First tests of this code snippet seem promising though:

function placeHelos(heading, radius)
  print("Heading: " .. heading .. ", radius: ".. radius)
  local angleStep = math.pi / (#aswShips + 1)
  local startAngle = - ((#aswShips + 1) * angleStep) / 2

  for i, ship in ipairs(aswShips) do
    local angle = startAngle + i * angleStep

    local offsetX = radius * math.cos(angle)
    local offsetZ = radius * math.sin(angle)
    print("From ship " .. ship.name .. ": X: ".. offsetX .. ", Z: " .. offsetZ)
  end
end
2 Likes

I’ve learned a few new tricks with MOOSE but still more or less doing stuff that I could otherwise do in the ME alone, except for randomization and endless spawning. One of the frustrating things I’ve found with scripting is that AI seems to behave differently. Say I have 5 different aircraft types fragged to do CAS in a specified zone, some work fine, some orbit but never engage, and some abort their mission shortly after takeoff with no rhyme or reason.

1 Like

Been there, done that. It sux. Until ED publishes the 'How’s and Why’s" of the AI you’re stuck with a LOT of experimentation (I spent hours and hours…months…on this). Then reasoning on why that behavior was such and such.

There is the task order and type to be considered; they have parameters that are unpublished (states that must be satisfied); inconsistency across platforms (this has improved in my eyes, but is hidden behind the hours of experimentation); detection abilities that are, again, not published.

And I suppose it depends on who your audience is. I have approached it with the idea that a lot of simple stuff gives the impression of, uhhh, intent? I just adjusted my ‘atmosphere’ flights (call them ‘filler’ I suppose). Some vareity and randomness and you might think they are actually doing something [intelligent]. I know they aren’t but I expect the users’ imagination to fill in the blanks. When I fly it works due to: variety + randomness = subtle surprises…

was testing my Afghanistan campaign yesterday with the addition of a “Trash Hauling” task (to allow for the C-130, CH-47, etc). Some hornets started up across the pad from me; C-130 launched from the runway; a C-17 taxied by; Hornets lined up in trail on the taxiway; heard a AH-1 starting up on the other side of Bagram…all are very simple processes but when combined (with a sunrise/sunset function that seems to work correctly now)…I just sat there enjoying the evening ambiance, eating my ham-sandwich and watched. Wait long enough and you will see some arrivals. Then I hear explosions? Oh yeah, there’s a chance we [at Bagram] could be hit with a rocket attack, followed by a siren, etc, etc. I’d forgotten about that simple bit of “do rocket attack” code.

I thought, “Cool” - and I wrote the code [so it shouldn’t ‘surprise’ me, even a little]

My BUFF’s (B-52’, B-1’s) will lay down strings of MK-82’s on ‘caves’ (where the bad guys are hiding let’s say) as the kickoff to an operation I’m flying (in an A-10/F-16/18/15E, etc). Sounds simple…now that I’ve done it…many curse words preceded that ‘system’. Moving that one operation to another map in a more efficient manner (think: time) sounds simple too[1].

In the end the big issue, to me: ED doesn’t publish the details, so you have ‘numbers’ you con work with. If they do publish this I’ve never heard about it. And I’m sure it’s changing as we speak because the DC dream is gonna need improvements in this area.

[1] In the example where the Hornet/C-130/C-17/UH-1 start up I have a lua table that ‘feeds’ the algorithm to make sure these types [of aircraft] make sense across different campaigns at different times. Say it’s 1970 then the Hornet gets swapped for an F-4 (or A-4, F-5 ,etc). Etcetera.

1 Like

Usually within the ME there’s enough options in the advanced waypoint actions or triggered actions section that you can micromanage the AI into doing precisely what you want. Great for a 2-hour scripted mission. Terrible for anything you want to have randomization or persistence which requires scripting.

1 Like

After I dabbled around in my showcase mission for the Vietnam War Vessels mod with MOOSE, I now tried my luck in adding AIRBOSS support for CVA-31 Bon Homme Richard and CVAN-65 Enterprise '66. Writing the test mission was strangely more challenging than extending the MOOSE Airboss class/table.
The diff in patch format is up at https://tetet.de/dcs/missions/Airboss_CVA31_CVAN65.patch and submitted to the MOOSE team. Let’s see what they say…

Need to look at this AirBoss thing. I’ve purposely left a ‘hole’ in my infrastructure to allow for DCS ATC (around the airports/carriers) - AirBoss may slide in there too. Soon, soon. :wink:

I’m really clueless about Airboss. Just need time to try it.

Airboss is pretty easy to set up. It was my first foray into lua coding. The one thing about it though is that it doesn’t play well with the AI. Half of that is a DCS issue of launching AI getting stuck on the deck if any AI are in the Marshal stack (or if any humans have made contact with the Supercarrier ATC), which completely fouls any semblance of cyclic ops. The other half is that the Airboss comms are not integrated with DCS itself, so while you get a realistic flow of having to actually change freqs between CATCC/Marshal/Approach/LSO, the AI may not properly sequence with players and of course you will get “no communications” on your landing grade. It’s been a while since I did modern carrier stuff but I recall some of them won’t even turn on the IFLOLS unless you’ve contacted the carrier through the native comms. So with the Supercarrier module at least, the player has to juggle both the Airboss comms and native comms.

In my case I simply don’t code the comms in at all, only using the recovery window/turn-into-wind function.

1 Like

Hmm. Yeah, the AI handling is a royal PITA. That may be the show-stopper.

As for comms, I purposely don’t touch DCS ATC (Tower or Marshal) simply telling you to contact them when returning at some distance, or giving you a 'contact departure" when I see you’ve slipped the surly bonds (an event).

Sounds like that part would slide right in: you switch to marshal in this example, and use Airboss and DCS ATC from there. Minus the Airboss that’s how I handle it now.

Now, the F10 menu items might get crowded; I dynamically swap these out as needed, but try to limit them to as few as I can get away with. VAICOMM Pro is wonderfu!

1 Like

I think there’s a way to disable/limit the Airboss F10 menu items though I don’t recall offhand. I’d have to dig through my pile of lua files.

1 Like

Hi,

the showcase mission for Vietnam War Vessels, utilizing MOOSE, is ready now. Unfortunately there are still some mid-air collisions of strike aircraft happening ever so often…

Some collaterals:

https://tetet.de/dcs/missions/vwv-showcase-moose-005.miz
and for those interested in the script:
https://tetet.de/dcs/missions/vwv-showcase-moose.lua

Here some screens:





















7 Likes

I need some ELI5 on writing lua conditions. I want flights to be fragged when certain conditions are met. I’ve succesfully done a “unit dead” condition using this code:

function UnitDead(name)
unit=UNIT:FindByName(name)
if not unit then
return true
else
return not unit:IsAlive()
end
end

But I don’t understand it well enough to reverse-engineer it for other conditions like group dead, group alive less than %, or part of coalition (specify unit type) inside zone.

The specific parts I don’t understand:

  • What is “(name)” doing here?
  • Is the “unit” in “if not unit then” referencing the “unit” defined in “unit=” portion?
  • What is “return true” doing? Why do I need something to return “true” if it’s not a “unit?” And what is that something that returns “true?”
  • Why do I need “else return not?”

My layman logic brain reads this as “if it’s not a ‘unit’ then give a ‘true’ value but if it is a ‘unit’ don’t give a ‘unit:IsAlive()’ value (which is equivalent to unit being dead),” which makes zero sense.

It is the parameter to the function. The function is doing the check for this particular unit called name.

Yes it is.

It seems that the function returns true also when the unit is not found in the first place. My guess is that the FindByName returns nil if no unit with the name can be found. nil is considered as false in lua’s comparison operations.

not negates the result of the IsAlive return value, i.e. if the unit is found and is alive (true) it negates to false and returned. Which stems with the function signature UnitDead().

Hope this helps. I did not dive into the underlying API, just dissected the code lines here.

And the conditionals if-else block is easier to digest with indentation:

function UnitDead(name)
  unit=UNIT:FindByName(name)
  if not unit then
    return true
  else
    return not unit:IsAlive()
  end
end
2 Likes

Okay, so I can basically name that whatever I want then as long as it doesn’t conflict with other…variables? Not sure what the correct term for these individual parts are.

Ah that makes sense, especially if I consider late-activate units. DCS likes to treat those as “dead” in the triggers.

This one is still doing my head in. If the unit is found and is alive (true) it negates to (false), but that’s equivalent to saying the unit is dead? I think I’m having a disconnect between code logic and actual logic.

How did you get the nice format on the forums? It’s formatted nicely and color coded on my Notepad+++ but I can’t seem to replicate it in other text windows.

1 Like

unit:IsAlive is basically the opposite of UnitDead. This is why the return of isAlive is negated.

Try to envision a table with three states for the unit: not present; dead; alive
The function returns for the inputs not present and dead unit, true
The function returns for the input alive unit, false

Makes sense to me.

2 Likes

Yes, there are also some reserved words, like if, true, etc that are part of the language.

And just to mention you can always override a variable (for example the unitvariable in your example code) just by reassigning it. In this case the old reference will be gone.

You can achieve that by using markdown code block. Remember to put lua as language specifier (after the first line three backticks). This ensures the syntax highlighting will be in lua.

I guess the indentation will have to come through copy paste from your editor.

1 Like