[Question] Behavior of MD script cues

The place to discuss scripting and game modifications for X4: Foundations.

Moderators: Moderators for English X Forum, Scripting / Modding Moderators

Post Reply
ns88ns
Posts: 90
Joined: Sun, 11. Sep 11, 22:00
x4

[Question] Behavior of MD script cues

Post by ns88ns » Wed, 30. Oct 19, 15:35

Hi, community and scripting experts.

I faced very odd behavior of MD scripts which is quite different from description in The Official "Mission Director Guide". Unfortunately, there is no actual documentation to X4 MD on W4 WIKI so I used MD Guide from XR. It looks as if logic of MD scripts is changed significantly in X4. Please, take a look on the simple example below:

Code: Select all

<?xml version="1.0" encoding="utf-8" ?>
<mdscript name="TestCueSet" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="md.xsd">
    <cues>
        <cue name="Cue1" instantiate="false">
            <conditions>
                <event_cue_signalled cue="md.Setup.Start"/>
            </conditions>
            <actions>
                <debug_text text="'activated'" filter="scripts"/>
                <signal_cue cue="SubCue1"/>
                <reset_cue cue="this"/>
            </actions>
            <cues>
                <cue name="SubCue1" instantiate="false">
                    <conditions>
                        <event_cue_signalled/>
                    </conditions>
                    <actions>
                        <debug_text text="'activated'" filter="scripts"/>
                    </actions>
                    <cues/>
                </cue>
            </cues>
        </cue>
    </cues>
</mdscript>
It is actually easy and fully predictable. Regarding The MissionDirector Guide, expected output MUST be:

Code: Select all

[Scripts] 0.00 *** Context:md.TestCueSet.Cue1: activated
[Scripts] 0.00 *** Context:md.TestCueSet.SubCue1: activated
But actual output is:

Code: Select all

[Scripts] 0.00 *** Context:md.TestCueSet.Cue1: activated
[=ERROR=] 0.00 Error in MD cue md.TestCueSet.Cue1: Signalled cue md.TestCueSet.SubCue1 has no corresponding listeners
* Expression: SubCue1
It isn't as expected. I read and re-read the MD Guide again and again tens times and regardign the Guide, SubCue1 MUST be in WAITING state already while Cue1 signalling it. I was digging forum several days and found that SubCue1 must be instantiated. But, again, regarding the Guide it isn't mandatory. Both the cues can be static and, anyway, SubCue1 must be signalled but it isn't. I wrote several tens of tests but behavior is the same. I spent several days reading the guide, digging forums, changing the script and starting it again and again. And no any luck. It really makes me crazy.

Cold you, please explain, what is wrong there? Or point me, please, to valid actual documentation for X4 MD.

Thank you a lot in advance for any help.

Xenon_Slayer
EGOSOFT
EGOSOFT
Posts: 13088
Joined: Sat, 9. Nov 02, 11:45
x4

Re: [Question] Behavior of MD script cues

Post by Xenon_Slayer » Wed, 30. Oct 19, 16:50

When the actions of Cue1 run, the subcues are not yet ready to be signalled.

Several things you can do about that.
- add a delay to Cue1, meaning the actions will run after the subcues have been set up. 1ms is enough
- have another subcue with no conditions which does the signalling
- change the condition to <event_cue_completed cue="Cue1"/>
Come watch me on Twitch where I occasionally play several of the X games

ns88ns
Posts: 90
Joined: Sun, 11. Sep 11, 22:00
x4

Re: [Question] Behavior of MD script cues

Post by ns88ns » Wed, 30. Oct 19, 22:11

Thank you for reply. Delay doesn't work. At all. Even delay in 5 seconds doesn't impact on this behavior. Regarding the Guide, a sub-cue is created and switched to WAITING state and the same moment as root cue is switched to ACTIVE state (i.e. conditions was met). But actuall behavior is quite different. It looks like a bug.

It there a way to get explanation from developers?

SirNukes
Posts: 546
Joined: Sat, 31. Mar 07, 23:44
x4

Re: [Question] Behavior of MD script cues

Post by SirNukes » Wed, 30. Oct 19, 23:12

The docs aren't super clear, but my experience leads me to this understanding:

When a cue triggers, it will try to run actions (maybe queueing them if there is a delay node), then will process subcues to set them up. If you had no delay, the subcues can reference variables created by the main cue, eg. for "checktime", but the parent cue cannot signal subcues that aren't set up yet. If you do have delayed actions, subcues cannot use parent variables right away, but the parent can signal subcues.

However, in your case, you are resetting the parent and killing off the subcue before it can be signaled regardless. Maybe part of the confusion is over the signal_cue; that isn't a function call to the subcue, and doesn't happen until after the action block is complete (and sometime later in the frame, when the md engine gets around to it).

Resetting cues can be finicky to get working as desired. I prefer to avoid resets in favor of just working with instances.

Also, as a side note, delays only work when the game is unpaused. If you want your md logic to run during a pause, avoid delay based solutions.

ns88ns
Posts: 90
Joined: Sun, 11. Sep 11, 22:00
x4

Re: [Question] Behavior of MD script cues

Post by ns88ns » Thu, 31. Oct 19, 02:09

2 SirNukes
It seems to be true. It looks as if it is related to how a running cue is tracking changes in states of other cues.

As per the guide:

Code: Select all

Waiting: Either this is a root cue, or the parent has become active. The cue is checking its conditions and will become active when they are met.
Active: The cue is about to perform the actions. Child cues have entered the waiting state.
I read this as: child cues enter the WAITING state immidiately after parrent cue is entered the ACTIVE state. Should instead it be understood as: child cues enter the WAITING state after parrent cue is exited the ACTIVE state ?

Actually, this behavior meas that either a running cue doesn't track changes in states of other cues or child cues enter WAITING state after parent cue completed.

Now I have an idea how to check it and isolate but... I need a delay within <actions>. Something like this:

Code: Select all

<set_value name="$i" exact="10"/>
<do_while value="$i > 0">
  <set_value "$i" operation="subtract" exact="1"/>
  --> something to cause delay here <---
</do_while>
Is there any way how to implement this?

ns88ns
Posts: 90
Joined: Sun, 11. Sep 11, 22:00
x4

Re: [Question] Behavior of MD script cues

Post by ns88ns » Thu, 31. Oct 19, 04:11

Also, it is wrong forum... Should be posted in X4...

UniTrader
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 14571
Joined: Sun, 20. Nov 05, 22:45
x4

Re: [Question] Behavior of MD script cues

Post by UniTrader » Thu, 31. Oct 19, 08:27

what's the purpose of your delay? You could instantiate the signalled cue, use signal-cue-instantly multiple times, and pass a time as param which the signalled instance uses as delay for example.
if not stated otherwise everything i post is licensed under WTFPL

Ich mache keine S&M-Auftragsarbeiten, aber wenn es fragen gibt wie man etwas umsetzen kann helfe ich gerne weiter ;)

I wont do Script&Mod Request work, but if there are questions how to do something i will GLaDly help ;)

ns88ns
Posts: 90
Joined: Sun, 11. Sep 11, 22:00
x4

Re: [Question] Behavior of MD script cues

Post by ns88ns » Thu, 31. Oct 19, 08:52

2 UniTrader

It seems I catched a bug in MD andI need delay for test purposes: I would like to keep a cue in active state for some time so that I would be able to perform come checks from other root cue. <delay> doesn't fit because cue is still in WAITING state until <delay> completes. I need put cue into ACTIVATED state and keep it in this state for some time with no generation of extra load. For this I need delay withing <actions>.

ns88ns
Posts: 90
Joined: Sun, 11. Sep 11, 22:00
x4

Re: [Question] Behavior of MD script cues

Post by ns88ns » Thu, 31. Oct 19, 09:31

Seems it actually bug.

What I'm checking: posibility to instantly signal a static child cue with parameters several times directly from its static parent cue. Regarding the MD guide - it is possible, Several conditions must met for this:

1. All cues are static (no instances).
2. <signal_cue_instantly> must be used because there are other way to pass parameters to signalled cue.
3. Child cue must be in WAITING state while its root parent cue is in ACTIVATED state.

Now let's test condition 3 as the most unclear condition.

So, this is test script:

Code: Select all

<?xml version="1.0" encoding="utf-8" ?>
<mdscript name="TestCueSet2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="md.xsd">
	<cues>
		<!-- resets Cue1 on demand -->
		<cue name="Cue0" instantiate="true">
			<conditions>
				<event_ui_triggered screen="'OptionsMenu'" control="''"/>
			</conditions>
			<actions>
				<debug_text text="'triggered: Reset Cue1'" filter="scripts"/>
				<reset_cue cue="Cue1"/>
			</actions>
		</cue>

		<!-- The Cue which is tested -->
		<cue name="Cue1" instantiate="false">
			<conditions>
				<event_ui_triggered screen="'DockedMenu'" control="''"/>
			</conditions>
			<actions>
				<debug_text text="'activated'" filter="scripts"/>
				<debug_text text="'[check 1] THIS state: %1'.[this.state]" filter="scripts"/>
				<debug_text text="'[check 1] SubCue1 state: %1'.[SubCue1.state]" filter="scripts"/>
				<signal_cue_instantly cue="Cue2"/>
				<debug_text text="'[check 1] THIS state: %1'.[this.state]" filter="scripts"/>
				<debug_text text="'[check 1] SubCue1 state: %1'.[SubCue1.state]" filter="scripts"/>
			</actions>
			<cues>
				<cue name="SubCue1" instantiate="false">
					<conditions>
						<event_cue_signalled/>
					</conditions>
					<actions>
						<debug_text text="'activated'" filter="scripts"/>
					</actions>
					<cues/>
				</cue>
			</cues>
		</cue>

		<!-- watcher of Cue1 -->
		<cue name="Cue2" instantiate="false">
			<conditions>
				<event_cue_signalled/>
			</conditions>
			<actions>
				<debug_text text="'activated'" filter="scripts"/>
				<debug_text text="'Cue1 ext state: %1'.[Cue1.state]" filter="scripts"/>
				<debug_text text="'SubCue1 ext state: %1'.[SubCue1.state]" filter="scripts"/>
				<reset_cue cue="this"/>
			</actions>
		</cue>

	</cues>
</mdscript>
In this test I check the condition 3: state of child static cue from its static parent root cue.

There are three cues defined:
Cue1/SubCue1 - are tested cues. Cue1 signalls its own child SubCue1.
Cue2 - just external watcher to get states of Cue1/SubCue2 from other root cue. Frankly speaking, it should be implemented as fully external watcher which is activated by separated event. not by Cue1 itself. There is no way to implement delay within <actions> so I can't implement true external watcher.
Cue0 - manual reset of Cue1 for further run of test.

What it does:

Cue1 is started by event and enters ACTIVATED state. At this time (regarding the MD guide) SubCue1 MUST enter WAITING state. So Cue1 prints states of itself and its child (expected states ACTIVATED/WAITING). After that Cue1 instantly signal Cue2, which get prints of Cue1/SubCue1 (expected states ACTIVATED/WAITING). After that Cue1 again prints states of itself and its child (expected states ACTIVATED/WAITING).

But logs show something quite different (I prepended each log line with sequential number):

Code: Select all

1   [Scripts] 2265175.68 *** Context:md.TestCueSet2.Cue1: activated
2   [Scripts] 2265175.68 *** Context:md.TestCueSet2.Cue1: [check 1] THIS state: active
3   [Scripts] 2265175.68 *** Context:md.TestCueSet2.Cue1: [check 1] SubCue1 state: disabled
4   [Scripts] 2265175.68 *** Context:md.TestCueSet2.Cue2: activated
5   [Scripts] 2265175.68 *** Context:md.TestCueSet2.Cue2: Cue1 ext state: active
6   [Scripts] 2265175.68 *** Context:md.TestCueSet2.Cue2: SubCue1 ext state: disabled
7   [Scripts] 2265175.68 *** Context:md.TestCueSet2.Cue1: [check 1] THIS state: active
8   [Scripts] 2265175.68 *** Context:md.TestCueSet2.Cue1: [check 1] SubCue1 state: disabled
Lines 1 and 2 shows that SubCue is still DISABLED after activation of Cue1. it isn't as expected. The same in lines 5/6 and 7/8. Child cue isn't in WAITING state while its root parent cue in is ACTIVATED state. It means, it is impossible to signal a child cue with paremeters directly from its root parent cue.

So... Whether it is a bug or a feature? What MD documentation say on this?

UniTrader
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 14571
Joined: Sun, 20. Nov 05, 22:45
x4

Re: [Question] Behavior of MD script cues

Post by UniTrader » Thu, 31. Oct 19, 09:51

to my knowledge a cue is in active state for 1 tick at most (maybe even less than that). After that it goes into completed State and will be removed when all child cues are either complete or cancelled.


Also as mentioned before you interfere with yourself by using the cancel cue on the root cue, because this will also implicitly cancel all child cues.


Regarding passing variables down to child cues: Unless you specify Namespaces all cues under a root cue share all their Variables, so usually you just write the stuff you want to pass to a variable and read this Car from the child (requires no delay in the parent or conditions which prevent the child from triggering before the parent is complete)
if not stated otherwise everything i post is licensed under WTFPL

Ich mache keine S&M-Auftragsarbeiten, aber wenn es fragen gibt wie man etwas umsetzen kann helfe ich gerne weiter ;)

I wont do Script&Mod Request work, but if there are questions how to do something i will GLaDly help ;)

ns88ns
Posts: 90
Joined: Sun, 11. Sep 11, 22:00
x4

Re: [Question] Behavior of MD script cues

Post by ns88ns » Thu, 31. Oct 19, 10:50

But the logs are the facts, isn't it? You can just easily reproduce it... And I would like to understand what is going on and how MD is actualy works. I can't write MD scripts unless I don't understand how it works. From documentation there is only the MD Guide which isn't clear enough.
UniTrader wrote:
Thu, 31. Oct 19, 09:51
Also as mentioned before you interfere with yourself by using the cancel cue on the root cue, because this will also implicitly cancel all child cues.
I don't use <cancel _cue> in the posted testing script... Could you, please point me, where I use <cancel_cue> there?
There is <reset_cue> is used by the event just to reset Cue1 before next run of test because the Cue1 becomes COMPLETED after the test and can't be signalled again without reset, isn't it?. Also I use <reset_cue> in Cue2 to automatically reset it after run of test.
UniTrader wrote:
Thu, 31. Oct 19, 09:51
Regarding passing variables down to child cues: Unless you specify Namespaces all cues under a root cue share all their Variables, so usually you just write the stuff you want to pass to a variable and read this Car from the child (requires no delay in the parent or conditions which prevent the child from triggering before the parent is complete)
Yea, I know how variables works. But it dosn't solve my task: instantly signal child cue several time from parent cue - because child static cue can't be signalled from parrent static cue due to DISABLED state. Just imagine - I need perform the same block of code several time in parent cue in different conditions. What is the solution? Correct - to move the block of code to sub-cue and signall it from parent cue. It is due to correct code style: code deduplication, etc.
UniTrader wrote:
Thu, 31. Oct 19, 09:51
to my knowledge a cue is in active state for 1 tick at most (maybe even less than that). After that it goes into completed State and will be removed when all child cues are either complete or cancelled.
complete)
Yes. I also know that chain. The question is: why it doesn't work??? As per the MD guide: child cue enters WAITING state as soon as the parrent cue enters ACTIVATED state. Why the test shows different behavior?

ns88ns
Posts: 90
Joined: Sun, 11. Sep 11, 22:00
x4

Re: [Question] Behavior of MD script cues

Post by ns88ns » Thu, 31. Oct 19, 14:10

Finally sorted it out. It is just race-conditions on changing of states... I must read documetation more attentive. <delay> in Cue1 solved the issue.
Thank you guys all for your assistance and attention. I appreсiate it.

Special thanks to Xenon_Slayer for the first hint. It was the solution but I didn't pay enough attention to it.

UniTrader
Moderator (Script&Mod)
Moderator (Script&Mod)
Posts: 14571
Joined: Sun, 20. Nov 05, 22:45
x4

Re: [Question] Behavior of MD script cues

Post by UniTrader » Thu, 31. Oct 19, 15:26

just for clarification: I meant reset-cue in my earlier post. it will afaik also cancel all sub cues.

sorry for the confusion, but I wrote from my phone where it's difficult the me to keep an overview of the conversation.
if not stated otherwise everything i post is licensed under WTFPL

Ich mache keine S&M-Auftragsarbeiten, aber wenn es fragen gibt wie man etwas umsetzen kann helfe ich gerne weiter ;)

I wont do Script&Mod Request work, but if there are questions how to do something i will GLaDly help ;)

Post Reply

Return to “X4: Foundations - Scripts and Modding”