Mes projets / Contre-Jour

Dans Contre-Jour, le joueur incarne Charles Desmoulins, un petit garçon dont l'ombre a été enchantée. Désormais, Charles ne doit jamais l'exposer entièrement à la lumière. Afin de rompre le sort, il devra traverser les lieux de l'exposition universelle de 1900. La réalisation de ce projet s'est étalée sur toute notre dernière année d'études à Supinfogame.

Gameplay

  • Le joueur contrôle Charles Desmoulins avec le joystick gauche et peut effectuer des rotations de l'ombre enchantée avec celui de droite. Il doit simplement éviter l'exposition complète de cette entité à la lumière.
  • Charles doit trouver des lucioles afin d'utiliser leur pouvoir pour avancer. La luciole observation se déplacer librement dans le niveau. La luciole obscurité permet de créer une ombre circulaire à proximité d'un spot d'ombre.
  • Notre héros peut faire appel à ses alliées, les lucioles, grâce au caroussel de sélection. Une fois choisie, le joueur en prend le contrôle et revient à Charles à l'aide d'une même touche de la manette.
  • Le garçon peut intéragir avec certains éléments du décor, ouvrir une porte, utiliser un interupteur, pousser une caisse...
  • Des vigiles peuvent intercepter Charles dans la lumière, le joueur doit donc éviter leur regard.

Ma mission

Créé en équipe de six personnes, mon rôle a été principalement la programmation de l'ensemble du jeu. J'ai aussi participé au Game Design lors des différents brainstormings, et j'ai eu l'occasion de travailler dans d'autres domaines...

Et Contre-Jour, aujourd'hui?

Malheureusement, le projet n'a pas été repris par notre équipe après la fin des études. Par contre, le prototype est jouable dans les salons auxquels participe Supinfogame et voit passer de nombreux joueurs curieux de tous les âges.



Lieu: Supinfogame
Temps de production: 9-10 mois
Sortie: juin 2010
Genre: Action/Aventure
Plateforme: XBOX 360
Moteur: Unity3D 2.6

L'équipe du projet:
Vincent Barrières
Grégoire Clémençon
Jérémy Leuliet
Raphaël Ollivier
Jonathan Rousseau
Vincent Villaume

Travail: La sauvegarde

22.04.2010
Réalisé pour le projet: Contre-Jour en 2010 à Supinfogame - Compétence: C#
Logiciels: Unity 3D

En tant que jeu d'aventure, Contre-Jour propose une histoire. Donc, il était nécessaire de pouvoir sauvegarder la progression du joueur. Aussi, le jeu est organisé en petits niveaux reliés par des entrées/sorties. Quand le héros se déplace dans un autre niveau, la progression est sauvegardée dans un fichier binaire.

La sauvegarde concerne différentes informations :

  • Les infos joueur : les pièces collectées, le niveau actuel, l'entrée actuelle dans le niveau... ;
  • Les informations concernant tous les niveaux : les positions des objets interactifs, les pièces et objets récupérés, les portes ouvertes, la position des interrupteurs,... ;
  • Les paramètres sauvegardables du GSE : Pour jouer un évènements une fois seulement...

Pour faire cela, J'ai utilisé un fichier binaire avec une nomenclature adaptée. Ce type de fichiers est organisé de manière séquentiel. Une tête de lecture lit et écrit les informations puis se déplace vers l'avant.

La nomenclature du fichier de sauvegarde

Dans le flux principal

  • Les infos joueur au début ;
  • Le nombre d'octets puis le flux concernant les niveaux.

Dans le flux des niveaux

Le flux contient le nombre total des niveaux et la liste des informations pour chaque niveau : le nombre d'octets et le flux du niveau correspondant.

Dans chaque flux de niveau

Chacun des flux contient le nombre d'objets sauvegardés et une liste séquentielle des informations pour chacun d'eux. Les informations d'un objet sont formées d'un identifiant et d'un flux spécifique (pour une caisse que l'on peut pousser, on conserve la position, par exemple) . Les boîtes du GSE sont gérées comme les autres objets mais on sauvegarde leurs paramètres à la place.

Côté code

A l'origine, j'ai utilisé deux types de fonctions basiques de C#.

Pour sauvegarder
//Créé un fichier ou ouvre le fichier existant et écraser le contenu
BinaryWriter binWriter = new BinaryWriter(File.Open("monfichier.txt",FileMode.Create));
//Ecrit des informations dans le fichier
binWriter.Write("CJSaveGame");//une chaîne: string
binWriter.Write(10);//un entier: int
binWriter.Write(10.5f);//un nombre à virgule flottante: float
binWriter.Write(true);//un booléen: bool
//etc.
binWriter.Close();//ferme le fichier
Pour charger:
if(File.Exists("monfichier.txt")){//Vérifie l'existence du fichier
//Ouvre le fichier
BinaryReader binReader = new BinaryReader(File.Open("monfichier.txt" , FileMode.Open));
try{
if(binReader.PeekChar() != -1)//Si le fichier n'est pas vide
{
//ReadString: lit les octets et déplace la tête de lecture
string str = binReader.ReadString();//une chaîne: string
int integer = binReader.ReadInt32();//un entier: int
float number = binReader.ReadSingle();//un nombre à virgule flottante: float
bool boolean = binReader.ReadBoolean();//un booléen: bool
//etc.
}
}
finally{
binReader.Close();//ferme le fichier
}
}

Résumé

Comme pour tous les jeux vidéo next-gen, Contre-Jour sauvegarde automatiquement la progression du joueur avec des checkpoints (Ici,le changement de niveau). Ainsi, le joueur peut reprendre au niveau en cours si il quitte.
Travail : J'ai programmé les processus de sauvegarde et de chargement.


Travail: GSE : Editeur Scripts Graphique

20.03.2010
Réalisé pour le projet: Contre-Jour en 2010 à Supinfogame - Compétence: C#
Logiciels: Unity 3D

Contre-Jour est avant tout un jeu d'aventure, avec un univers, une histoire, des personnages. Dans le jeu, Charles, le héros, communique souvent avec la reine des lucioles, croise un vigile plutôt patibulaire à plusieurs reprises... Pour mettre en place ces évènements et autres cinématiques, il fallait un outil. J'ai donc créé un éditeur destiné à l'équipe permettant de scripter ces éléments directement sur Unity3D.

L'idée a germé en début de production alors que nos ambitions en terme de scénarisation étaient grandissantes. Inspiré de l'outil disponible sur UDK, le Unreal Kismet, le GSE est une succession de boîtes reliées par des flèches.


Chaque script commence avec une boîte d'évènement (exemple : un personnage entre dans une zone qui déclenche un évènement) . D'autres boîtes sont connectées à elle et effectuent des actions (jouer une animation, émettre un son...) .


Un exemple plus précis


La mise en place

Mettre en place le GSE n'a pas été une décision simple. Il fallait que je vérifie que le temps de développement serait court et m'assurer que l'outil serait fonctionnel et facile à utiliser par toute l'équipe. J'ai donc pris une semaine pour faire un prototype pour quelques boîtes. Les résultats étaient plus qu'encourageants. En quelques jours, je pouvais faire des petites séquences d'actions simples et à l'utilisation, quelques cliquer/déposer permettaient de faire des enchaînements de boîtes.

L'étape suivante a été de communiquer le fonctionnement du GSE à l'ensemble de l'équipe. La plupart des membres du groupe connaissait le Kismet, ce qui m'a grandement facilité la tâche côté logique de l'éditeur. Au fur et à mesure de l'évolution du projet, j'ai ajouté des types de boîtes supplémentaires en fonction des besoins. A terme, nous en avions 65 en tout.

Résultat

Programmer cet éditeur m'a permis d'économiser beaucoup de temps en scripts d'évènements et de cinématiques. Désormais, l'équipe faisait ce travail. En outre, j'ai eu la possibilité de me concentrer sur d'autres features de code.

Résumé

J'ai créé un outil pour ajouter facilement des évènements et des cinématiques on jeu. Cela consiste en un ensemble de boîtes reliées entre elles par des flèches. Chaque type de boîte fait une action particulière (Emettre un son, jouer une animation, afficher des sous-titres...) . Inspiré de Unreal Kismet, l'outil était très utile car étant le seul programmeur du projet, j'aurais eu à intégrer les évènements moi-même sans cela. J'ai pu ainsi me concentrer sur d'autres features de code grâce à cet éditeur et le reste de l'équipe pouvait mettre en place ce qu'ils souhaitaient de manière très précise en jeu.
Travail : Design et code du GSE ; enseignement de son utilisation à l'équipe.


Travail: Le streaming de niveaux

05.02.2010
Réalisé pour le projet: Contre-Jour en 2010 à Supinfogame - Compétence: C#
Logiciels: Unity 3D

Dans Contre-Jour, les niveaux sont courts et le joueur les parcourt rapidement. Pour gagner du temps dans le chargement des scènes, j'ai créer un gestionnaire de streaming des niveaux.

Au lancement du jeu, il charge le niveau courant où le personnage se situe et lance la partie. Ensuite, le niveau est jouable directement mais pendant que l'on joue, le gestionnaire continue à charger les niveaux adjacents. Par exemple, quand le héros est dans la première carte (le point rouge), le deuxième niveau est préchargé.

Si il a fini son chargement quand le joueur termine le premier niveau alors on change de carte sans aucun écran de chargement. Une fois dans ce nouveau décor, le troisième se met en chargement et ainsi de suite. La première carte reste en mémoire parce qu'elle est adjacente. On peut donc revenir sur ses pas sans attente.

Côté code

Le gestionnaire de streaming des niveaux utilise une liste de niveaux. Chaque élément de la liste contient la scène à charger et une liste de booléens.

  • isLoading : Le niveau est-il en cours de chargement ;
  • isDataLoaded : La carte est-elle en mémoire.

[System.Serializable]
public class levelsList{
public string name;//identifiant du niveau
public string description;

[System.NonSerialized]
public bool isLoading = false;//Le niveau est-il en cours de chargement
[System.NonSerialized]
public bool isDataLoaded = false;//Le niveau est-il chargé
}

public class GameManager : MonoBehaviour {
public LevelsListElement[] levelsList;//Liste des niveaux
//...
}

Unity3D dispose d'une fonction simple de chargement de scène en asynchrone.

private IEnumerator streamLevelCoroutine(int level){
if(!levelsList[level].isLoading && !levelsList[level].isDataLoaded){//On lance le chargement que si nécessaire
//LoadLevelAdditiveAsync: Stream le chargement d'une scène.
yield return Application.LoadLevelAdditiveAsync(levelsList[level].name);
levelsList[level].isDataLoaded = true;//Le niveau est chargé et disponible

levelsList[level].isLoading = false;//Chargement terminé
}
}

Résumé

Pour avoir un jeu de qualité, nous avons décidé de diminuer le temps de l'écran de chargement entre les niveaux.
Travail : J'ai programmé un gestionnaire de streaming des niveaux.


Travail: Les lucioles

14.12.2009
Réalisé pour le projet: Contre-Jour en 2010 à Supinfogame - Compétence: Graphisme vectoriel
Logiciels: Adobe® Flash CSx

Les lucioles aident Charles, le héros, dans sa quête pour briser le sort jeté par leur reine, Eris. Elles peuvent être contrôlées par le joueur en jeu et ont des pouvoirs variés. J'ai travaillé sur leur design graphique.

Eris

Eris est la reine, elle suit Charles en permanence pour lui donner une leçon de vie. Le garçon est puni pour avoir détruit sa paisible cité. Elle est utile au joueur car elle donne des conseils à l'enfant. Je l'ai dessinée après les autres.

Les lucioles

Uranie : l'observatrice
Peut parcourir librement le niveau sans la contrainte du garçon et montre les éléments utiles dans le décor. Elle aide le joueur à comprendre l'environnement.

Terpsichore : l'ombre
Peut ajouter une ombre circulaire sur le sol près d'un spot d'ombre. Elle aide le joueur à traverser de larges zones de lumières.

Mnémé : Le pôchoir
Permet de copier une ombre pour l'utiliser ailleurs. C'est un gameplay de réflexion sur les ombres.

Aede : La protectrice
Stoppe un ennemi pour quelques secondes.

Euterpe : La révélatrice
Révèle l'ombre d'un objet qui n'en a pas.

Clio : La farfouilleuse
Peut atteindre des lieux inaccessible pour résoudre des énigmes.

Le design

Chaque luciole brille d'une couleur qui lui est propre. Ainsi, quand on les utilise dans le jeu, le joueur les reconnait alors qu'elles sont petites à l'écran. Chaque luciole s'inspire d'un insecte existant correspondant à ses capacités. Concernant la reine, nous voulions une luciole à forme humaine, car elle représente une mère pour Charles. L'histoire prend place en 1900 lors de l'exposition universelle de Paris, une période pendant laquelle "l'Art nouveau" français est célèbre. Le design sur les ailes s'inspire de ce mouvement artistique, avec des couleurs végétales et des formes rappelant des branches, la symétrie, etc.

Contour et remplissage

J'ai travaillé avec Flash pour créer ces lucioles. Je savais qu'elles devaient être petites à l'écran donc je voulais un design iconographique facile à interpréter pour elles. Je me suis inspiré des contours et remplissages dans le style de Dofus de Ankama.

En jeu, leurs personnages sont petits et pourtant très détaillés et faciles à reconnaître.

Résumé

Les lucioles sont au nombre de six dans le jeu et ont pour reine luciole, Eris. J'ai fait le concept art de ces personnages et les aies dessinées pour le carrousel de sélection.
Travail : Concept art et dessin de l'ensemble des lucioles de Contre-Jour.

Quelques images

firefliesqueen.png fireflies.png
contrejour_carrousel.png

Travail: Contre-Jour : Logo

10.12.2009
Réalisé pour le projet: Contre-Jour en 2010 à Supinfogame - Compétence: Dessin
Logiciels: Adobe® Photoshop CSx
contrejour_logo.png

Dès le début de Contre-Jour, nous commencions à réfléchir au logo du jeu. Finalement, après quelques propositions, j'ai eu le plaisir d'en être l'auteur.

Le logo

Le logo devait démontrer d'un seul coup d'oeil que :

  • Contre-Jour est un jeu vidéo ;
  • Il s'agit d'un jeu sur l'ombre et la lumière ;
  • L'histoire se déroule au début du XXéme siècle à Paris.

Première esquisse

C'est avec ces idées en tête que j'ai dessiné ce premier rough. Le logo est assez fantaisiste et représente le côté jeu. Les décorations autour du titres suggèrent un côté art nouveau caractéristique de l'architecture Parisienne en 1900. Le tout est surmonté d'une ampoule qui révèle les lettres dans le noir. J'ai ensuite directement travaillé sous Photoshop en vectoriel pour préciser l'idée.
contrejour_vector.png

Texture

Je voulais que les lettres et la décoration soient en fer forgé. Après quelques essais, j'ai trouvé une technique simple pour créer cet effet directement à partir des filtres de Photoshop.

J'ai ensuite dessiné l'ampoule et fini par le halo.

Résumé

Au début du projet, nous devions avoir un logo pour le jeu. Après avoir trouvé quelques idées, je l'ai finalement dessiné moi-même.
Travail : Design du logo de Contre-Jour.

Quelques images

contrejour_vector.png contrejour_logo.png

Travail: Le rendu Ombre/Lumière

05.10.2009
Réalisé pour le projet: Contre-Jour en 2010 à Supinfogame - Compétence: Game Design
Logiciels: Unity 3D

Contre-Jour joue sur l'ombre et la lumière. Le rendu de l'environnement devait être lisible facilement de manière à savoir en un seul coup d'oeil si l'ombre enchantée de Charles est en sécurité ou non. J'ai proposé un rendu et l'ai testé avec le leader graphiste pendant la préproduction.

La solution était d'avoir une limite franche entre les zones d'ombre sûres et les lumières dangereuses. Chaque partie devait être clairement identifiable et l'affichage de ce rendu devait être possible techniquement avec Unity3D 2.6.

  • Dans la lumière : le rendu est réaliste, avec des textures colorées;
  • Dans l'ombre : la forme de chaque objet a des contours et on peut voir des motifs à l'intérieur. Grâce à eux, on peut déterminer les volumes facilement.

Avec le lead graphiste, nous avons créé les premiers objets utilisant le rendu (la villa dans la vidéo ci-dessous). Nous en avons tiré le pipeline de production pour les assets.



Comment ça marche?

La solution est simple, chaque objet est couvert d'un matériau comprenant deux textures.

  • La texture de base : c'est la première couche du matériau. Cette texture réagit normalement à la lumière.
  • La texture de lightmap : C'est une texture qui simule la lumière. Dans l'obscurité totale, les pixels colorés révèlent la texture de base en dessous.

Résumé

J'ai proposé ce rendu sur l'environnement pour séparer ombre (contour et fond noir) et lumière (textures réalistes).
Travail : Proposition, premiers assets et mise en place du pipeline avec le lead graphiste.

Quelques images

testUnity.png house3dsmax.png
houseUnity.png