Voici un article tutoriel sur l’ajout de nouveaux verbes dans votre fiction interactive ; pour un autre article sur un aspect complémentaire, l’extension de verbes existants; c’est ici.

Dans une fiction interactive avec analyseur syntaxique, toute l’expérience du joueur repose sur la qualité de ce dernier. Fort heureusement, vous n’avez pas à en coder un vous-même : Inform inclut des fonctions génériques puissantes, qui permettent de reconnaître des entrées à partir d’une grammaire spécifiée ; et la bibliothèque francophone définit la grammaire d’une centaine de verbes usuels, ce qui vous donne déjà une bonne longueur d’avance. Mais fatalement, il vous faudra mettre les mains dans le cambouis à un moment ou un autre : votre verbe préféré n’est pas dans la bibliothèque de base, une joueuse a eu une difficulté car elle a utilisé un synonyme que vous n’aviez pas prévu, ou vous voulez définir votre propre commande. Voyons comment ajouter des verbes à la grammaire reconnue par le jeu.

Que la lumière soit !

Supposons que je sois en train de développer un jeu qui soit une fan fiction Harry Potter (ou mieux, l’adaptation officielle de Harry Potter en fiction interactive, et si c’est le cas, félicitations, on attend ça avec impatience !). Il vous faut implanter des sorts, comme « lumos », un sort qui vous permet de faire de la lumière. Pour cela, vous allez créer un nouveau verbe, comme ceci :

Verb 'lumos'
*   ->Lumos;

Les plus perspicaces reconnaîtront ce bout de code : en effet, dans notre tout premier tutoriel Inform 6, on avait déjà défini un verbe « voler » selon le même schéma !

La ligne en-dessous du verbe précise ce qui devra suivre le verbe (ici, rien, le joueur tape juste « lumos »), puis on écrit une petite flèche pour indiquer le nom de la routine à exécuter si c’est bon. Ici, on écrit Lumos, et le jeu ira donc chercher (c’est une convention) une routine qui s’appelle LumosSub. La routine pourra être par exemple :

[ LumosSub ;
  if (location has light) { "Rien d'évident ne se produit."; }
  else { give location light; "Votre baguette émet une lumière blanche qui se répand au plafond et illumine la pièce."; }
];

Attention, il faut que cette routine soit définie avant la ligne de grammaire qui y fait référence. Avec cette ligne de grammaire, voilà ce qu’on obtient :

Une pièce sombre
Il fait noir, et vous ne pouvez rien voir.

>lumos partout
Je ne comprends pas cette phrase.

>lumos chandelier
Je ne comprends pas cette phrase.

>lumos
Votre baguette émet une lumière blanche qui se répand au plafond et illumine la pièce.

Le jeu ne comprend pas « lumos partout » ou « lumos chandelier », car la grammaire spécifie « lumos, puis rien du tout ».

Patronus !

Prenons maintenant le sort pour faire apparaître un patronus : ça n’est plus un mot, mais deux. La grammaire correspondante sera :

Verb 'expecto'
*    'patronus' ->ExpectoPatronus;

C’est-à-dire un premier mot (qu’Inform 6 appelle « verbe »), et s’il est suivi de patronus, on exécute ExpectoPatronusSub ; si le joueur tape juste « expecto », ou « expecto mon patronus », le jeu ne le comprendra pas.

Le regard de la Méduse

On peut également créer un verbe s’appliquant à un objet ; il me semble qu’aucun des sorts d’Harry Potter ne comprend le nom de l’objet, mais faisons comme si on jetait un sort de pétrification en faisant « petrificus totalus grenouille », par exemple. Il faut alors écrire :

Verb 'petrificus'
*    'totalus' noun ->PetrificusTotalus;

Le noun veut dire que ça sera bon tant que c’est le nom d’un objet — une suite de mots dans le name, ou quelque chose de plus compliqué (capturé par parse_name). Pour la routine, ça pourra être quelque chose comme ça :

Attribute petrified;
Object neville "Neville Londubas"
   with name 'neville' 'londubas' 'ami',
   description ... ! Je vous laisse finir

[ PetrificusTotalusSub;
 if (noun == neville) { "Ah non, vous n'allez pas encore pétrifier Neville !";} else { give noun petrified; "Vous lancez le sort, et la chose se transforme en pierre."; }
];

Ainsi si le joueur tape « petrificus totalus neville », « petrificus totalus neville londubas », ou « petrificus totalus neville ami », le jeu comprendra qu’on veut lancer PetrificusTotalusSub sur l’objet neville. Et si le joueur tape « petrificus totalus », le jeu lui demandera de préciser le nom concerné par l’action, car la ligne de grammaire dit qu’il faut le nom d’un objet après ces mots. C’est plutôt pratique !

J’ai cependant un léger souci avec le code qui précède : le if (noun == neville) introduit une exception pour neville. Et si on veut aussi une exception pour ginny, pour dumbledore, pour dobby ? Est-ce qu’on va enchaîner les if (noun == ... ? Il vaut mieux mettre dans la routine le comportement normal, par défaut, et intercepter ce comportement dans les objets qui en ont besoin. On fait cela avec before, comme on l’a expliqué dans le premier tutoriel, et on utilise le nom de routine déclaré dans la grammaire ; ça devient

Attribute petrified;
Object neville "Neville Londubas"
 with name 'neville' 'londubas' 'ami',
      before [; PetrificusTotalus: print "Ah non, vous n'allez pas encore pétrifier Neville !"; rtrue;} ],
      description ... ! Je vous laisse finir

[ PetrificusTotalusSub;
 give noun petrified; "Vous lancez le sort, et la chose se transforme en pierre.";
];

Avada…

Je sais que ça risque de nous envoyer à Azkaban, mais faisons le sort de mort. Ce sort ne s’applique que si l’objet est animé : on ne peut pas le lancer sur un caillou. Ça donne :

[ AvadaKedavraSub ;
 "Vous fermez les yeux. Il y a sûrement une façon plus pacifique d'arriver à vos fins.";
];

Verb 'avada'
 * 'kedavra' animate -> AvadaKedavra;

Dans ce genre de déclarations, vous pouvez utiliser n’importe quel attribut, comme edible (pour ne cibler que la nourriture par exemple) ou openable !

Demain, je vous parlerai non pas de création de nouveaux verbes, mais d’extension et d’élargissement de la grammaire de verbes déjà définis. Alors, à demain !