Suggestion: Community Mission Editor

This forum is the ideal place for all discussion relating to X4. You will also find additional information from developers here.

Moderator: Moderators for English X Forum

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

Post by SirNukes » Mon, 16. Apr 18, 10:22

JSDD wrote: @ TOOL:
would be a great idea to "wrap" the node-tree MD stuff into procedural (and easier to read) code (back and forth without losses) if that is possible (?) ... but who`s gonna write it ? :roll: there are no x4 freaks with programming knowledge around (at release i guess) ...
It is certainly possible. As I see it, there are two problems with the MD as-is: xml makes a bit of a scary mess of things, and there should be a translation layer between the runtime engine and the design time script development. For fun, I spitballed some code to convert MD xml to something slightly more recognizable.

Example input, taken from whatever script I landed on when scrolling through the cat file list for rebirth (trade.performplayertraderun.xml in this case):

Original snippet (skipping some debug stuff that's mostly text prints):

Code: Select all

<?xml version="1.0" encoding="iso-8859-1" ?>
<aiscript name="trade.performplayertraderun" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="aiscripts.xsd" priority="60">
  <params>
    <param name="debugchance" default="0"/>
  </params>
  <attention min="unknown">
    <actions>
      <!-- debugging -->
      <set_value name="$failreason" exact="''" />

      <wait min="1s" max="2s" />

      <!-- get top item from shopping list -->
      <label name="check shoppinglist" />
      <get_trade_from_shoppinglist object="this.ship" result="$shoppinglist" multiple="true" />
      <do_all exact="$shoppinglist.count" counter="$c">
        <set_value name="$tradeorder" exact="$shoppinglist.{$c}" />
        <do_if value="$tradeorder.seller.exists">
          <add_ware_reservation object="$tradeorder.seller" result="$reserved" ware="$tradeorder.ware" entity="this" amount="0" />
          <do_if value="$reserved" min="$tradeorder.amount">
            <add_ware_reservation object="$tradeorder.seller" ware="$tradeorder.ware" entity="this" amount="$reserved" replace="true" duration="5h" />
          </do_if>
          <do_else>
            <add_ware_reservation object="$tradeorder.seller" ware="$tradeorder.ware" entity="this" amount="$tradeorder.amount" duration="5h" />
          </do_else>
        </do_if>
        <do_elseif value="not $tradeorder.unbundle">
          <add_ware_reservation object="$tradeorder.buyer" result="$reserved" ware="$tradeorder.ware" entity="this" amount="0" />
          <do_if value="$reserved" min="$tradeorder.amount">
            <add_ware_reservation object="$tradeorder.buyer" ware="$tradeorder.ware" entity="this" amount="$reserved" replace="true" duration="5h" />
          </do_if>
          <do_else>
            <add_ware_reservation object="$tradeorder.buyer" ware="$tradeorder.ware" entity="this" amount="$tradeorder.amount" duration="5h" />
          </do_else>
        </do_elseif>
      </do_all>
After a couple hours writing a reformatter:

Code: Select all

@aiscript (priority = 60)
def trade_performplayertraderun (debugchance = 0):
    # debugging 
    failreason = ''
    
    wait (max = "2s", min = "1s")
    
    # get top item from shopping list 
    label .check_shoppinglist
    shoppinglist = get_trade_from_shoppinglist (multiple = True, object = "this.ship")
    for c in range(shoppinglist.count):
        tradeorder = shoppinglist[c]
        if tradeorder.seller.exists:
            reserved = add_ware_reservation (amount = 0, entity = "this", object = "tradeorder.seller", ware = "tradeorder.ware")
            if reserved:
                add_ware_reservation (amount = "reserved", duration = "5h", entity = "this", object = "tradeorder.seller", replace = True, ware = "tradeorder.ware")
            else:
                add_ware_reservation (amount = "tradeorder.amount", duration = "5h", entity = "this", object = "tradeorder.seller", ware = "tradeorder.ware")
        elif not tradeorder.unbundle:
            reserved = add_ware_reservation (amount = 0, entity = "this", object = "tradeorder.buyer", ware = "tradeorder.ware")
            if reserved:
                add_ware_reservation (amount = "reserved", duration = "5h", entity = "this", object = "tradeorder.buyer", replace = True, ware = "tradeorder.ware")
            else:
                add_ware_reservation (amount = "tradeorder.amount", duration = "5h", entity = "this", object = "tradeorder.buyer", ware = "tradeorder.ware")
Or maybe this looks better:

Code: Select all

@aiscript (priority = 60)
def trade_performplayertraderun (debugchance = 0):
    # debugging 
    failreason = ''
    
    wait (
        max = "2s",
        min = "1s",
    )
    
    # get top item from shopping list 
    label .check_shoppinglist
    shoppinglist = get_trade_from_shoppinglist (
        multiple = True,
        object = "this.ship",
    )
    for c in range(shoppinglist.count):
        tradeorder = shoppinglist[c]
        if tradeorder.seller.exists:
            reserved = add_ware_reservation (
                amount = 0,
                entity = "this",
                object = "tradeorder.seller",
                ware = "tradeorder.ware",
            )
            if reserved:
                add_ware_reservation (
                    amount = "reserved",
                    duration = "5h",
                    entity = "this",
                    object = "tradeorder.seller",
                    replace = True,
                    ware = "tradeorder.ware",
                )
            else:
                add_ware_reservation (
                    amount = "tradeorder.amount",
                    duration = "5h",
                    entity = "this",
                    object = "tradeorder.seller",
                    ware = "tradeorder.ware",
                )
        elif not tradeorder.unbundle:
            reserved = add_ware_reservation (
                amount = 0,
                entity = "this",
                object = "tradeorder.buyer",
                ware = "tradeorder.ware",
            )
            if reserved:
                add_ware_reservation (
                    amount = "reserved",
                    duration = "5h",
                    entity = "this",
                    object = "tradeorder.buyer",
                    replace = True,
                    ware = "tradeorder.ware",
                )
            else:
                add_ware_reservation (
                    amount = "tradeorder.amount",
                    duration = "5h",
                    entity = "this",
                    object = "tradeorder.buyer",
                    ware = "tradeorder.ware",
                )
Of course it needs a fair amount of work on evaluating expressions to pick out nested variables and such, according to MD rules, and a lot of other little things would need sorting out as well; 2-3 hours only covers so much, especially without any experience Rebirth modding. :)

You might notice the second form is in python syntax. If you slap a framework behind it with various node definitions, code writing can then be done in any nice python IDE (pycharm, visual studio, etc.) with the usual autocompletions and documentation popups and such. Scripts would also be runnable as python code, though initially it would probably just be for some logic checks. Eventually, functional test support could be added.

Conversion from python back to MD xml would be slightly tougher, since it would take some ast parsing, but isn't that big of a deal (python makes it really easy to do ast traversal). All sorts of functionality can be injected into the reverse conversion, like compilation warnings/errors if node fields look wrong, function inlining, debug code injection or pruning, dead code removal, etc.
Author of X3 Customizer

User avatar
LittleBird
Posts: 703
Joined: Mon, 19. Dec 11, 03:02

Post by LittleBird » Mon, 16. Apr 18, 18:25

X2-Illuminatus wrote:I think you are too focussed on using level design gameplay in a sandbox. While in some instances in story telling it's beneficial to have independent areas (and again this has been done in previous X games already), it's by no means necessary to create content. You also do not have to take care of everything possible in that sandbox. In any way, the biggest obstacle to proper mission design is the player, finding ways around what you carefully planned before.
"level design gameplay"... I think that describes it really good.
By looking for game balance and posibilities I mean stuff like "massive Xenon invasion in Argon Prime". If we would have an easy to use tool many players would create... everything and everything is not practical in a sandbox.
JSDD wrote: if you really want to create missions, you have to start learning the language, it took me a long time (i dunno, at least 1year with almost no experience in programming except c++ basics, which doesnt help you much in terms of MD) to understand how to script stuff in x3. you`ve got to invest a bunch of time into that before you can create awesome stuff / missions / plugins / whatever ...
This is just not practical.
The idea should make it possible that many players can create content.
Killjaeden wrote: The main problem with it is the considerable time it would take to create this tool and have it run reliably. And it would of course still require people to learn it anyway. It might be quicker to learn than script. But once a beginner understand mission structure and all that - he might discard the tool and use text instead (whatever is more time efficient ).
I disagree in the last point.
The tool would be allways faster and more time efficient. That is its purpose.
But the tool is limited and for more complicated stuff experienced user would switch to coding. So it would be great if the tool could show you the code. This would also helps in learning it.
Killjaeden wrote: So this problem is, i think, more efficiently tackled with didactically better tutorials sound that go into all the basics of 1) mission structure in MD in general 2) structure in script s 3) concrete examples that break down a mission into it's components, explaining what is what and why.
I am sure that would help existent modding and scripting community. But face the truth it very unlikely that new people would take on what JSDD above described.



Sooooo my conclusion for this thread.

- Tool creation and support is to time consuming for realization.
- MD learning is very time consuming and it is unrealistic it could attract many players... even with a better documentation.

- The idea of independent areas for more level design like missions collides with the sandbox aspect.
- I still believe it would extent the design possibilities compared to sandbox missions. And I still believe it would be a great way to fill empty space with the help of the community.
Ich bin für die Einführung von Ironie- und Sarkasmustags.
Alle Klarheiten beseitigt!

User avatar
Ketraar
Moderator (DevNet)
Moderator (DevNet)
Posts: 8759
Joined: Fri, 21. May 04, 17:15
x4

Post by Ketraar » Mon, 16. Apr 18, 19:01

LittleBird wrote:- MD learning is very time consuming and it is unrealistic it could attract many players... even with a better documentation.
Here I think you are skewing the notion a bit. I doubt a mission tool will attract new players, it arguably would inspire existing players to create missions sure, but I think those that have the drive to create content usually find a way to do it, with more or less effort.

I'd also argue that the MD coding itself is pretty easy to learn, with existing documentation and tools. Cant speak too much about XR MD, but I think its not much different, in that the struggle to "learn MD" is to know how the game ticks. Its far more important imho to know the inner workings of the game's logic (Jobs, map design, assets, voices, text, etc) then MD itself, since it will be important to know when to make use of what and the impact that will have in the "universe".

Now if we were to just able to magically wish a tool into existence, I'd wish for it to be able to cross ref assets, so that one could say "make a Paranid actor" and it would create all the needed lines for a working NPC, that just needs lines fed, that would be nice.

MFG

Ketraar

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

Post by UniTrader » Tue, 17. Apr 18, 00:00

LittleBird wrote:
Killjaeden wrote: The main problem with it is the considerable time it would take to create this tool and have it run reliably. And it would of course still require people to learn it anyway. It might be quicker to learn than script. But once a beginner understand mission structure and all that - he might discard the tool and use text instead (whatever is more time efficient ).
I disagree in the last point.
The tool would be allways faster and more time efficient. That is its purpose.
But the tool is limited and for more complicated stuff experienced user would switch to coding. So it would be great if the tool could show you the code. This would also helps in learning it.
he meant the effort for egosoft (or whomever) to create such a tool, not the effort for the user which you refer to :roll: also why create such a Tool in the first place if it can only cover the simpler stuff if you have to switch to the already existing tool if you want to do more?

@Ketrar
for me a one-eyed Paranid please :D


@SirNukes
what you converted was an AI Script, which is similiar in many aspects to MD but not the same (it controls Ships and such stuff, but is not usedl for Missions), and compared to MD is pretty "classic" flow-wise.
try the same for any File in the md directory (best something really Mission-related). i guess this will turn out to be pretty complicated to convert because of the possibly many event conditions and parallel stuff happening...
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 ;)

User avatar
Killjaeden
Posts: 5035
Joined: Sun, 3. Sep 06, 18:19
x3tc

Post by Killjaeden » Tue, 17. Apr 18, 01:52

SirNukes wrote: For fun, I spitballed some code to convert MD xml to something slightly more recognizable.
Thank you very much for this efford. I personally think XML is eyecancer... and i would never get within 10m of "MD" if i had to deal with xml BS. I will never understand why they would chose xml over any other "language style" to embedd their script language in, especially for missions - and then also advertise it as beginner friendly...
I'm not a programmer by profession, but i can read and write c and python code (and "X3 script") just fine, because it's logical, clean and structured. "X3 script" was so easy to use with the script editor that it motivated me to write some smaller stuff on my own back in the days. XML has the opposite effect. XML is structured but ridiculously cluttered... obfuscating the real content with "fancy" tree structures and <word>tags</word>, wasting everyones space and time.

But we already had this topic i think a while ago... and that ship has already sunk, its not going to resurface differently anymore.

Edit: 5000th post. Celebrations. Insanity.
Image
XTC Mod Team Veteran. My current work:
Image

User avatar
Ketraar
Moderator (DevNet)
Moderator (DevNet)
Posts: 8759
Joined: Fri, 21. May 04, 17:15
x4

Post by Ketraar » Tue, 17. Apr 18, 02:15

Killjaeden wrote:"X3 script" was so easy to use with the script editor that it motivated me to write some smaller stuff on my own back in the days. XML has the opposite effect. XML is structured but ridiculously cluttered... obfuscating the real content with "fancy" tree structures and <word>tags</word>, wasting everyones space and time.
Guess we are opposite then. As a non programmer I found and still find that SE is just a nonsensical mess made by aliens and I just could never get through it, whereas MD cklicked pretty fast and still make more sense to me than any SE script. Mostly because one can actually read the MD script and see what it does, especially for (linear) Missions its like reading a storyboard.

That one can do ridiculous stuff with MD that is convoluted and frankly not really intended to be done using it, is just a nice bonus.
Edit: 5000th post. Celebrations. Insanity.
Welcome to the spammer club. :-P

MFG

Ketraar

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

Post by SirNukes » Tue, 17. Apr 18, 07:14

I gave a mission script a shot. It took a bit longer than I would like, mostly fiddling with different ways it could be displayed (actually getting it to parse was fine, it was just not satisfying my goals).

While not perfect, here an example snippet taken from the start of 'GM_Escort_Ships.xml' (with a little comment pruning for space), since I figure a ship escort should be reasonably complicated. The best cleanup comes later once cues get more complicated, but that is mostly just repeating what is shown in the AI script.

Code: Select all

<?xml version="1.0" encoding="utf-8"?>
<mdscript name="GM_Escort_Ships" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="md.xsd">
  <cues>

    <cue name="Force_Generic" instantiate="true">
      <conditions>
        <event_cue_signalled/>
      </conditions>
      <actions>
        <signal_cue cue="md.GenericMissions.RemoveAllOffers"/>
      </actions>
      <force name="GM_Escort_Ships"/>
      <cues>
        <cue name="Force_Generic_Signals">
          <delay exact="1s"/>
          <actions>
            <do_all exact="25">
              <signal_cue_instantly cue="md.GM_Escort_Ships.StartGeneric" param="100"/>
            </do_all>
          </actions>
        </cue>
      </cues>
    </cue>

    <cue name="StartGeneric" instantiate="true" namespace="this">
      <conditions>
        <check_any>
          <check_all>
            <!--Generic Mission Case (If this cue is to be signalled by other sources, add a parameter to differentiate)-->
            <!--signal_cue_instantly - event.param = $DebugChance 0 to 100-->
            <event_cue_signalled />
            <check_value value="player.sector"/>

            <!--No need to look for a destination station just yet. That will be handled in the variation checks-->
            <count_stations space="player.sector" min="1" canhaveofferlocation="tag.mission" result="$missionstations">
              <match_relation faction="faction.player" comparison="not" relation="enemy" />
              <match owner="faction.player" negate="true" />
              <match owner="null" negate="true"/>
              <match_distance object="player.primaryship" max="md.$MaxMissionOfferDistance" />
            </count_stations>
          </check_all>

          <check_all>
            <event_player_mission_opportunity/>
            <check_value value="false"/>
            <!--TODO: Filter what opportunities trigger this mission-->
          </check_all>
        </check_any>
      </conditions>
      <actions>
        <!--***event_cue_signalled case***-->
        <do_if value="event.name == 'event_cue_signalled'">
          <set_value name="$missionstation" exact="static.$missionstations.{md.$RandomIdx}"/>
          <set_value name="$EventOffer" exact="false"/>

          <set_value name="$DebugChance" exact="@event.param"/>
        </do_if>

        <do_elseif value="event.name == 'event_player_mission_opportunity'">
          <set_value name="$missionstation" exact="event.param"/>
          <set_value name="$EventOffer" exact="true"/>

          <set_value name="$DebugChance" exact="0"/>
        </do_elseif>
      </actions>
      <cues>
        <cue name="StartRef" ref="md.GM_Escort_Ships.Start">
          <param name="MissionStation" value="$missionstation" />
          <param name="EventOffer" value="$EventOffer"/>

          <param name="DebugChance" value="$DebugChance"/>
        </cue>
      </cues>
    </cue>

Code: Select all

@mdscript ()
def GM_Escort_Ships ():
    
    @cue (instantiate = True)
    def Force_Generic ():
        if(
            event_cue_signalled ()
        ):
            signal_cue (cue = md.GenericMissions.RemoveAllOffers)
            force (name = GM_Escort_Ships)
    
            @cue (delay = 1s)
            def Force_Generic_Signals ():
                for _ in range(25):
                    signal_cue_instantly (
                        cue = md.GM_Escort_Ships.StartGeneric, 
                        param = 100)
    
    @cue (instantiate = True, namespace = this)
    def StartGeneric ():
        if(
            (
                #Generic Mission Case (If this cue is to be signalled by other sources, add a parameter to differentiate)
                #signal_cue_instantly - event.param = $DebugChance 0 to 100
                event_cue_signalled ()
                and Player_is_not_in_highway()
                
                #No need to look for a destination station just yet. That will be handled in the variation checks
                and count_stations (
                    canhaveofferlocation = tag.mission, 
                    min = 1, 
                    result = missionstations, 
                    space = player.sector, 
                    options = [
                        match_relation (
                            comparison = not, 
                            faction = faction.player, 
                            relation = enemy),
                        match (
                            negate = True, 
                            owner = faction.player),
                        match (
                            negate = True, 
                            owner = None),
                        match_distance (
                            max = md.MaxMissionOfferDistance, 
                            object = player.primaryship),
                    ])
            )
            
            or (
                event_player_mission_opportunity ()
                and False
                #TODO: Filter what opportunities trigger this mission
            )
        ):
            #***event_cue_signalled case***
            if event.name == 'event_cue_signalled':
                missionstation = static.missionstations[md.RandomIdx]
                EventOffer = False
                
                DebugChance = @event.param
            
            elif event.name == 'event_player_mission_opportunity':
                missionstation = event.param
                EventOffer = True
                
                DebugChance = 0
    
            @cue ()
            def StartRef ():
                Cue_Ref("md.GM_Escort_Ships.Start", 
                    MissionStation = missionstation,
                    EventOffer = EventOffer,
                    DebugChance = DebugChance,
                )
Now, this could be cleaned up more visually, but I was aiming for something a little ambitious: by laying out cues as defined functions, they could potentially be dropped into a python model of the MD engine for running unit tests in a simulated environment (through some tricks with generator functions). Not that I plan to set that up (it would take a while), but I like to shoot for hard targets.

Some other things to note:
- This is still spitballed code; I'd probably reorganize it into a proper project if I wanted to keep going (and probably open it to community development).
- I don't know what a lot of the functionality is of the various nodes; my layout decisions could certainly be better with understanding, not to mention more development time.
- Is there documentation on the MD nodes somewhere outside the schema? Maybe with updates for X4? My main reference is an X3:AP pdf I have sitting around (which came from Phil's desktop in 2012).
- For fun, "<check_value value="player.sector"/>" was translated to "Player_is_not_in_highway()" after checking documentation, as an example of how splitting the run-time and coding layers gives opportunities to add clarity. Its a very short hop to Create_One_Eyed_Paranid(you_monster).

nemesis1982
Posts: 762
Joined: Wed, 29. Oct 08, 13:10
x4

Post by nemesis1982 » Tue, 17. Apr 18, 09:56

I think creating a workflow based tool would actually be beneficial for this and might drastically improve readability and time needed to create scripts.

Now I'm not saying you wouldn't be seeing the XML at all. The workflow block would still contain the XML however they'd be reusable if setup right.

Simply throwing something this together shouldn't be to difficult. Making it stable, complete and fool proof that's where the effort comes.
Save game editor XR and CAT/DAT Extractor
Keep in mind that it's still a work in progress although it's taking shape nicely.

If anyone is interested in a new save game editor for X4 and would like to contribute to the creation of one let me know. I do not have sufficient time to create it alone, but if there are enough people who want it and want to contribute we might be able to set something up.

User avatar
LittleBird
Posts: 703
Joined: Mon, 19. Dec 11, 03:02

Post by LittleBird » Tue, 17. Apr 18, 13:58

Ketraar wrote:
LittleBird wrote:- MD learning is very time consuming and it is unrealistic it could attract many players... even with a better documentation.
Here I think you are skewing the notion a bit. I doubt a mission tool will attract new players, it arguably would inspire existing players to create missions sure, but I think those that have the drive to create content usually find a way to do it, with more or less effort.
Not necessarily new players but new content creators who need are lower barrier for entry.
Ketraar wrote: I'd also argue that the MD coding itself is pretty easy to learn, with existing documentation and tools. Cant speak too much about XR MD, but I think its not much different, in that the struggle to "learn MD" is to know how the game ticks.
It is strange that the estimation of the difficulty varies from:
"it took me a long time (i dunno, at least 1year with almost no experience in programming" (JSDD)
to
"MD coding itself is pretty easy to learn, with existing documentation and tools"
Looking at the code presented here I tend to JSDD's view.
Ketraar wrote: Now if we were to just able to magically wish a tool into existence, I'd wish for it to be able to cross ref assets, so that one could say "make a Paranid actor" and it would create all the needed lines for a working NPC, that just needs lines fed, that would be nice.
Do you mean something like the format editor here? Press the button and you have the... well "code" plus structure?
UniTrader wrote:
LittleBird wrote:
Killjaeden wrote: The main problem with it is the considerable time it would take to create this tool and have it run reliably. And it would of course still require people to learn it anyway. It might be quicker to learn than script. But once a beginner understand mission structure and all that - he might discard the tool and use text instead (whatever is more time efficient ).
I disagree in the last point.
The tool would be allways faster and more time efficient. That is its purpose.
But the tool is limited and for more complicated stuff experienced user would switch to coding. So it would be great if the tool could show you the code. This would also helps in learning it.
he meant the effort for egosoft (or whomever) to create such a tool, not the effort for the user which you refer to
You are mistaken. He meant both. And I disagreed with his last point that the code would be more time efficient.
UniTrader wrote: also why create such a Tool in the first place if it can only cover the simpler stuff if you have to switch to the already existing tool if you want to do more?
To get the hang of it. To make the first steps less scary. To allow a wider range of user to create mission content.
Ich bin für die Einführung von Ironie- und Sarkasmustags.
Alle Klarheiten beseitigt!

User avatar
Ketraar
Moderator (DevNet)
Moderator (DevNet)
Posts: 8759
Joined: Fri, 21. May 04, 17:15
x4

Post by Ketraar » Tue, 17. Apr 18, 15:21

LittleBird wrote:It is strange that the estimation of the difficulty varies from:
"it took me a long time (i dunno, at least 1year with almost no experience in programming" (JSDD)
to
"MD coding itself is pretty easy to learn, with existing documentation and tools"
Looking at the code presented here I tend to JSDD's view.
Well I disagree. As I said in more detail, learning the structure and function of the MD takes about 10-20h to understand. Create_cue, add conditions, actions, close up stuff, done.

The tricky part is to know how the GAME reacts to it, what are the things you can influence, how to create conversations with NPC, which text is spoken and which is not, etc etc etc. This has little to do MD though as its stuff you would need to know for other modding scenarios, say using the SE. Which is my point, the entry difficulty is high due to the games complexity and the shear amount of stuff that is interconnected and can be influenced.

I'd argue that even a person that has not coded MD one bit will be able to open a Plot file and understand how the plot unfolds just be reading the xml lines. Many non MD coders have extracted information from MD files since the MD came out. This is a good indication that the MD itself is pretty simple to understand.
Do you mean something like the format editor here? Press the button and you have the... well "code" plus structure?
Tbh I dont know, as I said, I'm no programmer, all I can say is what the expected outcome could look like for this wishful-thinking tool.

MFG

Ketraar

User avatar
Killjaeden
Posts: 5035
Joined: Sun, 3. Sep 06, 18:19
x3tc

Post by Killjaeden » Tue, 17. Apr 18, 19:50

Dynamic sandbox missions can become really convoluted and messy, compared to linear missions. You can't just spawn stuff or hardcode a specific location (e.g. a station) in a fully dynamic world. The missions need to draw almost everything from the running game by evaluating current state via conditions (Example: Find me a ship that is a trader, has no cargo, is on route to station Y - whereby Y is a factory with ressource deficit in a friendly sector, has no ships landed, etc etc) Lots of conditions. And lots of conditions means it can get extremely nested and complicated.

This is where "node tools" come in super handy to visualize very complex structures in a lot more digestable format than with pure text. Arma uses FSM tools for AI scripts, because AI need to check for a lot of conditions, so a script in pure text form becomes really nested and convoluted -> hard to read.
AI example,Mission logic example

Imagine these examples in pure textform. Yeah you could totally write those. But how long will someone else take to fully understand it then? Or how long will you take until you understand what you did, once you have put the mission aside for a few weeks?
LittleBird wrote:You are mistaken. He meant both. And I disagreed with his last point that the code would be more time efficient.
My point was that the user will use whatever is more time efficient - in accordance with his skill level. If the tool is more efficient than writing code in text editor, most people will use that. If not, beginners will use the tool (most likely) and discard it later on.
Image
XTC Mod Team Veteran. My current work:
Image

User avatar
Ketraar
Moderator (DevNet)
Moderator (DevNet)
Posts: 8759
Joined: Fri, 21. May 04, 17:15
x4

Post by Ketraar » Tue, 17. Apr 18, 20:33

Thats why there are Libraries where you can define these "search parameters" (or anything else that repeats often) for reusage (I know its not a word, before the spelling police pesters me again). :-)

MFG

Ketraar

User avatar
JSDD
Posts: 890
Joined: Fri, 21. Mar 14, 21:51
x3tc

Post by JSDD » Tue, 17. Apr 18, 23:43

@littlebird:
without a tutorial, a documentation you can read / get, figuring out how MD works is like going to the pyramids in egypt and trying to read hieroglyphs ;)

you dont know if and how you can insert / remore code words, how to even begin ... where are the possible code words listed, what the hell is "auto-complete" and what is "visual web developer" (maybe a job descriptiion ?? ^^) thats how i started to learn MD ...

whats important:
--> a well documented scripting language (by egosoft)
--> a getting started guide, some little examples / tutorials
--> tools to validate / type-check the mess you wrote (thats where xml comes in handy, but still ... eyecancer-ish to read)


one might say that even the procedural code can be as nested as the MD, stuff, BUT you (often) can re-write that into not-soo-nested code easily:

Code: Select all

while true

if (A and B == C)
{
   if (D or E)
      dosomething();
}
else dosomethingelse();

endwhile
rewritten to:

Code: Select all

while true

// un-nest this case
if not (A and B == C)
{
   dosomethingelse();
   continue; // jump back and ignore the rest ...
}

// un-nest that case
if (D or E)
{
   dosomething();
   continue; // jump back and ignore the rest ...
}

// and so on ...


endwhile
even better, gosub endsub is available to wrap sub functions away from the bigger picture. thats another thing which isnt possible n MD (at least in x3 as far as i`m aware of, library cues arent comparable to that, @call script is another type of wrapping away code parts by reusability [or just to make code readable])

this type of writing code (filtering first all the abort-conditions) is my favourite and allows you to handle each abort case without having to add a new cue which takes care of cancelling all the others (just in case), and hopefully not 2 parallel cues do the same job at the same time resulting in undefined behavior (and debugging that mess afterwards) ... a mess! you cant really use that xml / MD language to build a big & complex system in a way so that a year later, littlebird can modify it in a way she/he wants to (maybe to improve it) because nobody will be able (and willing !!) to read that mess anymore
To err is human. To really foul things up you need a computer.
Irren ist menschlich. Aber wenn man richtig Fehler machen will, braucht man einen Computer.


Mission Director Beispiele

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

Post by UniTrader » Wed, 18. Apr 18, 00:45

@SirNukes
your conversion is very, very inaccurate. <conditions> are very diffrent from a <do_if/> if they are events. Event Conditions dont check something periodically, rather they leave a marker on the Object of intrest that they want to know when something happens and then go to sleep until said object tells them the Event they waited for has just happened. (in case of <check_value/> it might apply in a limited way because these are checked on events or periodically, but you still leave out the cue states entirely which makes any simulation you might try invalid if these are relevant, which is often the case even if not used explicitly)


JSDD wrote:even better, gosub endsub is available to wrap sub functions away from the bigger picture. thats another thing which isnt possible n MD (at least in x3 as far as i`m aware of, library cues arent comparable to that, @call script is another type of wrapping away code parts by reusability [or just to make code readable])
not sure why a lib cue doesnt fit for you, but you also have the option of putting said code in another cue and <signal_cue/>
JSDD wrote:this type of writing code (filtering first all the abort-conditions) is my favourite and allows you to handle each abort case without having to add a new cue which takes care of cancelling all the others (just in case),
If you do a Mission properly each instance of it should have its own root cue instance. cancelling this instance also cancels/removes all sub-cues of it. And you can put as many abort conditions as you want in a single abort cue, no need to make extra cues for that (except maybe the cleanup actions differ wildly)
JSDD wrote: and hopefully not 2 parallel cues do the same job at the same time resulting in undefined behavior (and debugging that mess afterwards) ... a mess!
if you do the same job in 2 cues you do something wrong. as said before you can put said actions in a seperate cue and signal it for each case its needed. if it is not instantiated or resets itself this even takes care that its actions are only performed once if desired.

JSDD wrote:you cant really use that xml / MD language to build a big & complex system in a way so that a year later, littlebird can modify it in a way she/he wants to (maybe to improve it) because nobody will be able (and willing !!) to read that mess anymore
your opinion. i find it really nice that all the conditions for an event are directly next to the actions it causes - which is very diffrent from the lua files for the UI where you have to go to an entirely diffrent section of the file (scrolling down to almost the bottom to find out under what conditions the code in the top third is performed) - that is a mess i tell you...
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 ;)

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

Post by SirNukes » Wed, 18. Apr 18, 02:50

UniTrader wrote:@SirNukes
your conversion is very, very inaccurate. <conditions> are very diffrent from a <do_if/> if they are events. ...
Interesting. As mentioned, it is just spitballed code by someone who hasn't worked with the Rebirth MD (or much with the X3 MD). That said, I took a look at the short Rebirth MD overview document, and I don't think anything needs to change in the example python representation. Logically, the conditions do map to an If construct.

If you are curious on how simulation might work: the @cue decorator would find the event triggers on function construction (ast parsing probably is the most reliable), and would then handle cue state annotation, registering the cue with the system, etc. Runtime handling of events would briefly set their corresponding value to True while calling each of their attached cues, so that the If conditions evaluate as might be expected by any user who has a breakpoint attached.

The more I think about it, the more compelled I am to put it together for lols. :) (Or to utterly fail and learn from the experience; either is good with me.)

Post Reply

Return to “X4: Foundations”