{"id":554,"date":"2017-04-20T11:50:13","date_gmt":"2017-04-20T10:50:13","guid":{"rendered":"http:\/\/oneiricworlds.com\/fr\/?p=554"},"modified":"2017-04-20T11:50:13","modified_gmt":"2017-04-20T10:50:13","slug":"nouveau-systeme-de-sauvegarde","status":"publish","type":"post","link":"https:\/\/oneiricworlds.com\/fr\/2017\/04\/nouveau-systeme-de-sauvegarde\/","title":{"rendered":"Nouveau syst\u00e8me de sauvegarde"},"content":{"rendered":"<p>Une fois de plus, \u00e7a fait un bon moment que je n&rsquo;ai rien partag\u00e9 sur ce blog&#8230; Mais j&rsquo;ai travaill\u00e9 sur beaucoup de choses derni\u00e8rement, notamment:<\/p>\n<ul>\n<li>l&rsquo;integration de la nouvelle interface utilisateur (UI) de Unity pour le HUD (= Head Up Display = les informations visibles \u00e0 l&rsquo;\u00e9cran pendant le jeu), le menu du Link et la carte du monde. Graphiquement, la diff\u00e9rence n&rsquo;est pour l&rsquo;instant pas \u00e9norme, mais \u00e7a devrait me permettre d&rsquo;int\u00e9grer plus facilement divers effets et animations pour la suite.<\/li>\n<li>la possibiliter de contr\u00f4ler l&rsquo;UI avec le joypad et avec le combo clavier\/souris (y compris la molette). Ce n&rsquo;est pas encore parfait, mais c&rsquo;est fonctionnel.<\/li>\n<li>pas mal de \u00ab\u00a0polish\u00a0\u00bb (= rajout de d\u00e9tails) sur l&rsquo;\u00eele Zephyr<\/li>\n<li>et un nouveau syst\u00e8me de sauvegarde&#8230; Et c&rsquo;est de \u00e7a dont je vais parler aujourd&rsquo;hui.<\/li>\n<\/ul>\n<p>Accrochez-vous, l&rsquo;article est un peu long.<\/p>\n<h3>I &#8211; Un nouveau syst\u00e8me de sauvegarde? Pourquoi? Dans quel but?<\/h3>\n<p>Le but principal de ce nouveau syst\u00e8me est de remplacer le syst\u00e8me actuel bas\u00e9 sur les \u00ab\u00a0points de sauvegarde\u00a0\u00bb qui impose au joueur de sauver sa progression \u00e0 certains endroits\/moments pr\u00e9cis du jeu. Cela coupe totalement la fluidit\u00e9 du d\u00e9roulement du jeu et le joueur peut oublier de sauvegarder (ou m\u00eame ne pas voir le point de sauvegarde) et peut ainsi perdre sa progression, ce qui est \u00e9videmment tr\u00e8s emb\u00eatant.<\/p>\n<p>Jusqu&rsquo;\u00e0 pr\u00e9sent, c&rsquo;\u00e9tait ce syst\u00e8me qui \u00e9tait pr\u00e9sent dans le jeu, car je n&rsquo;avais pas eu assez de temps et d&rsquo;\u00e9nergie \u00e0 consacrer \u00e0 ce point.<\/p>\n<p>Mais de nos jours, dans les jeux r\u00e9cents, les sauvegardes sont automatiques et le joueur peut m\u00eame ne pas les remarquer (souvent, une ic\u00f4ne apparait dans un coin de l&rsquo;\u00e9cran pour indiquer une sauvegarde en cours). C&rsquo;est ce que je souhaiterais avoir pour mon jeu, mais \u00e7a pose pas mal de probl\u00e8mes en terme de design, d&rsquo;architecture logicielle et de performances temps r\u00e9el.<\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_214508.png\" rel=\"attachment wp-att-557\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-557\" src=\"https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_214508-1024x571.png\" alt=\"20170419_214508\" width=\"840\" height=\"468\" srcset=\"https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_214508-1024x571.png 1024w, https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_214508-300x167.png 300w, https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_214508-768x428.png 768w, https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_214508-1200x669.png 1200w, https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_214508.png 1843w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>L&rsquo;icone \u00ab\u00a0engrenage\u00a0\u00bb dans le coin inf\u00e9rieur gauche indique que le jeu est en cours de sauvegarde.<\/em><\/p>\n<h3>II &#8211; Comment est-ce que \u00e7a devrait marcher?<\/h3>\n<p>D&rsquo;habitude, avant de me lancer dans la programmation \u00e0 proprement parler, j&rsquo;essaie de r\u00e9fl\u00e9chir aux diff\u00e9rents cas qui peuvent se pr\u00e9senter (c&rsquo;est plus ou moins une approche par \u00ab\u00a0use case\u00a0\u00bb ou \u00ab\u00a0cas d&rsquo;utilisation\u00a0\u00bb). Voici les cas principaux:<\/p>\n<ul>\n<li>le joueur commence une nouvelle partie. Que devrait-il se passer? Id\u00e9alement, le jeu devrait lui demander un pseudo\/identifiant qui sera utilis\u00e9 pour identifier la sauvegarde. Pour l&rsquo;instant, une nouvelle sauvegarde sera cr\u00e9\u00e9e automatiquement car je n&rsquo;ai pas le temps de faire quelque chose de mieux, mais \u00e7a devrait \u00eatre corrig\u00e9 \u00e0 l&rsquo;avenir.<\/li>\n<li>le joueur est dans le jeu. La partie devrait \u00eatre sauvegard\u00e9e r\u00e9guli\u00e8rement sur l&#8217;emplacement (le \u00ab\u00a0slot\u00a0\u00bb) courant. Le probl\u00e8me, c&rsquo;est qu&rsquo;il n&rsquo;y a pas forc\u00e9ment de slot courant. \u00ab\u00a0Comment \u00e7a?\u00a0\u00bb vous demandez-vous sans doute. Et bien, un nouveau slot est cr\u00e9\u00e9 pour chaque nouvelle partie lanc\u00e9e. Mais quand <strong>*JE*<\/strong> teste le jeu, je ne le lance pas du d\u00e9but \u00e0 chaque fois. G\u00e9n\u00e9ralement, je lance un niveau avec des variables modifi\u00e9es afin de choisir sp\u00e9cifiquement \u00ab\u00a0o\u00f9 et quand\u00a0\u00bb je veux \u00eatre situ\u00e9 dans le monde et dans l&rsquo;histoire, et je teste \u00e0 partir de l\u00e0. Cela signifie que je n&rsquo;ai pas de \u00ab\u00a0slot\u00a0\u00bb sp\u00e9cifique associ\u00e9 \u00e0 mon test. Du coup, o\u00f9 dois-je sauver la partie? Dois-je la sauver? Puis-je la sauver? Comment faire si je veux tester le syst\u00e8me de sauvegarde lui-m\u00eame?<\/li>\n<li>le joueur veut charger une partie. Je dois lister toutes les parties pr\u00e9c\u00e9demment enregistr\u00e9es avec diverses infos pour chaque slot: quel niveau est en cours? Combien d&rsquo;items le joueur\u00a0a d\u00e9bloqu\u00e9s? Combien de qu\u00eates sont compl\u00e9t\u00e9es? Peut-\u00eatre une image pour rappeler au joueur \u00e0 quoi ressemble l&rsquo;endroit? Et surement aussi son identifiant\/pseudo&#8230;<\/li>\n<\/ul>\n<p>Evidemment, \u00e0 chaque fois que je sauvegarde le jeu, je ne veux pas qu&rsquo;on puisse remarquer le moindre ralentissement (lag). Mais malheureusement, lorsqu&rsquo;on \u00e9crit sur le disque dur, les op\u00e9rations sont assez lentes (en comparaison avec le nombre d&rsquo;images par secondes affich\u00e9es par une carte graphique par exemple). Je dois donc utiliser des threads pour que les fichiers de sauvegarde puissent \u00eatre \u00e9crits en arri\u00e8re-plan pendant que le jeu continue de tourner de mani\u00e8re fluide (en tout cas c&rsquo;est le but).<\/p>\n<h3>III &#8211; Comment le faire marcher?<\/h3>\n<h4>1 &#8211; La classe de base<\/h4>\n<p>Jusqu&rsquo;\u00e0 pr\u00e9sent, j&rsquo;avais une simple classe\/structure principalement bas\u00e9e sur les dictionnaires .NET pour sauver chaque aspect du jeu:<\/p>\n<ul>\n<li>les infos du joueur: vie, items, munitions, position, \u00e9tat, &#8230;<\/li>\n<li>les collectables et les qu\u00eates: ce qui a \u00e9t\u00e9 demand\u00e9, ce qui a \u00e9t\u00e9 accompli\/collect\u00e9, combien de fois, o\u00f9, &#8230;<\/li>\n<li>les infos des m\u00e9caniques de gameplay: quelle porte est ouverte, quel interrupteur est connect\u00e9 \u00e0 quoi, l&#8217;emplacement des plateformes mobiles, etc&#8230;<\/li>\n<li>les infos des ennemis: position, \u00e9tat, &#8230;<\/li>\n<li>les infos des PNJ (personnages non joueurs): qu&rsquo;est-ce qui a \u00e9t\u00e9 dit \u00e0 qui, &#8230;<\/li>\n<li>les infos du monde: le niveau courant, le moment de la journ\u00e9e, le temps de jeu, &#8230;<\/li>\n<\/ul>\n<p>L&rsquo;id\u00e9e est de ne <strong>PAS<\/strong> sauver l&rsquo;int\u00e9gralit\u00e9 du jeu, mais juste ce qui est <strong>REELLEMENT<\/strong> n\u00e9cessaire pour recharger une partie. Ca devrait permettre d&rsquo;avoir des sauvegardes assez l\u00e9g\u00e8res et des temps de chargement assez courts.<\/p>\n<p>Bien s\u00fbr, toutes ces infos doivent \u00eatre accessibles de n&rsquo;importe o\u00f9 dans le code et \u00e0 n&rsquo;importe quel moment, c&rsquo;est pourquoi j&rsquo;ai utilis\u00e9 une sorte de classe Singleton pour stocker l&rsquo;info (ce n&rsquo;est pas aussi simple que \u00e7a, mais c&rsquo;est l&rsquo;id\u00e9e principale).<\/p>\n<h4>2 &#8211; Les structures de plus haut niveau<\/h4>\n<p>Maintenant que je sais QUOI sauvegarder, voyons COMMENT le faire. Pour r\u00e9pondre aux probl\u00e8mes et objectifs list\u00e9s dans la partie II, j&rsquo;ai choisi de mettre en place:<\/p>\n<ul>\n<li>des sauvegardes de NIVEAU 0, c&rsquo;est \u00e0 dire les fichiers sur le disque dur.<\/li>\n<li>des sauvegardes de NIVEAU 1, qui sont une version clone des fichiers du disque, mais stock\u00e9es en RAM (sous forme de variables dans le code)<\/li>\n<li>une UNIQUE sauvegarde de NIVEAU 2, qui est celle qui sera directement lue et modifi\u00e9e par tous les objets du jeu, en RAM \u00e9videmment.<\/li>\n<\/ul>\n<p>L&rsquo;id\u00e9e est d&rsquo;avoir plusieurs couches de sauvegarde, chacune communiquant UNIQUEMENT avec les couches imm\u00e9diatement sup\u00e9rieures ou inf\u00e9rieures, en fonction de leur but principal et de leur vitesse de traitement.<\/p>\n<p>La moteur temps r\u00e9el du jeu travaille uniquement avec la sauvegarde de NIVEAU 2. Elle est unique. De temps en temps, quand les conditions sont OK (le joueur n&rsquo;est pas en train de combattre, il est dans une zone sans danger, il n&rsquo;est pas dans une zone o\u00f9 la sauvegarde est interdite, &#8230;), je fais une copie compl\u00e8te dans un des slots de NIVEAU 1. Et enfin, quand le jeu n&rsquo;est pas d\u00e9j\u00e0 en train d&rsquo;\u00e9crire sur le disque et que les conditions sont OK (la derni\u00e8re sauvegarde date de X minutes, &#8230;), je copie le slot de NIVEAU 1 dans un fichier sur le disque (NIVEAU 0). Les donn\u00e9es sont \u00e9crites sur le disque via les serialiser binaires de la librairie .NET.<\/p>\n<p>Bien s\u00fbr, afin de copier les donn\u00e9es dans les slots de NIVEAU 1 et 0, je dois savoir quel slot choisir. Par d\u00e9faut, il n&rsquo;y a pas de slot courant. Dans ce cas, aucune copie n&rsquo;est faite. Si le joueur a d\u00e9marr\u00e9 une nouvelle partie, un nouveau slot est cr\u00e9\u00e9 et ce sera le slot courant pour la suite. Si le joueur charge une partie, ce slot sera consid\u00e9r\u00e9 comme le slot courant. Et quand je suis en mode \u00ab\u00a0Test\u00a0\u00bb, je peux cr\u00e9er un nouveau slot \u00ab\u00a0\u00e0 la vol\u00e9e\u00a0\u00bb \u00e0 tout moment en appuyant sur une touche magique. D\u00e8s lors, ce nouveau slot est consid\u00e9r\u00e9 comme le slot courant. Cette m\u00e9thode semble r\u00e9pondre \u00e0 tous les cas que j&rsquo;ai list\u00e9s en II.<br \/>\nQuelques infos suppl\u00e9mentaires:<\/p>\n<ul>\n<li>la sauvegarde de NIVEAU 2 est celle qui est constamment lue et \u00e9crite par tous les objets du jeu; Ainsi, chaque objet peut savoir si un dialogue a \u00e9t\u00e9 lu, si une qu\u00eate a \u00e9t\u00e9 accomplie ou si un object a \u00e9t\u00e9 r\u00e9cup\u00e9r\u00e9. C&rsquo;est extr\u00eamement rapide \u00e0 lire et \u00e0 \u00e9crire car c&rsquo;est une (pas si) simple variable en RAM. C&rsquo;est l&rsquo;information la plus r\u00e9cente sur le jeu.<\/li>\n<li>Les sauvegardes de NIVEAU 1 sont une sorte de tampon entre la sauvegarde \u00ab\u00a0vivante\u00a0\u00bb de NIVEAU 2 et les sauvegardes sur disque de NIVEAU 0. Ce sont des\u00a0copies des donn\u00e9es de NIVEAU 2 que je fais de temps \u00e0 autre. Elles sont principalement utiles car l&rsquo;\u00e9criture sur le disque est LENTE. Ca signifie qu&rsquo;il est possible que le jeu \u00e9crive un fichier PENDANT qu&rsquo;il est en train de modifier la sauvegarde, ce qui cr\u00e9\u00e9 un acc\u00e8s simultan\u00e9 aux donn\u00e9es. Ceci est \u00e0 proscrire \u00e0 tout prix si je veux garantir l&rsquo;int\u00e9grit\u00e9 des donn\u00e9es. Si je n&rsquo;avais pas ces sauvegardes interm\u00e9diaires de NIVEAU 1, le jeu pourrait d\u00e9finitivement alt\u00e9rer les sauvegardes sur le disque et la sauvegarde en m\u00e9moire&#8230; D&rsquo;o\u00f9 l&rsquo;int\u00e9r\u00eat de ces sauvegardes tampons de NIVEAU 1.<\/li>\n<li>les sauvegardes de NIVEAU 0 sont les sauvegardes sur le disque. Elle sont \u00e9crites depuis ou copi\u00e9es dans les sauvegardes de NIVEAU 1, et cette op\u00e9ration peut durer plusieurs frames.<\/li>\n<\/ul>\n<p>Bien s\u00fbr, avec ce syst\u00e8me, il est aussi possible de sauver \u00e0 des moments ou endroits bien sp\u00e9cifiques (quand le joueur quitte, finit une qu\u00eate, ouvre un menu). C&rsquo;est assez permissif.<\/p>\n<h4>3 &#8211; Et le chargement?<\/h4>\n<p>Pour l&rsquo;instant, j&rsquo;ai surtout parl\u00e9 du processus de sauvegarde, car c&rsquo;est le plus compliqu\u00e9. Le chargement est assez imm\u00e9diat: on charge toutes les donn\u00e9es de NIVEAU 0 depuis le disque dur et on les copie dans les slots de NIVEAU 1 quand le jeu est lanc\u00e9. Quand le joueur charge une partie, on copie les donn\u00e9es de NIVEAU 1 dans la sauvegarde de NIVEAU 2 et on charge le niveau correspondant dans Unity.<\/p>\n<p>On peut se demander si tout ceci n&rsquo;est pas trop lourd en m\u00e9moire, mais chaque slot devrait contenir quelques 10 000 entr\u00e9es de type \u00ab\u00a0string\u00a0\u00bb. Avec un rapide calcul approximatif, on trouve une taille de quelques 100 Ko en m\u00e9moire pour chaque sauvegarde. Mes plus gros tests sur le disque dur montent jusqu&rsquo;\u00e0 2 Mo chacun, ce qui reste raisonnable.<\/p>\n<p><a href=\"https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_211708.png\" rel=\"attachment wp-att-556\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-556\" src=\"https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_211708-1024x571.png\" alt=\"20170419_211708\" width=\"840\" height=\"468\" srcset=\"https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_211708-1024x571.png 1024w, https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_211708-300x167.png 300w, https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_211708-768x428.png 768w, https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_211708-1200x669.png 1200w, https:\/\/oneiricworlds.com\/fr\/wp-content\/uploads\/2017\/04\/20170419_211708.png 1843w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><\/a><\/p>\n<p style=\"text-align: center;\"><em>Le nouvel \u00e9cran de chargement. Simple mais fonctionnel.<\/em><\/p>\n<h4>4 &#8211; Performances<\/h4>\n<p>Vous l&rsquo;avez surement compris, l&rsquo;\u00e9criture sur le disque dur est lente. Donc les copies de NIVEAU 1 vers le NIVEAU 0 sont lentes. Mais ce n&rsquo;est pas un probl\u00e8me car \u00e7a a \u00e9t\u00e9 pens\u00e9 comme une op\u00e9ration thread\u00e9e et \u00e7a ne ralentit pas le jeu. Pendant cette op\u00e9ration, j&rsquo;affiche la fameuse icone de chargement dans un coin de l&rsquo;\u00e9cran. Au d\u00e9but du jeu, c&rsquo;est \u00e0 peine visible car c&rsquo;est tr\u00e8s rapide (et qu&rsquo;il n&rsquo;y a quasiment rien \u00e0 sauver). Toutefois Unity n&rsquo;est pas \u00ab\u00a0thread safe\u00a0\u00bb, ce qui m&rsquo;a oblig\u00e9 \u00e0 choisir avec pr\u00e9caution mes structures de donn\u00e9es (car je n&rsquo;ai pas acc\u00e8s par exemple aux donn\u00e9es de type Transform et\/ou Monobehavior dans le thread).<\/p>\n<p>Mais un plus gros probl\u00e8me est la copie de NIVEAU 2 vers le NIVEAU 1: celle-ci <strong>DOIT<\/strong> \u00eatre une copie <strong>PROFONDE<\/strong>, car sinon on peut se retrouver \u00e0 nouveau face au probl\u00e8me d&rsquo;acc\u00e8s simultan\u00e9 au donn\u00e9es (\u00e0 cause du type \u00ab\u00a0class\u00a0\u00bb de beaucoup de variables C#; ce n&rsquo;est pas super intuitif, n&rsquo;h\u00e9sitez pas \u00e0 creuser les recherches sur google si vous voulez en savoir plus). Malheureusement, les copies profondes sont assez lentes et ne peuvent pas \u00eatre thread\u00e9es (enfin pas facilement) car je copie depuis le NIVEAU 2 qui est \u00ab\u00a0vivant\u00a0\u00bb\/constamment modifi\u00e9. On commence \u00e0 voir un l\u00e9ger lag \u00e0 partir de 20 000 entr\u00e9es dans les dictionnaires de donn\u00e9es, ce qui devrait \u00eatre OK pour la totalit\u00e9 du jeu, mais je n&rsquo;en suis pas encore s\u00fbr. Il faudra faire d&rsquo;autres tests quand le jeu sera plus abouti.<\/p>\n<p>Toutefois, si l&rsquo;avenir rev\u00e8le que les copies de NIVEAU 2 \u00e0 NIVEAU 1 sont trop lente, j&rsquo;ai quelques pistes en t\u00eate pour am\u00e9liorer tout \u00e7a, mais je ne les d\u00e9taillerai pas ici car cet article est d\u00e9j\u00e0 trop long&#8230;<\/p>\n<h3>IV &#8211; Et maintenant?<\/h3>\n<p>Voil\u00e0, j&rsquo;esp\u00e8re que ces explications permettent d&rsquo;avoir un bon aper\u00e7u du nouveau syst\u00e8me de sauvegarde. Je sais qu&rsquo;il n&rsquo;est pas parfait et qu&rsquo;il y aura quelques bugs \u00e0 venir et \u00e0 corriger, mais c&rsquo;est tr\u00e8s appr\u00e9ciable de ne pas avoir \u00e0 penser \u00e0 sauvegarder pendant le jeu. L&rsquo;exp\u00e9rience est bien plus immersive.<\/p>\n<p>Il reste cependant quelques probl\u00e8mes potentiels:<\/p>\n<ul>\n<li>les slots de sauvegarde ne sont pas clairement identifi\u00e9s et il est difficile d&rsquo;en trouver une particuli\u00e8re s&rsquo;il y en a beaucoup, mais j&rsquo;esp\u00e8re corriger \u00e7a prochainement (m\u00eame s&rsquo;il faudra certainement coder un clavier virtuel pour les gens qui jouent au joypad)<\/li>\n<li>Il n&rsquo;y a pas de capture d&rsquo;\u00e9cran des sauvegardes (alors que c&rsquo;\u00e9tait le cas dans les versions pr\u00e9c\u00e9dentes) car j&rsquo;ai chang\u00e9 le syst\u00e8me de sauvegarde. Jusqu&rsquo;\u00e0 pr\u00e9sent, je prenais une capture d&rsquo;\u00e9cran juste avant l&rsquo;ouverture du menu ce qui causait un mini lag, mais qui n&rsquo;\u00e9tait pas visible car le menu apparaissait dans la foul\u00e9e. Mais maintenant, le jeu est continuellement sauvegard\u00e9 et m\u00eame un mini lag est TRES visible.<\/li>\n<li>J&rsquo;aimerais ajouter des sauvegardes de NIVEAU\u00a0-1, qui seraient des copies de la derni\u00e8re sauvegarde de NIVEAU 0. Pourquoi? Car le nouveau syst\u00e8me de sauvegarde n&rsquo;a pas \u00e9t\u00e9 encore \u00e9t\u00e9 suffisamment test\u00e9 et je suis \u00e0 peu pr\u00e8s s\u00fbr que certains joueurs rencontreront des cas qui crasheront le syst\u00e8me. Pour \u00e9viter qu&rsquo;ils ne perdent toute leur progression, faire des copies sur le disque parait \u00eatre une m\u00e9thode suffisamment simple et efficace.<\/li>\n<\/ul>\n<p>Pour le moment, le syst\u00e8me est op\u00e9rationnel pour le <a href=\"https:\/\/oneiricworlds.com\/fr\/index.php\/2017\/03\/15\/toulouse-game-show-springbreak-2017\/\">Toulouse Game Show ce<\/a> week end, ce qui \u00e9tait l&rsquo;objectif principal. Au passage, n&rsquo;h\u00e9sitez pas \u00e0 venir me voir sur le stand ce week end!<\/p>\n<p>J&rsquo;esp\u00e8re que cet article n&rsquo;\u00e9tait pas trop long, ou technique ou ennuyeux&#8230; Mais j&rsquo;en doute!<\/p>\n<p>A+<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Une fois de plus, \u00e7a fait un bon moment que je n&rsquo;ai rien partag\u00e9 sur ce blog&#8230; Mais j&rsquo;ai travaill\u00e9 sur beaucoup de choses derni\u00e8rement, notamment: l&rsquo;integration de la nouvelle interface utilisateur (UI) de Unity pour le HUD (= Head Up Display = les informations visibles \u00e0 l&rsquo;\u00e9cran pendant le jeu), le menu du Link [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":557,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,10],"tags":[],"class_list":["post-554","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev","category-tutorial"],"_links":{"self":[{"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/posts\/554","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/comments?post=554"}],"version-history":[{"count":8,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/posts\/554\/revisions"}],"predecessor-version":[{"id":564,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/posts\/554\/revisions\/564"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/media\/557"}],"wp:attachment":[{"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/media?parent=554"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/categories?post=554"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oneiricworlds.com\/fr\/wp-json\/wp\/v2\/tags?post=554"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}