X
 
  • Filtre
  • Heure
  • Afficher
Tout nettoyer
nouveaux messages

  • Script et Cie

    PRINCIPES DE BASE




    Qu'est ce qu'un script ?
    Un script est un fichier de code, ou une partie de ce code qui va avoir une action spécifique. Scripter ou scripting c'est créer un script.
    La différence entre codding et scripting ? Le codding (comme par exemple les symboles des factions, les bâtiments, les unités recrutables) est toujours le même ; il est codé au départ, et ne changera pas durant le jeu. Le script est justement ce qui va être soumis au "hasard", et donc ne pas se répéter de la même manière (exemple : les traits de caractères des personnages dépendent de leurs actes).
    Les scripts s'appliquent aussi bien à la carte de campagne qu'à celle des batailles.


    Les scripts dans Medieval 2 total war
    Ils se trouvent principalement dans 5 fichiers :
    - campaign_script (data/world/maps/campaign/imperial_campaign/), il sert presque à tout
    - export_descr_ancillaries (dans data), pour gérer les suites des personnages
    - export_descr_character_traits (dans data), pour gérer les traits des personnages
    - descr_faction_standing (dans data), pour les relations entre factions
    - export_descr_guilds (data), pour les attributions des guildes
    Avant toutes modifications, veuillez bien sauver le fichier initial, car la moindre erreur peut tout faire planter. Heureusement le log généré vous indiquera souvent les erreurs de base à corriger.
    Les scripts sont générés pour chaque début de campagne, ainsi si vous les changez impossible de profiter de ces changements sans recommencer une partie.
    Campaign script est de loin le plus utile de ces fichiers. Il est généré au lancement de la partie et fonctionnera jusqu'à sa fin, restant sauvé dans la sauvegarde de la partie.


    De quoi se compose un script ?
    Si vous avez déjà moddé des jeux vous connaissez le principe des déclencheurs ; condition définie => effet si condition remplie. C'est exactement la même chose, en plus complexe.

    I ]CAMPAIGN_SCRIPT

    Si l'on ouvre campaign script vanilla, que voit-on ? Bien sûr je raccourcis et ne garde que le début et la fin.
    Code:
    ;
    ; Campaign script
    ;
    script
    ; ---------------------
    ; counters
     
     declare_counter Opened_Faction_Overview_Scroll
     declare_counter Opened_Settlement_Scroll
    [.....]
    wait_monitors
    end_script
    1) SCRIPT et END_SCRIPT
    "script" et "end_script" délimitent le script de la campagne. C'est dans cet espace que le jeu cherchera les données à tester. Donc c'est un code incontournable pour campaign script.
    Les ; (points virgules) servent à inactiver une ligne ; en effet le jeu teste les scripts ligne après ligne ; si un ";" se trouve dans une ligne, cette ligne ne sera pas prise en compte et n'aura donc aucune incidence sur le jeu. Cela sert donc à inactiver des phrases comme "ici commence le script de monnaie" ou "ce mod est du au génial Caulaincourt". Bref vous pouvez écrire ce que vous voulez tant qu'un ";" commence une ligne. Notez que dans la pratique, l'accumulation de scripts rend appréciable le ";" pour nommer les scripts pour mieux les identifier.
    Le "wait_monitors" indique au jeu de ne rien faire jusqu'à ce que tout le script ait été testé. Les monitors seront abordés plus bas.
    Quant aux "declare_counter ", ce sont des codes de script, un par ligne (le jeu lit le fichier ligne après ligne, suivez donc un peu !).

    2) MONITORS
    Donc votre script est délimité par script et end_script. Il va falloir le remplir. C'est la que le monitor (c'est l'élément de base du script qui contient des conditions et des effets) intervient. Il existe deux types de monitors ;
    - monitor_event
    - monitor_conditions
    Le premier va voir ses conditions testées lors d'un "event" (càd un moment précis du jeu, comme par exemple la fin d'un tour, la construction d'un bâtiment, etc...) alors que le second verra ses conditions testées en permanence, de sorte que dès qu'elles seront vérifiées ses effets seront déclenchés. Souvent on utilise le monitor_events.
    Un monitor contient comme dit précédemment des conditions et des effets. Voici un schéma simplifié :
    Code:
    monitor_event <Event>  <Condition>
           <Effet>
    end_monitor
    Lorsque l'Event a lieu, le jeu teste la condition ; si elle est vraie (=vérifiée=juste) alors l'effet a lieu.
    Mettons un bel exemple que tous les français comprendront aisément. Transformons medieval 2 en match de rugby france/angleterre. Si l'event est un essai anglais, la condition un supporter anglais exultant de joie, et l'effet une claque dans sa g...., alors à chaque fois qu'un anglais marquera un essai, le jeu vérifiera si un supporter anglais crie sa joie ; et si c'est le cas, il se prendra une bonne correction cet arrogant. Voilà l'idée générale.

    Code:
    monitor_conditions   <Condition>
          <Effet>
    end_monitor
    Avec un monitor_conditions, le supporter se prendra une claque dès qu'il criera de joie, essai ou pas.
    Vous allez me dire : "pourquoi on ne fait pas que des monitors_conditions, ils sont plus simples ?!" Certes, mais comme ils sont testés en permanence il font ramer le jeu. Alors que les monitors_event ne sont testés qu'à des moments précis.
    Le "end_monitor" sert tout simplement à délimiter la fin du monitor. A indiquer que les effets s'arrêtent à cette ligne. Après vous pouvez mettre votre wait_monitors et votre end_script si vous estimez qu'un seul monitor suffit, on alors un autre monitor.
    A chaque fois que les conditions seront justes le monitor se déclenchera. Il peut donc se répéter en permanence tour après tour si les conditions restent justes. Cependant vous pouvez aussi choisir de ne le laisser se déclencher qu'une seule fois. il suffit de rajouter "terminate_monitor" juste avant le "end_monitor".
    Code:
    monitor_conditions   <Condition>
          <Effet>
    terminate_monitor
    end_monitor
    Lorsque la condition sera juste, l'effet aura lieu ; si jamais la condition redevient juste ensuite, il n'y aura plus d'effet, car le terminate monitor signifie au jeu de ne plus tester ce monitor ; un seul déclenchement est possible.


    II ]AUTRES FICHIERS

    Les autres fichiers de script ne nécessitent pas de "script" / "end_script" ni de monitors. Il suffit de regarder la structure et de l'imiter. Leur logique est la même, seule les formulations changent. Nous traîterons de leur forme et de leur coddage plus bas.


    Typographie

    Les scripts ont toujours une drôle d'allure. Des espacements assez déconcertants, des ";", etc... Cependant ils sont simples à comprendre.
    Les codes ne s'improvisent pas, ce sont ceux des développeurs du jeu. Comme ils sont nombreux, on les trouve dans un fichier appelé "docudemons". Téléchargeable ici, et indispensable. Il contient plusieurs renseignements sur le codding, mais seuls "commands" (liste des effets), "conditions" (liste des conditions) et "event" (liste des events) nous intéressent.
    I ]CAMPAIGN_SCRIPT
    Si je veux plusieurs effets pour un même event, il suffit de les rajouter à raison d'un par ligne, jusqu'au end_monitor.
    Code:
    monitor_conditions   <Condition 1>
          <Effet 1>
          <Effet 2>
    end_monitor
    Mais si je veux plusieurs conditions ? Je ne peux pas procéder de la même façon, en mettant <condition 2> en dessous de <condition1>, car le jeu la prendrait pour un effet. Il faut lier les conditions entre elles, et pour cela, on utilise le "and". Démonstration :
    Code:
    monitor_conditions   <Condition 1>
          and <Condition 2>
          <Effet 1>
          <Effet 2>
    end_monitor
    On peut rajouter autant de "and" que l'on veut. Dans le cas ci-dessus, le script ne sera déclenché que si les deux conditions sont vraies en même temps.
    Enfin, un autre petit accessoire d'écriture, le "not". Il sert... à nier les conditions ! qui l'eût cru ? Un exemple tout simple :
    Code:
    monitor_conditions   <Condition 1>
          and not <Condition 2>
          <Effet 1>
          <Effet 2>
    end_monitor
    Cette fois, le script ne sera déclenché et les effets appliqués que si <condition 1> est vraie, et si <condition 2> n'est pas vraie au même moment.
    En résumé, ce qui compte :
    - respecter les espacements entre les mots d'une même ligne (svt un seul espace)
    - les lignes sont lues à la suite les unes des autres ; si la ligne commence par monitor_event le jeu sait que juste après il doit trouver un <event>, puis ensuite (après 1 espace) une <condition>. Après cela le jeur revient à la ligne pour lire la suite.
    - un ";" annule la lecture de la ligne
    - des lignes sautées ne changent rien à la lecture, tout comme les écartements (nombre d'espaces) avant le premier mot d'une ligne. Si je mets mes effets en décalage par rapport au début des lignes, c'est uniquement pour aérer et mieux visualiser les composants du script.

    II]AUTRES FICHIERS
    Quelle est la mise en forme des autres fichiers de script ?
    Tout d'abord, sachez que si elle diffère de celle de campaign_script, elle est la même dans tous les autres fichiers. Vous trouverez ce genre de script :
    Code:
    ;------------------------------------------
    Trigger <nom du déclencheur>
     WhenToTest  <event>
     Condition <condition 1>
        and <condition 2>
     <Effet 1>
    Comme vous le voyez, les éléments sont les mêmes que dans campaign_script, seule la disposition est différente. Tout d'abord chaque ensemble s'appelle un trigger et non un monitor ; et ce trigger porte un nom spécifique. Ce nom du déclencheur, c'est à vous de l'inventer. Ce que vous voulez, tant qu'il est en un seul bloc (ainsi on doit avoir "tintin_et_milou" et non "tintin et milou"). Il permet juste d'identifier le trigger.
    "WhenToTest" a exactement la même fonction qu'un "monitor_event" ; juste après on indique lors de quel event doit se tester le script.
    "Condition" introduit les conditions ; notez qu'il faut espacer d'un espace condition et <condition 1>.
    "Effet" a une formulation spéciale ; ce n'est pas un effet listé dans la liste "commands" du docudemon mais une formule particulière au fichier. Par exemple pour export_descr_ancillaries, l'effet est :
    Code:
       AcquireAncillary <nom_de_l'objet> chance  50


    Comprendre le docudemons

    Lorsque vous l'ouvrez, vous trouvez de nombreuses sous-sections. "Commands" (pour les effets), "conditions" et "event" servent au scripting. Ces fichiers listent les codes utilisables, mais aussi leurs caractéristiques. Voici des exemples de chacun de ces trois fichiers et leur description.
    EVENTS
    Spoiler:
    Code:
    Identifier: BuildingCompleted    
    Event: A building has been completed    
    Exports: faction, settlement, prior_build, advised_build    
    Class: ET_BUILDING_COMPLETED
    Identifier : c'est le code
    Event : à quel event correspond ce code ? Ici c'est simple, BuildingCompleted traduit pour le jeu l'idée qu'un bâtiment vient d'être achevé.
    Exports : toutes les conditions ne sont pas valables pour tous les types d'events. Ici cet event pourra être complété de conditions faisant référence à des factions, des communautés, des constructions, et des conseils de construction. Se reporter à l'explication de la liste des conditions.
    Class : aucune importance

    Condition
    Spoiler:
    Code:
    Identifier: SettlementType    
    Trigger requirements: settlement    
    Parameters: castle | city    
    Sample use: SettlementType castle    
    Description: Test if the settlement is the specified type    
    Battle or Strat: Strat    
    Class: SETTLEMENT_TYPE
    Identifier : c'est le code ; ici il s'agit de déterminer la nature de la communauté.
    Trigger requirements : c'est le type d'event auquel cette condition peut être adjointe. Donc on pourra adjoindre cette condition à BuildingCompleted, car il peut supporter des conditions relatives aux "settlement" c'est à dire aux communautés. Se reporter à l'explication de la liste "event".
    Parameters: les paramètres de cette condition, ce que vous devez mettre à sa suite pour qu'elle prenne du sens. Ici la nature de la communauté peut être soit châteu, soit ville.
    Sample use : un exemple d'utilisation extrêment pratique, il permet de mieux comprendre.
    Description : que fait ce code ?
    Battle or Strat: ce code marche-t'il sur la carte de bataille, celle de campagne, ou les deux ? Ici, celle de campagne.
    Class : aucune importance

    COMMANDS
    Spoiler:
    Code:
    Identifier: add_money    
    Parameters: faction, amount    
    Description: Adds money (negative value subtracts) to a faction's treasury.    
    Sample use: add_money England 2007    
    Class: ADD_MONEY
    Identifier : c'est le code
    Parameters: les paramètres de cette commande, ce que vous devez mettre à sa suite pour qu'elle prenne du sens. Ici le nom d'une faction et un montant.
    Description : que fait ce code ? Ici il peut ajouter ou retirer de l'argent.
    Sample use : un exemple d'utilisation extrêment pratique, il permet de mieux comprendre.
    Class : aucune importance




    Exemples simples de scripts simples pour simplets

    Nous allons donc scripter un petit monitor avec ce que nous avons appris :
    Code:
    monitor_event BuildingCompleted   SettlementType City
          add_money England 1000
    end_monitor
    Ainsi, à chaque fois qu'un bâtiment sera construit dans une communauté de type ville, l'angleterre touchera 1000 guinées.
    Mais c'est là où l'on touche du doight la complexité du scripting ; car le script ci-dessus donnera 1000 pièces aux anglais chaque fois qu'un bâtiment sera construit dans une ville par n'importe quelle faction du vaste monde ! Il faut donc préciser avec une nouvelle condition :
    Code:
    monitor_event BuildingCompleted   SettlementType City
         and FactionType England
          add_money England 1000
    end_monitor
    Comme BuildingCompleted exporte vers faction, et que FactionType est une condition de type "faction", je peux l'utiliser.
    Cette fois-ci, le script donnera 1000 pièces aux anglais à chaque bâtiment construit par leur misérable nation.


    Passons aux choses sérieuses

    Désormais, les bases étant acquises, nous traiterons de tout ce qui peut être un peu plus complexe.
    Tout d'abord, les conditions indépendantes. Comme vu avant, chaque condition a dans le docudemons un "trigger requirement", qui fait référence à l' "export" de l'event. Or certaines conditions n'ont justement pas de trigger requirement dans leurs caractéristiques ; ce sont des conditions indépendantes (sous-entendu vis à vis de l'event). C'est à dire qu'elles sont toujours testables car elles ne dépendent d'aucun autre paramètre. Prenons un exemple simple.
    Code:
    Identifier: I_CharacterExists    
    Trigger requirements:     
    Parameters: character name    
    Sample use: I_CharacterExists Gaius Julius    
    Description: Is this character alive and in the campaign?    
    Battle or Strat: Strat    
    Class: I_CHARACTER_EXISTS
    Là, il s'agit de tester si tartenpion existe ; cela est vrai ou pas, indépendemment de tout event. Donc pas besoin de vérifier l'export de l'event car c'est forcément compatible avec n'importe quel event.
    Notez que le I_ au début d'une condition indique qu'elle est indépendante.
    L'intérêt de ce genre de conditions, c'est qu'elles servent à utiliser la commande "if "/ "end_if".
    If veut dire "si". Cela permet de créer des sous-conditions.
    Exemple : je désire aider l'IA de ma campagne. Pour cela je veux créer un script lui donnant de l'argent.
    Code:
    monitor_event FactionTurnEnd  FactionType Slave
         and I_IsFactionAIControlled England
          add_money England 1000
    end_monitor
    monitor_event FactionTurnEnd  FactionType Slave
         and I_IsFactionAIControlled Spain
         add_money Spain 1000
    end_monitor
    monitor_event FactionTurnEnd  FactionType Slave
         and I_IsFactionAIControlled France
          add_money France 1000
    end_monitor
    Un peu long non ? Surtout si je dois y mettre toutes les factions. Voilà l'intérêt du if ; mettre en commun un event et ses conditions dépendantes pour pleins de sous-conditions. Démonstration :
    Code:
    monitor_event FactionTurnEnd  FactionType Slave
         if I_IsFactionAIControlled England
          add_money England 1000
         end_if
         if I_IsFactionAIControlled Spain
          add_money Spain 1000
         end_if
         if I_IsFactionAIControlled France 
          add_money France 1000
         end_if
    end_monitor
    Notez que le end_if signale la fin des blocs de sous-conditions et de leurs effets (vous pouvez en effet en mettre plusieurs, avec des "and" pour les lier, tant qu'elles sont indépendantes). Plus court non ?

    Maintenant passons aux compteurs. Leur utilisation est essentielle dans le code du campaign_script (ils ne peuvent malheureusement pas être utilisés dans d'autres fichiers de script).
    Les compteurs (counters en anglais) ... comptent ! Ils permettent de chiffrer ce que vous voulez. Cela parait un peu abstrait mais ils vous seront très utiles.
    Un exemple vaut mieux que de vagues théories.
    Tout d'abord, pour que le jeu puisse compter et prendre en compte le compteur, il faut le déclarer, comme un chantier finalement .
    Code:
    declare_counter France_vaincra 0
    En mettant cela dans le campaign_script, je crée le compteur "France_vaincra" ; le 0 n'est pas obligatoire car tout compteur déclaré sans valeur indiquée aura une valeur de base de 0. Sauf si justement, à la place de mon 0, vous mettez un autre chiffre ; par exemple "declare_counter France_vaincra 2" => le compteur sera considéré comme ayant une valeur de base de 2.

    Il ne vous reste donc plus qu'à scripter les "commands" (= effets) permettant de modifier les valeurs des compteurs. Voici les caractéristiques du docudemons :
    Spoiler:
    ---------------------------------------------------
    Identifier: inc_counter
    Parameters: name of the counter, quantity to modify it by.
    Description: change a counter by a particular amount
    Sample use: inc_counter blib -137
    ---------------------------------------------------
    Identifier: set_counter
    Parameters: name of the counter, quantity to set it to.
    Description: change a counter to a particular value
    Sample use: set_counter blib -137
    ---------------------------------------------------

    Et un exemple ;
    Code:
    monitor_conditions  <condition>
          set_counter france_vaincra 1
    end_monitor
    Si les conditions sont remplies (libre à vous de les fixer), le compteur verra sa valeur fixée à 1. Utiliser le inc_counter augmente (ou diminue si la valeur numérique est -x) la valeur du compteur ; cela peut être utile lorsque l'on désire scripter des choses dans le temps, pour qu'elles augmentent ou diminuent à chaque tour.

    L'intérêt des compteurs est dans leur test. Il existe des conditions pour tester leurs valeurs. Voici la description de la condition dans les "conditions" du docudemons.
    Identifier: I_CompareCounter
    Trigger requirements:
    Parameters: script counter, logic token, value
    Sample use: I_CompareCounter blib < 17
    Description: Compare a script counter to a value
    Battle or Strat: Either
    Notez que les "logic token" utilisables sont les suivants (n'oubliez pas de mettre un espace avant et après ; = > < >= <= != (ce dernier signe signifiant différent de).
    Code:
    monitor_conditions  I_CompareCounter France_vaincra = 1
          <Effet 1>
          <Effet 2>
    end_monitor
    Ainsi, le monitor_conditions ci-dessus se lancera lorsque le compteur France_vaincra aura une valeur de 1 exactement.

    Voilà, cela peut encore paraître flou, mais l'exemple ci-dessous vous convaincra .

    Code:
    declare_counter France_vaincra
     
    monitor_event GeneralCaptureSettlement SettlementsTaken >= 10
       and FactionType france
          set_counter France_vaincra 1
    end_monitor
     
    monitor_event BuildingCompleted FactionType france
          and I_CompareCounter France_vaincra = 1
          add_money france 1000
    end_monitor
    Donc lorsque les français auront pris au moins 10 villes, cela activera en partie le deuxième monitor, qui, dès qu'un bâtiment sera construit par les français, donnera du fric à la france. Bon, j'admets que ce script est farfelu et ne signifie pas grand chose de logique ; mais c'est un exemple.
    Voilà, j'espère que vous avez compris.

    Il existe un autre type de counters, les event_counters. Ils correspondent comme leur nom l'indique à des events (= évènements) précis ; ce sont ceux qui désignent les catastrophes naturelles, les events historiques, etc. Bref, ils correspondents toujours à un event ; ils comptent le nombre d'event.
    Et surtout, intérêt énorme, on peut créer des event counters personnalisés, et exportables dans les autres ficheirs de script (donc les autres fichiers de script vont pouvoir être soumis à des counters créés dans le campagne script !).
    Bon, technique, et abstrait, je l'avoue. Mais super pratique.


    A SUIVRE
    Dernière modification par Caulaincourt, 08-09-2011, 18h05.

  • #2
    Remarquable tutorial ! Et tr?s int?ressant pour tous ceux qui souhaitent faire leur mod.
    Cependant, sans se plonger dans une utilisation pratique, sans prendre le temps de tester soit-m?me, cela reste vraiment tr?s complexe ? appr?hender.
    Je n'en suis pas encore l?, mais j'aurai s?rement besoin d'aide pour cr?er mes scripts. Je ferai appel ? tes comp?tances.

    Commentaire


    • #3
      Ajo?t d'un chapitre (non-exhaustif, suite ? venir) sur les compteurs.

      Commentaire


      • #4
        Bravo pour ce d?but de tuto
        Est-ce que cela fonctionne en totalit? sur Rome Total War?

        Commentaire


        • #5
          Il y a les scripts de bataille aussi, dont tu n'a pas parl?e, qui permettent de scripter les d?but des batailles hsitoriques.

          Je me demandais d'ailleurs s'il n'?tait pas possible de scripter carr?ment l'IA pour les batailles en g?n?ral (et donc dans les campagnes)

          Commentaire


          • #6
            @chou2714 : malheureusement je ne connais que le scriptage de med2. Pour RTW, il faut passer via le conseiller car le fichier campaign_script n'exite pas. Je présume que certains des codes de med2 existaient déjà sur RTW.

            Mais déjà que les scripts de med2 sont assez limités (en théorie non, mais en pratique beaucoup de codes ne marchent tout simplement pas !), sur RTW scripter doit être vraiment très restreint, désolé. Mais j'avoue parler sans connaissances sur RTW.

            @Raphl ; pour les batailles je vais apprendre t'inquiète .
            Mais pour les campagnes c'est plus complexe ; il y a pas mal de fichiers de code (autres que ceux cités dans mon tuto). Et j'y connais pas grand chose pour le moment.

            Commentaire


            • #7
              malheureusement je ne connais que le scriptage de med2. Pour RTW, il faut passer via le conseiller car le fichier campaign_script n'exite pas. Je pr?sume que certains des codes de med2 existaient d?j? sur RTW.

              Mais d?j? que les scripts de med2 sont assez limit?s (en th?orie non, mais en pratique beaucoup de codes ne marchent tout simplement pas !), sur RTW scripter doit ?tre vraiment tr?s restreint, d?sol?. Mais j'avoue parler sans connaissances sur RTW.
              snif snif
              Bon bah je vais resortir mes vieilles feuilles que j'avais jadis imprim?s et pseudo traduit de TW center.
              Pour le caract?re limit? des cript je suis un peu ?tonn? pour RTW j'avais souvenir d'un large panel mais la barri?re de langue assombrit peut ?tre mon jugement

              Commentaire


              • #8
                Nan, il doit y en avoir beaucoup, mais à côté de med2 ça fait toujours moins. C'est ce que je voulais dire.

                Commentaire


                • #9
                  Alors la suite pour quand ?

                  Commentaire


                  • #10
                    Hhéhé, comme si c'était simple. Bon, ok, je vais tenter de continuer.

                    Commentaire


                    • #11
                      Un tuto bien utile !
                      Merci Caulaincourt

                      Commentaire


                      • #12
                        Se tuto marche aussi pour RTW?

                        Commentaire


                        • #13
                          C'est marqué juste au dessus...
                          Spoiler:
                          Si tu as la flemme de chercher la réponse :
                          Spoiler:

                          J'en sais rien.

                          Commentaire


                          • #14
                            Est-ce qu'il existe un moyen de conter les tours, c'est à dire un compteur qui prend la valeur 0, qui augmente de 1 à chaque tour, et que l'on peut remettre à zéro.

                            Commentaire


                            • #15
                              Regarde au niveau du script de saisons de TATW

                              Commentaire

                              Chargement...
                              X