Jump to content

Recommended Posts

Posted (edited)
Hi Sven,

 

I am sad to say making your corrections did not solve the problem I am having. Some groups still don't make it into the databases. Looking at the correction you mention, do I have to replace "eventData:getGroup():getName()" everywhere by "(eventData:getName()):getGroup():getName()"? This code appears also in several lines you have not indicated to require that change... Haven't tried that yet. Have I interpreted the Grimes' code correctly that eventData contains the initiator unit of a spawning event. If so, it should not be required to get its name before calling getGroup(), correct? In your opinion, what type of object is eventData?

 

Looking at Grimes' code I start to suspect that some spawning events do not trigger a "world.event.S_EVENT_BIRTH". What do you think of this?

 

Hi Wolle!

 

First of all, we will find the root cause of your issue using mist 3.3. Secondly, i would like to comment that thanks to Grimes, we get all this logic for free, and doing some help debugging his code will only help improving the quality of the utility, no?

 

You're spot on with your feedback, but let me try to help you first by describing what happens, and how i found this bug. The way i found my issue is through debugging the code by putting in between env.info lines... And nail down the issue gradually, observing the env.info lines in the dcs.log, and observing what happens in the mission.

 

Sequently, we'll try to get something working for you.

 

My Issue description:

 

My issue was that the code within local function checkSpawnedEvents() contains some flaws. When an error occurs, in a function that is triggered by a scheduled event, the function will just stop working, and will trace nothing. In other words, if there is a nil value in some variable, and that variable is used within the code of the scheduled event function, it will stop and act like nothing happened. :cry:

 

 

:book: The local function checkSpawnedEvents() uses a variable 'addToDBs'. This variable is being populated with Group structures when dynAdd spawns a new Group.

:book: The function also uses another variable called 'tempSpawnedUnits', which is filled when a new Unit enters the scene within the event local function groupSpawned(event). You can trust that this function will always populate the Units that are appearing within the scene.

 

Now, what i found is that spawning groups 'through coalition.addGroup(...)' does not necessarily mean that the groups and its units within are actually also immediately appearing within the scene. For example, helicopters have a lead time to startup after a spawning call.

 

The issue I found is that when a group is spawned on the same place as the previous group, and the spawning call happens before the actual startup time of the previous Group has not been finished, the spawing will be queued internally within the simulator. :doh: The group will only appear within the scene when the previous group has completely started up and is flying.

When this happens, the local function groupSpawned(event) will only be called when the actual unit is appearing within the scene, and not when the actual unit was spawned.:poster_oops:

 

To translate this into the logic that Grimes wrote and what the issue was.

Imagine i've spawned 2 Groups within 2 seconds of time... The first is starting up, the second however, is not started up at all, it is queued until the first is completely started...

This is the sequence of events:

 

 


  1. Call dynAdd for the first spawned Group A. The table 'addToDBs' is being populated with Group A within mist.
  2. Due to the spawning, Group A appears within the scene, and the function local function groupSpawned(event) is called, filling out 'tempSpawnedUnits'.
  3. Then, the scheduled function checkSpawnedEvents() is called after some seconds (ideally), which would use both variables addToDBs, and tempSpawnedUnits. Using the logic of the code, it would iterate through tempSpawnedUnits.
    for eventId, eventData in pairs(tempSpawnedUnits) do
      if eventData then


  4. Because mist added the group, the structure 'groupsToAdd' would be populated with the Groups that are to be added within the internal DB tables of mist. In this case, it would be populated with Group A. The code will find the group within the groupsToAdd and it will do nothing... All fine.
  5. Now, Group B is spawned with dynAdd, but after 2 seconds... Group A is still starting up, so no function groupSpawned(event) is called. Thus, 'tempSpawnedUnits' is not populated with the initiator unit...
  6. However, the scheduled function checkSpawnedEvents() is called within some seconds, and will actually have groupsToAdd populated, and as such, Group B will be added to the internal DB tables...
  7. Oops... Now, here it comes, :mad: Group B, still queued, appears within the scene after Group A has been completely started... The event function groupSpawned(event) is called, and 'tempSpawnedUnits' is being populated with the new Unit.
  8. The scheduled function checkSpawnedEvents() is called after some seconds, and ... a bug... The logic will fall into the line
    else -- no groups added by mist
         groupsToAdd[#groupsToAdd + 1] = Unit.getByName(eventData):getGroup():getName()

    , and that call is erroneous. Because eventData contains a Unit table, not a string... The function would just stop working and the structure 'tempSpawnedUnits' would never be emptied. It would always continuously execute this logic without ever having a new unit being added to the internal tables...

So, the above illustrates how the fixes resolved my issue.

 

Now, your issue:

 

Find attached my "mist 3_3_Debug.lua" file. It contains env.info lines at crucial places. Try to run your mission, and check if the logic in scheduled function checkSpawnedEvents() is completely executed (after my modifications), by observing the env.info dumps within the dcs.log file.

 

You can trust that the event function groupSpawned(event) is correctly adding to 'tempSpawnedUnits' the units just entering within the scene.

 

Maybe what you can also do, is send me your mission, so that i can check myself... Find my mission also attached within this post.

 

 

 

hope it helps,

Sven

Edited by FlightControl

[TABLE][sIGPIC][/sIGPIC]|

[/TABLE]

Posted

Hi Sven,

 

Thanks for the explanations, I think I now understand the issue Unit table vs. string. Now that I understand it a little better, let me do some more tests tonight, using the mist file you provided. I would gladly send you my mission, but it is a complicated mission. I feel I would owe you to simplify it before I send it to you.

[sIGPIC][/sIGPIC]

 

Intel Core I7 4820K @4.3 GHz, Asus P9X79 motherboard, 16 GB RAM @ 933 MHz, NVidia GTX 1070 with 8 GB VRAM, Windows 10 Pro

Posted

Hi Sven,

 

I have narrowed down the issue I am having to the following:

 

In the same lines that we have talked about:

 

  for eventId, eventData in pairs(tempSpawnedUnits) do
  if eventData then
   if eventData:getCategory() == 1 then -- normal groups
    local match = false
    if #groupsToAdd > 0 then -- if groups are expected
     for groupId, groupData in pairs(groupsToAdd) do -- iterate through known groups to add
      if (type(groupData) == 'string' and groupData == eventData:getGroup():getName()) or (type(groupData) == 'table' and groupData.name == eventData:getGroup():getName()) then -- already added, do nothing
       match = true
       break
      end
     end

The issue that causes me problems is the line:

 

   if eventData:getCategory() == 1 then -- normal groups

The issue is the following: if, at the time of execution of the code one group does not exist any more (e.g. it has been killed), the loop will terminate prematurely (with a message "Object doesn't exist" in the log file), and the remaining new groups will not be added.

 

Make sense? I'll look into it in more detail tonight.

[sIGPIC][/sIGPIC]

 

Intel Core I7 4820K @4.3 GHz, Asus P9X79 motherboard, 16 GB RAM @ 933 MHz, NVidia GTX 1070 with 8 GB VRAM, Windows 10 Pro

Posted
Can you send the log?

 

Hi Sven,

 

I attached two logs (both covering one minute), one before the correction, one after the following correction:

 

   if eventData and eventData:isExist() then
   if eventData:getCategory() == 1 then -- normal groups

instead of the old

 

   if eventData then
   if eventData:getCategory() == 1 then -- normal groups

Unfortunately I could get your debug version to work with my particular mission, so this is just the regular log output. In the log before correction, look for lines "INFO SCRIPTING: mist.scheduleFunction, error in scheduled function: [string "C:\Users\Markus\AppData\Local\Temp\DCS\/~mi..."]:4241: Object doesn't exist"

 

I attached the uncorrected version of mist, and also the corrected one, and also the mission I used for this test (with the correct MIST script)

Airmobile Assault.miz

Mistv3_3Incorrect.lua

Mistv3_3Markus.lua

LogBeforeCorrection.txt

LogForCorrectedMIST.txt

[sIGPIC][/sIGPIC]

 

Intel Core I7 4820K @4.3 GHz, Asus P9X79 motherboard, 16 GB RAM @ 933 MHz, NVidia GTX 1070 with 8 GB VRAM, Windows 10 Pro

Posted

Alright. I've been messing about with trying to make AI Fighters that respawn when dead, and head back towards the combat area. After lots of testing with mist.respawnInZone and respawnGroup, I can't make the aircraft reliably grab their previous waypoints, so they end up idly orbiting nothing, then landing when out of fuel.

 

I'm using a continuous action trigger, with the condition "Group Dead", then running this:

 

if not Group.getByName('Su27Flight1') then

mist.respawnInZone('Su27Flight1', 'FlankerRespawnZone', false)

mist.goRoute('Su27Flight1', mist.getGroupRoute('Su27Flight1'))

end

 

I'll be blunt: I have no idea what I'm doing. I understand the gist of what that's supposed to do, but I haven't a clue as to why it doesn't work. Please go easy on me.

Posted (edited)
Alright. I've been messing about with trying to make AI Fighters that respawn when dead, and head back towards the combat area. After lots of testing with mist.respawnInZone and respawnGroup, I can't make the aircraft reliably grab their previous waypoints, so they end up idly orbiting nothing, then landing when out of fuel.

 

I'm using a continuous action trigger, with the condition "Group Dead", then running this:

 

if not Group.getByName('Su27Flight1') then

mist.respawnInZone('Su27Flight1', 'FlankerRespawnZone', false)

mist.goRoute('Su27Flight1', mist.getGroupRoute('Su27Flight1'))

end

 

I'll be blunt: I have no idea what I'm doing. I understand the gist of what that's supposed to do, but I haven't a clue as to why it doesn't work. Please go easy on me.

 

And when you change 'false' to 'true'? Isn't that the command for copy n pasting the original settings of the group and use it the respawned duplicate?

I'm curious how it works out though, i ran into a similar problem that i haven't been able to fix. In my case i can't influence triggering response with zones.

 

Is there anything other special going on with the choice of 'continuous action'? Switched condition might do it too. It doesn't check the the condition x number of times in a second, but only when a unit or group is dead. However, some guys seem to be onto something in the last few pages.

Edited by BRooDJeRo
Posted
And when you change 'false' to 'true'? Isn't that the command for copy n pasting the original settings of the group and use it the respawned duplicate?

I'm curious how it works out though, i ran into a similar problem that i haven't been able to fix. In my case i can't influence triggering response with zones.

 

Is there anything other special going on with the choice of 'continuous action'? Switched condition might do it too. It doesn't check the the condition x number of times in a second, but only when a unit or group is dead. However, some guys seem to be onto something in the last few pages.

 

According to http://wiki.hoggit.us/view/RespawnInZone , the 'false' is for dispersal of units, which I don't want. Using just plain' ol "respawnGroup" works now suddenly. They all continue to fly at eachother and spare their lives for the motherland. However, anything to do with random spawning, such as respawnInZone doesn't keep waypoints apparently.

Posted
Hi Sven,

 

I attached two logs (both covering one minute), one before the correction, one after the following correction:

 

   if eventData and eventData:isExist() then
   if eventData:getCategory() == 1 then -- normal groups

instead of the old

 

   if eventData then
   if eventData:getCategory() == 1 then -- normal groups

Unfortunately I could get your debug version to work with my particular mission, so this is just the regular log output. In the log before correction, look for lines "INFO SCRIPTING: mist.scheduleFunction, error in scheduled function: [string "C:\Users\Markus\AppData\Local\Temp\DCS\/~mi..."]:4241: Object doesn't exist"

 

I attached the uncorrected version of mist, and also the corrected one, and also the mission I used for this test (with the correct MIST script)

 

So, as i read, Wolle, the script is now working for you with the modification. In that case i'll also adjust the modification in my temp 3.3 version.

 

Sven

[TABLE][sIGPIC][/sIGPIC]|

[/TABLE]

Posted
So, as i read, Wolle, the script is now working for you with the modification. In that case i'll also adjust the modification in my temp 3.3 version.

 

Sven

 

Yes, works perfectly for me now. I guess the next step is to get the corrections we discovered to Grimes' attention. Should we PM him?

[sIGPIC][/sIGPIC]

 

Intel Core I7 4820K @4.3 GHz, Asus P9X79 motherboard, 16 GB RAM @ 933 MHz, NVidia GTX 1070 with 8 GB VRAM, Windows 10 Pro

  • 2 weeks later...
Posted
Yes, works perfectly for me now. I guess the next step is to get the corrections we discovered to Grimes' attention. Should we PM him?

Damn I just found this thread and was about to post about this problem. Great to see it addressed already.

By the way some comments about the code:

       for eventId, eventData in pairs(tempSpawnedUnits) do
           if eventData then
               if eventData:getCategory() == 1 then -- normal groups

The eventData is event.initiator (Unit) right?

tempSpawnedUnits[#tempSpawnedUnits + 1] = (event.initiator)

So a meaningful variable name could be something like event_initiator or eventInitiator depending on naming convention. So that the code becomes readable. The eventId is actually only an index like i.

So a much more readable version could be

for i, eventInitiator in pairs(tempSpawnedUnits) do

Just my 2 cents. :)

Posted

I'm not having particularly good results right now. Working on setting up a good test environment for developing my Medevac v2.0 script. I am setting up the test environment so that I can reload my Lua scripts during runtime.

By repeating my test cycle I

 

  • respawn a Stryker ATGM which was added through ME. I have tried respawning by using mist.dynAdd() (copied data from mission file) and also by using mist.respawnGroup().
  • do a Group.destroy() on the dynamically added infantry group which represents a group of survivors from the destroyed Stryker (trigger explosion). The infantry were added by the mist.dynAdd() method. I have also tried trigger.action.explosion().

I run the script from a radio command.

 

 

First I had the nil error at row 4241 error from MiST and after adding

if eventData and eventData:isExist() then

I get

00036.825 INFO    SCRIPTING: mist.scheduleFunction, error in scheduled function: [string "C:\Users\User\AppData\Local\Temp\DCS\/~mi..."]:4469: bad argument #1 to 'upper' (string expected, go
t nil)

and the faulting line is

 

if string.upper(newTable['category']) == 'GROUND_UNIT' then

Any help appreciated.

 

This the respawn script:

do
   writedebug("Respawning started")
   missionCommands.removeItem(Group.getByName("Medevac Group 1"):getID(), "SubmenuFlare")
   missionCommands.removeItem(Group.getByName("Medevac Group 1"):getID(), "SubmenuSmoke")
   writedebug("Radio items removed")
   --trigger.action.explosion(Group.getByName("Stryker 1 rescuees"):getUnits()[1]:getPosition().p, 50)
   Group.getByName("Stryker 1 rescuees"):destroy()
   writedebug("Rescuees destroyed")
   
   mist.respawnGroup("Stryker Group")
   --[[
   if respawnAPCCount == nil then
       respawnPosy = 635434.28571429
       respawnPosx = -318167.7142857
       respawnAPCOffset = 1
       respawnAPCCount = 0
   end
   
   if respawnAPCCount == 10 then
       respawnPosy = respawnPosy - 11
       respawnPosx = respawnPosx - 11
       respawnAPCCount = 0
   end
   respawnPosy = respawnPosy + respawnAPCOffset
   respawnPosx = respawnPosx + respawnAPCOffset
   respawnAPCCount = respawnAPCCount + 1    
   writedebug("Calling mist.dynAdd()..")
   mist.dynAdd(
           {
                units = {
                   [1] = {
                     ["y"] = respawnPosy,
                     ["type"] = "M1134 Stryker ATGM",
                     ["name"] = "Stryker 1",
                     ["unitId"] = mist.getNextUnitId(),
                     ["heading"] = 0,
                     ["playerCanDrive"] = true,
                     ["category"] = Unit.Category.GROUND_UNIT,
                     ["skill"] = "Excellent",
                     ["x"] = respawnPosx,
                   },
                },
                country = "USA",
                category = Group.Category.GROUND,
                name = "Stryker Group",
                groupId = mist.getNextGroupId(),
           }
       )
   ]]
   writedebug("Calling trigger.action.explosion()..")
   trigger.action.explosion(Unit.getByName("Stryker 1"):getPosition().p, 10)
end

Posted

Problem (and potential fix) with mist.getLeadPos() - as used indirectly by mist.groupToRandomZone() et al

 

I'm calling groupToRandomZone() in a UNIT death event handler. Most of the time it works fine until the lead unit of the group is killed. I then get a 'nil value' script assertion. Hunting it down I believe it's the 'mist.getLeadPos()' that's causing us issues. Looking at getLeadPos() -

 

[font=Courier New]mist.getLeadPos = function(group)
if type(group) == 'string' then -- group name
 group = Group.getByName(group)
end

local units = group:getUnits()

local leader = units[1][/font]
[font=Courier New]
if not leader then  [/font]
[font=Courier New]  local lowestInd = math.huge 
 for ind, unit in pairs(units) do
  if ind < lowestInd then
   lowestInd = ind
   leader = unit
  end
 end
end
if leader and Unit.isExist(leader) then  -- maybe a little too paranoid now...
 return leader:getPosition().p
end
end[/font]
 

It seems that units[1] can be non-nil but the unit is still dead (i.e. Unit.isExist() is false). This results in a nil being returned from this function

 

Here's a tweaked version (with suggested highlights) that takes this into account and iterates to the next living unit.

 

[font=Courier New]mist.getLeadPos = function(group)
if type(group) == 'string' then -- group name
 group = Group.getByName(group)
end

local units = group:getUnits()

local leader = units[1]

if (not leader) [color=red][b]or[/b][/color] [b][color=red](not Unit.isExist(leader)[/color][/b]) then  
 local lowestInd = math.huge 
 for ind, unit in pairs(units) do
  if [b][color=red]Unit.isExist(unit) and[/color][/b] (ind < lowestInd) then
   lowestInd = ind
   leader = unit
  end
 end
end
if leader and Unit.isExist(leader) then  -- maybe a little too paranoid now...
 return leader:getPosition().p
end
end[/font]

Cheers.

i7-4790K@4.7GHz : EVGA 1070 SC : 16GB Corsair Vengence Pro : 2xEVO 840 SSD : EVGA 850W PSU : CORSAIR H100i Cooler : ASUS Z97-AR MB : CORSAIR OBSIDIAN 750D FULL TOWER

Posted
Problem (and potential fix) with mist.getLeadPos() - as used indirectly by mist.groupToRandomZone() et al

 

I'm calling groupToRandomZone() in a UNIT death event handler. Most of the time it works fine until the lead unit of the group is killed. I then get a 'nil value' script assertion. Hunting it down I believe it's the 'mist.getLeadPos()' that's causing us issues. Looking at getLeadPos() -

 

[font=Courier New]mist.getLeadPos = function(group)
if type(group) == 'string' then -- group name
 group = Group.getByName(group)
end

local units = group:getUnits()

local leader = units[1][/font]
[font=Courier New]
if not leader then  [/font]
[font=Courier New]  local lowestInd = math.huge 
 for ind, unit in pairs(units) do
  if ind < lowestInd then
   lowestInd = ind
   leader = unit
  end
 end
end
if leader and Unit.isExist(leader) then  -- maybe a little too paranoid now...
 return leader:getPosition().p
end
end[/font]
 

It seems that units[1] can be non-nil but the unit is still dead (i.e. Unit.isExist() is false). This results in a nil being returned from this function

 

Here's a tweaked version (with suggested highlights) that takes this into account and iterates to the next living unit.

 

[font=Courier New]mist.getLeadPos = function(group)
if type(group) == 'string' then -- group name
 group = Group.getByName(group)
end

local units = group:getUnits()

local leader = units[1]

if (not leader) [color=red][b]or[/b][/color] [b][color=red](not Unit.isExist(leader)[/color][/b]) then  
 local lowestInd = math.huge 
 for ind, unit in pairs(units) do
  if [b][color=red]Unit.isExist(unit) and[/color][/b] (ind < lowestInd) then
   lowestInd = ind
   leader = unit
  end
 end
end
if leader and Unit.isExist(leader) then  -- maybe a little too paranoid now...
 return leader:getPosition().p
end
end[/font]

Cheers.

 

I have noticed this as well in the past: the table returned by the scripting function Group.getUnits() often also contains units that do not exist any more. Have not yet tested why and when that happens exactly. Anyone knows?

[sIGPIC][/sIGPIC]

 

Intel Core I7 4820K @4.3 GHz, Asus P9X79 motherboard, 16 GB RAM @ 933 MHz, NVidia GTX 1070 with 8 GB VRAM, Windows 10 Pro

Posted

It's fairly simple to reproduce the getLeadPos() issue - Create a red group containing 3 Ural's. Put unit's 2 & 3 far away and then drop a blue tank next to unit 1. Add an event handler that calls mist.groupToRandomZone() on the group of the dead unit and you'll get a script error immediately upon the death of unit 1.

i7-4790K@4.7GHz : EVGA 1070 SC : 16GB Corsair Vengence Pro : 2xEVO 840 SSD : EVGA 850W PSU : CORSAIR H100i Cooler : ASUS Z97-AR MB : CORSAIR OBSIDIAN 750D FULL TOWER

Posted

Could it be an idea to have MiST configurable so that you could choose to disable the background running processes?

So that the stand alone functions still could be used? I am getting into a three front fight here, Lua, DCS and MiST. :)

I'd like to use as much of the functions as possible but without having to worry about all the loops and machinery running in the background that obviously causes problems. Make the development a lot more problematic.

 

A global variable and each function marked whether it needs the background processes or not. Good or BS?

Posted

FWIW I never had any problems with MiST, but I haven't used latest version.

DCS AJS37 HACKERMAN

 

There will always be bugs. If everything is a priority nothing is.

Posted

I think this may have already been reported but in case it helps had a non-crash causing error last night described here (the logs / track are included)

 

http://forums.eagle.ru/showpost.php?p=2020469&postcount=31

 

The lines mentioned in the error were:

 

4241: if eventData:getCategory() == 1 then -- normal groups

4254: groupsToAdd[#groupsToAdd + 1] = Unit.getByName(eventData):getGroup():getName()

 

 

Given the times, it would have happened right around the time tankers were running low on fuel and would be respawned / cloned by the tanker script.

"ENO"

Type in anger and you will make the greatest post you will ever regret.

 

"Sweetest's" Military Aviation Art

Posted

Open miz file in lua

 

Hi,

 

I would like to modify a .miz file while i'm playing it.

 

Say i have a mission.miz. I flight it and i have lua script inside monitoring what happen.

What i want it is to delete an unit for the mission.miz if my script detected that this unit has been destroy. Then, the next time i play this mission, this unit is not present anymore. It is a kind of dynamic mission.

I know how to do that except how to open, with a lua script, a .miz file, extract the mission file, make changes and save it all.

 

Well, my question could be : how to modify the mission file in a miz file in lua ?

 

Thanks

Posted (edited)

MIssion Scripting Tools (Mist)- enhancing mission scripting Lua

 

Well you have the problem of .miz files being compressed, and I don't know if there are any possibilities to use external zip-libraries from within DCS. You might change your approach in that you save to a save-file, and then load it when mission starts. Here's some info on reading and writing to a file: http://forums.eagle.ru/showpost.php?p=2015759

 

Someone also started working on a "Save to file"-script a while back, I think it was a user named xcom. You might want to look at his work.

 

Edit: found it! http://forums.eagle.ru/showthread.php?t=116134

Edited by RagnarDa

DCS AJS37 HACKERMAN

 

There will always be bugs. If everything is a priority nothing is.

Posted
Well you have the problem of .miz files being compressed, and I don't know if there are any possibilities to use external zip-libraries from within DCS. You might change your approach in that you save to a save-file, and then load it when mission starts. Here's some info on reading and writing to a file: http://forums.eagle.ru/showpost.php?p=2015759

 

Someone also started working on a "Save to file"-script a while back, I think it was a user named xcom. You might want to look at his work.

 

Edit: found it! http://forums.eagle.ru/showthread.php?t=116134

 

Ok, thanks Ragnar. I will try this solution if i don't find a way to read a compressed file from lua script.

 

But the problem, in this case is that if you open the .miz in the mission editor, it won't be update.

 

I searched but i didn't find something. I'm surprise it's not possible ...

Posted

 

But the problem, in this case is that if you open the .miz in the mission editor, it won't be update.

 

Yes, but the mission will update when you start the mission...?

DCS AJS37 HACKERMAN

 

There will always be bugs. If everything is a priority nothing is.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...