Help needed - very weird behavior
Moderators: angster, RoryAndersonCDT, michaelm75au, MOD_Command
- nukkxx5058
- Posts: 3141
- Joined: Thu Feb 03, 2005 2:57 pm
- Location: France
Help needed - very weird behavior
Hi,
I setup a support mission which is made of 3 groups of units. The last group is named "Trucks Convoy" and is the important one. What I want is that each time a truck from the "Trucks Convoy" group arrives at destination (ie enters the area defined in the event's trigger) the side France scores 100 points and the truck is deleted. There are 20 trucks so the maximum points that France can score is 2.000.
In the attached save, please try first to run the game with the EVENT named "Convoy Truck Arrived" deactivated. Everything will be OK. The group "trucks convoy" reaches the mission final destination (i.e. the last ref point of the mission) as do the two other groups part of the mission before the trucks.
But when you run it with the event "Convoy Truck Arrived" activated and repeatable , most of the trucks refuse to enter the area and leave the mission (other groups of units ("AD MANPAD" and "convoy logistics") are not affected). But if I comment the last line of lua code that deletes the trucks, then it's OK , truck will complete the mission and score the points (but won't be deleted as I want them to be).
--ScenEdit_DeleteUnit({"France",guid=unit.guid}) <if I delete this, trucks will compete the mission
So it's linked with the delete function but I can't figure out why nor how ...
I'm puzzled... I already pulled all my hair on this one. I heed help.
Thank you
I setup a support mission which is made of 3 groups of units. The last group is named "Trucks Convoy" and is the important one. What I want is that each time a truck from the "Trucks Convoy" group arrives at destination (ie enters the area defined in the event's trigger) the side France scores 100 points and the truck is deleted. There are 20 trucks so the maximum points that France can score is 2.000.
In the attached save, please try first to run the game with the EVENT named "Convoy Truck Arrived" deactivated. Everything will be OK. The group "trucks convoy" reaches the mission final destination (i.e. the last ref point of the mission) as do the two other groups part of the mission before the trucks.
But when you run it with the event "Convoy Truck Arrived" activated and repeatable , most of the trucks refuse to enter the area and leave the mission (other groups of units ("AD MANPAD" and "convoy logistics") are not affected). But if I comment the last line of lua code that deletes the trucks, then it's OK , truck will complete the mission and score the points (but won't be deleted as I want them to be).
--ScenEdit_DeleteUnit({"France",guid=unit.guid}) <if I delete this, trucks will compete the mission
So it's linked with the delete function but I can't figure out why nor how ...
I'm puzzled... I already pulled all my hair on this one. I heed help.
Thank you
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) 
- nukkxx5058
- Posts: 3141
- Joined: Thu Feb 03, 2005 2:57 pm
- Location: France
Re: Help needed - very weird behavior
OK, I might have found the reason .... It seems that it's when my script deletes the Leader of the group then units start to behave the strange way and remaining units are not completing the mission.
Not sure what to do with this ...
Not sure what to do with this ...
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) 
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
Re: Help needed - very weird behavior
I'll look at the scene later tonight, but have you tried assigning a new lead for the group, before removing what was the old lead?nukkxx5058 wrote: Tue Mar 22, 2022 9:49 pm OK, I might have found the reason .... It seems that it's when my script deletes the Leader of the group then units start to behave the strange way and remaining units are not completing the mission.
Not sure what to do with this ...
- nukkxx5058
- Posts: 3141
- Joined: Thu Feb 03, 2005 2:57 pm
- Location: France
Re: Help needed - very weird behavior
Not yet, will have to figure out the lua function first ... but it's probably a good thing to try ...
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) 
- nukkxx5058
- Posts: 3141
- Joined: Thu Feb 03, 2005 2:57 pm
- Location: France
Re: Help needed - very weird behavior
First, is this a bug that should be reported to the devs ? In my opinion, yes but I'm not sure if it's intended or not.
For my script, there are actually other possibilities. The main reason for deletion of the unit is that I don't want the user to get an exploit by reusing the same truck to score again and again by entering-exiting re-entering the triggering area (it's a PBEM-only scen). The secondary reason is that trucks are useless after completing the mission and use CPU resources (they are 40 trucks in the final version of the scen) so they better get deleted as the scen is already huge (3.000 AU).
But another possibility is to build a table of trucks guid's that scored and check whether one particular truck has already scored or not and prevent a second scoring. This would work because they are no other trucks of this type (that trigger the event) in the France side so the maximum number of points is achieved only when all trucks manage to reach final destination.
I had something like that in mind:
But of course I would prefer the deletion ...
For my script, there are actually other possibilities. The main reason for deletion of the unit is that I don't want the user to get an exploit by reusing the same truck to score again and again by entering-exiting re-entering the triggering area (it's a PBEM-only scen). The secondary reason is that trucks are useless after completing the mission and use CPU resources (they are 40 trucks in the final version of the scen) so they better get deleted as the scen is already huge (3.000 AU).
But another possibility is to build a table of trucks guid's that scored and check whether one particular truck has already scored or not and prevent a second scoring. This would work because they are no other trucks of this type (that trigger the event) in the France side so the maximum number of points is achieved only when all trucks manage to reach final destination.
I had something like that in mind:
--this script awards points for convoy truck arriving at destination
local currentScoreFR = ScenEdit_GetScore("France")
local currentScoreCH = ScenEdit_GetScore("China")
local points = 100
local unit = ScenEdit_UnitX()
--checks if the triggering truck already scored
if trucks >1 then
for i =1, trucks do
if ScenEdit_UnitX().guid == trucksTable[ i ] then ScenEdit_SpecialMessage("France","This truck already scored") return
--trucksTable = { } is a global variable declared in the startup script
end
end
end
trucks = trucks +1 -- trucks is a global variable declared and initialized to 0 in the startup lua script.
trucksTable[trucks] = ScenEdit_UnitX().guid --trucksTable = { } is declared in the startup script
--incrementing scores
currentScoreFR = currentScoreFR + points
currentScoreCH = currentScoreCH - points
--scoring
ScenEdit_SetScore("France", currentScoreFR, "Convoy Truck arrived at destination:"..points.." points")
ScenEdit_SetScore("China", currentScoreCH, "Convoy Truck arrived at destination:"..-points.." points")
--sends messages
ScenEdit_SpecialMessage("France","Congratulations ! A truck from the convoy has reached its final destination (Garoua). +100 points for France.")
ScenEdit_SpecialMessage("China","Bad news Sir: A supply truck from the convoy has reached its final destination (Garoua): -100 points for China")
But of course I would prefer the deletion ...
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) 
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
Re: Help needed - very weird behavior
If you do the tracking part, just don't forget to store/serialize the table and unpack it upon each startup if it exists.
I played around with various things the issue is the lead getting removed, it apparently holds the 'state' of what mission navigation waypoint it's currently on, and resetting/removing the lead resets that state for the group and there is no way for us to get the old state before delete nor set the waypoint state for the new lead . Only other way that comes to mind is building a course table off the marker points and assigning the course to the group/all group members, either from the get-go, or as they near the area via yet another trigger.
Or don't add them to the mission grouped.
--sample version with course additions made on every trigger.
I played around with various things the issue is the lead getting removed, it apparently holds the 'state' of what mission navigation waypoint it's currently on, and resetting/removing the lead resets that state for the group and there is no way for us to get the old state before delete nor set the waypoint state for the new lead . Only other way that comes to mind is building a course table off the marker points and assigning the course to the group/all group members, either from the get-go, or as they near the area via yet another trigger.
Or don't add them to the mission grouped.
--sample version with course additions made on every trigger.
Code: Select all
local course = {[1]={latitude='9.270731',longitude='13.459372'}};
local function setCourseOnGroupMembers(g,c)
g.course = c; --group lead
for i=1,#g.group.unitlist do
local u = SE_GetUnit({guid=g.group.unitlist[i]});
if u ~=nil then
u.course = c; --force application on each member.
end
end
end
--points for convoy truck arriving at destination
local currentScoreFR = ScenEdit_GetScore("France")
local currentScoreCH = ScenEdit_GetScore("China")
local points = 100
local unit = ScenEdit_UnitX()
--increment scores
currentScoreFR = currentScoreFR + points
currentScoreCH = currentScoreCH - points
--scoring function
ScenEdit_SetScore("France", currentScoreFR, "Convoy Truck arrived at destination:"..points.." points")
ScenEdit_SetScore("China", currentScoreCH, "Convoy Truck arrived at destination:"..-points.." points")
--delete truck after arrival (if you comment the following line, it works, i.e. trucks finish the mission !)
if unit.group ~=nil and unit.group.guid ~=nil then
setCourseOnGroupMembers( SE_GetUnit( {guid=unit.group.guid} ), course)
end
unit.group = "none"
unit.mission = "none"
ScenEdit_DeleteUnit({guid=unit.guid})
- nukkxx5058
- Posts: 3141
- Joined: Thu Feb 03, 2005 2:57 pm
- Location: France
Re: Help needed - very weird behavior
I'm not sure to understand this one ... do you mean that I will lose my table when I reload a save ?KnightHawk75 wrote: Thu Mar 24, 2022 6:50 pm If you do the tracking part, just don't forget to store/serialize the table and unpack it upon each startup if it exists.
I thought that my (local and global) variables values are automatically stored when I save the game. Or maybe did I misunderstood what you say ? The tracking table with guid's of trucks that already scored is declared in a startup script with a "scenario is loaded" trigger. So when I load the scen the first time it gets initialised to trucksTable = { }, which is fine because a new game is starting. But when I load a previous save, I guess that its variable content remains (and the "scen is loaded" trigger is not activated) ?
Last edited by nukkxx5058 on Thu Mar 24, 2022 8:59 pm, edited 1 time in total.
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) 
- nukkxx5058
- Posts: 3141
- Joined: Thu Feb 03, 2005 2:57 pm
- Location: France
Re: Help needed - very weird behavior
Unfortunately, I have to group them because I have 40 trucks so managing the speeds individually would be nightmarish. I could reduce to 20 but it's still a pain ... but could I add them individualy to the mission and group them afterwards ? Does it makes sense ?
Other thing: I guess that if the lead unit is killed, the result will be the same. In this case IMO it's a bug that should be fixed...
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) 
- nukkxx5058
- Posts: 3141
- Joined: Thu Feb 03, 2005 2:57 pm
- Location: France
Re: Help needed - very weird behavior
Gee ... You're right !! How can I do that ??nukkxx5058 wrote: Thu Mar 24, 2022 8:39 pmKnightHawk75 wrote: Thu Mar 24, 2022 6:50 pm If you do the tracking part, just don't forget to store/serialize the table and unpack it upon each startup if it exists.
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) 
- nukkxx5058
- Posts: 3141
- Joined: Thu Feb 03, 2005 2:57 pm
- Location: France
Re: Help needed - very weird behavior
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) 
Re: Help needed - very weird behavior
Hi nukkxx5058,nukkxx5058 wrote: Fri Mar 25, 2022 4:16 pm
I found this link above but io.open doesn't seem to workERROR: [string "Console"]:12: attempt to index a nil value (global 'io')
Yeah, the LUA IO library is not for the commercial version of C:MO for security reasons. LUA file I/O is available as an option for the professional version. What would be nice is a restricted version of the LUA file I/O that can only read and write from a scenario specific directory only.
Right now, for reading static data, I convert it to a LUA table and make it part of my script. For data to be written, I use the print statement and extract the output from the LUA log file. I hope this helps you a little bit even if it's probably not too applicable.
Re: Help needed - very weird behavior
Hi nukkxx5058,nukkxx5058 wrote: Fri Mar 25, 2022 4:16 pm
I found this link above but io.open doesn't seem to workERROR: [string "Console"]:12: attempt to index a nil value (global 'io')
Yeah, the LUA IO library is not for the commercial version of C:MO for security reasons. LUA file I/O is available as an option for the professional version. What would be nice is a restricted version of the LUA file I/O that can only read and write from a scenario specific directory only.
Right now, for reading static data, I convert it to a LUA table and make it part of my script. For data to be written, I use the print statement and extract the output from the LUA log file. I hope this helps you a little bit even if it's probably not too applicable.
- nukkxx5058
- Posts: 3141
- Joined: Thu Feb 03, 2005 2:57 pm
- Location: France
Re: Help needed - very weird behavior
Ah thanks for this ! Will have to dig a bit to find the way. I even didn't realise that there was a LuaHistory.txt file where Lua command are sent as well as printed stuff from the print("blabla") command ...
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) 
- nukkxx5058
- Posts: 3141
- Joined: Thu Feb 03, 2005 2:57 pm
- Location: France
Re: Help needed - very weird behavior
Hi, I just got a solution from Discord (thank you Yooper !)
He suggested to use :
ScenEdit_SetKeyValue (key,value,forCampaign)
and
ScenEdit_GetKeyValue (key,forCampaign)
https://commandlua.github.io/#ScenEdit_SetKeyValue
Need to change the table into string first to use the function. HEre's what he suggests.
He suggested to use :
ScenEdit_SetKeyValue (key,value,forCampaign)
and
ScenEdit_GetKeyValue (key,forCampaign)
https://commandlua.github.io/#ScenEdit_SetKeyValue
Looks exactly like what I needed !ScenEdit_SetKeyValue (key,value,forCampaign)
Sets the value for a key in the persistent key store.
This function allows you to add values,associated with keys,to a persistent store KeyStorethat is retained when the game is saved and resumed.Keys and values are both represented as non-nilstrings.The value is retrieved by ScenEdit_GetKeyValue.
Need to change the table into string first to use the function. HEre's what he suggests.
local truckstable = { [1] = '4YWDWP-0HMGEF37B8V13', [2] = '4YWDWP-0HMGEF37B8V23', [3] = '4YWDWP-0HMGEF37B8V1J', [4] = '4YWDWP-0HMGEF37B8V2J', [5] = '4YWDWP-0HMGEF37B8V33', [6] = '4YWDWP-0HMGEF37B8V3J' }
a = (table.concat(truckstable, ","))
--print(a)
ScenEdit_SetKeyValue ("trucksStored",a)
str = ScenEdit_GetKeyValue("trucksStored")
newTrucksTable={}
for word in string.gmatch(str, '([^,]+)') do
table.insert(newTrucksTable, word)
end
print(newTrucksTable)
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) 
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
Re: Help needed - very weird behavior
They are not, you must do this yourself for each item you want to persist from Lua memory to the savefile context, and you must on loadup re-load said data yourself.I thought that my (local and global) variables values are automatically stored when I save the game.
Some will tell you to create keys for every var..etc or do what your doing with tbl concat, that just doesn't scale well beyond a few vars, and doesn't work well at all for tables that also contain tables or data where you want the type preserved. You want to use the following to strigy and destringify table data to save to into the keys, this method handles tables with-in tables so long as they are plain lua 'tables' and not userfunctions (wrappers).
I have posted this a couple times before, but I'll post it again in an attachment here, it's handy state saving functions using https://gist.github.com/tylerneylon/59f ... be525b30ab as the work horse. Anyway please note this is ripped from a larger private library but tweaked for semi-standalone usage. Feel free to rename the namespace, but if you do make sure you do it correctly everywhere that is needed.
say you have a table like
Code: Select all
sceneGlobals={}; --sometoplevel namspace for your scene.
sceneGlobals.MyDataStorageKey="MyDataTable" -- our key name.
sceneGlobals.MyData = { -- a table that has 2 entries that who's entries each contain another table of values etc.
[1] = {SomeOtherTableData1={id=1234}},
[2] = {SomeOtherTableData1={id=4321}}
}
You use:
Code: Select all
gKH.State.SaveTableToKey(sceneGlobals.MyData,sceneGlobals.MyDataStorageKey);Code: Select all
sceneGlobals.MyData = gKH.State.LoadTableFromKey(sceneGlobals.MyDataStorageKey);If you find this useful, help pass it along to next person.
att: gKH_State_PublicStandalone-Posted.zip gKH_State_PublicStandalone-Posted.lua -
Paste the code from the file into an action that runs upon SceneLoaded, if you have multiple actions that run at startup make sure this one is included in the order before any that make use of the functions with-in it are called.
SampleStateLibraryLoading.scen - This is 1.04 build 1147.42 db3k492 sample scene that demos the basics of the above including the sceneload order,etc.
Been using this for years now, saving multimegabyte data structures without any data problems.
- nukkxx5058
- Posts: 3141
- Joined: Thu Feb 03, 2005 2:57 pm
- Location: France
Re: Help needed - very weird behavior
Thank you for this message.
I already implemented the solution in my post above with the ScenEdit_SetKeyValue and ScenEdit_GetKeyValue + concat.
I struggled a lot to do it and lost a substantial amount of hair as I'm not (yet) a seasoned programmer
I will have to study your doc and it definitely seems interesting but will probably need time to digest it !
Re ScenEdit_SetKeyValue and ScenEdit_GetKeyValue + concat , I realized afterwards that it was not just my table with guid's that should be stored but all the involved variables ! Fortunately there was just 2 or 3 vars but I really had bad time to have it work (hopefully) bugs free. I nearly gave-up a few times and was near apoplexy ... I definitely need to progress so I will certainly study your article in details and try to implement it. It takes time to become a coder. I was coding a bit earlier in my life but as an amateur, to help me in my work, with visual basic in Excel. I also once managed to code the Mandelbrot set with zooms using an old C compilator (this was my masterpiece) but I've never been good at programming. I'm struggling with algorithms despite some courses in numerical analysis when I was a student and and I'm a total mess at organizing my code, like using functions and having clean optimized code. My code is %*@^%%@ and definitely not optimized.
The good news: there's a lot of room for improvement
Thanks again, will definitely study the suggested method. And thank you for highlighting this variables permanence issue ! Would have totally missed it otherwise
I already implemented the solution in my post above with the ScenEdit_SetKeyValue and ScenEdit_GetKeyValue + concat.
I struggled a lot to do it and lost a substantial amount of hair as I'm not (yet) a seasoned programmer
I will have to study your doc and it definitely seems interesting but will probably need time to digest it !
Re ScenEdit_SetKeyValue and ScenEdit_GetKeyValue + concat , I realized afterwards that it was not just my table with guid's that should be stored but all the involved variables ! Fortunately there was just 2 or 3 vars but I really had bad time to have it work (hopefully) bugs free. I nearly gave-up a few times and was near apoplexy ... I definitely need to progress so I will certainly study your article in details and try to implement it. It takes time to become a coder. I was coding a bit earlier in my life but as an amateur, to help me in my work, with visual basic in Excel. I also once managed to code the Mandelbrot set with zooms using an old C compilator (this was my masterpiece) but I've never been good at programming. I'm struggling with algorithms despite some courses in numerical analysis when I was a student and and I'm a total mess at organizing my code, like using functions and having clean optimized code. My code is %*@^%%@ and definitely not optimized.
The good news: there's a lot of room for improvement
Thanks again, will definitely study the suggested method. And thank you for highlighting this variables permanence issue ! Would have totally missed it otherwise
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) 
-
KnightHawk75
- Posts: 1850
- Joined: Thu Nov 15, 2018 7:24 pm
Re: Help needed - very weird behavior
Glad it helped. That said you don't have to full understand the json stringify code to use it though. 
For those storing a lot of global var's it's why I recommend storing them in table/namespace.
For me personally this is typically always gKH.SceneGlobals such that I can quickly store and restore everything stored under SceneGlobals (and below it) as one/a whole as it relates to that scene, and keep my functions and sudo classes and other objects in other tables. It also helps avoid naming conflicts with other code that may hanging around from other scenes since the environment is not reset between scene loads\reloads, and only between command exe starts.
For those storing a lot of global var's it's why I recommend storing them in table/namespace.
For me personally this is typically always gKH.SceneGlobals such that I can quickly store and restore everything stored under SceneGlobals (and below it) as one/a whole as it relates to that scene, and keep my functions and sudo classes and other objects in other tables. It also helps avoid naming conflicts with other code that may hanging around from other scenes since the environment is not reset between scene loads\reloads, and only between command exe starts.
- nukkxx5058
- Posts: 3141
- Joined: Thu Feb 03, 2005 2:57 pm
- Location: France
Re: Help needed - very weird behavior
Ah ! This explains things !!KnightHawk75 wrote: Sun Mar 27, 2022 8:40 pm [...] since the environment is not reset between scene loads\reloads, and only between command exe starts.
Thanks again for your help !
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) 
- nukkxx5058
- Posts: 3141
- Joined: Thu Feb 03, 2005 2:57 pm
- Location: France
Re: Help needed - very weird behavior
OK, I tried it. It's cool. Will use it from now ! 
Winner of the first edition of the Command: Modern Operations COMPLEX PBEM Tournament (IKE) (April 2022) 
