Homemade Pixels

Des pixels frais qui sortent du four le blog de MrHelmut.

Archive pour novembre 2012

« Articles plus anciens

Il y a peu, j’ai ressorti Hoy de mes cartons afin de le montrer en public à une soirée. Je ne l’avais pas modifié depuis sa création qui m’avait pris une poignée d’heures au cours de la Global Game Jam 2012. J’avais entre temps pesté sur la politique de licensing de Microsoft au sujet de Kinect sur PC, puis plus ou moins abandonné l’idée de continuer tout développement sur Hoy. Mais le ressortir a été une bonne occasion pour m’y remettre, et notamment pour passer à la dernière version du SDK Kinect qui, entre la création de Hoy et aujourd’hui, est passé de la Beta 2 à la version finale 1.6.

Pas de bol pour moi, les changements dans le SDK étaient plutôt majeurs et j’ai du au final re-coder l’ensemble de Hoy (pas bien long cela dit, en tout et pour tout, j’ai 600 lignes de code). Quitte à tout refaire, j’en ai profité pour remettre à plat mon algorithme de reconnaissance de postures. D’où le présent article, histoire de poser un peu la démarche.

(Lisez l’article en pleine page si les figures sont rognées.)

Mais qu’est-ce que Hoy déjà ?

Voir la vidéo de gameplay.

Hoy est un jeu PC pour Kinect au principe tout simple : une posture apparait à l’écran, le joueur doit la reproduire et crier “Hoy !” pour la valider. Si elle est bien reproduite, le jeu passe à la posture suivante. Le but du jeu est alors d’enchainer un maximum de postures en une minute, l’ordre des postures étant aléatoire (parmi 10 postures différentes).

Un principe tout bête mais qui marche diablement bien en soirée et qui fait perdre des kilos (et donnait des méga crampes à son concepteur avant que le SDK Kinect n’intègre Kinect Studio).

L’enjeu, d’un point de vue programmation, est de reconnaître ces fameuses 10 postures avec Kinect. Mais en fin de compte, Kinect n’a pas grand chose à voir la dedans, c’est un problème purement algorithmique.

Les 10 postures de Hoy

Les 10 postures de Hoy.

Le SDK Kinect, la simplicité même

Le SDK Kinect officiel a un très très gros avantage sur ses “concurrents” (tels que OpenKinect) : l’API est d’une simplicité rare et la reconnaissance du corps est très performante.

Je vous aurais bien fait un article dédié à l’utilisation du SDK, mais honnêtement, il est déjà super bien documenté et sa mise en œuvre est un jeu d’enfant. C’est simple, en C#, cela se résume à de la programmation événementielle : on déclare un délégué qu’on associe à un événement. Et voilà, c’est fini, Kinect appelle alors votre délégué à chaque fois qu’un (ou des) squelette est reconnu (30x/seconde). Le SDK vous renvoie alors l’intégralité des squelettes, des jointures reconnues, leurs positions dans l’espace, leurs angles, etc. Et il se charge aussi tout seul du tracking.

Tous les joints que Kinect reconnait

Tous les joints que Kinect reconnait.

Première version de Hoy, approche très naïve

Dans la première version que j’avais développé, complètement à l’arrache en ~4h, j’avais implémenté une reconnaissance ultra basique où je mesurais simplement le positionnement de points relativement à d’autres. Prenons l’exemple de la posture suivante.

Les joints important dans la reconnaissance de cette posture

Les joints important dans la reconnaissance de cette posture.

Grosso modo, pour déterminer si le joueur est en train de faire cette posture, je vérifie si les coudes sont vers l’extérieur (elbowRight.X < handRight.X && elbowLeft.X > handLeft.X) et que les mains sont bien levées au dessus de la tête (handRight.Y < head.Y && handLeft.Y < head.Y). Simple comme bonjour, et efficace dans la majorité des cas.

Problème : plus on a de postures différentes, et plus certaines conditions commencent à se recouvrir. Dans les faits, l’algorithme a des fois des ratés et peut considérer une posture comme étant valide alors que le joueur en fait une autre qui partage des similarités. Par effet de bord, si le joueur valide une posture et que la posture suivante fait parti de ces cas limites, alors le jeu valide directement la posture (car très peu de temps s’est écoulé et que le cri de validation est encore actif). Pour résumer, mes conditions et mes postures ne sont pas suffisamment discriminées pour que cette approche soit optimale. De plus, Kinect part ponctuellement en sucette et donne pendant une fraction de seconde des valeurs aberrantes, qui parfois peuvent ressembler à une posture.

Résultat : le jeu accorde bien plus de postures qu’il n’est censé le faire, et donc dans de rares cas, 2, 3 ou 4 postures peuvent être validées d’un coup d’un seul.

Donc Thomas W., si tu me lis, NON, TU N’ES PAS LE CHAMPION DE HOY, tu as juste fait un putain de bug exploit. ^^ (Et le connaissant il me répondra que les bug exploit font parti de la maîtrise d’un jeu, et enchainera avec les speedruns, etc.)

J’ai tenté bien des choses pour amortir le problème. Ajouter un timestamp pour empêcher trop de validations si le joueur cri comme un barbare, empêcher que des postures trop semblables se suivent, avoir des conditions plus nombreuses et précises, etc. Ça marchait plus ou moins, mais je n’en étais pas vraiment satisfait parce que ça atrophiait un peu trop le gameplay rapide du jeu.

Nouvelle version, pattern matching et apprentissage

Un autre problème de la méthode précédente est que les valeurs des conditions ont été choisies sur base de ma propre physionomie et de ma propre compréhension des postures. Ce qui fait que le jeu n’est pas adapté à tous et ça énerve certains joueurs. Je considère qu’à partir du moment où le joueur doit crier 4 fois “Hoy !” pour valider, mon algorithme a chier dans le pâté. Et ça arrivait régulièrement.

Comment faire pour que ma reconnaissance soit générique pour toutes les physionomies, tout en ayant un certain degré de tolérance pour que tout le monde fasse les postures à sa façon et tout en levant le problème de l’ambiguïté entre certaines postures ? Le Pattern Matching ! (ou reconnaissance de patron)

Le pattern matching consiste à comparer deux ensembles de points entre eux, point à point, et de mesurer une “distance” entre ces deux ensembles. Plus la distance est courte, plus les deux ensembles sont similaires. C’est par exemple ce type d’algorithmes qui est utilisé pour la reconnaissance d’empreintes digitales (les points étant les nœuds et imperfections naturelles de votre peau). Voyez un peu ça comme une version informatique d’un jeu de formes pour enfant.

Une illustration un peu quelconque du pattern matching piqué au pif sur google images (http://www.cs.helsinki.fi/research/pmdm/cpm/)

Une illustration un peu quelconque du pattern matching piqué au pif sur google images (source en lien sur l'image).

Un tel algorithme repose alors sur une base de données de patterns (ensembles de points) représentant les postures à détecter.

Une schématisation de la base de données de patterns de Hoy (et non, le point dans l'entre jambe n'est pas ce que vous vous imaginez, bande de perverts).

Une schématisation de la base de données de patterns de Hoy (et non, le point dans l'entre jambes n'est pas ce que vous vous imaginez, bande de pervers).

Une fois que l’on a une base de données de points, on compare tous les patterns à ce que Kinect a reconnu comme points. Dans la pratique, j’ai implémenté un algorithme de comparaison point à point assez simple connu, elastic matching. Vous ai-je déjà dit que je suis chercheur en informatique ? Car oui le lien précédent pointe vers un article scientifique et que ça m’arrive de mettre en application une partie de mes recherches dans mes jeux (en l’occurrence, j’ai repris un algorithme que j’avais déjà développé pour faire de la reconnaissance d’écriture manuscrite, ça marche aussi à base de points). En sorti de cet algorithme, on a un histogramme du résultat de la reconnaissance.

Un exemple de reconnaissance, une valeur de 1 étant une concordance parfaite avec une figure.

Un exemple de reconnaissance, une valeur de 1 étant une concordance parfaite avec une posture.

On peut alors aisément supposer que la posture ayant le meilleur taux de reconnaissance est la posture que le joueur est bel et bien en train de faire. Bingo ? Pas tout à fait.

Le problème des algorithmes de matching (cette catégorie ci en tout cas) est que leur qualité dépend grandement de la base de données de patterns sous-jacente. Dans mon cas, cette base de données a été faite à partir de mes propres postures, et donc toujours de ma seule et unique physionomie. Ce qui fait que l’algorithme marche très bien avec des gens qui me ressemblent, mais lorsque que d’autres personnes s’y collent, les taux de reconnaissance se resserrent. Comment être certain que la meilleure posture reconnue est bien la bonne lorsque la suivante a à peine 2% d’écart ? L’incertitude est trop faible pour que l’on puisse conclure de manière sure, et donc valider la posture en toute sérénité.

Il faut donc construire une base de patterns la plus générique possible, et pour cela, j’ai enregistré tout un ensemble de patterns sur la base de postures de deux amis à la physionomie radicalement différente de la mienne. Résultat ?

Le même exemple qu'avant avec une base de patterns composées à partir de plusieurs personnes.

Le même exemple qu'avant avec une base de patterns composées à partir de plusieurs personnes.

Les écarts sont beaucoup plus importants ! Ce qui signifie que deux choses : qu’il y a beaucoup moins d’ambiguïté entre les postures et que l’algorithme est beaucoup plus tolérant aux différentes physionomies.

Mieux encore, la base de données de patterns peut être enrichi à volonté au fur et à mesure que Hoy est joué. Vous vous souvenez des postures mal reconnues où le joueur cri plus de 4 fois ? Lorsqu’un tel cas de figure survient, je considère toujours que l’algorithme a merdé, mais ici, je peux ajouter la posture du joueur au pattern de la posture qu’il est censé reproduire. Ceci aura pour effet d’alimenter la base de donnée et de la rendre de plus en plus générique au fil des échecs de l’algorithme. En d’autres termes, Hoy apprend et devient de plus en plus performant au fur et à mesure qu’il est joué.

A titre de comparaison, l’algorithme de Kinect qui reconnait le squelette a un peu été conçu de la même manière. Sauf que chez Microsoft, on n’y va pas avec le dos de la cuillère et on utilise des centaines de milliers d’échantillons. Et je suis persuadé que des jeux comme Dance Central fonctionnent sur ce genre de principe, avec une dimension temporelle en plus cela dit (car il s’agit de mouvements, et non plus de simple poses).

Fun facts autour de Hoy

  • Je ne reconnais pas le mot “Hoy” en tant que tel lorsqu’un joueur le cri. Je reconnais uniquement le volume ! C’est assez rigolo car le tutoriel demande bien de dire “Hoy”, mais la supercherie est telle que les gens ne s’en rendent pas compte et crient “Hoy” comme des damnés ^^. Tout ce que je fais, c’est une mesure du bruit de fond à chaque début de partie pour déterminer le seuil de volume qui représente un cri. Kinect peut faire de la vrai reconnaissance vocale, mais il y a une trop grande latence pour que ce soit exploitable dans le gameplay rapide de Hoy.
  • Dans sa première version, sur certaines postures, je ne reconnaissais pas tout. Par exemple sur les postures avec les bras bien écartés, je ne faisais pas de reconnaissance sur les bras. On pouvait mettre les bras comme on voulait. Mais les joueurs étaient bernés par le fait que l’image leur demandait d’écarter les bras, et en faisaient donc autant. Je me suis bien poilé à regarder les gens jouer tout en sachant qu’ils transpiraient pour RIEN.
  • Kinect permet de localiser spatialement un son. En clair, on est capable de déterminer si c’est bien le joueur qui vient de crier. J’ai donc voulu implémenter un mode versus, où deux joueurs font chacun des postures et doivent crier. Dans la théorie c’était parfait, mais Kinect ne fait pas de mesure de son suffisamment rapidement. Il donne la position générale d’un son que toutes les 500ms environ, un temps beaucoup trop grand qui est bloquant. J’ai donc laissé tomber le mode versus.

Si vous n’êtes pas membres wefrag, vos commentaires peuvent être recueillis par mail :

contact

Les Game Jam font beaucoup parler d’elles ces temps-ci. Entre la Global Game Jam, l’Adventure Time Jam, la Fuck This Jam, le Ludum Dare, l’initiative de Game Dev Party, la 0h Jam et j’en passe des plus farfelus comme la Jean-Claude Van Damme Jam, on peut dire qu’on est servi.

Mais en tant qu’organisateur local de la Global Game Jam et ayant participé à certaines d’entre elles, il y a un point particulier que j’aimerais clarifier au mieux : il ne faut pas avoir peur de participer.

Je m’explique, en faisant ma pub à droite et à gauche, auprès des passionnés de jeux vidéo qui ont un brin de compétence en programmation, dessin, game design ou qui touche un peu d’un instrument, j’ai typiquement une réaction à effet kiss-cool.

1) “Ça a l’air génial !”

2) “Mais je n’ai jamais créé de jeux… Ce n’est pas pour moi !”

Une réaction tout à fait compréhensible fasse à l’inconnu. Mais à ces gens la, j’aimerais leur dire une simple chose : vous avez une raison d’autant plus grande de venir participer à une Game Jam !

Pourquoi ? Clarifions quelques points.

“Je n’ai jamais participé à la création d’un jeu vidéo. Ai-je ma place dans une Game Jam ?”

Vous avez même plus que quiconque votre place dans une Game Jam ! C’est justement le moment d’essayer et de se bloquer du temps pour le faire. Tout le monde est passé par une première fois.

Un Game Jam est un lieu de partage et d’apprentissage. Ce n’est pas une compétition, et la majorité des autres participants sont très curieux de voir ce que les autres sont en train de faire. Les gens n’hésites pas à parler avec vous, à vous donner des conseils, à vous demander pourquoi vous faites tel ou tel choix, à rigoler devant les idées loufoques des autres, etc. C’est un véritable échange entre passionnés, et certains de vos interlocuteurs seront des professionnels qui se feront une joie de vous conseiller alors qu’en temps normal ils sont parfois difficiles d’atteinte.

Une Game Jam est une école, on y ressort toujours plus grand. Quoi qu’il arrive à la fin des 48h, vous aurez forcément appris quelque chose. Sous la contrainte du temps, vous aurez appris à mieux travailler avec vos outils, à mieux gérer votre temps et des situations de crises, et vous aurez surement appris beaucoup des autres.

Et plus que tout, vous vous serez amusé.

Besoin d’exemples ? J’en ai plusieurs de l’année dernière à la GGJ de l’Est.

Plus de la moitié des participants n’avait jamais créé de jeux avant. Ils ont tous, sans exception, terminé leur jeu.

Un professionnel n’a pas hésité à faire le tour de la salle entre deux cafés, et à aider les gens quand ils étaient embourbés. Il a notamment conseillé des musiciens sur leur musique, il a montrer des outils spécialisés à des graphistes qui ne connaissaient pas les méthodes associées à la création de jeux, etc.

Une équipe a littéralement appris à faire des jeux iPad. Ils sont arrivés les mains dans les poches (ou presque), et après le pitch de départ, ils ont décidé de faire un jeu iPad alors qu’aucun des membres de leur équipe n’avait ne serait-ce que touché à de l’Objective-C… Ça leur a valu le nom de l’Agence Tous Risques mais voila, ils ont terminé leur jeu ET ils ont appris à faire des jeux pour iOS. Deux d’entre eux sont même en passe d’en faire une activité professionnelle.

Une autre équipe s’est composée de 7 développeurs et d’un seul graphiste/game designer ! Ils ont appris à leur dépend que sur un petit projet de 48h, se répartir un travail à 7 sur une techno pas toujours adaptées est couteux. Mais avec cette expérience, ils savent que cette année il vaut mieux répartir les équipes et bosser sur une techno avec un prototypage plus rapide.

Et même dans l’échec vous apprendrez. Prenons l’exemple d’une équipe qui au bout de 12h de travail, se rend compte que leur prototype est beaucoup trop ambitieux et que les outils qu’ils utilisent ne leur sont pas adaptés. Ils n’ont pas hésité à tout mettre à la poubelle et à quand même terminer un jeu dans les temps, même si ce n’était qu’un Snake++ ! Ils auront appris à mieux gérer l’ampleur d’un projet et ont très bien géré la situation de crise.

Le résultat n’est pas important, la participation l’est ! On peut tirer un enseignement de chaque participation.

“Mais, je suis graphiste/développeur/musicien, je ne sais pas faire un jeu de A à Z !”

Justement ! Une Game Jam est l’endroit idéal pour rencontrer des gens qui vous complètent.

Une Game Jam se fait essentiellement en équipe, et vous trouverez toujours quelqu’un sur place pour bosser avec vous.

N’est-il pas intéressant d’enfin pouvoir se lancer dans la création d’un jeu alors que vous ne pouviez pas le faire seul ?

Mieux encore, bosser ensemble lors d’une Game Jam peut créer des affinités. Pourquoi ne pas se lancer dans un projet après le Jam ? Je dirais que bien 50% des jeux créés ont une vie après une Game Jam.

“Mes amis ne sont pas vraiment branchés sur la création, je n’ai pas envie de venir seul.”

Vous passerez alors à côté de l’opportunité de rencontrer des gens qui peuvent vous aider à concrétiser vos idées ! Les autres passionnés comme vous n’ont qu’une envie : partager et avancer ensemble dans un but commun, créer votre propre jeu.

C’est une expérience que l’on peut capitaliser et peut être un premier pas dans l’industrie du jeu vidéo

Dites-vous bien que, au bout des 48h, vous aurez un produit “fini”. Ou en tout cas, vous aurez quelque chose dont vous pourrez être fier et afficher sur votre portfolio. Plus vous ferez de Game Jam, plus celui-ci sera gros.

Je ne sais pas pour vous, mais moi, j’ai bien du mal à trouver du temps pour terminer un projet que j’ai commencé. Alors que dans une Game Jam, on a un résultat exploitable. C’est donc idéal pour se bloquer du temps utile.

J’ai aussi vu des participants se faire recruter en plein Game Jam. Une Game Jam aide aussi beaucoup à construire votre communauté, à vous faire connaître.

N’oubliez pas que…

…une Game Jam n’est pas une compétition, mais un moment de franche camaraderie, rigolade et de découverte autour d’une passion que l’on a tous en commun : la création de jeux.

Si vous adhérer au concept, si l’idée d’un Game Jam vous donne cette petite lueur de passion, alors vous avez votre place dans un Game Jam et rien d’autre ne doit venir vous contredire.

Venez nombreux et nombreuses !

Je vais encore vous bassiner avec ça, mais les 25-27 janvier, c’est la Global Game Jam. Si il y a une Game Jam à laquelle vous devez participer, c’est celle-ci. C’est la plus grosse au monde et le fait qu’elle se déroule en simultané dans le monde entier lui rajoute une ambiance unique.

La liste des villes de France qui y participent est disponible par ici. Et c’est maintenant qu’il faut s’inscrire ! Les places partent très vite.

Et le teaser qui résume tout

YouTube Preview Image

Fort d’une belle édition 2012 à Metz, le Global Game Jam de l’Est de la France est de retour, cette fois à Nancy ! 48h de création de jeux vidéo et de jeux de société, avec une ambiance hors norme. Ca se passe toujours le dernier week-end de janvier, soit les 25-27 janvier 2013 pour cette nouvelle édition.

Global Game Jam de l'Est de la France - 25-27 janvierUn Game Jam, c’est quoi ?

Prenez des game designers, illustrateurs, développeurs et musiciens, amateurs ou professionnels, enfermez les ensemble pendant 48h, mélangez le tout, et vous obtenez un étonnant cocktail de jeux vidéo et de jeux de société ! En d’autres mots, un game jam est un rassemblement ponctuel dont le but est de créer des jeux en 48h.
Quel intérêt ? Créativité, innovation, challenge et surtout une ambiance unique entre gens passionnés !

Et le Global Game Jam ?

C’est la même chose, mais à échelle mondiale ! Plus de 240 villes dans le monde y participent en simultané.

25 au 27 janvier, à EPITECH Nancy

Pour cette année, COIN s’associe à EPITECH Nancy pour organiser un Game Jam en béton armé. Plus grand et toujours plein de services.

Les inscriptions sont ouvertes sur le site dédié : http://www.ggj-est.fr/

Et dans l’Est, nous fournissons les victuailles, le cheat code “café infini” et nous aurons un jury de pro pour décerner un prix symbolique.

Ailleurs en France ?

Comme d’habitude, nos copains de 3hitcombo l’organisent à Rennes, et Nemo de SwingSwing rejoint Oliver Lejade dans l’organisation du GGJ Parisien. Ils se feront surement un plaisir de vous en parler en temps et en heure.

Un p’tit verre pour préparer le terrain ?

Pour marquer le coup, COIN organise le 24 novembre à Metz une soirée jeux indé’ ouverte à tous. Une bonne occasion pour voir les jeux réalisés l’année dernière et papoter idées farfelues.