Catégorie « Développements perso »

Tintecrabe

Jeu de plateau en ligne multijoueur

Tintecrabe

TL;DR : le jeu se trouve ici.

Historique

J’ai profité du premier confinement, il y a plus de deux ans, pour démarrer un développement que j’avais en tête depuis un moment : une version web du jeu de plateau Carcassonne, de Klaus-Jürgen Wrede. En effet, ça faisait quelques années, que je réalisais de temps en temps des petites extensions et que l’idée d’avoir un environnement pour les tester sans avoir à réaliser les tuiles physiques, trouver des pions, etc. m’intéressait.

Du coup comme j’avais un peu de temps entre le télétravail et le chômage partiel, je me suis lancé. C’est parti comme un PoC, juste pour voir si c’était compliqué de rendre un plateau, placer des tuiles, etc. Finalement, comme souvent ça s’est avéré à la fois plus simple et plus compliqué que prévu ‘^^

Mais surtout ça a largement dépassé le stade du PoC pour arriver en quelques mois à quelque chose de tout à fait jouable. Et deux ans après, on en est à quelque chose d’assez abouti. Je rajoute régulièrement des nouveaux éléments et des améliorations d’ergonomie, mais les base ne changent plus trop.

J’ai rapidement évacué l’idée de rester proche de Carcassonne pour prendre mes distances à chaque fois que ça m’arrangeait : le vocabulaire reste proche de la version française d’origine, avec un certain nombre de différences. De même, si les pions et tuiles de base sont très proches, au fur et à mesure que j’ajoute des nouvelles choses, on part de plus en plus loin.

Les règles de base sont sensiblement les mêmes, mais là aussi, avec certaines différences, issues soit de contraintes techniques (j’ai simplifié certains éléments qui ne me semblaient pas apporter grand-chose), soit d’adaptations de règles qu’on applique lorsqu’on joue en famille et qui collent mieux à notre façon de jouer ou bien qui s’adaptent mieux à certaines extensions.

J’ai aussi fait un autre choix : n’utiliser aucun élément graphique du jeu d’origine. Je dessine toutes les tuiles, pions, etc (même si les premiers éléments sont très proches de ceux de Carcassonne). Ceci, pour être libéré de toute contrainte que pourrait m’imposer l’ayant droit, mais aussi parce que c’est plus satisfaisant d’avoir tout réalisé soi-même. De plus, c’est plus simple d’avoir un style homogène si c’est moi qui fais tout.

Le jeu

Le jeu est disponible ici et peut être joué soit localement (les joueurs se relaient sur la même machine), soit en ligne (l’un des joueur crée la partie puis envoie son identifiant serveur aux autres).

Tintecrabe - page d'accueil
Tintecrabe - page d'accueil

Une fois le jeu lancé, il fonctionne à peu près comme Carcassonne : on pioche une tuile, on la place sur le plateau, puis on y place éventuellement un pion.

Tintecrabe - écran de jeu
Tintecrabe - écran de jeu

Les différentes extensions et règles optionnelles apportent ensuite une foule de possibilités supplémentaires que je ne vais pas détailler ici et vous laisse découvrir.

Le jeu évolue régulièrement, donc n’hésitez pas à me signaler les bugs que vous rencontrez et me remonter vos idées, que ce soit ici ou sur Mastodon.

Aller plus loin

Hors-mis la mise en relation via l’identifiant serveur, tout se passe entre navigateurs et le “serveur” ne fait que servir des ressources statiques, ce qui veut dire que vous pouvez également vous installer le jeu en local depuis le dépôt GitLab et y apporter les modifications que vous souhaitez, voire déployer votre propre version personnalisée sur n’importe quel serveur (le code est sous licence MPL, donc faites-vous plaisir). Je n’ai pas trop documenté l’installation, du coup si vous rencontrez des problèmes à ce niveau, n’hésitez pas à me contacter, ici ou sur Mastodon.


Plugin de groupement des catégories pour Jekyll

Voici mon second plugin pour Jekyll, toujours lié à mon menu de catégories.

Contexte

En plus de 10 ans d’existence de ce blog, j’ai beaucoup varié les thématiques de mes articles. Au début j’étais purement en mode bloc-notes sur des astuces techniques pour pouvoir les retrouver facilement. Puis j’ai pas mal parlé de l’iPhone, de mes développements perso, de mes créations “artistiques” (BD, cartes Magic, etc)… à force ça commence à faire beaucoup de catégories et ce n’est plus très lisible dans une liste en vrac.

Du coup j’ai voulu refaire ce que WordPress proposait via les sous-catégories : grouper les catégories par thématiques. Je n’ai pas trouvé de plugin qui le fasse bien. J’en avais testé un qui avait l’air de faire ce que je voulais mais je n’ai pas réussi à le faire marcher… peut-être que j’aurais dû insister mais je ne l’ai plus retrouvé donc j’ai fini par décider d’en développer un moi-même. Après tout le fonctionnel est simple.

Pour le coup effectivement, rien de bien compliqué, un connaisseur de Ruby y aurait sans doute passé moins d’un quart d’heure. Bon perso je n’y connais rien à Ruby, je l’ai découvert en débugant des plugins ces trois derniers mois, donc forcément ça m’a pris un peu plus de temps mais j’ai finalement ce que je voulais ^^

Le plugin

Ce plugin se résume donc à un nouveau filtre Liquid qui prend en entrée les catégories et renvoie en sortie une un tableau à double-entrée avec pour chaque thématique un sous-tableau contenant l’ensemble de ses catégories.

Les thématiques ou « groupes de catégories » sont définis dans le fichier de configuration _config.yml, avec la liste des groupes et pour chacune la liste des catégories qui la composent. Les catégories non-affectées étant regroupées dans un groupe « Default » (une seconde entrée de configuration permettant de définir son libellé).

Le plugin ainsi qu’une documentation plus détaillée sont accessibles ici : jekyll-group-categories-filter

Utilisation sur ce blog

J’ai donc appliqué ça à ce blog en découpant la liste des catégories en 4 thématiques :

  • jeux : vu que ces derniers temps j’ai posté pas mal de trucs sur Magic et Carcassonne ça ne me semble pas superflu d’en faire une thématique à part
  • réalisations perso : mes diverses réalisations perso que ce soit du dev ou des trucs plus « artistiques »
  • informatique : un peu fourre-tout… j’ai hésité à découper plus mais j’ai du mal à délimiter les choses, donc dans l’immédiat on va rester là dessus
  • autres : tout le reste

Dans chaque thématique j’ai gardé le tri alphabétique grâce à mon précédent plugin, ce qui me donne le code suivant dans la sidebar :

<h2>Catégories</h2>
{% assign groupedCategories = site.categories | group_categories %}
{% for group in groupedCategories %}
  <h3>{{ group[0] }}</h3>
  <ul>
    {% assign categories = group[1] | sort_by_keys %}
    {% for category in categories %}
      <li><a href="/categories/{{ category[0]|slugify:'latin' }}/">{{ category[0] }}</a> ({{ category[1].size }})</li>
    {% endfor %}
  </ul>
{% endfor %}

Voilà, n’hésitez pas à me faire un retour, soit ici, soit dans le bug tracker du plugin s’il s’agit d’un bug ou d’une idée d’amélioration ^^


Plugin de tri des catégories pour Jekyll

Comme je le disais la semaine dernière, il restait des ajustements à faire sur le blog. L’un d’entre eux était d’afficher un menu présentant notamment les catégories (et aussi les archives par années mais ça viendra plus tard).

J’ai pas mal galéré pour trouver comment faire (ça me semble être un truc assez basique mais ce n’est pas trop mis en évidence dans la doc). J’ai assez rapidement fini par trouver dans quelle variable chercher les catégories (il s’agit de site.categories) qui se trouvent sous la forme d’un tableau associatif où la clé est le nom de la catégorie et la valeur un tableau des articles.

Ce qui m’a pris beaucoup plus de temps c’est trouver comment récupérer la clé lors de l’itération. J’ai fini par trouver dans la doc de Liquid (le moteur de templates de Jekyll) : lorsqu’on itère sur un tel tableau chaque item qu’on reçoit contient un tableau à deux entrées : la clé en 0 et la valeur en 1 (pour le coup je préfère les syntaxes de Twig ou AngularJS qui sont plus claires). Pour afficher les catégories, j’en étais donc arrivé à :

<ul>
  {% for category in site.categories %}
    <li><a href="/categories/{{ category[0]|slugify:'latin' }}/">{{ category[0] }}</a> ({{ category[1].size }})</li>
  {% endfor %}
</ul>

Restait à les trier parce que j’en ai quand même beaucoup… Et là pour le coup je n’ai rien trouvé de natif. Je suis tombé sur plusieurs plugins. D’abord un premier qui avait l’air riche mais que je n’ai pas réussi à faire fonctionner… Puis un deuxième beaucoup plus simple mais pas complètement satisfaisant (notamment le tri ne mettait à la fin ma catégorie “À propos du blog” à cause de l’accent). Ne connaissant rien à Ruby, j’ai un peu tâtonné pour épurer le truc et corriger ce qui me gênait.

Le résultat est accessible ici : jekyll-hash-table-sort-filters

L’exemple de code précédent, après installation du plugin, devient le suivant :

<ul>
  {% assign categories = site.categories | sort_by_keys %}
  {% for category in categories %}
    <li><a href="/categories/{{ category[0]|slugify:'latin' }}/">{{ category[0] }}</a> ({{ category[1].size }})</li>
  {% endfor %}
</ul>

EDIT du 10/06/2018 à 11h10 : forcément y avait une erreur dans la version du plugin que j’ai publiée… et qui faisait tout planter. C’est corrigé : jekyll-hash-table-sort-filters.

Et comme tout est généré une fois pour toute, je n’ai vu le problème qu’à la génération suivante, donc aujourd’hui.


AMT : archiver ses tweets

Ça faisait longtemps que je voulais sortir mes tweets et favoris de Twitter et ce pour plusieurs raisons :

  • éviter de perdre ce qui est supprimé (y compris les images)
  • faire des recherches efficaces (Twitter est lamentable de ce côté-là)
  • garder tout ça chez moi sous mon contrôle

En début d'année, je me suis finalement décidé à prendre le temps de regarder ce qui existait. J'ai fini par tomber sur Archive My Tweets qui semblait faire ce que je voulais. Et que j'ai donc installé : bingo, mes tweets sont exportés \o/

Du coup, forcément, j'ai commencé à modifier un peu le thème et traduire l'interface en français... et là c'est le drame. Comme souvent quand on creuse un peu ben c'est bugué et très limité :

  • les retweets sont tronqués
  • le thème n'est pas remplaçable sans écraser les fichiers
  • pas de système de traduction de l'interface et, pire, la moitié des textes sont directement dans le code et pas dans les templates
  • ...

Au premier bug je me dis que vais le corriger puis proposer les corrections à l'auteur. Au troisième gros changement, je laisse tomber l'idée et je pars sur un fork.

Du coup de fil en aiguille j'ai dû réécrire plus de la moitié du code pour aboutir à une application qui :

  • archive mes tweets, retweets et favoris
  • archive les images et avatars qu'ils contiennent (c'était nécessaire pour pouvoir les afficher et de toute façon c'est pas plus mal, comme ça ils sont archivés aussi)
  • permet de rechercher dans l'ensemble des tweets et de filtrer entre tweets, retweets, favoris et réponses
  • gère des traductions de l'interface (français et anglais même si je ne garantis rien sur la qualité de la seconde)
  • permet d'ajouter d'autres thèmes graphiques

J'envisage d'autres améliorations encore mais c'est déjà pas mal :)

Le code est évidemment libre (hébergé sur la forge de Framasoft) et j'ai même pris le temps de le documenter ! Quant à mon instance à moi, elle est consultable ici : tweets.darathor.net.

L'application n'est pas encore totalement stable mais n'hésitez pas à la tester. Par contre si vous l'utilisez effectivement, n'hésitez pas à m'en avertir parce que tant que personne d'autre que moi ne s'en sert, je ne perdrai pas de temps à publier des procédures de migration lors des mises à jour...

Voilà voilà... Ça faisait longtemps que j'avais plus fait un article pour autre chose qu'ironiser sur la dérive sécuritaire ^^

PS : Bon par contre, j'ai eu la mauvaise surprise de constater qu'en termes de favoris, on ne peut récupérer que les 3200 derniers (et contrairement aux tweets et retweets ils ne sont pas dans l'archive qu'on peut exporter depuis son compte). Et j'ai bien l'impression qu'ils sont vraiment perdus parce que j'ai pris le temps de supprimer tous ceux que j'avais exportés mais je suis juste arrivé à une liste vide, aucune trace des plus anciens... Ou comment perdre 10000 tweets que j'avais mis en favoris justement pour en garder une trace :blase: Ça m'apprendra à faire confiance à un silo.


Application web de gestion d'achats groupés

Voici un autre module Change que je suis en train de développer. Pour le coup il répond à un besoin très spécifique et correspond plus à un extranet qu'à un site web classique. Mais bon, puisque moi j'en avais besoin, peut-être que d'autres en auront l'usage aussi. Ou pas mais on peut difficilement savoir avant d'en parler :)

De quoi s'agit-il ?

Depuis des années, j'achète souvent sur le net, en particulier des biens culturels et ludiques : livres, mangas, DVD CD, jeux de plateaux, jeux à collectionner, jeux vidéos, etc. Grouper les achats permet en général de réduire les frais de port et en bonus allège un peu le coût écologique total des livraisons. Donc on a pris l'habitude avec mes frère, sœur et parents principalement de grouper nos achats de ce type. Ceci implique de gérer des comptes puisqu'à chaque commande, une seule personne paye effectivement et le autres doivent le rembourser. Le même principe vaut pour les cadeaux groupés ou autres courses occasionnellement faites pour le compte des autres.

S'échanger du liquide à chaque fois c'est chiant, donc pendant longtemps on est passés par du mail pour se tenir au courant de l'état du solde de chacun. Mais le mail c'est quand même assez peu adapté : quand on se plante et qu'on part du mauvais mail pour calculer les nouveaux soldes ou quand on se demande si on a bien pensé à prendre en compte tel ou tel achat c'est vite le bazar. Puis faut faire tous les calculs à la main, c'est lourd et ça introduit un risque d'erreur non négligeable.

Du coup comme on est quand même une famille de développeurs on se disait que faire une appli web accessible de n'importe où pour gérer tout ça ce serait cool et ça nous faciliterait la vie (enfin sauf ma mère qui elle se cantonne en général à rappeler qu'en achetant moins ça serait tout de suite plus simple mais avant de prendre sa retraite elle était prof de maths, pas informaticienne, donc on lui pardonne). Comme toujours, avec les supers solutions ça s'est éternisé quelques temps à l'état de projet hypothétique parce que bon, c'est bien beau de se dire qu'il faudrait le faire mais c'est quand même vachement plus simple que de le faire réellement.

Mais bon, un jour on se dit qu'au final si on veut pas arriver au point où on aura passé plus de temps à se dire qu'il faudrait le faire que le temps nécessaire pour le faire réellement il faut se lancer. Et donc il y a quelques mois j'ai pris mon courage à deux mains et finalisé une première version utilisable (loin d'être complète et ergonomiquement optimale mais utilisable).

Comme j'ai l'habitude de travailler avec Change, c'est donc un module Change. Ça aurait pu être fait avec n'importe quelle autre techno mais c'est celle là que je maitrise.

Bon et donc ça fait quoi concrètement ?

Pour l'instant ce module va vraiment à l'essentiel : il gère des "factures" (que j'aurais pu appeler aussi "transactions") correspondant à un achat dans une boutique avec le montant total payé, les réductions et les frais inclus dans ce total et enfin le détail des achats avec la répartition entre les acheteurs.

Formulaire de création d'une facture
Formulaire de création d'une facture

L'outil valide la cohérence globale de ce qui est saisi, en particulier :
- les répartitions doivent correspondre au total des quantités saisies
- le montant payé doit correspondre au total des lignes après application des réductions et frais
On évite ainsi pas mal d'erreurs de saisie.

Validation de la cohérence de la facture
Validation de la cohérence de la facture

Une fois la facture enregistrée, la répartition des coûts entre les différents acheteurs est calculée (les réductions et frais indiqués étant répartis au prorata des achats) et leurs soldes sont automatiquement mis à jour. Les différents intervenants sont alors avertis par e-mail qu'une facture qui les concerne vient d'être saisie.

Détail d'une facture
Détail d'une facture

On peut également consulter la liste des comptes utilisateurs avec leurs soldes et accéder au détail d'un compte qui donne la liste de ses factures.

Liste des comptes
Détail d'une facture
Détail d'un compte
Détail d'un compte

Et enfin on peut également accéder à l'historique complet des factures enregistrées.

Liste des factures
Liste des factures

C'est tout pour le moment, ce qui suffit à répondre nos besoins minimaux et apporte déjà nettement plus de simplicité que le mail et moins d'erreurs grâce aux différents contrôles de cohérence.

Évolutions envisagées

Même si l'ensemble répond au besoins minimaux, c'est encore loin d'être complet et ergonomique.

Gestion des boutiques

En effet, la création d'une nouvelle boutique implique de passer par le backoffice, ce qui est assez contraignant. De même il n'y a pas encore de listing des boutiques sur le site qui permettrait de suivre l'historique des dépenses dans chacune d'entre elles.

Saisie des factures

La saisie des factures est encore assez figée : tous les comptes ont systématiquement leur colonne dédiée, ce qui fonctionne à note échelle actuelle de 5 personnes mais poserait des problèmes avec une plus grosse volumétrie (qui pourrait être vite atteinte si l'on ajoute des acheteurs plus occasionnels).

De même le nombre de lignes est figé d'autorité à 30, ce qui est à la fois beaucoup trop la plupart du temps et pas assez dans certains cas exceptionnels.

Modification et validation des factures

À l'heure actuelle, les factures sont "validées" automatiquement lors de leur saisie. C'est-à-dire qu'elles ne sont pas modifiables et que les soldes des intervenants sont mis à jour immédiatement.

Pour une utilisation plus pratique et rigoureuse il est prévu d'ajouter une validation par l'ensemble des intervenant avant de mettre à jour les soldes, ceci permettant de détecter les éventuelles erreurs. De plus tant qu'elle n'est pas validée par tout le monde, la facture restera modifiable, voire annulable.

Autres évolutions envisagées

D'autres évolutions seraient intéressantes à mettre en œuvre :

  • Gestion de versements directs : dans notre cas, certaines personnes passent plus fréquemment des commandes que d'autres. Il en résulte que les soldes ont tendance à se déséquilibrer, déséquilibres qui se règlent en général par un versement (liquide, chèque, virement...). Il serait donc intéressant de pouvoir matérialiser dans une entrée dédiée un versement direct d'une personne à une autre dans un formulaire simplifié.
  • Pour certains achats (au hasard les cadeaux), il peut être pratique de ne rendre visibles certaines commandes (voire certaines lignes seulement) que par les personnes concernées (notamment pas le destinataire du cadeau).

Je ne dis pas que tout sera fait et encore moins sous quels délais mais dans l'idée c'est pour l'instant l'essentiel qu'on ait détecté comme évolutions à faire pour améliorer l'appli.

Accès au code

Comme la plupart de mes modules, celui-ci a vocation à être publié (d'ailleurs en théorie l'Afero GPL l'impose un peu) une fois qu'il sera suffisamment finalisé. Je compte également l'archiver dans un repository publique mais je n'ai pas encore tranché entre passer par un site existant genre GitHub ou SourceForge comme pour mes précédents modules (qui aurait l'avantage d'une mise en place simplifiée) et m'installer un repository local sur mon serveur avec un accès web au fichiers (qui d'un côté me plait mieux parce que je garde la maitrise de mon repository plutôt que de le stocker sur une plateforme tierce centralisée mais implique de passer du temps à le mettre en place).

Quoiqu'il en soit, si jamais quelqu'un est intéressé (sait-on sait jamais) je peux déjà lui fournir la version actuelle sur simple demande ^^