Cybernimos : Un overlay JDR pour OBS piloté par Google Sheets
Des animaux anthropomorphes cyberpunk, des jets de dés et un overlay OBS piloté par Google Sheets
Aperçu général
Depuis peu, on joue (sporadiquement) à un jeu de rôle dans un univers qui mélange cyberpunk et animaux anthropomorphes.
Nous sommes quatre personnages aux talents divers (bagarre, investigation, pilotage, hacking) à la recherche de petits boulots qui tournent souvent mal.
Pour jouer, on utilise notamment une feuille Google Sheets partagée qui centralise les fiches des personnages et les jets de dés. Ce qui m’a amené à la question suivante :
Comment développer un overlay de jeu de rôle original sans avoir à afficher les webcams des joueurs et des joueuses ?
Comment synchroniser les informations d’une feuille Google Sheets en quasi temps réel dans un overlay de jeu de rôle ?
L’idée était de créer un overlay JDR pour OBS capable de récupérer certaines informations depuis Google Sheets et de les transformer automatiquement en éléments graphiques : statistiques des personnages, points de vie, armure, monnaie, jets de dés, mais aussi scènes dédiées aux personnages et indicateurs de prise de parole.
Concevoir l’overlay JDR
Les premières maquettes
Je ne pensais pas que ça irait si loin au début.
Je m’étais juste contenté de faire quelques tests sur Figma, essentiellement des bandeaux avec les personnages et leurs noms.
Une fois passée la première session de jeu, j’ai travaillé sur les premières maquettes de l’overlay : les scènes, les divers éléments d’overlays et les mises en forme des personnages.
Je suis passé par pas mal d’allers-retours pour trouver des idées, des couleurs satisfaisantes et des “gimmicks” graphiques.
J’ai finalement abandonné l’idée des webcams. Ça prend beaucoup de place, ça rigidifie assez vite la composition et, dans ce cas précis, je trouvais que les illustrations des personnages racontaient déjà suffisamment de choses.
Pour l’overlay, quasiment tous les éléments graphiques, hormis les illustrations, ont ensuite été codés en HTML/CSS/JavaScript.
Et comme j’utilise déjà régulièrement NodeCG pour mes expérimentations d’overlays, je m’en suis servi comme intermédiaire pour gérer et rassembler tout ça.
Connecter Google Sheets à OBS avec NodeCG
C’est finalement là que le projet devient un peu plus intéressant.
Notre jeu est un “homebrew” (un jeu fait-maison), plus ou moins adapté avec le système de jeu “Powered By the Apocalypse” (PBtA), qui se joue principalement avec 2d6.
On joue sur un Google Spreadsheet partagé, mis en forme par RandallFlagg, dans lequel chaque personnage dispose de sa propre fiche.
On y retrouve notamment les points de vie, l’armure, les statistiques, les compétences et les fameux 🥕 Carotcoins.
L’idée était donc de faire le chemin suivant :
Google Sheets → API Google Sheets → NodeCG → overlay HTML/CSS/JavaScript → OBS Studio
NodeCG joue ici le rôle d’intermédiaire. J’ai développé un petit script maison qui utilise l’API Google Sheets pour aller chercher certaines valeurs dans le tableur et les transmettre aux différents éléments de l’overlay.
Quelles données sont récupérées ?
Pour chaque personnage, je récupère notamment :
- les PV maximum et actuels, afin de générer une barre de vie
- le niveau d’armure
- les statistiques de base : Force, Dextérité, Intelligence, Sagesse et Bagout
- le nombre de 🥕 Carotcoins (la monnaie du jeu)
Je récupère également les informations liées aux jets de dés.
Pour chaque nouveau jet, le script peut notamment récupérer :
- Pour les jets de dés :
- la date et l’heure du dernier lancer : pour être sûr d’afficher le dernier joué
- le personnage qui a effectué l’action
- la compétence utilisée, par exemple Force, Voler dans les plumes ou Hacker
- La formule du jet de dés avec le modificateur : 2d6 +2, 2d6 -1
- Le le résultat de chaque dé : 🎲5 🎲1 🎲0 +2
- Le total du jet
Le problème du temps réel
Évidemment, je me suis rapidement retrouvé face à un petit problème.
L’API Google Sheets n’est pas vraiment pensée pour que je lui demande en permanence : « Alors ? Il y a un nouveau jet ? Et maintenant ? Et maintenant ? ».
Étant donné les quotas de requêtes, je limite donc la récupération des données à une requête toutes les deux secondes environ.
Pour les statistiques des personnages, ce n’est pas vraiment gênant, mais pour un jet de dés en revanche, ça l’est davantage.
Le résultat peut mettre quelques secondes à apparaître sur l’overlay, ce qui casse un peu l’impression de temps réel. Ça fonctionne, mais ce n’est clairement pas la solution la plus élégante.
Une version plus avancée pourrait utiliser un système permettant de pousser directement l’événement vers NodeCG plutôt que d’interroger régulièrement la feuille.
Pour un prototype, cela suffit et cela m’a permis d’au moins valider le concept.
Les scènes FOCUS
Une fois les données accessibles, il fallait évidemment leur trouver une place dans l’overlay.
Les scènes FOCUS servent à montrer un personnage en particulier.
Chaque scène est composée du personnage en version « holographique », avec différents shaders et effets, ainsi que d’un écran qui récapitule ses informations : nom, points de vie, armure et statistiques.
Les shaders, que ce soit via du code ou les plugins OBS, c’est rigolo et joli mais c’est gourmand en ressources. Au final j’ai du drastiquement réduire les shaders pour éviter de mettre le PC à genoux ¯\(ツ)/¯
Dans mon jargon, j’appelle ça des scènes “FOCUS” car c’est le mot-clé que je mets systématiquement au début du nom de scène sur OBS (c’est très important).
J’utilise toujours le même préfixe parce que j’ai codé un petit script sur NodeCG qui repère toutes les scènes OBS dont le nom commence par ce mot-clé. NodeCG peut ensuite les lister automatiquement.
Résultat : dès que je change d’overlay de JDR, hop, la liste se met à jour et je peux m’en servir comme télécommande.
C’est un détail, mais c’est typiquement le genre de petit système qui devient très pratique dès qu’on commence à avoir beaucoup de scènes.
Le « Codec » façon Metal Gear Solid
J’appelle ici “Codec”, le module qui permet d’afficher deux personnage à l’écran.
Je me sers de cette scène pour les phases de jeu où l’on se concentre sur une discussion entre deux personnages, ou pour illustrer des conversations à distance.
Et forcément, la référence était assez évidente et je me suis fait plaisir : Metal Gear Solid.
Chaque personnage dispose de sa propre barre de volume, réalisée avec le plugin Waveform.
Côté technique, j’ai codé un petit panneau d’administration sur NodeCG pour choisir qui apparaît dans la colonne de gauche et qui apparaît dans la colonne de droite.
L’idée est de pouvoir changer les personnages sans avoir à bricoler directement les scènes OBS à chaque fois.
Je sélectionne les deux personnages dans NodeCG et le module s’occupe du reste.
Afficher les jets de dés en temps réel
C’est probablement la partie qui m’a demandé le plus de réflexion.
Je savais récupérer les données depuis Google Sheets, mais il fallait maintenant transformer un résultat de tableur en événement visuel suffisamment lisible et amusant à regarder à l’écran.
À chaque nouveau jet effectué dans la feuille de calcul, toutes les informations sont consignées dans une feuille dédiée aux logs.
Le script va ensuite chercher la dernière entrée. Il récupère le personnage, la compétence, la formule du jet, les différents résultats et le total.
Il peut alors transmettre ces informations à l’overlay et déclencher l’affichage correspondant.
Le principe est donc assez simple : un nouveau jet apparaît dans Google Sheets → NodeCG le détecte → les données sont transmises à l’overlay → l’animation du jet se lance
L’animation est encore un peu bancale et ça manque parfois de réactivité, mais ça fonctionne plutôt bien.
Et surtout, c’est assez satisfaisant de lancer un dé dans le tableur et de le voir quelques secondes plus tard apparaître directement à l’écran.
Cybernews : une chaîne de télévision dans le jeu de rôle
Durant la seconde session, une autre idée est venue avec le MJ.
Pourquoi ne pas créer un bulletin d’informations afin de donner de petits indices sur les intrigues aux joueurs et aux joueuses en cours de partie ?
Et comme nous étions déjà dans un univers cyberpunk avec des animaux anthropomorphes, il fallait évidemment une chaîne de télévision complètement fictive.
Bienvenue sur Inter Terrier News.
J’ai repris et réadapté une petite animation réalisée avec GSAP pour en faire une sorte d’introduction de chaîne de télévision.
Puis j’ai codé le faux écran de télé avec les différents éléments graphiques.
J’ai notamment pas mal travaillé sur les bandeaux du bas et l’affichage des différentes illustrations.
Encore une fois, j’ai fini par créer un petit module permettant de préparer les bandeaux et de les diffuser à la volée.
C’est typiquement le genre de fonctionnalité qui n’était absolument pas prévue au départ.
Mais une fois que j’avais le système de modules et de données en place, c’était finalement assez facile de détourner l’outil pour faire autre chose.
La scène principale
Il fallait évidemment une scène plus classique pour les phases normales de jeu.
On y retrouve les hologrammes des personnages et, pour chacun et chacune, un petit écran de statistiques avec uniquement les informations les plus utiles :
- PV actuels et maximums
- armure
- argent
- classe et espèce du personnage
L’idée était de garder suffisamment d’informations à l’écran pour que les spectateurs puissent suivre la partie, sans transformer l’overlay en énorme fiche Excel.
Détecter automatiquement qui parle
Je ne suis pas particulièrement fan des overlays de JDR qui affichent systématiquement les caméras des joueurs et des joueuses.
Souvent, ça prend beaucoup de place, ça n’apporte pas forcément grand-chose ou ça rend l’habillage assez rigide (mais ca dépend des fois).
Ici, je voulais tout de même avoir un moyen de savoir qui est en train de parler.
J’ai donc préféré intégrer des indicateurs vocaux directement aux personnages.
Séparer les voix avec VDO.Ninja
Tout d’abord, j’ai créé un salon vocal commun sur VDO.Ninja.
L’intérêt est de pouvoir récupérer les pistes voix de chaque personne séparément grâce à des liens personnalisés.
Dans une scène dédiée sur OBS, je rassemble ensuite chaque voix dans une source « Navigateur ».
Cela me permet ensuite de les avoir séparément dans le mélangeur audio.
Et à partir de là, je peux m’amuser avec les plugins OBS.
Détecter la prise de parole avec Advanced Scene Switcher
J’utilise notamment Advanced Scene Switcher, un plugin d’automatisation pour OBS.
J’ai créé une macro pour chaque voix qui fonctionne sur un principe assez simple :
si le volume du micro dépasse un certain seuil pendant au moins 0,5 seconde → afficher l’indicateur vocal
Sinon : masquer l’indicateur.
J’utilise ensuite le plugin Waveform pour afficher une forme d’onde audio par personne.
Dans la scène « Codec », j’active simplement la waveform correspondant au personnage sélectionné dans NodeCG.
Cela permet d’avoir une sorte de version « webcam-less » du traditionnel indicateur de prise de parole.
On voit le personnage, on voit son nom, et quand la personne parle, l’overlay réagit.
C’est beaucoup plus cohérent avec la direction artistique que d’ajouter quatre webcams dans des petits rectangles.
Quelques limites et pistes d’amélioration
Ce projet m’a surtout permis de tester jusqu’où je pouvais pousser un overlay JDR pour OBS en connectant plusieurs outils entre eux. Et évidemment, tout n’est pas parfait.
Le premier problème reste la réactivité des données Google Sheets. Le système de polling fonctionne, mais deux secondes peuvent être assez longues lorsqu’on vient de lancer un jet de dés.
Une autre piste serait de revoir complètement la manière dont les événements sont transmis à NodeCG afin d’éviter de devoir interroger régulièrement le tableur.
Côté graphique, les shaders sont également à surveiller.
C’est très joli, jusqu’au moment où OBS commence à demander gentiment au PC pourquoi on lui fait subir ça (j’ai pas une très grosse carte graphique).
J’ai donc dû réduire certains effets pour conserver des performances acceptables.
Il y aurait également pas mal de choses à améliorer dans les animations, notamment pour rendre l’apparition des jets de dés plus spectaculaire et surtout plus immédiate.
Et évidemment, maintenant que le système est en place, il serait assez facile d’ajouter encore d’autres modules :
- des événements et alertes liés aux statistiques des personnages
- davantage d’animations pour les jets de dés
- des transitions automatiques entre certaines scènes
- de nouveaux écrans façon interface cyberpunk
- des interactions supplémentaires avec le Google Spreadsheet
- ou même un système permettant au MJ de piloter davantage d’éléments directement depuis NodeCG
Fiche technique
Fonctionnalités
- Synchronisation des données de Google Spreadsheet via NodeCG
- Changement de scène via NodeCG
- 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
- Univers et jeu
- Kobal
- Illustrations des personnages
- RandallFlagg_ & Kobal