Quoter reloaded (IV) : habituelles déceptions

Comme d’habitude, passé un certain temps de développement, la motivation se dégonfle petit à petit… mais j’espère bien parvenir à boucler une version à peu près fonctionnelle. J’avais dis, il y a deux mois, que j’aurais une version fonctionnelle dans la semaine, je m’étais beaucoup trop avancé. Certes, pour le moment, l’application est utilisable, mais il y a beaucoup de choses à régler.

Voici pour les modifications déjà apportées:

- Amélioration du framework de génération de formulaire, qui laisse désormais la possibilité de générer des composants personnalisés, si on donne leur classe et la classe d’un générateur. Le code derrière n’est pas génial, mais le principe fonctionne bien et c’est refactorisable.

- Une pelletée de bugs divers et variés a été corrigé.

- L’interface a été quelque peu amélioré, mais il reste un problème de combobox devenant trop grande, je dois travailler un peu avec les options du migLayout pour rendre ça plus clair.

- La recherche a été ajouté et fonctionne à peu près (un ou deux bugs encore, à régler d’ici peu).

- J’ai ajouté une classe héritant de DefaultComboBoxModel pour gérer des combobox avec un premier objet null, qui s’affiche sous la forme d’un « ———— » dans la liste.

- Un splahscreen, toujours rigolo. Cela m’a permis de découvrir que Java, depuis la version 5, permet de lancer le splash-screen avant même le lancement de la JVM. Là où c’est un peu délicat, du coup, c’est qu’une fois que la JVM est lancée, il faut récupérer dans le code du programme le splashscreen, et tout dessiner « à la main », ce qui est un peu pénible. Du coup, le splashscreen n’est pas magnifique, mais bon…

Le principal problème va sans doute être de gérer l’affichage des citations d’une façon configurable, et je dois dire que pour le moment, j’ai un peu laissé tomber, faute d’idée. La première version ne proposera sans doute pas cette fonctionnalité.

L’idéal serait d’assurer une compatibilité avec BibTex, ce que je vais essayer de faire puisque pour le moment je peux retoucher le modèle tant que je veux. Bref, ça avance, mais j’apprends le C# en parallèle, donc je ne vais pas aussi vite que je ne devrais…

Quoter reloaded (III) : Vers une première version

Je disais que je ne voulais pas trop tout automatiser… je me repens… j’ai automatisé l’essentiel des gestions de formulaires et les objets simples sont plus que jamais faciles à gérer : une classe modèle, quelques annotations, et hop, tout est dans le sac.

Malheureusement, des objets plus complexes nécessitent des traitements à part, et je suis en train de laisser se développer du code peu propre et très lourdement couplé : la gestion du formulaire d’entrée des citations est particulièrement problématique. La première difficulté réside dans le modèle. En effet, une citation n’est pas « bêtement » localisée selon un système de page. Une citation est parfois identifiée dans un chapitre particulier. Par ex. :

Amédée Boutarel, « Forme et idéal », dans L’œuvre symphonique de Franz Liszt et l’esthétique moderne (Paris : Au Ménestrel, Librairie Fischbacher, 1886), 1-7; 2.

J’ai cherché la référence au hasard sur Internet, et je l’ai trouvé sur ce site. Une citation peut être localisée simplement selon des pages (qui selon les conventions s’écrivent différemment : j’avais l’habitude de mettre « pp. » lorsqu’il y avait plusieurs pages, mais je constate que c’est de moins en moins usité) ; elle peut l’être à la façon des pièces de théâtre, avec la série Acte / Scène (et éventuellement Vers) ; elle peut l’être pour un poème (Titre du poème – généralement entre guillemets – in titre du recueil, référence bibliographique du recueil, et enfin références des vers) ; et ainsi de suite. Bref, c’est un petit cauchemar de cas particuliers.

Pour l’heure, mon modèle estime qu’une citation comprendre une Source, une Autorité, une Localisation et une Position. La localisation comprenant une situation générale (chapitre, tome, volume, acte, scène, poème, recueil, article, etc.) et la position la situation exacte (page(s), vers). C’est déjà bien assez compliqué comme ça ! Il s’agit à présent « d’hibernatiser » toute cette partie, c’est encore loin d’être gagné.

Mais j’ai bien avancé : outre l’automatisation du traitement de 80 % des données, j’ai créé un composant permettant d’ajouter des tags, qui, du point de vue du code, est abominable, mais en pratique rend assez bien. Transformer la JComboBox de Swing en lui ajoutant l’auto-complétion n’est pas un parcours du combattant mais demande un peu d’acharnement. Cet article m’a beaucoup, beaucoup aidé.

Et enfin, pour parfaire l’IHM, il restait à avoir une zone de saisie permettant de rendre les italiques et les gras (tiens, en écrivant ce texte, je m’aperçois que j’ai oublié les soulignés… bon, plus tard !). Très honnêtement, j’abhorre la façon dont Swing gère ce genre de chose même si je ne suis pas sûr que ça soit possible de traiter plus simplement ce type de données. Une ou deux heures plus tard, j’ai quand même obtenu un résultat satisfaisant. Surtout, il fallait pouvoir stocker la mise en forme dans la base de donnée. Formater le JTextPane directement en HTML n’était pas satisfaisant (trop de balises, souvent inutiles); j’ai donc opté pour un formattage en RTF, avec parsing derrière qui se contente d’ajouter des <b></b> et <i></i> si besoin est (oui, c’est du vieux HTML tout pourri, sans <str> ou <em>, mais c’est fonctionnel). Je peux coder du RTF dans ce format minimaliste, reste à arriver à le décoder. Le tout en 2 classes et un total inférieur à 200 lignes, c’est pas si mal.

Maintenant, deux objectifs : parfaire un peu le modèle et rendre le code plus propre. Je pense essayer d’avoir une version utilisable pour la fin de la semaine prochaine (doux rêve) et nettoyer sérieusement le code après. Je sais, ça n’est pas très sérieux de repousser le refactoring à plus tard… mais je ne suis pas du tout à plein temps sur ce projet, donc, pour l’heure, on fera comme ça ! Restera ensuite surtout à coder un « transformateur » qui génèrera une référence bibliographique selon le format qu’on souhaite à partir de toutes les données stockées. Bref, encore pas mal de choses à faire.

Quoter reloaded (II) : hsqldb vs. sqlite

Quoter progresse petit à petit. Hibernate est désormais bien intégré, et le modèle de générateur de formulaire commence à montrer sa puissance potentielle.Malheureusement, j’ai du abandonner Sqlite (que j’ai toujours bien aimé…).

Le modèle de base repose sur une trilogie d’abstraction : une Citation provient d’une Source et a une Autorité (notion d’auteur). Il existe plusieurs types de Source (livre, article, archive…) et plusieurs types d’Autorité (auteur, collectif, institution…). Le type Autorité est tellement variable que c’est une classe abstraite entièrement vide :

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public abstract class Authority implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
	public long idAuthority;

	public long getIdAuthority() {
		return idAuthority;
	}

	public void setIdAuthority(long id) {
		idAuthority = id;
	}
}

Bref, une classe qui va donner une table à une seule colonne ne contenant que des identifiants. Pour des raisons complètement inconnues de moi, le module sqlite proposé pour Hibernate ne gère pas bien du tout ce cas, et la requête d’insertion me créait un magnifique :

insert into Authority values ()

Hélas, même Stack Overflow ne m’a pas permis de trouver de solution, j’ai donc décidé de changer de SGBD. L’autre solution embarquée accessible dans ce contexte était clairement Hsqldb et, malgré quelques petites avanies de configurations (par défaut, Hsqldb fonctionne uniquement en mémoire…), j’en suis très satisfait. J’ai donc des schémas générés dynamiquement sans problèmes et, pour le moment, du Create & Read qui passe très bien (et très vite, les performances d’Hsqldb sont excellentes).

Il va maintenant falloir muscler un peu la génération de formulaires… le principe actuel est très simple (et architecturalement très discutable…). J’utilise l’annotation maison suivante :

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AsForm {
	public TypesOfForm formType();
	public String label();
	public int preferredSize() default 0;
	public int order();

	public enum TypesOfForm
	{
		TEXTFIELD,
		TEXTAREA,
		CHECKBOX,
		COMBOBOX
	}
}

Pour une classe donnée, au-dessus des getters (je ne sais pas trop pourquoi j’ai choisi les getters, d’ailleurs… pas une excellente idée à mon avis !), il suffit de mettre une annotation comme celle-ci :

@AsForm(order=1, formType=TypesOfForm.TEXTFIELD, label=fieldLastName, preferredSize=15)

Order indique l’ordre d’affichage du champ lorsque le formulaire sera construit ; formType est une énumération qui permet de choisir le type de champ, le label est un code associé à la zone et on peut indiquer si nécessaire une taille préférée.

Un générateur se charge ensuite, en utilisant l’introspection Java, de lire les champs pertinents et de construire un formulaire basique. Il pioche dans un fichier de type properties avec le label pour clef afin de construire un JLabel, stocke le tout dans une classe JAutoPanel qui est un JPanel customisé, et construit le champ nécessaire (JTextField, JTextArea, etc. On peut bien sûr tout à fait concevoir un générateur utilisant un autre moteur de GUI que Swing).

Le problème est de récupérer les informations sur ces panneaux générés automatiquement, et là je dois avouer que mon manque d’expérience en programmation de client lourd me laisse quelques doutes quant à la pertinence du code employé. Pour le moment, j’ai besoin d’un JAutoPanel plutôt que d’un JPanel pour pouvoir stocker les components créés automatiquement dans des Hashtable<Label, Component>(une hashtable par type de components pour ne pas avoir à faire des casts). Derrière, le JPanel est lié par un pattern Observer / Observable à une classe de type « handler » (ce qui fera hurler tous les architectes objets puristes, et ils auront sans doute raison). L’interface pour ces handlers est assez simple :

public interface ActionHandler extends ActionObserver {
	public void manageForm();
	public void setFormToValidate(JAutoPanel panel);
	public void preFill();
}

(ActionHandler est un nom trop flou, il faut que je trouve mieux). L’interface doit pouvoir recevoir un observable (le JAutoPanel directement, pour le moment, mais je vais passer ça à un niveau plus abstrait), c’est le setFormToValidate(JAutoPanel panel). Elle doit pouvoir pré-remplir certains champs, c’est le preFill(). Et enfin, elle doit pouvoir gérer la validation du formulaire : c’est le manageForm(). Dans le manageForm, il est facile de récupérer les champs pertinents, puisque les méthodes de JAutoPanel permettent de récupérer les composants à partir de la propriété Label des @AsForm. Je pourrais automatiser tout ça, mais je préfère garder une certaine souplesse pour des traitements spécifiques – c’est rapide et facile à coder, plus qu’un calvaire de configuration si on faisait tout un système automatique.

Ce système est assez pratique (et performant surtout si on pré-crée tous les formulaires et qu’on les mets en cache ; un bon programme Java, au fond, c’est un programme qui agresse la RAM comme un sauvage au chargement, et la laisse aussi tranquille que possible à l’exécution). Pour le moment, le couplage est assez fort mais je dois pouvoir le diminuer drastiquement. La librairie miglayout est tellement puissante qu’on pourrait rajouter plus de configuration sur le formulaire et obtenir quelque chose de plus joli (et plus configurable).

Surtout, pour le moment, j’ai besoin de gérer ce que j’évite soigneusement jusqu’à présent, c’est à dire un panneau à onglet pour sélectionner les différents sous-types (par exemple : « Auteur / Collectif / Institution »). J’évite aussi parce que ça signifie qu’il faut que je soigne de plus près le modèle, et l’art des bibliographies est un véritable calvaire…

Quoter reloaded (I)

Lors de ma dernière tentative de créer un blog « geek oriented », j’avais mentionné un projet sur lequel je planchais : Quoter, un gestionnaire de citation. Il s’agissait de porter en client lourd et en Java une application PHP que j’avais déjà créée. Après avoir perdu beaucoup de temps dessus, j’ai finalement abandonné ce projet et oeuvré sur d’autres sujets dans d’autres langages. Le travail m’ayant permis de faire du Java à très hautes doses, j’ai décidé de revenir sur ce projet mais en le reprenant à zéro.

Voilà le périmètre fonctionnel de l’application:

- Quoter a pour but de permettre de stocker des citations. L’outil étant plutôt orienté pour la recherche, il suppose plutôt qu’on va lire systématiquement un livre, enregistrer celui-ci dans la base de donnée de l’application; au fur et à mesure qu’on le lit, on rentrera plusieurs citations tirées du livre.

- Le système doit donc disposer de fonctionnalités CRUD (Create, Read, Update, Delete) de base. Lorsque l’utilisateur cherche une ou plusieurs citations, l’affichage doit donner, en plus de la citation, la référence bibliographique standard, sous deux formats: référence complète, et référenceavec Ibid., de telle sorte qu’il suffise de faire un copier / coller pour obtenir la note de bas de page. Le format exact de la citation doit pouvoir être configuré. Idéalement (mais là, c’est optionnel), l’outil doit pouvoir cracher une bibliographie (au format OpenOffice ou Word si la librairie POI le permet).

Les objectifs « techniques » sont les  suivants :

- Extensivité maximale de l’application. Dans la mesure où des applications de ce type existent déjà et que je doute parvenir à leur faire une concurrence sérieuse, cette « extensivité » est vraiment plus un challenge que je me donne à moi-même qu’autre chose. La première fois que j’ai codé Quoter en Java, j’ai constaté qu’il y avait de nombreux problèmes liés aux différents types de bibliographies et références possibles. Outre la complexité des références pour les revues, actes de colloques, périodiques, etc., se pose la question des profils d’utilisateurs. Ainsi, un chercheur en Droit pourrait vouloir stocker des références à des codes (français ou internationaux, avec chacun leurs propres règles). Bref, je livrerai l’application finale avec un module assez simple (livres et périodiques, plutôt orienté recherche en histoire / littérature), mais on doit pouvoir rajouter assez simplement de nouvelles classes, permettant de gérer des références plus complexes. Je n’ai aucune idée précise sur comment faire ça exactement, mais c’est le challenge.

- Le moins de lignes de code possible. C’est évidemment un objectif pour tout projet. Ici, j’entend l’appliquer de plusieurs manières différentes. La première version de Quoter utilisait une connexion JDBC qui contraignait à écrire moi-même les requêtes. Outre que c’était lourd, que ça posait plusieurs problèmes d’architecture, et que c’était laid, ça aurait compliqué la possibilité d’ajouter de nouvelles classes à l’application. Je pars donc sur du Hibernate classique. Evidemment, ça pose plusieurs problèmes (génération à l’exécution d’un nouveau type de base selon le genre de classes que l’utilisateur va utiliser, et laisser Hibernate faire lui-même l’ensemble du schéma, ce qui risque d’être très bugogène).

Deuxième (et très gros) problème lié au premier Quoter, la gestion de l’IHM. J’utilisais à l’époque Netbeans et ses outils graphiques, mais entre temps, il m’est devenu encore plus pénible d’avoir du code autogénéré, et là encore, l’ajout de nouveau type de données poserait de gros problèmes. Il me faut donc au moins un générateur automatique de formulaires pour l’ajout de données. J’ai codé un peu à l’arrache un système à base d’annotation que je présenterai dans un prochain billet.

- Les meilleures performances possibles. Et qui dit meilleures performances, dit : limiter les accès à la BDD. D’où, passage dans la RAM de l’essentiel des données. Evidemment, ça posera problème si l’utilisateur se retrouve avec un énorme corpus de citations, mais sur une machine un tant soit peu moderne, c’est on ne peut plus gérable. Le problème est bien sûr d’arriver à organiser le cache d’une façon suffisament intelligente pour que la recherche puisse se faire sans SQL. Je pense que des grosses, grosses hashtable vont être utiles…

 

Les outils pour tout ça :

- Eclipse pour le développement. Un peu moins lourd que Netbeans.

- A terme, sans doute du Maven pour les build et le déploiement, mais je n’en suis pas encore là (et l’intégration de Maven dans Eclipse est vraiment mal foutue).

- ORM : Hibernate, connecté à une base SQLLite pour que l’utilisateur final n’est pas à se compliquer la vie.

- Swing pour l’IHM.

 

Ca me paraît assez raisonnable. Je connais nettement mieux le Java côté serveur que côté client riche, mais en essayant d’automatiser et de laisser « open for extension » un maximum de choses, j’ai de bonnes chances d’arriver à tout coder.

Dwarf Fortress : de la futilité en jeux vidéo

Nota Bene. Cet article avait d’abord été écrit sur mon blog Posterous. Comme je ne m’occupe plus d’icelui, et qu’il a de grande chance de se faire supprimer, je le rappatrie donc ici.

 

Beaucoup, beaucoup de choses ont déjà été écrites sur Dwarf Fortress, et pourtant il y a quelques chances pour que le lecteur, fut-il un hardcore gamer qui le revendique haut et fort, ignore jusqu’à l’existence de ce jeu extraordinaire. Lacune à corriger dans les plus brefs délais. Ceux qui le connaissent peuvent sauter mes premiers paragraphes de présentation. Ceux qui n’ont pas envie d’y jouer et ne s’intéressent pas aux jeux vidéos peuvent également passer directement à la deuxième partie de ce billet, avec ce résumé très bref : Dwarf Fortress est au jeu vidéo de gestion ce qu’Evelyn Waugh est à la littérature. (Le lecteur qui ne s’intéresse ni aux jeux vidéos, ni à Evelyn Waugh, est invité à revenir plus tard – et à lire Scoop sans plus tarder, ça le déridera un peu).

Présentation sommaire à l’intention du néophyte

Il y a, dans le monde du jeu vidéo, des fous plus ou moins dangereux. Prenez Peter Molyneux, qui, outre laisser à n’importe qui la possibilité d’exercer ses pulsions autocrates, décrit chacun de ses jeux comme la vie 2.0. Ou encore Will Wright, qui a poussé la simulation jusqu’à l’absurde (et le degré zéro de la gameplayitude) – et prouvé qu’on pouvait amasser une quantité effarante d’argent par la même occasion. Mais il faut bien le dire : Tarn Adams, le seul et unique développeur de Dwarf Fortress, est probablement le plus dangereusement atteint de tous. L’histoire de Tarn Adams, toutefois, est un véritable conte de fée geek. Voilà quelqu’un dont la création (pourtant en freeware) a eu tellement de succès qu’il a peu arrêter d’enseigner les mathématiques pour se concentrer pleinement et entièrement au développement.

Maintenant, de quoi parle Dwarf Fortress ? Vaste question… à laquelle on apportera d’abord une réponse terre à terre. Tarn Adams l’a développé en abandonnant un projet de RPG-3D trop ambitieux qu’il ne parvenait plus à maîtriser. Il y a de quoi sourire, parce que Dwarf Fortress n’est pas dénué d’ambition. Ce jeu vous offre deux possibilités : diriger une forteresse naine dans un monde généré automatiquement (avec un niveau de détail géographique et géologique qui frise la démence, plusieurs centaines d’années d’histoires et de légendes pré-générés, une gestion des civilisations principales, une génération de noms en plusieurs langages – là encore, avec une quantité de vocabulaire légèrement effrayante) ; ce mode étant le coeur du jeu. Ou incarner un aventurier dans le même univers pré-générés et visiter la… ou plus probablement les nombreuses ruines de forteresses que vous aurez désespérément tenté d’édifier. Voilà pour le principe général.

Deuxième chose à dire : Dwarf Fortress, ou DF pour les intimes, est, pour les puristes, un jeu qui se joue en ASCII. Donc, ça ressemble à ça :

Evidemment, c’est un peu austère. D’où l’emploi, pour ceux que le charme de l’ancien rebute ou qui n’ont pas perdu d’innombrables heures à jouer à NetHack sur leur console. Avec un tileset, le jeu peut ressembler à ça :

 

Dwtst

(Nous avons ici une modeste forge, sur la gauche ; le gros truc rouge à droit étant l’extrêmité d’une piscine de magma alimentant ces petites forges). Bon, on le voit, ce ne sont pas les graphismes qui forment le point fort. Mais par là même DF démontre spectaculairement un postulat que tout joueur connaît bien : le gameplay n’a rien à voir avec les graphismes.

Le gameplay de Dwarf Fortress, précisément, est sans conteste possible, là où il se démarque. Pour avoir joué à de nombreuses simulations économiques, j’ai rarement rencontré un tel degré de précision et de richesse. Y compris dans les détails les plus inutiles. Prenez le bois, par exemple. Dans la plupart des jeux médiévaux, il y a un moment où il faut aller récupérer du bois, comme ressource primaire. C’est « du bois ». Dans Dwarf Fortress, même si la notion de « bois » existe, vous n’irez jamais couper « du bois » : vous allez couper un hêtre. Ou un bouleau. Ou un cyprès. Ou diverses variétés imaginaires sous-terraines. Ca ne sert absolument à rien (concrètement, le joueur se contente de désigner une énorme zone boisée et dire : « allez-y les gars, coupez tout », mais quand on regarde les stocks de bois, chaque fagot est identifié en fonction de son type exact), mais c’est à ce genre de détails qu’on commence à comprendre le degré avancé de démence du concepteur.

De même, on ne va pas bêtement avoir des « pierres » et des « métaux ». Ni bêtement « miner » ou « creuser ». Vos mineurs iront plus ou moins vite selon qu’ils piochent dans de la roche sédimentaire, métamorphique… etc.  La simple liste des différentes roches laisse rêveur. Les corps sont gérés avec le même principe quasi-encyclopédique, et on ne s’étonnera donc pas, après un combat quelque peu rude, de trouver parmi les objets au sol « le 3e doigt de la main gauche » d’un de ses nains (lequel, bien sûr, s’il est gauché, s’en verra diminué dans la plupart des tâches qu’il entreprendra).

Le système économique est de même extrêmement élaboré. Il faut tout construire à partir de rien, meubles, décorations, armes ; cultiver une bonne dizaine de plantes ; gérer une population animale qui à parfois tendance à exploser ; plus les visites d’envahisseurs divers et variés, en nombre et irritants (goblins qui vous inviteront à rechercher des délices de sadisme en cherchant tous les pièges possibles et imaginables), ou seuls et monstrueux (dragons, titans et tout le toutim). Je passe sur l’apparition soudaine, passé un certain développement, d’un véritable système économique alors que vos nains vivaient dans une espèce d’anarchie joyeuse, qui vous obligent à gérer crise du logement et pouvoir d’achat tandis qu’une aristocratie capricieuse et insupportable vient tout perturber à coups de décrets absurdes et d’exigences aussi pénibles que redoutables à satisfaire.

Les mécanismes de jeu repose sur un principe délicieusement pervers : le joueur ne contrôle pas vraiment les nains. Il peut donner de grandes indications (où creuser, que construire…) mais il ne peut pas s’emparer de l’un d’entre eux et lui dire : « Maintenant, fais ça ». Et il est merveilleusement agaçant de voir son distillateur décider qu’il va faire une pause au moment même où les stocks d’alcools sont bas (les nains ne boivent pratiquement que de l’alcool, sauf s’ils sont malade; à défaut, ils boiront de l’eau, mais leur moral va en prendre un sacré coup). De même, l’équilibre de la forteresse peut être déstabilisé très rapidement si quelque chose ne tourne pas rond. Un de vos nains ne va pas fort ? Il risque de s’énerver et de tout casser sur son passage. Ou de tuer quelqu’un. Ou d’aller se faire tuer. Si votre nain avait fait ami-ami avec tout le monde, ses proches se désoleront de son trépas éventuel. Et se mettront à aller mal. Et risquent donc, eux aussi, de disjoncter. Et ainsi de suite.

Je n’ai pu donner un aperçu que très, très incomplet des principes du jeu, et j’invite ceux qui seraient intéressés à s’y pencher de plus près. C’est gratuit, il vous faut juste abandonner de nombreuses heures pour trouver le temps d’y jouer mais surtout de l’apprendre, parce que ce n’est pas franchement le petit casual-game facile à intégrer.

De la profondeur vidéoludique de Dwarf Fortress

Mais venons en aux aspects les plus intéressants de ce jeu et ce qui le rendent unique malgré des principes souvent empruntés ici ou là : son caractère auto-référentiel ; sa dimension narrative ; et enfin son aspect philosophique.

Le début d’une partie de DF est toujours le même : vous avez sept nains (oui, comme dans Blanche-Neige), dont vous choisissez les spécialités et l’équipement, qui se retrouvent dans un environnement plus ou moins hostile. Mais même en choisissant un coin tranquille, ne vous y trompez pas : l’environnement est toujours hostile. Les débuts sont difficiles, laborieux et à tout moment, quelque chose peut venir tout casser. Or la situation du joueur est exactement la même. De même que les nains peinent à tirer la moindre chose de leur environnement, de même, le joueur novice doit passer beaucoup, beaucoup de temps à apprendre les mécanismes du jeu (et, s’il a opté pour la version ASCII, son interface). Une bonne centaine de raccourcis claviers différents, des possibilités d’actions infinies, et des tas de problèmes en perspective. Même le moment d’apprentissage initial passé (souvent grâce à tel ou tel tutoriel), chaque nouvel aspect du gameplay va exiger de se remettre à tâtonner.

Un exemple simple : le jeu gère très précisément les fluides, essentiellement l’eau et le magma. La nécessité de nourrir les nains poussera  très vite le joueur à chercher à créer une agriculture. Problème : dans 95 % des cas, cela nécessite soit de cultiver en plein air (solution dangereuse et source de problèmes dès que les voisins commencent à s’agiter, peu commode logistiquement, et peu satisfaisante intellectuellement), soit d’irriguer le sol. Une rapide recherche sur le wiki de DF vous montrera qu’il existe quatre ou cinq systèmes d’irrigations différents (plus d’innombrables variantes). Le temps de les maîtriser, de comprendre les principes physiques derrières… il y en a déjà pour un nombre d’heure variable en fonction de votre motivation. Plus tard, voire beaucoup plus tard et plusieurs parties après, vous arriverez à un puits de magma. Nouveau problème : comment tirer profit de cette mane dont tout le monde parle comme d’un don des dieux mais qui représente autant d’occasion de griller votre population ? Nouveaux tatonnements, et ainsi de suite. Même pour s’habituer à la « 3e dimension » (le jeu vous propose en effet d’étendre votre forteresse très, très, mais alors très en profondeur, et 160 étages différents devraient vous suffire amplement pour loger tout le monde et produire ce dont vous aurez besoin).

Si on fait abstraction des limites de l’interface liés à la complexité et aux nécessités d’un graphisme minimaliste, le jeu est pensé pour être difficile à appréhender sans être pour autant mal conçu. Et quand, avec l’expérience, on bâtit à l’entrée des couloirs cyclopéens dans lesquels on place amoureusement de quoi exterminer une petite invasion gobline, on réalise que c’est exactement ce que le développeur a fait avec son utilisateur final.

La devise, devenue très populaire, de ce jeu est : loosing is fun. S’il s’agissait, à l’origine, d’une boutade, la communauté fort active des joueurs s’est approprié cet aphorisme, à tel point que le wiki ne dit jamais « this could lead to the destruction of your fortress » mais « this is a source of (massive) fun ». Contrairement à de nombreux jeux de ce type, Dwarf Fortress postule bien que la partie a un début et une fin. Il est, bien sûr, théoriquement possible, d’optimiser à tel point sa stratégie pour survivre perpétuellement. Mais dans la majorité des cas, tel ou tel événement s’abattra sur votre fortresse et vous forcera à l’abandonner (à moins de faire partie des gens tenaces qui attendent la destruction du dernier nain, errant à moitié estropié dans les couloirs, fuyant quelque envahisseurs, innondation ou incendie). La chaine des causalités amenant à cette hécatombe, du reste, n’est pas gratuite, contrairement aux désastres de Sim City qui s’abattait sur votre cité pour un oui ou pour un non. Les envahisseurs pénètrent parce que vous n’avez pas bien fermé les portes. Les incendies arrivent parce que vous avez laissé du matériel inflammable traîner là où il ne fallait pas. Les nains s’autodétruisent parce que la mort plane sur la forteresse ou parce qu’ils n’ont plus assez de nourriture, suite à tel ou tel désastre (ou accident de gestion de votre part, ahem !).

Le but du jeu est de raconter des histoires. N’importe lesquelles, pourvu que ce soient des histoires. La page d’accueil du jeu l’indique bien du reste ; elle génère une phrase aléatoire, toujours du type « Histories of X and X« . Par exemple, en trois essais : « Histories of greed and entreprise« ; « Histories of jealousy and perseverance« ; « Histories of glutonny and exertion« . En cela, le jeu a trouvé un remarquable équilibre entre l’implication du joueur (hors laquelle point de gameplay) et son manque de contrôle de l’univers (la fatalité de l’histoire s’exerce encore et toujours).

Si Tarn Adams développe pratiquement tout seul (et il y a vraiment là un tour de force, quand on voit la complexité du jeu – même si certaines optimisations seraient salutaires au processeur, notamment en terme de pathfinding), il réfléchit à ce qu’il va ajouter avec son frère. C’est à deux, notamment, qu’ils ont conçus le générateur d’histoire du monde, permettant d’associer à chaque univers créé ses propres mythes, légendes, dynasties, et ainsi de suite. Si, comme tout générateur, on voit parfois un peu trop les ficelles et la mécanique derrière, la volonté de narrer est toujours au coeur du projet. La plupart des projets à long terme de développement visent du reste à enrichir cette dimension. Sur un dilemme classique (liberté du joueur vs. narration), DF arrive à trouver un équilibre particulièrement réussi, impliquant le joueur dans l’histoire, lui laissant une grande liberté notamment par la profusion d’organisation possible, tout en lui imposant malgré tout les mécanismes d’un monde hostile. Le joueur écrira la conclusion de certains récits, mais fatalement, l’histoire de sa propre forteresse s’achèvera à un moment, et le mode « Aventurier » permettra de la relire d’un tout autre point de vue.

Le monde du jeu vidéo paraîtrait facilement futile, surtout à celui qui ne le connaît pas. Nous sommes un certain nombre à refuser cette idée, et à croire à la neutralité du média – il faut juger sur les contenus. Dwarf Fortress donne une véritable leçon sur la futilité. En plongeant sans cesse dans le chaos le monde ordonné, économique, huilé et mécanique des nains, en dressant le tableau de l’éternelle hostilité des événements, en faisant assister, parfois en quelques instants, à la destruction de longs et patients efforts, comme les mandalas de sables que certaines sectes bouddhistes assemblent durant des heures et des heures avant de les détruire, Dwarf Fortress amène nécessairement à appréhender la futilité, sans pour autant en faire l’éloge. Dépeindre n’est point louer, et au contraire, DF n’amène nullement au nihilisme, puisque les ruines de la forteresse demeurent comme signe qu’elle a existé, quand le mandala de sable est totalement soufflé à la fin de sa réalisation. Ce n’est pas parce que les choses sont fragiles qu’elles perdent tout leur sens ; c’est parce qu’elles sont fragiles que leur sens ne réside pas dans le fait de leur existence et dans la foi en leur immuabilité.

On touche ici en somme à un thème particulièrement intéressant (et problématique) : le masochisme intellectuel des encyclopédistes. On retrouverait ce genre de thématique, au cinéma, chez un Greenaway. L’encyclopédisme répète la tragédie de  Babel : la volonté humaine de tout brasser, et le spectacle éternel du déversement chaotique qui en résulte. En mettant en abîme ce thème, consciemment ou non, le jeu de Dwarf Fortress invite à sonder cet éternel problème, et à ne pas tomber dans les deux travers qu’il génère perpétuellement : l’obscurantisme blasé, d’un côté, la foi aveugle en la nouvelle Babel à construire, de l’autre. DF fait vasciller le joueur d’un côté comme de l’autre, mais ne le laisse jamais tomber.

Il n’est de gravitas qui ne succombe à la loi de la gravité. On me permettra donc cette conclusion darwinienne à ce premier aphorisme newtonien : à la fin, seule la mutation finit par vaincre, parce qu’elle laisse toujours la solution à son l’avenir. En fin de compte, ce sont les optimistes qui ont raison. Mais trève de philosphie, qui n’exprime que maladroitement (l’heure tardive n’aidant pas) ce que le jeu véhicule bien mieux. Rendez-vous sans plus tarder l’essayer (sur toute plateforme ! Linux et Mac OS compris !), et, munissez vous de patience et de sens de la futilité.