Aperçu général

Démonstration de l'overlay JDR Cybernimos dans OBS Studio

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.

Premiers tests graphiques pour l'overlay JDR Cybernimos sur Figma
Les premiers tests graphiques sur Figma, avec des bandeaux pour les personnages
Bandeau de bas d'écran avec avatar et informations du personnage
Un premier bandeau avec l'avatar et les informations du personnage

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.

Première maquette de l'overlay JDR Cybernimos avec webcam
Une première maquette qui devait à l'origine faire apparaître la webcam du joueur ou de la joueuse

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.

Maquettes finales des différentes scènes de l'overlay JDR Cybernimos sur Figma
Sur Figma, les maquettes des différentes scènes et des différents personnages

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.

Google Sheets contenant les fiches des personnages et les jets de dés de Cybernimos
Le Google Spreadsheet qui sert à gérer les personnages et les jets de dés

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 :

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 :

Google Sheets et affichage des données du jet de dés dans l'overlay OBS
À gauche, le tableur avec les données du personnage et du jet. À droite, les informations récupérées apparaissent directement dans OBS.

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.

Scène FOCUS d'un personnage dans l'overlay JDR Cybernimos
Une scène FOCUS : le personnage à gauche et ses informations à droite

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).

Liste des scènes FOCUS de l'overlay JDR dans OBS Studio
Les différentes scènes FOCUS dans OBS Studio

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.

Gestion des scènes FOCUS de l'overlay JDR avec NodeCG

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.

Le codec sur l'overlay
Le codec tel que representé sur l'overlay sur OBS

Et forcément, la référence était assez évidente et je me suis fait plaisir : Metal Gear Solid.

Le codec de Metal Gear Solid
Le codec tel qu'il est représenté dans 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.

Panneau NodeCG permettant de choisir les personnages du Codec

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.

Affichage d'un jet de dés sur l'overlay JDR Cybernimos
Le résultat d'un jet de dés affiché sur l'overlay

À chaque nouveau jet effectué dans la feuille de calcul, toutes les informations sont consignées dans une feuille dédiée aux logs.

Journal des jets de dés dans Google Sheets
Les logs des différents jets de dés dans le Google Spreadsheet

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

Synchronisation d'un jet de dés entre Google Sheets et l'overlay OBS
Le jet effectué dans Google Sheets est ensuite affiché dans l'overlay

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.

Un jet de dés effectué dans Google Sheets déclenche son affichage dans l'overlay OBS

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.

Écran de télévision Inter Terrier News dans l'overlay JDR Cybernimos
L'écran de télévision d'Inter Terrier News qui affiche les informations en cours de partie

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.

Démonstration de l'affichage des informations Cybernews dans l'overlay JDR

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.

Scène principale de l'overlay JDR Cybernimos avec les statistiques des personnages
La scène principale qui récapitule les informations essentielles des personnages

On y retrouve les hologrammes des personnages et, pour chacun et chacune, un petit écran de statistiques avec uniquement les informations les plus utiles :

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.

Indicateur vocal affiché à côté d'un personnage dans l'overlay JDR
L'indicateur vocal apparaît lorsqu'une personne prend la parole

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 ».

Scène OBS regroupant les différentes sources vocales de VDO.Ninja
Une scène OBS qui rassemble séparément les voix des différents joueurs et joueuses

Cela me permet ensuite de les avoir séparément dans le mélangeur audio.

Mélangeur audio OBS avec les différentes voix séparées
Chaque voix apparaît séparément dans le mélangeur audio OBS

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.

Macro Advanced Scene Switcher utilisée pour détecter la prise de parole
La macro qui détecte quand une personne prend la parole
Indicateur vocal qui apparaît et disparaît selon la voix de la personne

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.

Waveform audio affichée à côté du personnage qui parle dans le Codec
Une barre de volume apparaît lorsque le personnage parle dans le Codec

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 :

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