EDCD / EDDI

Companion application for Elite Dangerous
Other
443 stars 81 forks source link

Populated State variable is 'void' in the middle of scripts #2607

Closed Darkcyde13 closed 3 months ago

Darkcyde13 commented 5 months ago

What's Wrong (please be as specific as possible)

Expected

State variables to retain their value throughout the execution of a script.

Observed

Populated State variable is OK at the start of scripts, but becomes void in the middle, and then populated again at the end, even though no code interacts with it.

Steps to reproduce

  1. Set a State variable. i.e. {SetState('rescue_mission_data', "961292804-1-Claim,961293060-1-Complete,961293569-0-Active")}
  2. Add some checks to a script, for example Mission accepted, with {dump(state.rescue_mission_data)}, at the start, middle, and ends of the script.
  3. Run the script either by the Test button, or naturally by playing the game and causing it to trigger.
  4. Observe that at the start it is populated, in the middle it is 'void', and (depending on the length of the script?) the end will be populated again.

Configuration

My Investigation

Investigation Notes

As discussed with T'kael on the forum via DM. Reproduced below:

Hi T'kael,

I've been finishing up some functionality in my EDDI personality, and I've come across some strangeness happening. I just wanted to run it by you before opening an issue in GitHub.

Back in June last year, I reported an issue on GitHub regarding state variables being void (issue #2554), and now I'm experiencing the same problem again, even though it was fixed in that issue.

I've been updating my version of a route planner to handle 'Rescue' type missions correctly, because the game doesn't produce events for them properly. By this I mean that the game doesn't trigger the 'mission redirected' event until some time after you've collected the required commodities. This can be triggered anywhere from your first jump to your 3rd or 4th jump, making it useless for route planning.

Anyway, I've been storing the 'Rescue' missions data (mission ID, amount of commodity collected, manually created mission status) in a State variable, like this: "961292804-1-Claim,961293060-1-Complete,961293569-0-Active"

My code works perfectly fine when used in a single test script, but when I added it to the event scripts I needed it in, the data was getting overwritten in the 'Mission accepted' script, or ignored in others like 'Entered supercruise'. After adding some test code to dump the State variable at various points in the scripts, I found that it was 'void' at the beginning and in the middle (of 'Mission accepted for example), but was populated with the correct data by the end of the script, even when the variable was not used or modified during script execution.

I then made a copy of the EDDI default personality, set the State variable, checked it's contents, and added the dump commands to 'Mission accepted' again. This time, running the script results in the variable being populated at the start, but not in the middle or at the end, even though the default script does nothing with it.

I've also tried setting the State variable with other separators, like using an underscore instead of the comma, but it made no difference (just in case the commas were interfering with how EDDI handles State variables in the background).

This is the first time I've come across this since it was fixed back in June last year. So I'm a bit confused as to how the problem has come back. I am using the latest release version of EDDI, v4.0.3, and I've tried with and without VoiceAttack, but still the same results.

So, I just wanted your opinion on the above first, before I go to open an issue, just in case there could be anything I'm doing wrong. I can provide my entire personality as it is at the moment, if that would help. I'll open it as a GitHub issue if you think it best to handle it there anyway.


The state dictionary is manipulated from the Speech Responder and VoiceAttack Responder. There is also no code that should intermittently take it offline.

🤔If the issue occurs without VoiceAttack running then that limits the code that could potentially change / null the state variable essentially to the speech responder itself. If this doesn't occur when testing single scripts but does exist when executing scripts naturally in-game then one possibility which may exist could be that the state is being modified between when planned speech is enqueued and when that planned speech is dequeued and resolved.

Do your scripts ever set those particular values to null?

Do any of these scripts have priority values other than the default of priority 3?

Thanks for the reply. I'll go over what you have said, and hopefully add some clarity to the problem. I've also run some additional, more structured, tests this evening, so that I have more accurate results.

T'kael said: If this doesn't occur when testing single scripts but does exist when executing scripts naturally in-game then one possibility which may exist could be that the state is being modified between when planned speech is enqueued and when that planned speech is dequeued and resolved.

Unfortunately, it does occur both when executing naturally in-game, and when clicking the Test button. I first noticed it when testing my scripts in-game, but then in trying to find out what was happening, I was mostly using the Test button with test code of {dump(state.rescue_mission_data)} placed at the start, middle, and ends of the scripts. These I have numbered in the scripts so I know where things are.

The code I've added in my scripts, for the Routing update I'm working on, is set to only run if the event mission is a 'Rescue' mission (what the game calls surface salvage type missions). Using the Test button on 'Mission accepted', the test mission is of a different type (Wing Delivery mission), so my added code does not run, and so does not interact with the State variable at all.

So, when running the 'Mission accepted' script for example, either naturally in-game or with the Test button, the dump() at the start and at the end are populated, but those I've put in the middle are always void: 1:"961292804-1-Claim,961293060-1-Complete,961293569-0-Active". Wing Delivery mission accepted for Hip 2 0 2 7 7 Party.. 2:. 3:. You have no missions to plot a route with. 6:"961292804-1-Claim,961293060-1-Complete,961293569-0-Active".

Here you can see numbers 2 & 3 are blank, and EDDI says 'void' for these. Numbers 4 & 5 are within the new code I've added, and so are not spoken. Numbers 1 & 6 are populated as expected, 1 being right near the beginning, and 6 right on the last line.

This is the output I get for 'Mission completed': 1:"961292804-1-Claim,961293060-1-Complete,961293569-0-Active". You have completed the mission successfully. 2:. You have been awarded nearly 261 thousand credits and 2 units of Suit Schematic. 3:. Take off to re-calculate mission route. 4:"961292804-1-Claim,961293060-1-Complete,961293569-0-Active".

Again, 2 & 3 are void, but 1 & 4 are populated. I'm only using four instances in this one.

However, when I made a direct copy of the EDDI default personality, and added the dump() lines to the default 'Mission accepted', then the start one was populated, but the middle and end ones were not, and the EDDI default script obviously has no interaction with my State variable to change it. 1:"961292804-1-Claim,961293060-1-Complete,961293569-0-Active". Wing Delivery mission for HIP 2 0 2 7 7 Party accepted. 2:. 3:.

As the default script is quite short, I only used three instances to test with.

I can flip between my personality and the copy of the EDDI default, click the Test button on 'Mission accepted', and the points that the variable are populated repeated every time as above. So, in mine, the start and end ones are populated, and in the EDDI default, only the start one is populated. I have no idea why they should be different.

Unless... could it be a timing thing? My scripts take longer to run, so the void entries in the middle would equate to the void entries in the default, but as mine is longer, the variable is no longer void by the time it gets to the last dump() check? I dunno, I'm kinda clutching at straws at the moment. 🤷‍♂️ 😕

T'kael said: Do your scripts ever set those particular values to null?

The only time I set the State variable to null (void) is in my 'Mission completed' script, where it will be set to void only if the variable that I use (before copying it to the State variable) is of zero length or is an empty string. This is near the end of the code section I've added for the Routing update, which will run if the completed mission is a Rescue mission. As the State variable is void at this point, even when I know it is populated, the void code is always run. I have tried commenting that line out to check the State variables state, and it is the same as above.

T'kael said: Do any of these scripts have priority values other than the default of priority 3?

The only script that uses my new State variable and I've changed the priority of, is 'FSD engaged', which I have changed to priority 2 at some point in the past (I don't even remember when or why). All other scripts that I've made changes to for this update, are still set as priority 3.

So, with the fact that it's happening even with a copy of the EDDI default personality, would seem to indicate that it's probably not any of my code that's causing the problem. I'm also at a loss as to why I've only started to experience it now, so long after it was fixed last year. It's even more of a mystery as to why it becomes void in the middle of scripts, but is OK at the start and end, even though nothing interacts with it at all during the execution of the scripts.


I see what you are describing. Speech resolution is a recursive process and we seem to be losing information somewhere during those recursions. Thinking about how to address this one. Please do submit a ticket so that this stays on the radar until addressed. o7

EDDI Logs

N/A

Player journals

N/A

Tkael commented 3 months ago

Hah! It turns out that this issue is simpler (and more script specific) than I had thought. The Mission faction state script is overwriting our state map because of this line:

{set state to mission.FactionState.invariantName}

Changing state to factionState in the Mission faction state script fixes the problem we're seeing in the Mission accepted script.

Darkcyde13 commented 3 months ago

Oh! Something so simple? I didn't realise that we could actually overwrite EDDI's State() with a simple variable declaration using 'state'. I'm glad you found it, and that is was so simple! 😃

I'll give that a try, thank you!