I. Introduction

Jonathan Blow, le créateur de Braid, nous présente son implémentation du retour en arrière (rewind) pour Braid (paru en 2008 sur Xbox 360, Windows, Mac OS X, Linux, PlayStation 3).

Si le jeu ne vous rappelle rien, voici sa bande-annonce :


Cliquez pour lire la vidéo


II. Vidéo


GDC 2010 - Implémentation du retour dans le temps dans Braid


Vous pouvez aussi regarder la vidéo sur le site officiel de la Game Developers Conference : http://gdcvault.com/play/1012210/The-Implementation-of-Rewind-in.

III. Résumé

III-A. Objectifs

Jonathan Blow ne parle pas d'un simple retour en arrière, de quelques secondes, comme nous avons l'habitude d'en voir dans de nombreux jeux. Ici, il s'agit d'une ressource illimitée. Toutefois, il ne faut pas qu'il soit trop compliqué à intégrer dans le code, ne doit pas utiliser trop de mémoire (le jeu fonctionne en 60 FPS) et surtout, il ne doit pas permettre de casser le gameplay du jeu (passer à travers les murs ou autres).

III-A-1. Implémentation

Plusieurs possibilités existent pour implémenter le retour en arrière :

  • simulation déterministe (enregistrement des contrôles du joueur) : non robuste et compliquée à implémenter (ajoute des contraintes dans le code) ;
  • simulation réversible : code trop compliqué, comment avoir un accès aléatoire ;
  • enregistrer l'intégralité du monde, sauter des images, interpoler : pas assez précis, qualité insuffisante, comment éviter les triches.

La solution de Jonathan Blow c'est d'enregistrer l'intégralité du monde, et cela pour toutes les images. C'est la solution la plus robuste, mais elle nécessite une compression des données afin de ne pas surcharger la machine.

III-A-1-a. Comment enregistrer les entités du jeu

Les programmeurs savent déjà comment enregistrer des entités : la sérialisation. Un des avantages est que les données sérialisées sont facilement compressibles. Mais cela fait énormément de données. Un niveau de jeu est entre 25 Ko et 175 Ko. Pour réduire le nombre de valeurs à sauvegarder, Jonathan Blow factorise les constantes (collisions, graphismes, dispositions).
Au lieu de sauvegarder les particules, il est nécessaire, pour le cas du retour dans le temps, de les rendre constantes. Pour rendre déterministe le comportement des particules, la graine pour la génération de nombres aléatoires pour les particules est fonction du temps.
Toutefois, malgré ces optimisations, les données restent trop importantes. Pour réduire toujours plus ce nombre, le jeu va faire des captures de toutes les entités non constantes toutes les N images (appelées images de base) et pour chaque image, seules les valeurs qui ont été modifiées depuis l'image de base seront sauvegardées.
À présent, les images de base occupent plus de la moitié de la mémoire. Une seconde passe est effectuée, comparant l'image de base avec les valeurs par défaut du constructeur et retirant toutes informations n'ayant pas été modifiées depuis la construction de l'objet.
Pour les objets construits au cours du jeu, la construction sera reportée à une image de base.
Finalement, pour gérer la dilatation du temps (qui s'applique sur les particules), deux types de systèmes de particules existent : un avec les images de base, et l'autre sans celles-ci, enregistrant l'historique complet (limité à 120 images). De plus, une compression Run Length Encoding est utilisée pour ces dernières.

IV. Commenter

Vous pouvez commenter et donner vos avis dans la discussion associée sur le forum.