Traditionnellement, on oppose les jeux à analyseur syntaxique, où tout se passe au clavier, et les jeux à embranchements, où on ne fait que cliquer. Mais la frontière n’est pas si étanche que ça ; il y a plein de jeux à parser avec des choix multiples (par exemple, les conversations), des jeux Twine où on explore des lieux, parfois avec des directions nord-sud-est-ouest, des jeux Inform avec des hyperliens, des Twine où on tape des choses au clavier, etc. Dans l’article d’aujourd’hui, on va faire un jeu à embranchements à la Twine, à l’intérieur de Vorple, la surcouche JavaScript/CSS pour Inform !

« Pourquoi ferait-on ça ? demandez-vous avec un regard hébété. Pourquoi ne pas utiliser Twine pour faire un Twine ? » Pour moi, une des grandes forces d’Inform, c’est la modélisation du monde et des actions de base. Déjà codés dans Inform, vous trouverez : un système d’inventaire sophistiqué, une géographie, des personnages qui peuvent bouger de pièce en pièce, des tests de visibilité d’objets, des choses sur d’autres choses, et j’en passe. Twine n’a que des variables : si vous voulez tous ces systèmes, il va falloir les recoder, et c’est pas évident ; alors si on peut marier la modélisation du monde par Inform avec une façon de jouer à la Twine, c’est génial.

Un excellent exemple de jeu écrit en Vorple mais sans utiliser l’analyseur syntaxique est Re: Dragon, de Jack Welch, qui se passe en grande partie dans une interface rappelant une application de messagerie — un tour de force, et encore un exemple de la puissance de Vorple ! Si ça vous intéresse, le code Inform 7 est sur le dépôt GitHub de Jack ; la démarche est sensiblement la même que celle dans cet article !

Message personnel adressé à Stéphane F., que je sens que je vais interviewer bientôt pour le site : le système d’Azthath est génial, la liste des actions proposées est organique et super flexible, c’est un plaisir de voir tout ce qui est généré par le jeu aussi intelligemment. Dépêche-toi de publier ça, potentiellement en version Vorple, ça fera un carton.

Liens correspondant à une action

Commençons par la base : pour faire une interface à la Twine, il faut des hyperliens et pas d’invite de commande. C’est impossible à faire en Glulx : bien qu’il soit possible de ne pas afficher la commande résultant d’un lien quand on clique sur ce dernier, impossible d’enlever le champ où le joueur tape sa commande. Mais bien sûr, Vorple sait faire !

Pour cacher l’invite de commande, il suffit de dire VorpleHidePrompt() en I6 ou hide the prompt en I7. Reste à créer des hyperliens vers une commande, en spécifiant bien qu’il faut cacher la commande exécutée (pour ne rien afficher à part le résultat de la commande). En I6, ça serait :

print "Voulez-vous ";
VorpleLinkCommandText("la flûte", "acheter la flûte", DONT_SHOW_COMMAND);
print " ou ";
VorpleLinkCommandText("la baguette", "acheter la baguette", DONT_SHOW_COMMAND);
print ", ou ";
VorpleLinkCommand("sortir", DONT_SHOW_COMMAND);
print " ?"

Et en I7, ça donnerait :

say "Voulez-vous ";
place a link to command "acheter la flûte" reading "la flûte", without showing the command;
say " ou ";
place a link to command "acheter la baguette" reading "la baguette", without showing the command;
say ", ou ";
place a link to command "sortir", without showing the command;
say "[_]?";

Vous n’avez plus qu’à coder le résultat de chacune de ces commandes pour spécifier ce qui doit se passer si on clique sur un des liens.

Et n’oubliez pas de sortir l’invite de commande de l’ombre quand vous voulez revenir en mode parser ; c’est VorpleUnhidePrompt(); en I6 et unhide the prompt en I7.

Des choix plus complexes

Si vous voulez maintenant avoir des choix plus complexes, qui ne correspondent pas forcément à des actions, on peut adopter une autre tactique. Ça n’est pas forcément la plus maline, et il y a peut-être plus propre, mais c’est un début. Nous allons créer un faux verbe, et attribuer un numéro interne à chaque choix, de sorte à ce que lorsque le joueur clique sur le choix, le jeu exécute en secret une commande de la forme « choix 12 ». Le code en Inform 6 pour ceci serait :

[ ChoixSub n ;
   switch(n) {
      1: consequencesChoix1(); rtrue;
      ...
      87: consequencesChoix87(); rtrue;
      default: print "Bug !";
   }
];
Verb 'choix'
*number ->Choix;

Vous n’avez plus qu’à écrire les conséquences de chacun des choix, que j’ai mis chacun dans leur petite fonction pour plus de lisibilité.

Vous pouvez sans doute découper ce gros switch en plusieurs petits : écrivez une fonction avec un switch correspondant aux choix proposés au 1er étage du château, une autre pour le 2e étage, etc. ; puis et faites en sorte que le switch de ChoixSub vous envoie sur la bonne fonction.

Le code I7 est similaire. Il faut créer une action s’appliquant à un nombre (ou à un topic, au choix), puis écrire des règles carry out pour cette action (carry out choosing 1, carry out choosing 2 et ainsi de suite, avec optionnellement des conditions avec when). Si vous voulez une idée d’un code complet, vous pouvez regarder le code source de Re:Dragon par Jack Welsh (après la ligne 184) : une action qu’il appelle linkaging, et chaque conséquence est mise dans une règle séparée, de la forme after Linkaging when topicDuJour is "blablabla".

Pour finir, un petit raffinement important : la joueuse ne connaît pas a priori l’existence du verbe choix, mais si jamais elle le découvre, elle peut le taper la prochaine fois qu’elle a accès à l’invite de commandes, et ça peut lui donner accès à des choix interdits et casser le jeu ! Une solution est de bloquer ChoixSub si le prompt est visible ; pour savoir s’il l’est, il faut utiliser une commande JavaScript spéciale. Pour I6, le code devient :

[ ChoixSub n ;
  VorpleExecuteJavaScriptCommand("return $('#lineinput').hasClass('force-hidden')");
  if (~~VorpleWhatBooleanWasReturned()) return false; ! S'il n'est pas caché, ne pas lancer le reste du code
  switch(n) {...

Pour I7, une règle check semble tout à propos :

Check choosing:
	execute JavaScript command "return $('#lineinput').hasClass('force-hidden')";
	if the JavaScript command returned false, stop the action.

Et voilà : le switch ou les règles carry out/after(et l’exécution des conséquences) ne sera jamais regardé si le prompt est visible (ce qui veut dire que la joueuse a tapé « choix 12 », ce qu’elle n’est pas censée faire).

Il est aussi possible d’utiliser la convention de faire débuter toutes les commandes qui ne sont pas destinées à être tapées (et qui ne peuvent  donc résulter que d’un lien)  par deux tirets bas. On écrirait donc Verb '__choix' en I6 et Understand "__choix [number]" as choosing. D’une part, cela permet de bien différencier les commandes venant de liens ; d’autre part, il sera plus difficile de deviner une telle commande. (Bien sûr, vous connaissez désormais cette astuce si vous venez de lire ce paragraphe…)

Je termine en rappelant cet article de Corax, qui expliquait comment il avait écrit sa FI hypertexte avec Vorple et I7. Cela pourra donner plus d’idées concernant l’utilisation de liens avec Inform 7.

Voilà ! Si vous suivez cette voie pour votre projet, n’hésitez pas à écrire un commentaire pour montrer comment vous avez fait !

Le mois Vorple, c’est fini ! J’espère que ces articles vous auront donné des idées et envie d’utiliser cet outil ! Nous continuerons à écrire sur cet outil de temps en temps. Je tiens à remercier Nathanaël Marion pour son aide dans la préparation de ces articles, notamment pour tout ce qui touche à Inform 7 !