[Tutorial] The MD - First Contact

The place to discuss scripting and game modifications for X³: Terran Conflict and X³: Albion Prelude.

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

User avatar
enenra
Posts: 7150
Joined: Fri, 8. Apr 05, 19:09
x4

Post by enenra »

Hey guys,

I just wanted to mention two things I've noticed.

1. I never use special characters or even spaces in variable names. That prevents a lot of confusion and generally IMO keeps the whole thing less messy.

Code: Select all

 <set_value name="this.conversation" value="LIFE.GNS.conversation.{object.race.name@{value@this.owner}}"/>
can be read much easier like this:

Code: Select all

 <set_value name="L2M134.Conversation" value="L2M134.GNSConversation.{object.race.name@{value@L2M134.Owner}}"/> 
At least I see it this way. :)

2. I also recommend saving variables to the top level cue whenever possible. It's another way to keep the structure clean and easy. Except with briefings this always works fine as far as I've seen.
Of course, if you use a variable just in one cue then by all means, this. should be used. :)
User avatar
ScRaT_GER
Posts: 1962
Joined: Tue, 8. Jan 08, 18:19
x3tc

Post by ScRaT_GER »

I bet that this is related to how the object changes sector.
Yes, that could be the reason.
Unfortunately this can be problematic, when you try to write generic code, which works equally well for the playership and non-playerships.
I never use special characters or even spaces in variable names. That prevents a lot of confusion and generally IMO keeps the whole thing less messy.
So you prefer the cryptic name "L2M134" over "LIFE.GNS" or, what I'd choose, "LIFE_GNS"?
I also recommend saving variables to the top level cue whenever possible. It's another way to keep the structure clean and easy.
Normally I try to keep the variable scope as small as possible and to avoid global variables. Of course the MD technically only knows global variables, but I still find it cleaner to save the variable to the cue it was created in. Maybe this also depends on what kind script you're writing (e.g. "conventional" mission vs. "dynamic" mission, which corresponds to the state of the universe).
I guess in the face of instances this top-level-saving approach doesn't really work.

Btw: Does anyone know how to use event parameters correctly? I tried to catch the parameters of the object_changed_sector event, but I'm not really successfull. This is the code I'm using:

Code: Select all

  <cues>
    <cue name="X_SectorChange">
      <condition>
        <check_all>
          <object_changed_sector/>
        </check_all>
      </condition>
      <action>
        <do_all>
          <incoming_message author="DEBUG" text="Object: {value@{event.object}}\nParam 1: {value@{event.param}}\nParam 2: {value@{event.param2}}"/>
          <reset_cue cue="X_SectorChange"/>
        </do_all>
      </action>
    </cue>
  </cues>
I fires correctly, when changing the sector, but object, param and param2 are always 0.

Greetings,
ScRaT
User avatar
enenra
Posts: 7150
Joined: Fri, 8. Apr 05, 19:09
x4

Post by enenra »

ScRaT_GER wrote:
I never use special characters or even spaces in variable names. That prevents a lot of confusion and generally IMO keeps the whole thing less messy.
So you prefer the cryptic name "L2M134" over "LIFE.GNS" or, what I'd choose, "LIFE_GNS"?
Yes, because that's the unique identification code for the mission as it was used in most vanilla MD files. :)
L2 is level two, meaning a mission that might use L1 files - libraries
134 would be an unique identification number for the MD file.
I also recommend saving variables to the top level cue whenever possible. It's another way to keep the structure clean and easy.
Normally I try to keep the variable scope as small as possible and to avoid global variables. Of course the MD technically only knows global variables, but I still find it cleaner to save the variable to the cue it was created in. Maybe this also depends on what kind script you're writing (e.g. "conventional" mission vs. "dynamic" mission, which corresponds to the state of the universe).
I guess in the face of instances this top-level-saving approach doesn't really work.
I don't mean global variables. What I mean is that the top level cue (the cue into which all other cues are nested) should be the mission code - for example L2M134 - and as many variables as possible should be saved to it because it's much easier to remember that one code than having to remember the cue to which each variable was saved to. This is independent from whether it's a generic mission, a plot or a library. :)
I've yet to work with instances though - hasn't been necessary until now - so I can't tell whether it's possible there.
Btw: Does anyone know how to use event parameters correctly? I tried to catch the parameters of the object_changed_sector event, but I'm not really successfull. This is the code I'm using:

Code: Select all

  <cues>
    <cue name="X_SectorChange">
      <condition>
        <check_all>
          <object_changed_sector/>
        </check_all>
      </condition>
      <action>
        <do_all>
          <incoming_message author="DEBUG" text="Object: {value@{event.object}}\nParam 1: {value@{event.param}}\nParam 2: {value@{event.param2}}"/>
          <reset_cue cue="X_SectorChange"/>
        </do_all>
      </action>
    </cue>
  </cues>
I fires correctly, when changing the sector, but object, param and param2 are always 0.

Greetings,
ScRaT
Not all (IIRC not even many) event conditions support the event variables. This might be one of the ones that don't.
Shush
Posts: 244
Joined: Sat, 6. Dec 03, 16:21
x4

Post by Shush »

Btw: Does anyone know how to use event parameters correctly? I tried to catch the parameters of the object_changed_sector event, but I'm not really successfull. This is the code I'm using:

Code: Select all

<cues> 
    <cue name="X_SectorChange"> 
      <condition> 
        <check_all> 
          <object_changed_sector/> 
        </check_all> 
      </condition> 
      <action> 
        <do_all> 
          <incoming_message author="DEBUG" text="Object: {value@{event.object}}\nParam 1: {value@{event.param}}\nParam 2: {value@{event.param2}}"/> 
          <reset_cue cue="X_SectorChange"/> 
        </do_all> 
      </action> 
    </cue> 
  </cues> 
I fires correctly, when changing the sector, but object, param and param2 are always 0.
You can't use value@ with these MD inbuilt variables, value@ is only for your own local and global variables. So change that above line to something like:

Code: Select all

<incoming_message author="DEBUG" text="Object: {event.object}\nParam 1: {event.param}\nParam 2: {event.param2}"/>
There's a much more subtle problem if you use <object_changed_sector/> though, we know that leaving the object unassigned causes the event to fire for the player ship by default. That's all well and good, but, (and this is speculation on my part), {event.object} will not be assigned a valid value unless the object attribute is assigned with something...

My guess is that the contents of the object attribute are copied to the {event.object}, instead of the actual object that caused the event. If this is true, it would probably be an easy fix, but as it stands right now, {event.object} is useless for <object_changed_sector/>, i.e. when used for the player ship.

*Edit: added the i.e.
User avatar
ScRaT_GER
Posts: 1962
Joined: Tue, 8. Jan 08, 18:19
x3tc

Post by ScRaT_GER »

@Shush

Just as as side note on the conversation responses. For a MD script of mine I had to do the same and I tried it myself - and it works!
But I didn't use {object.race.name@this.station} but rather {object.race@this.station}, because its more portable (using object.race.name would result in different names for different languages).

So my conversations look like this:

Code: Select all

<conversation name="MyConversation_1"> <!--Argon-->
<conversation name="MyConversation_3> <!--Split-->
And the MD file:

Code: Select all

<conversation_completed actor="..." conversation="MyConversation_{object.race@this.station}" outcome="..."
You can't use value@ with these MD inbuilt variables, value@ is only for your own local and global variables. So change that above line to something like:
Thanks, now it works. The problem weren't the @ signs, but the {value@...}, it should have been {object@...} or {object.name@...}.
Unfortunately the {event.object} is still non-existent, but this is most likely because of your and Gazz' explanations.

If anybody is interested, these are the values of {object@param} and {object@param2} for the object_changed_sector event:
param: New sector
param2: Old sector (none, if undocking from a station or at the first game start)
event.object: most likely the object, which changed the sector, but it seemingly doesn't work for the playership.
Yes, because that's the unique identification code for the mission as it was used in most vanilla MD files. Smile
L2 is level two, meaning a mission that might use L1 files - libraries
Mh, I still find it strange to name cues after what they use instead of what they do. But I guess Egosoft started this system, so they will use it until the end. :)


And yet another question:
Did anybody (Shush? :D) already use library cues in combination with instances? I'm asking, because I tried to put the <conversation_completed> condition from above into a library cue, to use it for several other cues, but I just didn't get it to work. I guess the problem was, that the actor name, which was "parent.MyActor" before, didn't work inside the library-cue.

Greetings,
ScRaT
Shush
Posts: 244
Joined: Sat, 6. Dec 03, 16:21
x4

Post by Shush »

Just as as side note on the conversation responses. For a MD script of mine I had to do the same and I tried it myself - and it works! But I didn't use {object.race.name@this.station} but rather {object.race@this.station}, because its more portable (using object.race.name would result in different names for different languages).
Dang it, that's excellent it does work, I have a whole bunch of code to re-write now :)

Just one thing, I thought the problem was that the xml expression evaluation wasn't consistant within the command attributes and that combined with the non existant text/string handling meant you couldn't do what you did.

I was a lot wrong and a little bit right, I just verified what is actually going on. I had only ever tried expression evaluation using strings, i.e. "conversation.argon" not stuff like "conversation.1" and then mistakenly assumed the expression evaluation was borked, it isn't as you found out, what's actually borked is the text/string handling.

So this will never work as it results in a string.

Code: Select all

<conversation_completed actor="..." conversation="MyConversation_{object.race.name@this.station}" outcome="..."
But this does work as it results in an integer, as you found out.

Code: Select all

<conversation_completed actor="..." conversation="MyConversation_{object.race@this.station}" outcome="..."
And yet another question:
Did anybody (Shush? ) already use library cues in combination with instances? I'm asking, because I tried to put the <conversation_completed> condition from above into a library cue, to use it for several other cues, but I just didn't get it to work. I guess the problem was, that the actor name, which was "parent.MyActor" before, didn't work inside the library-cue.
Ok, I've tried using library cues in instances and never gotten them to work, no matter where I put the library cue, i.e. whether it was a local cue within the instance or a global cue in a top level instance. One thing I haven't tried though is using the instantiate="static" attribute with a library, I am guessing they are an invalid combo but it's worth a long shot.

One thing that does work though, but has limited use is the <cue ref="blah"/> and <action ref="blah"/> commands, you can call reused cues and action components of cues within an instance without using the library command, but they must be at the same cue level to make any sense if you are using this. or parent. etc, hence the limited use inside instances.

I'll try and give you a psuedo example as I am doing a poor job of explaining this.

Code: Select all

<cue name="Blah.Cue0">
  <action>
    <set_value "this.blahCheck"/>
    <set_value "this.blahAction"/>
  </action>

  <cues>
    <cue name="Blah.Cue1">
      <condition>
        <blah_condition "parent.blahCheck"/>
      </condition>

      <action>
        <blah_action "parent.blahAction"/>
      </action>
    </cue>

    <cue name="Blah.Cue2">
      <action ref="Blah.Cue1"/>
    </cue>
  </cues>
</cue>
Blah.Cue2 executes the action of Blah.Cue1 as if it was a library, for this to work Blah.Cue1 has to be in scope, (which it is for this example), and importantly the "parent.*" have to make sense. In this case because the two cues are at the same level "parent.*" makes sense for both of them, but if Blah.Cue2 was a sub cue of Blah.Cue1 it wouldn't work as Blah.Cue2 would need "parent.parent.*" instead of "parent.*" :/

*Edit fixed the example
Last edited by Shush on Wed, 18. Aug 10, 09:32, edited 1 time in total.
User avatar
ScRaT_GER
Posts: 1962
Joined: Tue, 8. Jan 08, 18:19
x3tc

Post by ScRaT_GER »

Dang it, that's excellent it does work, I have a whole bunch of code to re-write now :)
:thumb_up:
I had only ever tried expression evaluation using strings, i.e. "conversation.argon" not stuff like "conversation.1" and then mistakenly assumed the expression evaluation was borked, it isn't as you found out, what's actually borked is the text/string handling.
I also tried it using {object.race.name@this.station} and I guess even that would work, because I used a debug message, which displayed exactly the correct string. The problem lies more within the language dependency of that command.

Code: Select all

conversation="MyConversation_{object.race.name@this.station}"
So this correctly evaluates to "MyConversation_Argon" (if this.station is an Argon station) in an English game, but for a German game the result will be "MyConversation_Argonen".
Ok, I've tried using library cues in instances and never gotten them to work, no matter where I put the library cue, i.e. whether it was a local cue within the instance or a global cue in a top level instance.
Oh, good. So it's not just me. :)

That's really a major drawback, if it's not possible to use libraries correctly in an instantiated cue. Maybe one of the devs knows more about this.
One thing that does work though, but has limited use is the <cue ref="blah"/> and <action ref="blah"/> commands
Yes, at least that's something.

Greetings,
ScRaT
Shush
Posts: 244
Joined: Sat, 6. Dec 03, 16:21
x4

Post by Shush »

I also tried it using {object.race.name@this.station} and I guess even that would work, because I used a debug message, which displayed exactly the correct string. The problem lies more within the language dependency of that command.

Code: Select all

conversation="MyConversation_{object.race.name@this.station}" 
So this correctly evaluates to "MyConversation_Argon" (if this.station is an Argon station) in an English game, but for a German game the result will be "MyConversation_Argonen".
Yup that makes sense, the less code we have to write to support locale the better. I understand that it prints out ok as a debug message, but do any of the conversation commands work for you that use the string version? As they don't for me, only the {object.race@this.station} ones work for me.

Obviously it's just a thought excercise because of the language dependancy as you noted above.

And yeah, if a dev could chime in and set us straight on some of these instantiation issues that would be fairly kickarse.
User avatar
ScRaT_GER
Posts: 1962
Joined: Tue, 8. Jan 08, 18:19
x3tc

Post by ScRaT_GER »

I understand that it prints out ok as a debug message, but do any of the conversation commands work for you that use the string version? As they don't for me, only the {object.race@this.station} ones work for me.
That's why I underlined "guess". I didn't try it, as soon as I saw the language problem.
But, for the sake of certainty, I just tried it and it works, too. Maybe you named your conversations wrong (i.e. you didn't use capital letters, so wrote "argon" instead of "Argon")?
And yeah, if a dev could chime in and set us straight on some of these instantiation issues that would be fairly kickarse.
Hopefully enenra will look into this thread again. Even though he might not have used instantiations, he still has "access" to the documentation and other devs.

Greetings,
ScRaT
User avatar
enenra
Posts: 7150
Joined: Fri, 8. Apr 05, 19:09
x4

Post by enenra »

Regarding the conversation_completed - be sure that it's placed in a subcue of the cue in which the conversation is created. Otherwise it won't fire IIRC.

Regarding the instances I can't help you but I'll point Owen to this thread. Maybe he can. :)
I'm not sure whether he's got time for it though. ;)
Shush
Posts: 244
Joined: Sat, 6. Dec 03, 16:21
x4

Post by Shush »

Regarding the conversation_completed - be sure that it's placed in a subcue of the cue in which the conversation is created. Otherwise it won't fire IIRC.
Yeah I found that out very early on when I first started playing with the MD.
Regarding the instances I can't help you but I'll point Owen to this thread. Maybe he can.
I'm not sure whether he's got time for it though.
Cheers :)
User avatar
ScRaT_GER
Posts: 1962
Joined: Tue, 8. Jan 08, 18:19
x3tc

Post by ScRaT_GER »

I'm not sure whether he's got time for it though.
Apparently not. :(

Well, I did a little testing on my own and found out, that libraries are not run as childs of the calling cue but they are rather exectued in place, as if they were part of the calling cue.
A little code should explain what I mean:

Code: Select all

  <cues>
    <cue name="CounterLib" library="1">
      <action>
        <incoming_message author="DEBUG" text="Library Cue instance: {instance@this}\nParent instance: {instance@parent}\nArgument instance: {param@myinstance}\nShip: {object.name@parent.ship}"/>
      </action>
    </cue>
    <cue name="CreateFiveInstances">
      <condition>
        <check_age min="1s"/>
      </condition>
      <action>
        <set_value name="this.counter" exact="5"/>
      </action>
      <cues>
        <cue name="InstanceTest_Init" instantiate="static" delay="1s">
          <condition>
            <check_all>
              <check_value value="{value@parent.counter}" min="1"/>
            </check_all>
          </condition>
          <action>
            <do_all>
              <set_value name="parent.counter" exact="1" operation="subtract"/>
              <create_ship typename="SS_SH_A_M3" race="argon" name="this.ship">
                <sector sector="{player.sector}"/>
              </create_ship>
              <set_pilot_data object="this.ship" shipname="{value@parent.counter}"/>
            </do_all>
          </action>
          <cues>
            <cue ref="CounterLib">
              <params>
                <param name="myinstance" value="{instance@parent}"/>
              </params>
            </cue>
          </cues>
        </cue>
      </cues>
    </cue>
  </cues>
I know that the cue names are not appropriate, but that's not the point. What's important is the debug message. It will print something like this:

Code: Select all

Library Cue instance: -35031
Parent instance: -35030
Argument instance: -35030
Ship: 4
Ship "4" is simply the name of the first ship created. I just put it in there, to see how one can reference an object from within a library of an instantiated cue.

So actually it is quite simple: The library will behave exactly as if it was put directly into the code at the calling cue. That's why
{instance@parent} and {param@myinstance} in the debug message are the same.
I still got some problems referencing an actor from inside a library, although it should work exactly the same way as referencing the ships in the example code - but, well, it doesn't. :/
Anyways, I'll continue experimenting with this - maybe I'll find out how to do it correctly.

Greetings,
ScRaT
ThisIsHarsh
Posts: 1135
Joined: Sun, 19. Oct 08, 18:46
x3tc

Post by ThisIsHarsh »

Really great thread guys. I don't know much of anything to do with the MD and this thread has definately helped.

I was just wondering if anyone had found any useful tricks to integrate MSCI and MD code together.

A lofty goal as a case study:

I have my military response script, where military outpost -owned ships jump to sectors for defense when, say, an enemy ship starts attacking a station. This is all handled in MSCI. What would be wonderful is if the player could go up to a capital ship that is part of the defense fleet and accept a mission from them to destroy X percent of the invaders...
There are 10 types of people in the S&M forums - those who understand binary, and those who don't.

Black holes are where God divided by zero.
User avatar
ScRaT_GER
Posts: 1962
Joined: Tue, 8. Jan 08, 18:19
x3tc

Post by ScRaT_GER »

What would be wonderful is if the player could go up to a capital ship that is part of the defense fleet and accept a mission from them to destroy X percent of the invaders...
Yes, that is definitely possible.
What you'd basically do is scan the player sector for capital ships and the ships names for a special name. If the name fitsand there are still enemies in the sector, you could spawn an actor on that ship, which will offer the mission to destroy the enemies.
Unfortunately you cannot check, if a some special script is running on a ship, so you'll have to go by a special name or some other significant feature of an object (at least if you want to do it purely with the MD).
I was just wondering if anyone had found any useful tricks to integrate MSCI and MD code together.
No, not yet. I'm currently experimenting a bit, but I didn't find an easy, clean solution until now.
MD-SE communication is a one way street.

Greetings,
ScRaT
User avatar
Gazz
Posts: 13244
Joined: Fri, 13. Jan 06, 16:39
x4

Post by Gazz »

The MD can read very little information about an actor.

Object / Pilot name as strings,
Engine/rudder tunings as positive integer (not limited by the cargo bay),
Destination and Attack Target as objects. (They stay set until a script changes them)
The ware count of a cargo pod can be negative integer.
Owned ships (of a station) as an array of ships.
Wares can be set as products/resources of a dummy station/dock.
My complete script download page. . . . . . I AM THE LAW!
There is no sense crying over every mistake. You just keep on trying till you run out of cake.
User avatar
ScRaT_GER
Posts: 1962
Joined: Tue, 8. Jan 08, 18:19
x3tc

Post by ScRaT_GER »

So, I experimented with instances and libraries again and I think I found the reason, why they never wanted to work for me. Here's the relevant code:

Code: Select all

  <cues>
    <cue name="CreateInstances">
      <action>
        <set_value name="instanceCount" exact="5"/>
      </action>
      <cues>
        <cue name="MyLibrary" library="1">
          <action>
            <do_all>
              <incoming_message author="DEBUG" text="{param@arg}\nInstance count: {value@instanceCount}"/>
            </do_all>
          </action>
        </cue>
        <cue name="InstantiatedCue" instantiate="static" delay="1s">
          <condition>
            <check_value value="{value@instanceCount}" min="1"/>
          </condition>
          <action>
            <set_value name="instanceCount" exact="1" operation="subtract"/>
          </action>
          <cues>
            <cue name="CallLibrary1" ref="MyLibrary">
              <params>
                <param name="arg" value="cue1"/>
              </params>
            </cue>
            <cue name="CallLibrary2" ref="MyLibrary">
              <params>
                <param name="arg" value="cue2"/>
              </params>
            </cue>
          </cues>
        </cue>
      </cues>
    </cue>
  </cues>
The intent of the code should be clear: The top level cue "CreateInstances" sets the global variable "instanceCount" to 5 and then uses Shush's technique to create the instantiated cues.
Each sub cue uses the cue "MyLibrary", which simply prints the instance count and the argument it was given.
Now, what output would you expect? I'd expect the following:
cue1
Instance count: 4
cue 2
Instance count: 4
cue 2
Instance count: 3
cue 1
Instance count: 3
...
(I don't expect them to be in the declared order, which is why I switched "cue1" and "cue2" for the second instance)

But that's what you get:
cue2
Instance count: 4
cue 2
Instance count: 3
cue 2
Instance count: 2
...

As you see, only "CallLibrary2" really calls the library. I guess the problem lies within the "concurrency" (I know, that X doesn't use that).

Until now, I didn't find a way to solve this problem. The following approach only works partly, since it solves the "concurrency" problem, but it creates something even worse:

Code: Select all

          <cues>
            <cue name="CallLibrary1">
              <action ref="MyLibrary">
                <params>
                  <param name="arg" value="cue1"/>
                </params>
              </action>              
            </cue>
            <cue name="CallLibrary2">
              <condition>
                <cue_is_complete cue="CallLibrary1"/>
              </condition>
              <action ref="MyLibrary">
                <params>
                  <param name="arg" value="cue2"/>
                </params>
              </action>
            </cue>
          </cues>
So I only changed the second sub-cue to wait for the first one to complete. The result is the following:
cue 1
Instance count: 4
cue 2
Instance count: 4
param@arg
Instance count: 3
param@arg
Instance count: 3
...

As you see, it somehow "looses" the argument. I don't know what to make of that...

Anyways, I'll keep on experimenting. If someone has found out how to use libraries correctly with instances, I'd be glad if he shared his knowledge with us. :)

Greetings,
ScRaT
Xenon_Slayer
EGOSOFT
EGOSOFT
Posts: 13131
Joined: Sat, 9. Nov 02, 11:45
x4

Post by Xenon_Slayer »

Hi guys,

I'll try and start watching this thread and helping where I can.

In regards to the last posted issue about calling the same library twice on the same level, that doesn't work. Don't ask me why as I don't know. I just work with it.
The way around it is to call them on different cue branches, such as:

Code: Select all

<cues>
  <cue name="Branch1">
    <cues>
      <cue name="CallLibrary1" ref="MyLibrary">
        <params>
          <param name="arg" value="cue1"/>
        </params>
      </cue>
    </cues>
  </cue>
  </cue>
  <cue name="Branch2">
    <cues>
      <cue name="CallLibrary2" ref="MyLibrary">
        <params>
          <param name="arg" value="cue2"/>
        </params>
      </cue>
    </cues>
  </cue>
</cues> 
That 'should' work. Hope there isn't a typo. Didn't use the schema. That's all I have time for today :-p
Come watch me on Twitch where I occasionally play several of the X games
User avatar
ScRaT_GER
Posts: 1962
Joined: Tue, 8. Jan 08, 18:19
x3tc

Post by ScRaT_GER »

Hi Xenon_Slayer,
thanks for chiming in.

I'll try this as soon as I get the chance to.

Btw: The XMDGuide mentions a director.dmp, which can help debugging director code. The guide says that it will be located in the games root directory. Since I can't find that file, I assume this function was disabled.
So the question is: Can the director.dmp be reenabled somehow?

Greetings,
ScRaT
User avatar
Ketraar
EGOSOFT
EGOSOFT
Posts: 12272
Joined: Fri, 21. May 04, 17:15
x4

Post by Ketraar »

First of apologies I only got as far as the first post and will be addressing it without considering any post done after it. Here a few comments on what is stated there.
5. When are MD files read / activated / patched?

When loading a game, the buffered code of all cues in the savegame (including those "waiting to fire"!)
is overwritten by yourscript.xml, provided that the cue names match.

Therefore there is no need to "patch" the MD code itself and no need for a version check.
All that could require fixing is the state of the cues and which are currently "hot".
This isn't more or less work than with the SE... just different.
This is not entirely correct. If the cue is already active patching will be needed. For minor changes to the loaded cue using version="{incremental number here}" is enough for more serious changes the patching node is required.
6. When do Cues unload? How to get rid of them?

No idea if that automatically destroys all subcues with it. I would assume so, but...
Yes, all subcues are destroyed.
8. Variable Scope
Here you have to differentiate 2 types of variables. Usually we differentiate the HC variables listed in the xsd ({object@objet}, {player.ship}, etc) and the ones set in set_value.
The 1st type is fix and will return a value, usually an id number, so {object@ship} will return the internal id number of that specific ship. {object.type@ship} will return the internal id number of the type of the ship. You get the Idea.

As for the other type of variables you can set any value you like as long as its a number. You can combine the set_value with HC variables and have them set the value for you, like

Code: Select all

<set_value name="mycue.myvalue" value="{object.type@ship}"/>
You can use this value in checks or counts, by just referring to using

Code: Select all

{value@mycue.myvalue}
A global variable value will be available even if the cue gets destroyed (does not need the cue), where a local one is attached to it. (I'm not 100% sure though)
12. When do Cues fire and what do they fire?
A cue will always wait patiently until all specified conditions are met.
Then it executes the <action> and all included subcues.
This so not correct, all sub-cues are parsed IF their conditions are met. Has a cue no conditions it will get parsed instantly like any other cue, given the parent cue is finished. Exception to this is if the parent cue has a timing.

Code: Select all

<cues>
    <cue>
      <condition>
        <object_exists object="gzstation"/>
      </condition>
      <timing>
        <time exact="10s"/>
      </timing>
      <action>
        <incoming_message popup="1" text="Test for condition: station EXIST"/>
      </action>
      <cues>
        <cue name="subcue_test">
          <action>
            <incoming_message popup="1" text="Unconditional subcue of station EXIST"/>
          </action>
        </cue>
      </cues>
    </cue>
  </cues>
Here the sub-cue will trigger first as it has no condition. To prevent this it would have needed a condition checking the parent cue for completion.

That's about it.

MFG

Ketraar
Image
Zloth
Posts: 456
Joined: Tue, 20. Jan 09, 03:48
x3tc

Post by Zloth »

ScRaT_GER wrote: Btw: The XMDGuide mentions a director.dmp, which can help debugging director code. The guide says that it will be located in the games root directory. Since I can't find that file, I assume this function was disabled.
So the question is: Can the director.dmp be reenabled somehow?
This. Is the director dump dead and gone? Or am I just doing something wrong.

Also, I was able to pull out the director.xsl file but I didn't see any sign of a director.html file.

Return to “X³: Terran Conflict / Albion Prelude - Scripts and Modding”