Hard Light Productions Forums

Modding, Mission Design, and Coding => The FRED Workshop => Topic started by: General Battuta on November 26, 2020, 11:41:19 am

Title: How do I invalidate arguments for ships that have left the mission?
Post by: General Battuta on November 26, 2020, 11:41:19 am
I've got an event.

I want it to look at ships on an argument list. I want it to pick out ships that are still in the mission. I want it to check those ships' class, and, depending on the class, run a series of sexps on them.

How can I do this without resorting to LUA?

Spoiler:
it's apparently much, much more difficult than you'd imagine?
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: General Battuta on November 26, 2020, 11:42:17 am
Unless I'm missing something obvious here, the problem is that every means I can find to detect that a ship is not in the mission will - once it finds a ship not in the mission - declare that ALL SUBSEQUENT SHIPS on the argument list are also not in the mission, ruining everything forever.
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: General Battuta on November 26, 2020, 12:08:40 pm
Turns out that this problem will not occur as long as you are checking the argument ships for departure in the PARENT conditional (the outermost in any group of nested conditionals). That one is flushed properly, but nested conditionals are not.

This is all very cursed
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: Goober5000 on November 27, 2020, 01:16:36 pm
Can you post the event in question?
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: Phantom Hoover on November 28, 2020, 10:27:16 am
The general problem is hopefully something I can communicate: when you have (when-argument (any-of <some ships...>) <condition> <body...>), each of the body nodes will be evaluated for each valid argument for which the condition is true, right? The thing is, a lot of sexps short-circuit by returning NAN_FOREVER or KNOWN_TRUE when called on destroyed or departed ships, and the short circuiting is never reset when the argument changes. It is for the condition node, which is basically how we worked around Battuta's problem, but the fact that nodes in the body can get 'stuck' like this is a massive footgun and requires FREDders to know far too much about the guts of the SEXP evaluator to understand and avoid. I think when-argument should really just flush the tree between runs, although I'm somewhat concerned that someone has somehow made missions that rely on this bizarre behaviour.
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: AdmiralRalwood on November 28, 2020, 01:30:49 pm
I'm more worried about the performance implications of flushing the entire tree every evaluation than I am about breaking backwards compatibility.
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: karajorma on November 29, 2020, 09:50:04 am
Give me a simple case where I can see this behaviour. I'm still kind of lost as to why it's an issue.
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: General Battuta on November 29, 2020, 10:13:20 am
Event repeating once every second (via high trigger count) that accepts a list of posters and, if they are in the mission, does something.

Code: [Select]
When-argument (Battuta, Karajorma, Phantom Hoover)
—true
—when
——is-in-mission(argument) = true
——do-something(argument)

If Battuta leaves, is-in-mission returns NAN_FOREVER (since Battuta is gone) and gets stuck there: it also returns NAN_FOREVER for Karajorma and Phantom Hoover even if they are still in the mission.

However, this works:

Code: [Select]
When-argument (Battuta, Karajorma, Phantom Hoover)
—is-in-mission(argument) = true
—do-something(argument)

Because the outermost 'when' gets 'flushed' (whatever this means, coder speak) when it moves to a new argument.


Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: karajorma on November 29, 2020, 10:20:26 am
Just out of interest, what happens if you have

Code: [Select]
When-argument (Battuta, Karajorma, Phantom Hoover)
—any-sexp-that-will-always-return-true(argument)
—when
——is-in-mission(argument) = true
——do-something(argument)

Cause I suspect this might be a consequence of using an inner conditional when the outer one is doing nothing with the argument.
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: General Battuta on November 29, 2020, 10:28:14 am
Oh, interesting. I'll check...
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: General Battuta on November 29, 2020, 11:02:49 am
Changing the outermost 'true' to "has-arrived-delay <argument>" makes the entire event stop evaluating? Even though the ships are present at mission start?? I'm confused
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: General Battuta on November 29, 2020, 11:12:36 am
If I change the outermost "when" to "not is ship-stealthy <argument>", which should always return true:

The moment one of the ships in the argument list dies, the inner check (actually an is-ship-class, not in-mission) breaks for all ships of the same class.

So:

Code: [Select]
When-argument (Battuta, Karajorma, Phantom Hoover)
—not is-ship-stealthy(argument)
—when
——is-class(argument) = Poster
——do-something(argument)

This will break for all ships in the argument list the moment one of those ships is destroyed (which changes is-class to NAN_FOREVER).

Did I, uh, correctly execute the question?
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: General Battuta on November 29, 2020, 11:17:53 am
Changing the outermost 'true' to "has-arrived-delay <argument>" makes the entire event stop evaluating? Even though the ships are present at mission start?? I'm confused

I'm guessing ships present at mission start haven't actually 'arrived'?

Further test, if I do

Code: [Select]
When-argument (Battuta, Karajorma, Phantom Hoover)
—not is-disarmed-delay(argument)
—when
——is-class(argument) = Poster
——do-something(argument)

If I destroy any of the ships in the argument list, the event breaks for all ships of the class. is-class is short circuiting to NAN_FOREVER for the whole argument list, I think.
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: Goober5000 on November 29, 2020, 02:40:05 pm
Short-circuiting is the correct behavior.  The when-argument sexp is designed to complete like any normal event once it finds itself in a state where it can be short-circuited.  If short-circuiting is not desired, then every-time should be used.
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: AdmiralRalwood on November 29, 2020, 02:46:02 pm
Short-circuiting is the correct behavior.  The when-argument sexp is designed to complete like any normal event once it finds itself in a state where it can be short-circuited.  If short-circuiting is not desired, then every-time should be used.
The when-argument isn't short-circuiting; the when inside the when-argument is short-circuiting.
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: Goober5000 on November 29, 2020, 02:50:13 pm
Hmm, that would make a difference, wouldn't it.
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: karajorma on November 29, 2020, 05:53:05 pm
But every-time should be flushing that inner when, right?
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: Phantom Hoover on November 29, 2020, 06:13:18 pm
Pull request #2942 (https://github.com/scp-fs2open/fs2open.github.com/pull/2942) should fix this, although being a FREDless linux user I have not been able to directly confirm this.
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: Goober5000 on November 29, 2020, 08:12:43 pm
But every-time should be flushing that inner when, right?

Every-time would flush it, but every-time isn't being used here.


Pull request #2942 (https://github.com/scp-fs2open/fs2open.github.com/pull/2942) should fix this, although being a FREDless linux user I have not been able to directly confirm this.

The problem is, we need to be certain that 1) we have identified the correct root cause, and 2) the change will not adversely affect any other missions.  This issue is confusing enough that I don't think #1 or #2 are certain.
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: Colonol Dekker on November 30, 2020, 01:21:15 am
Whatever this is for, I look forward to the final output.
Title: Re: How do I invalidate arguments for ships that have left the mission?
Post by: Goober5000 on December 02, 2020, 01:03:36 pm
The PR has been merged.