Exemples à copier-coller

Voici quelques exemples de code à copier-coller-éditer lors de l'écriture de votre jeu. Consultez également la French Inform Library.


Un jeu vide

Cet exemple est inspiré de ORLibrary.

!% ! Les options ci-dessous sont destinées au compilateur :
!% ! (toutes sont désactivées dans cet exemple)
!% ! +include_path=..\..\bibliotheques
!% ! +language_name=French
!% ! -v5	! version souhaitée : v5, v8, G, etc...
!% ! -s		! give statistics
!% ! -X		! infix (ne pas laisser dans la version publiée ; non disponible avec Glulx)
!% ! -D		! debug (ne pas laisser dans la version publiée)
!% ! -r		! imprime le contenu du jeu pour envoi vers un correcteur d'orthographe
!% !+transcript_name=gametext.txt	! fichier d'arrivée
!% !$MAX_SOURCE_FILES=512
!% !$MAX_INCLUSION_DEPTH=10
!% !$MAX_LABELS=50000	
!% !$MAX_INDIV_PROP_TABLE_SIZE=50000					
!% !$MAX_STATIC_DATA=20000

!--------------------------------------------
! Constantes générales
!--------------------------------------------

Constant Story "NOM_DU_JEU";
Constant Headline "^SOUS_TITRE^
		Copyright (c) 2004 par NOM_DE_L'AUTEUR.^";

! Constant DESACTIVER_IMPERATIF_DPS;
! Constant DESACTIVER_IMPERATIF_DPP;
! Constant DESACTIVER_INDICATIF_PPS; ! nécessite l'IMPERATIF_DPS
! Constant DESACTIVER_IMPERATIF_PPP;

!--------------------------------------------
! Directives de remplacement
!--------------------------------------------
!	[DeathMessage; print "Game Over";]; 

!--------------------------------------------
! Attributs 
!--------------------------------------------
 
!--------------------------------------------
#Include "Parser";
#Include "VerbLib";
!--------------------------------------------

!--------------------------------------------
! Variables 
!--------------------------------------------

!--------------------------------------------
! Modèles d'objets (déclarations de classes) 
!--------------------------------------------

!--------------------------------------------
! Plan des lieux (pièces, portes...) 
!--------------------------------------------

!--------------------------------------------
! NPCs 
!--------------------------------------------

!--------------------------------------------
! Objets déplaçables
!--------------------------------------------

!--------------------------------------------
! Code 
!--------------------------------------------
[Initialise;
	location=piece_de_depart;
	move objet_de_depart to player;
	print "^^^^^^Quelques phrases d'introduction.^^^";
	return;
]; 

!--------------------------------------------
#Include "FrenchG";
!--------------------------------------------

!--------------------------------------------
! Verbes (extension de FrenchG.h)
!--------------------------------------------

Une pièce

Object Piece_banale "Pièce banale"
	with name 'piece' 'banale',
	description
		"Une pièce somme toute assez banale, mais
		lumineuse.",
	direction1_to piece1,
	direction2_to piece2,
	has light;

Une porte à une face

Parfois suffisant. La pièce de départ doit avoir une propriété direction_to porte et la pièce d'arrivée une propriété direction_to piece1.

Object -> porte_banale "porte banale"
	with description "C'est une porte, voilà tout.",
		name 'porte' 'banale',
		when_closed "La porte est fermée.",
		when_open "La porte est ouverte.",
		door_to piece2,
		door_dir direction_to,
		with_key cle,
	has female static door openable lockable locked;

Une porte à deux faces

Les deux pièces contenant la porte doivent avoir respectivement une propriété direction1_to porte et direction2_to porte.

Object -> porte_banale "porte banale"
	with description "C'est une porte, voilà tout.",
		name 'porte' 'banale',
		when_closed "La porte est fermée.",
		when_open "La porte est ouverte.",
		door_to [;
			if (self in piece1) return piece2; return piece1;
		],
		door_dir [;
			if (self in piece1) return direction1_to; return direction2_to;
		],
		with_key cle,
		found_in piece1 piece2,
	has female static door openable lockable locked;

Une clé

En fait rien de spécial, c'est la propriété with_key de la porte qui fait la différence.

Object cle_banale "clé banale"
	with name 'cle' 'banale',
	has female;

Des liquides (eau...)

Plusieurs solutions existent. Choisir en fonction des besoins du jeu.

Des liquides, solution très simple : de l'eau, une bouteille, plusieurs sources et une plante...

Cet exemple est inspiré d'aventure.inf . Il suppose que le joueur a des gestes brusques et vide toujours la bouteille d'un coup (jamais à moitié). La possibilité de "prendre de l'eau" sans faire préciser le récipient est peut-être exagérée. La solution citée ensuite risque de mieux vous convenir.

Cette partie va dans la section "Plan des lieux" ou dans la section "Objets déplaçables" du jeu :

Object -> ruisseau "ruisseau"
  with name 'ruisseau' 'eau',
       before
       [; Drink: "Vous buvez de l'eau du ruisseau.";
          Take: if (bouteille notin player)
                    "Vous n'avez pas de quoi emporter de l'eau.";
                <<Fill bouteille>>;
          Insert: if (second == bouteille) <<Fill bouteille>>;
                    "Vous n'avez pas de quoi emporter de l'eau.";
          Receive: if (noun == bouteille) <<Fill bouteille>>;
                remove noun;
                print_ret (The)noun, " ", (isorare)noun, " emporté", (es)noun, " par le courant.";
       ],
  has  scenery;

Object -> Plant "plante"
  with height 0,
       name 'plante',
       describe
       [; switch(self.height)
          {   0: "Dans un coin, une plante minuscule murmure ~De l'eau, de l'eau, ...~";
              1: "Surgi d'un coin de la pièce, une plante braille ~De l'eau !! De l'eau !!~";
              2: "Un plante gigantesque s'étire à travers toute la pièce.";
          }
       ],
       before
       [;
         Take:  "La plante a des racines très profondes et ne peut être arrachée.";
         Arroser: if (bouteille notin player)
                    "Vous n'avez rien pour arroser la plante.";
                if (child(bouteille)==nothing) "La bouteille est vide.";
                remove eau_en_bouteille;
                switch((self.height)++)
                {   0: print "La plante croît brutalement.^^";
                    1: print "La plante se déploie explosivement, remplissant toute la pièce.^^";
                    2: print "Vous avez noyé la plante ! Elle se ratatine ! Elle, elle...^^";
                        self.height = 0;
                }
                <<Examine self>>;
         Examine: self.describe(); rtrue;
          Receive: if (noun == eau_en_bouteille) <<Arroser self>>;
       ],
       has female;

Object -> bouteille "bouteille"
  with name 'bouteille',
       before
       [; LetGo: if (noun in bouteille) "Vous en avez déjà (dans la bouteille).";
         Receive:
             if (noun == ruisseau) <<Fill self>>;
             else "La bouteille est censée contenir uniquement des liquides.";
         Fill:
             if (child(bouteille) ~= nothing)
               "La bouteille est déjà pleine.";
             if (ruisseau in location) ! liste des sources d'eau
             {   move eau_en_bouteille to bouteille;
                 "La bouteille est à présent pleine d'eau.";
             }
             "Il n'y a pas ici de quoi remplir la bouteille.";
         Empty: if (child(bouteille) == nothing) "La bouteille est déjà vide !";
             remove child(bouteille);
             "Maintenant votre bouteille est vide et le sol mouillé.";
       ],
  has  container open female;

Object eau_en_bouteille "eau"
  with name 'eau',
       article "de l'",
       before
       [; Drink:  remove eau_en_bouteille; <<Drink ruisseau>>;
	  Insert: print self.name; <<Arroser second>>;
       ],
       description "C'est de l'eau ordinaire, à première vue.",
  has female;

Cette partie va dans la section "Code" du jeu :

[ ArroserSub;
  if (bouteille in player) <<Empty bouteille>>;
  print_ret "Arroser ", (the) noun ," ? Mais vous n'avez pas d'eau !";
];

Cette partie va dans la section "Verbes" du jeu :

[ LiquideOuRecipient; if (noun==eau_en_bouteille or ruisseau or bouteille) rtrue; rfalse; ];
[ Recipient; if (noun==bouteille) rtrue; rfalse; ];
Verb "verser" "renverser" = "vider";
Extend "vider" first
		* noun=LiquideOuRecipient	  				-> Empty
		* noun=LiquideOuRecipient "sur"/"dans"/"vers" noun  		-> Arroser reverse;
Verb "arroser" "inonder" "tremper" 
                * noun                            				-> Arroser;
Extend "remplir" first
		* noun=Recipient						-> Fill
		* noun=Recipient "de"/"d^"/"avec" noun=LiquideOuRecipient 	-> Fill;

Des liquides, solution simple : des liquides, des récipients, des sources... sans dosage ni mélange.

Cet exemple simple sans être simpliste est tiré des Roger Firth's IF pages. Il suppose que le joueur a des gestes brusques et vide toujours les récipients d'un coup, mais cela peut suffire.

Cette partie va dans la section "Modèles" du jeu :

  Class   Eau(2)
    with  name 'eau',
          short_name "eau",
          article "de l'",
          infinite false,     ! is this an inexhaustible source of liquid?
          before [;
            Drink:
              "Une petite gorgée vous rafraîchit.";
            Take:
              "[Utilisez REMPLIR suivi du nom d'un récipient adapté.]";
            Insert,Transfer:
              if (parent(self) ofclass Recipient) <<EmptyT (parent(self)) second>>;
              if (second ofclass Recipient)       <<Fill second>>;
              "Je ne suis pas sûr qu'il s'agisse d'un récipient adapté.";
            Drop,Empty,EmptyT:
              if (parent(self) ofclass Recipient) <<(action) (parent(self)) second>>;
          ],
          react_before [;
            Fill:
              if (noun ofclass Recipient) rfalse;
              "Je ne suis pas sûr qu'il s'agisse d'un récipient adapté.";
          ];

  Class   Recipient
    with  before [ x y; x = child(self);
            Empty:
              if (~~x ofclass Eau) rfalse;      ! follow standard action
              Eau.destroy(x);
              print_ret (The) x, " s'écoule sur le sol et disparaît.";
            EmptyT:
              if (~~x ofclass Eau) rfalse;      ! follow standard action
              if (second ofclass Recipient) {
                  y = child(second);
                  if (~~y) {                      ! second is empty
                      move x to second;
                      "Vous versez ", (the) x, " dans ", (the) second, ".";
                  }
                  if (y ofclass Eau)
                      print_ret (The) second, " est déjà plein", (es) second, " d'", (name) y, ".";
                  else
                      print_ret (The) second, " contient déjà quelque chose.";
              }
              else {
                  if (second == d_obj) <<Empty self>>;
                  "Je ne suis pas sûr qu'il s'agisse d'un récipient adapté.";
              }
            Fill:
              if (~~x) {                          ! is there a water source in scope?
                  objectloop (x ofclass Eau && x.infinite && TestScope(x)) {
                      x = Eau.create(); move x to self;
                      "Vous remplissez ", (the) self, " d'", (name) x, ".";
                  }
                  rfalse;                         ! no water available
              }
              if (x ofclass Eau)
                  print_ret (The) self, " est déjà plein", (es) self, " d'", (name) x, ".";
              else
                  print_ret (The) self, " contient déjà quelque chose.";
            Receive:
              if (x ofclass Eau)
                  print_ret (The) self, " est déjà plein", (es) self, " d'", (name) x, ".";
          ],
    has   container open;

Cette partie va dans la section "Plan des lieux" ou dans la section "Objets déplaçables" du jeu :

Object -> fontaine "fontaine" with name 'petite' 'pierre' 'fontaine' 'bassin', description "L'eau sort de la petite fontaine de pierre pour être collectée dans le bassin en dessous.", before [; EmptyT: if (second ofclass Recipient) <<Fill second>>; "Je ne suis pas sûr qu'il s'agisse d'un récipient adapté."; ], has static transparent female; Eau -> -> "eau" with infinite true; Recipient -> "jarre" with name 'jarre' 'poterie' 'pot' has female; Recipient -> "barril" with name 'barril' 'tonneau';

Cette partie va dans la section "Code" du jeu :

  [ ChooseObjects obj code; ! puiser en priorité dans les récipients infinis
      if (code == 2 && obj ofclass Eau)
          if (obj.infinite) return 1; else return 2;
  ];

Cette partie va dans la section "Verbes" du jeu :

  Verb 'verser' = 'vider';
  [ Liquide; if (noun ofclass Eau) rtrue; rfalse; ];
  Extend 'remplir'
      * noun 'avec' noun=Liquide      -> Fill
      * noun 'a'/'au'/'avec' noun     -> EmptyT reverse;

Des liquides, autre solution simple : un verre, une bouteille de vin... de la modération (et sans mélanger).

Cet exemple, moins simple et moins achevé que le précédent (beaucoup moins de phrases fonctionnent, impossible de remettre du vin dans la bouteille, ...), est tiré des Roger Firth's IF pages. Il gère des quantités de liquide : le verre peut-être à moitié plein.

Cette partie va dans la section "Modèles" du jeu :

Class   liquide(1)
  with  name 'liquide' '.spare' '.spare' '.spare' '.spare' '.spare',
        short_name "liquide",
        rename [ sn n0 n1 n2 n3 n4 n5;
            if (sn) self.short_name = sn;
            if (n0) self.&name-->0 = n0;
            if (n1) self.&name-->1 = n1;
            if (n2) self.&name-->2 = n2;
            if (n3) self.&name-->3 = n3;
            if (n4) self.&name-->4 = n4;
            if (n5) self.&name-->5 = n5;
            ],
        add_liquid [ qty;
            self.capacity = self.capacity + qty;
            if (self.capacity > 0)
                return self.capacity;
            else
                { liquide.destroy(self); return 0; }
            ],
        description [; print_ret "Cela ressemble assez à ", (a) self, "."; ],
        article "du",
        before [ container; container = parent(self);
            Take:
                if (container ofclass Recipient) <<Take container>>;
                print_ret "Vous ne pouvez pas ramasser une flaque.";
            Drink:
                if (container ofclass Recipient) <<Drink container>>;
                print_ret "Vous ne pouvez pas boire dans une flaque.";
            ],
        capacity 0;                 ! liquide currently in the recipient

Class   Recipient
  with  parse_name [ liq qty wd container_count contents_count;
            if (parser_action == ##TheSame) return -2;
            liq = ChildOfClass(self,liquide);
            if (liq ~= 0) qty = liq.add_liquid(0);
            for (wd=NextWord() : wd~=0 : wd=NextWord()) switch (wd) {
                'de':
                    if (container_count > 0) container_count++;
                'vide','rien':
                    if (qty == 0) contents_count++;
                default:
                    if (IsAWordIn(wd,self,name)) container_count++;
                    else
                        if (qty > 0 && IsAWordIn(wd,liq,name)) contents_count++;
                        else jump exitRecipient;
                }
            .exitRecipient;
            if (container_count > 0) return container_count + contents_count;
            return 0;
            ],
        invent [ liq qty;
            liq = ChildOfClass(self,liquide);
            if (liq ~= 0) qty = liq.add_liquid(0);
            if (inventory_stage == 2) {
                if (qty == self.capacity) print " (plein",(es)self,")";
                else
                    if (qty > 0) print " (à moitié plein",(es)self,")";
                }
            ],
        description [ liq qty;
            liq = ChildOfClass(self,liquide);
            if (liq ~= 0) qty = liq.add_liquid(0);
            print "Actuellement ";
            if (qty == self.capacity) print_ret "plein",(es)self," de ", (name) liq, ".";
            else
                if (qty > 0) print_ret "à moitié plein",(es)self," de ", (name) liq, ".";
                else "vide.";
            ],
        before [ liq qty;
            liq = ChildOfClass(self,liquide);
            if (liq ~= 0) qty = liq.add_liquid(0);
            Drink, Empty:
                if (self notin player)
                    print_ret "Vous devez tenir ", (the) self, ".";
                if (qty > 1)
                    print "Vous prenez une gorgée de ", (name) liq, ".^";!*!
                else
                    if (qty == 1)
                        print "Vous finissez ", (the) liq, ".^";
                    else print_ret "Il n'y a rien dans ", (the) self, ".";
                liq.add_liquid(-1);
                rtrue;
            Receive: print_ret (The) self, " est fait pour contenir des liquides.";
            ],
        capacity 0              ! liquide the recipient can contain
  has   transparent;

Cette partie va dans la section "Plan des lieux" ou dans la section "Objets déplaçables" du jeu :

Object  bouteille "bouteille" hall
  with  parse_name [ wd adj_count noun_count;
            if (parser_action == ##TheSame) return -2;
            wd = NextWord();
            while (wd == 'verte' or 'verre' or 'de' or 'vin' or 'bouchee')
                { wd = NextWord(); adj_count++; }
            while (wd == 'bouteille')
                { wd = NextWord(); noun_count++; }
            if (noun_count > 0) return noun_count + adj_count;
            return 0;
            ],
        short_name [;
            if (bouchon in self) {print "bouteille bouchée"; rtrue;}
	    ! else rfalse;
            ],
        description [ liq;
            liq = ChildOfClass(self,liquide);
            print "Vous voyez une bouteille de vin ordinaire, en verre vert,
                avec une étiquette effacée et un ";
            if (bouchon in self) print "bouchon dépassant d'un ";
            print "goulot étroit";
            if (liq ~= 0) print ". Il y a du liquide à l'intérieur";
            ".";
            ],
        before [ liq qty liq2;
            liq = ChildOfClass(self,liquide);
            if (liq ~= 0) qty = liq.add_liquid(0);
            Deboucher: <<Remove bouchon self>>;
            Reboucher:   <<Insert bouchon self>>;
            EmptyT: if (bouchon in self)
                        print_ret "Vous avez beau incliner ", (the) self,
                            ", rien ne se passe.";
                    if (qty == 0) print_ret (The) self, " est vide.";
                    if (~~(second ofclass Recipient))
                        "Ca serait du gâchis.";
                    liq2 = ChildOfClass(second,liquide);
                    if (liq2 == 0) {    ! no liquide in Recipient
                        if (qty > second.capacity) qty = second.capacity;
                        liq2 = liquide.create();
                        if (liq2 == 0) "*** Can't create liquide object! ***";
                        liq2.rename("vin rouge",'rouge','vin','piquette');
                        print "Vous versez ", (a) liq, " dans ", (the) second, ".^";
                        move liq2 to second;
                        }
                    else {              ! already some liquide in Recipient
                        qty = second.capacity - liq2.add_liquid(0);
                        if (qty == 0)
                            print_ret (The) second, " est déjà plein",(es)second,".";
                        print "Vous ajoutez un peu de ", (name) liq,
                            " dans ", (the) second, ".^";
                        }
                    liq2.add_liquid(qty); liq.add_liquid(-qty);
                    rtrue;
            ],
        capacity 10                     ! liquide the bouteille can contain
  has   transparent female;


Object  label "étiquette" bouteille
  with  name 'effacee' 'etiquette',
        description
            "Bien qu'un peu fanée et difficile à lire,
            l'étiquette semble indiquer ~Chat Eau~.",
	has female;

Object  bouchon "bouchon" bouteille
  with  name 'bouchon' 'liege',
        before [;
            Remove, Take, Pull:
                if ((self notin bouteille) || (second ~= nothing or bouteille))
                    rfalse;
                move self to player;
                "Vous sortez le bouchon de la bouteille.";
            Insert:
                if ((self notin player) || (second ~= bouteille)) rfalse;
                move self to bouteille;
                "Vous mettez le bouchon dans la bouteille.";
            ],
        description
            "C'est un petit bouchon de liège pour bouteilles de vin.";



Object  verre hall
  class Recipient
  with  name 'verre' 'ebreche' 'gobelet',
        short_name [ liq qty;
            liq = ChildOfClass(self,liquide);
            if (liq ~= 0) qty = liq.add_liquid(0);
            if (qty > 0)
                print "verre de ", (name) liq;
            else
                print "verre vide";
            rtrue;
            ],
        description [;
            print "Le verre est légèrement ébréché,
                mais encore utilisable à condition de faire attention. ";
            Self.Recipient::description();
            ],
        capacity 2;             ! liquide the glass can contain

Liquide "liquide" bouteille
  with  capacity 4;             ! Liquid currently in the bottle

Cette partie va dans la section "Code" du jeu :

[ ChildOfClass obj class
        k;
        objectloop (k in obj) if (k ofclass class) return k;
        return 0;
        ];

Cette partie va dans la section "Verbes" du jeu :

[ DeboucherSub;    "Vous ne pouvez pas déboucher cela."; ];
[ ReboucherSub;    "Vous ne pouvez pas reboucher cela."; ];
Verb    'deboucher'    	* noun            -> Deboucher;
Verb    'reboucher'     * noun            -> Reboucher;

Verb    'verser'      = 'vider';
[ unliquide; if (noun ofclass liquide) rtrue; rfalse; ];
Extend 'remplir'
      * noun 'avec' noun=unliquide    -> Fill
      * noun 'a'/'au'/'avec' noun     -> EmptyT reverse;