Rayane Hassani Explorer le jeuLe jeu
FR EN
Projets

Portfolio RPG

8–13 mspar image au 95e centile sur processeur bridé 4×, contre 35–45 ms avant la passe perf

Aucun fichier image dans le village : décors, bâtiments et personnages sont dessinés par le code au démarrage.

Deux mondesPartagéJeuPhaservillage, caméra, PNJet collisionsPasserelleEventBridgedes événements, aucunimport croiséInterfaceReactHUD, dialogues etsept salles intérieuresDémarrageTextures Canvas2Ddessinées une fois,au démarrageLangueStore de languehors React, lu parles deux mondesContenuContenu JSONchaque projet etexpérience, en françaiset en anglais
Explorer le jeu
Le village se visite sur ordinateur comme sur téléphone, en français et en anglais.

Montrer comment je décide en quelques minutes de jeu

Un CV dit ce qu'on a fait, mais il ne montre ni la façon dont on décide ni le soin qu'on met dans son travail, et un recruteur ne lui accorde souvent que quelques dizaines de secondes. Je voulais un portfolio qui démontre ces compétences au lieu de les déclarer, en proposant une expérience que l'on parcourt et dont la construction elle-même constitue la preuve.

Le jeu devait rester fluide sur un ordinateur ordinaire, être lisible en français comme en anglais, et ne pas faire perdre son temps au visiteur pressé, d'où une version plus classique proposée en parallèle pour ceux qui veulent aller droit à l'essentiel. C'est celle que vous êtes en train de lire, et je vous remercie sincèrement d'avoir pris le temps de vous y arrêter.

Phaser pour le village et React pour l'interface

L'application associe deux mondes qui ont chacun leur rôle. Phaser fait tourner le village, avec sa carte, ses personnages, sa caméra et ses collisions, tandis que React porte tout ce qui relève de l'interface, comme le HUD, les fenêtres de dialogue et les sept salles intérieures dans lesquelles on lit le contenu. Le visiteur se déplace au clavier ou à la souris, entre dans un bâtiment par sa porte, et la salle prend le relais en plein écran.

Les textes passent par un store de langue écrit sans dépendance, que Phaser comme React lisent directement, et le contenu de chaque projet ou expérience est stocké en français et en anglais dans des fichiers JSON.

Un village dessiné par le code et une passe de performance

Le premier choix structurant est d'avoir isolé Phaser et React l'un de l'autre. Les deux ne s'appellent jamais directement : ils communiquent par un bus d'événements unique, sur lequel le jeu annonce par exemple qu'une porte a été franchie et sur lequel l'interface répond qu'une salle a été refermée. Cette séparation permet de faire évoluer l'interface sans toucher au moteur de jeu, et elle m'a évité les effets de bord qui apparaissent dès que deux systèmes de rendu partagent le même état.

Le deuxième choix concerne les graphismes du village. Les décors, les bâtiments et les personnages sont dessinés par le code en Canvas2D au démarrage, au lieu d'être chargés depuis des fichiers d'images. Ce choix m'a donné une liberté totale sur la direction artistique, jusqu'aux contours des places, que je génère avec du bruit sur plusieurs octaves pour éviter les formes trop géométriques. Il a aussi posé un problème de performance au début : poser une image par tuile sur une carte de cette taille faisait ramer le jeu. J'ai donc regroupé le sol en grandes textures précalculées par blocs, ce qui ramène des dizaines de milliers de tuiles à une poignée de textures.

Le troisième choix est la passe de performance que j'ai menée avant d'ajouter du contenu. Phaser parcourt et dessine toute sa liste d'objets à chaque image, y compris ce qui se trouve à l'autre bout de la carte. J'ai mis en place un culling qui retire de cette liste les décors éloignés de la caméra et les y remet à l'approche, une coupure des émetteurs de particules hors de la vue, et une mise à jour de la profondeur des objets seulement quand ils se déplacent, puisque chaque changement relance le tri de toute la scène. Pour mesurer le gain honnêtement, j'ai profilé un build de production avec le processeur bridé quatre fois, car sur une machine rapide l'écran à 120 Hz masquait tout écart.

Une documentation tenue au même rythme que le code

Je développe ce projet avec Claude Code, l'agent de code d'Anthropic, ce qui m'a conduit à traiter la documentation comme une pièce maîtresse du projet. Après une période où elle avait dérivé du code au point que les décisions écrites ne correspondaient plus à ce qui tournait réellement, je l'ai réécrite à partir d'un audit, puis découpée en quatre documents qui ont chacun un rythme de mise à jour : une constitution qui fixe la stack et les décisions verrouillées, un suivi du chantier en cours, un registre de la dette classée par priorité et une roadmap des améliorations souhaitées.

Un rendu passé de 35–45 ms à 8–13 ms par image

Le temps de rendu d'une image au 95ᵉ centile, mesuré sur la place centrale avec le processeur bridé, est passé de 35–45 ms à 8–13 ms grâce à la passe de performance. Le village compte aujourd'hui sept bâtiments habités, chacun avec sa salle intérieure animée, et l'ensemble du contenu est disponible en français et en anglais. Les prochaines étapes portent sur l'adaptation au mobile et le déploiement sur mon propre serveur.