Apercu général

Cet overlay OBS est synchronisé en temps réel avec FoundryVTT. Les points de vie, l’armure, les jets de dés, les changements de décor et même les animations des personnages sont mis à jour automatiquement pendant la partie grâce à NodeCG et aux sockets de FoundryVTT.

Présentation de l'overlay JDR Arkonautes

Depuis quelques temps, on joue à plusieurs et à distance à une campagne de jeu de rôle. Petit à petit, notre lore (la mythologie et l’histoire de notre jeu) s’est étoffé et j’ai fini par en faire un overlay assez complexe au final.

On joue via FoundryVTT, un service qui permet de jouer à distance, de gérer sa fiche de personnage, jeter les dés. On joue à Dungeon World, qui utilise le système de jeu PBtA.

Petit à petit, le projet à pris de l’ampleur et deux questions se sont imposées :

Comment imaginer et développer un overlay de jeu de rôle original sans avoir à afficher les caméras des joueurs et des joueuses ?
Comment synchroniser les informations de FoundryVTT en temps réel dans un overlay de jeu de rôle ?

C’est un overlay assez complexe, tant au niveau graphique que technique. D’une part pour l’intégration avec FoundryVTT pour récuperer des données de jeu, d’autre part pour la construction de l’overlay qui comprend une grande part de développement.

Récuperer les données de jeu : le grand périple

La pierre angulaire de cet overlay est la synchronisation entre les visuels affichés à l’écran et les informations de jeu de FoundryVTT.

La synchronisation des informations de jeu et d’un overlay fait partie d’une longue phase de réflexion autour du format jeu de rôle et j’ai déjà eu l’occasion d’expérimenter quelque chose de similaire avec des feuilles de calcul Google Spreadsheet.

J’ai fait beaucoup de recherches là dessus et je n’ai trouvé personne proposant quelque chose de similaire, j’ai donc beaucoup galéré pour développer le système.

L'overlay affiche les infos des personnages (points de vie, armure, stats…) en temps réel.
L’overlay affiche les infos des personnages (points de vie, armure, stats…) en temps réel

Pourquoi les logs ne suffisent pas ?

Lors des premiers tests, j’ai réussi à extraire des informations venant des logs.

A chaque nouvelle session de jeu, des fichiers consignent tous nos événements de jeu : changement de points de vie, modification d’une statistique, jets de dés…

J’ai donc commencé par faire un script qui, toutes les 2 secondes, récupérait dans ces fichiers les nouvelles informations pour chaque personnage, ainsi que le dernier jet de dés.

Dès qu’un nouvel événement avait lieu, comme un changement de points de vie, le log consignait une nouvelle entrée qui ressemble à ça. :

Un exemple tiré du log, un gros pavé de texte non formatté, avec diverses statistiques de personnage dedans (pv, armure, argent…)
Un exemple tiré du log, un gros pavé de texte non formatté, avec diverses statistiques de personnage dedans (pv, armure, argent…)

Dans cet amas de données, je pouvais récupérer des valeurs type : Points de vie, Points de vie max, Armure, Statistiques (Force, Dextérité…) pour ensuite les afficher dans l’overlay.

Les premiers tests pour l’overlay ressemblaient à ça :

Premier test, changer les valeurs du personnage modifiait le fichier HTML contenant les infos à gauche
A droite, changer les valeurs du personnage modifiait le fichier HTML contenant les infos à gauche
Premier test d'affichage des jets de dés, avec un visuel plus poussé
Premier test d'affichage des jets de dés, avec un visuel plus poussé

Cette méthode était clairement assez laborieuse et bancale. Certains logs présentaient souvent des problèmes d’encodage de caractères qui pétaient tout mon script et le tout manquait de réactivité, car je ne pouvais pas récupérer les infos en temps réel.

Une autre limitation venait du fait que si FoundryVTT est hébergé sur un serveur à distance, il y a quelques galères de configuration pour pouvoir accéder à ces logs de l’extérieur (coucou le Cross-Origin Resource Sharing).

Récupérer les données via le socket de FoundryVTT

Au fur et à mesure de mes tests, j’ai commencé à retravailler sur une méthode qui n’avait pas marché jusque-là.

J’ai repéré le “socket” utilisé par FoundryVTT, un port de communication qui gère l’échange de données entre le serveur le client web et j’ai codé un script qui surveille les événements durant le jeu pour récupérer les infos en jeu.

Quelques infos des jets de dés récupérés sur la console de NodeCG
Quelques infos des jets de dés récupérés sur la console de NodeCG

Cette méthode n’est pas parfaite mais à deux avantages : une récupération plus simple des infos et en temps-réel !

Cela fonctionne plutôt bien mais le principal obstacle à l’heure actuelle est la difficulté de pouvoir décliner simplement cette méthode sur d’autres systèmes de jeu, pour l’instant je ne l’utilise que sur le système PBtA.

A terme, j’ai carrément developpé mon propre plugin FoundryVTT (encore en privé et en tests) pour assurer une livraison plus simple et formatée des données de jeu, adaptable pour n’importe quel système de jeu !

Premiere maquette visuelle de l’overlay

Côté graphisme, j’ai mis beaucoup de temps à trouver la bonne idée car les premiers tests graphiques ne me plaisaient pas vraiment.

Pour moi, un des soucis de certains overlays est le fait de vouloir afficher tout le temps les caméras des joueurs et des joueuses. C’est sympa mais souvent cela prend souvent énormément de place et alourdit énormément le rendu visuel. Afficher 4 ou 5 webcams rend l’overlay assez vite brouillon.

J’ai tout de même fait des premiers tests assez satisfaisants mais ce n’est pas la direction vers laquelle je souhaitais aller, par exemple :

Premiere maquette visuel de l'overlay sur OBS

Au niveau de l’identité graphique, j’avais commencé à décliner certains éléments (avatars, cartouches de personnage…) sur Figma au format SVG, pour pouvoir ensuite dynamiquement les remplir avec les données que je récupérais du jeu.

Les templates graphiques réalisés sur Figma
Les templates graphiques réalisés sur Figma.
Les premiers tests d’affichage des jets de dés sur l’overlay
Les premiers tests d’affichage des jets de dés sur l’overlay
Les différentes cartouches des personnages
Les différentes cartouches des personnages

Le visuel définitif de l’overlay

Après pas mal de tests, j’ai fini par creuser une idée d’overlay dans le style d’un petit théâtre de marionnettes, type “guignol”. Un petit théâtre avec un fond, des lumières et où les personnages sont représentés par des petites poupées/marionnettes.

On retrouve principalement deux types de scènes : une scène principale et une scène Focus.

La scène principale

La scène principale de l’overlay, qui ressemble toutes les marionnettes des personnages

La scène principale rassemble tous les personnages et chacun dispose d’une petite cartouche avec son nom, sa classe, ses points de vie et son armure. On ne le voit pas ici, mais la scène peut afficher d’autres éléments, comme un panneau pour afficher les résultats des jets de dés par exemple.

Les scènes “FOCUS”

Les scènes “FOCUS” servent à montrer un personnage en particulier.

Une scène Focus pour chaque personnage, avec son avatar et ses infos

Les scènes “Focus” (dans mon jargon), servent à mettre en avant un personnage. Chaque scène montre donc le personnage, son blason, un fond personnalisé et un carton récapitulatif des statistiques.

J’ai paramétré une transition de scène particulière, pour faire en sorte que le personnage apparaisse du dessous et le carton de stats par la droite ou par la gauche (c’est bête mais c’est pas si simple à faire).

Afficher les jets de dés automatiquement

Une grosse partie du travail a été de trouver un moyen sympa d’afficher les résultats des jets de dés des joueurs et des joueuses.

Un panneau avec les résultats du jet de dés se déploie en haut de l’écran
Un panneau avec les résultats du jet de dés se déploie en haut de l’écran

J’ai crée un template de panneau au format SVG, et codé un script qui permet de récupérer certaines infos quand un jet de dé est fait sur FoundryVTT. Cela active une animation qui fait apparaitre un petit panneau du haut de l’écran.

Le script me permet de récupérer et d’afficher les informations suivantes :

En fait, récupérer ces données via le socket a été plus dur que prévu. Je pensais que les données seraient facilement accessibles, mais elles ne sont pas présentés de la même manière selon s’il s’agit d’un jet public, d’un jet basé sur la fiche de personnage, ou d’un jet du maître de jeu, etc.

Les jets de dés sur FoundryVTT s’affichent en temps réel sur l’overlay

J’ai également mis en place une liste de phrases personnalisées qui s’affichent en fonction du personnage, de la compétence et du résultat du jet de dés.

Le système de jeu utilise principalement deux dés à six faces et des modificateurs (-1, +1, +2…). Les résultats sont classés en trois catégories :

J’ai donc listé de nombreuses phrases qui se déclenchent aléatoirement en fonction du score et de la compétence.

Une liste de phrases personnalisées pour la compétence “FORCE”, au format JSON
Une liste de phrases personnalisées pour la compétence “FORCE”, au format JSON

Animer les personnages par la voix, avec Advanced Scene Switcher

Pour représenter les personnages, j’utilise les avatars dessinés par RandallFlagg_, que j’ai ensuite décliné sous forme de marionnettes sur Figma.

Les marionnettes s’activent et une bulle de dialogue apparait quand le joueur ou la joueuse prend la parole
GIF - Les marionnettes s’activent et une bulle de dialogue apparait quand le joueur ou la joueuse prend la parole

Comme je ne souhaite pas afficher les webcams des joueurs et des joueuses, il faut trouver un moyen de dynamiser et montrer qui parle, et quand. Ainsi quand un joueur ou une joueuse parle, un système permet d’activer une animation de la marionnette et afficher un indicateur vocal.

Je décline la marionnette dans un fichier HTML avec deux animations : une simple animation de flottement au repos, mais une animation de mouvement quand elle est “active”. Une petite bulle animée s’affiche également.

Pour faire cela, j’ai crée un salon vocal VDO Ninja et j’utilise un système de liens personnalisés pour récupérer séparément la voix de chacune des personnes connectées.

Ainsi, je récupère séparément les voix via une source “Navigateur Internet”, qui s’affichent ensuite dans le mélangeur audio d’OBS.

Sur OBS, les voix sont récupérées via une source “Navigateur Internet” et apparaissent ensuite dans le mélangeur audio
Sur OBS, les voix sont récupérées via une source “Navigateur Internet” et apparaissent ensuite dans le mélangeur audio

Ensuite j’utilise Advanced Scene Switcher, un plugin qui permet de créer des macros et des actions automatiques dans OBS. Ainsi j’ai crée une macro pour chaque joueur et joueuse :

Si le volume de la voix est supérieur à un certain seuil pendant 0.5s, alors masque la marionnette en mode “repos”, mais affiche la marionnette en mouvement, ainsi que la bulle de dialogue

Et inversement si la personne arrête de parler.

La macro utilisée par le plugin “Advanced Scene Switcher” pour animer la marionnette au son de la voix
La macro utilisée par le plugin “Advanced Scene Switcher” pour animer la marionnette au son de la voix
La macro utilisée par le plugin “Advanced Scene Switcher” pour animer la marionnette au son de la voix
La macro utilisée par le plugin “Advanced Scene Switcher” pour animer la marionnette au son de la voix

Changer dynamiquement le décor de jeu

Pour renforcer l’aspect pièce de théâtre, j’ai imaginé un petit système de changement du décor qui vont et viennent depuis le haut de la scène.

Le module NodeCG à droite permet d’afficher et masquer différents objets et décors

J’ai donc commencé à coder sur NodeCG un module de gestion du décor pour faire apparaitre différents types de fond (taverne, forêt, donjon…), mais également des objets animés (torches, nuages, lune…)

J’ai également commencé à créer des presets, des configurations toutes faites en un clic, comme par exemple un fond de forêt avec des nuages et la lune.

Les personnages dans un décor de forêt, avec des nuages, la lune et un effet de pluie
Les personnages dans un décor de forêt, avec des nuages, la lune et un effet de pluie

Des effets de confettis pour les effets de sang et de soin

Quelques confettis rouges volent quand un personnage prend des dégâts
Quelques confettis rouges volent quand un personnage prend des dégâts

J’utilise la librairie Javascript “Canvas Confetti” pour générer des gerbes de confettis et illustrer les soins et les dégâts. Chaque effet est accompagné d’un petit visuel qui décompte les PVs reçus ou gagnés.

Le système de confettis en action, quand un personnage gagne ou perd des points de vie

Pour aller plus loin, j’ai mis en place trois configurations pour l’effet de sang, selon le nombre de dégâts pris :

Fiche technique

Fonctionnalités

  • Synchronisation des données de FoundryVTT via NodeCG
  • Plugin fait-maison pour ordonner les données
  • Affichage des statistiques des personnages (hp, armure)
  • Affichage des jets de dés en temps réel
  • Animation des personnages au son de la voix
  • Compatible OBS Studio via une Source Navigateur

Outils et technologies

Crédits

Illustrations des personnages et objets
RandallFlagg_
Univers du jeu
Kobal