J'ai codé un jeu où tout est généré par du code (comme à l'époque de la NES)
Tout est parti d'une question idiote
Un soir, j'ai demandé : « est-ce qu'on peut faire de la musique avec du code ? » Quelques heures plus tard, la boule de neige s'était transformée en un jeu complet et jouable. Aucun asset téléchargé. Aucun moteur de jeu. Aucune dépendance. Tout ce que vous voyez et entendez est calculé à partir d'une courte recette.
Voici l'histoire de cette boule de neige — et de l'idée unique qui a tout fait basculer.
1. De la musique à partir d'une formule
La première expérience, c'était un synthétiseur écrit à la main : remplir un tableau d'échantillons, échantillon par échantillon. Une onde sinusoïdale par-ci, une onde carrée par-là, une enveloppe pour façonner chaque note. En une heure, ça avait grandi en :
- une boucle lo-fi posée,
- un chiptune 8-bit avec de vrais canaux à la NES (deux ondes pulse, une basse triangle, un canal de bruit pour la batterie) — y compris l'astuce signature où les accords sont arpégés à ~50 Hz parce que chaque canal est monophonique,
- un thème de combat de boss en la mineur harmonique.
Rien de tout ça n'est un enregistrement. Ce sont les notes, les formes d'onde, les maths.
2. Des sprites à partir d'une grille
Si la musique c'est « des notes, pas un enregistrement », quel est l'équivalent pour un sprite ? La grille, pas l'image. Un personnage dessiné en lignes de texte :
"....KhhhhhhK...."
"...KhhsssshhK..."
"...Khsessesh K.." // eyes
Plus un dictionnaire qui associe chaque caractère à une couleur. Un sprite de 16×16, c'est ~256 caractères de texte. Pour prouver que c'était autonome, j'ai même écrit l'encodeur PNG à la main (zlib + quelques chunks). L'animer ? On échange quatre lignes de texte entre deux poses.
3. Le détour qui a livré la vraie leçon
Quelqu'un m'a demandé : « et pourquoi ne pas générer une image 1080p en code ? » Excellente question. J'ai rendu un ensemble de Mandelbrot en 1920×1080 en ~50 lignes, en 9 secondes.
C'est là que le principe s'est cristallisé :
Un fichier, c'est soit du détail calculé, soit du détail stocké. Le code vous offre le premier gratuitement. Pas le second.
Une fractale a un détail infini issu d'une formule de 2 lignes. Un sprite de 16×16 a 256 pixels placés à la main. Une photographie a ~2 millions de pixels qu'aucune formule courte ne peut régénérer — c'est exactement pour ça qu'on ne peut pas la « coder », et que c'est le boulot d'un modèle d'image IA ou d'un artiste. La ligne de partage, ce n'est pas la résolution. C'est la compressibilité : le contenu est-il descriptible par des règles ?
4. Le jeu
Avec la musique et les sprites réglés, le reste n'était que de l'assemblage. CodeQuest est un jeu de survie façon Vampire Survivors : des hordes d'ennemis qui foncent sur vous, une arme à tir automatique, des gemmes d'XP, des montées de niveau, et un boss tête de mort avec sa propre bande-son qui démarre dès qu'il apparaît.
Le tout — le rendu, la physique, l'IA des ennemis, deux bandes-son procédurales, des effets de particules, une caméra qui défile — tient dans un seul index.html, ~28 Ko, zéro dépendance, aucune étape de build. C'est le jeu entier, dans un fichier texte que vous pouvez versionner.
5. C'est littéralement comme ça que les classiques étaient faits
Voici le moment où un bricolage de week-end se transforme en leçon d'histoire : c'est exactement comme ça que les jeux de votre enfance ont été construits.
La NES ne pouvait pas stocker d'audio enregistré. Sa puce sonore — le Ricoh 2A03 — offrait cinq canaux aux compositeurs : deux ondes carrées, un triangle, un canal de bruit, et un coûteux canal d'échantillonnage que la plupart des jeux touchaient à peine. Une cartouche contenait des kilo-octets ; pas la place pour un MP3. Alors la musique n'était pas enregistrée, elle était décrite — hauteurs, formes d'onde, durées. La recette, pas le résultat. Exactement ce que fait CodeQuest. (Zelda est un indice révélateur : sa version japonaise sur Famicom Disk System avait du matériel audio supplémentaire, et Nintendo a revu la musique à la baisse pour la sortie sur cartouche.)
Et les contraintes ont engendré du génie, pas du compromis. Koji Kondo a fait tenir toute la bande-son de Super Mario Bros. dans environ 40 Ko répartis sur ces cinq canaux lo-fi — et il en a tiré des mélodies que la planète entière fredonne encore. Il réutilisait le matériel comme moi je réutilise une fonction :
- Le jingle de power-up qu'on entend quand Mario attrape un champignon, c'est la fanfare de fin de niveau « Course Clear », jouée à un tempo carrément plus rapide — un seul motif composé, deux usages.
- Les thèmes étaient volontairement courts et bouclables, conçus pour se répéter pendant des minutes sans agacer. La contrainte est devenue le style.
On n'a pas aimé cette musique malgré les limites. Les limites sont la raison pour laquelle on l'a aimée — la rareté force la mélodie. CodeQuest n'est qu'un minuscule écho moderne de la même astuce : quand on ne peut pas tout stocker, on le décrit — et il s'avère que « descriptible » et « beau » se recoupent bien plus qu'on ne le croit.
6. Pourquoi ça compte (au-delà du fun)
Pour un jeu minimaliste, la génération procédurale est un super-pouvoir :
- Minuscule. Des kilo-octets, pas des méga-octets. Aucun pipeline d'assets.
- Versionnable. Chaque sprite et chaque morceau est un diff dans un fichier texte.
- Modifiable à l'infini. On change deux chiffres, on obtient un nouveau niveau ou un nouvel air.
Et le futur hybride est évident : utiliser un modèle d'image IA (Nano Banana, GPT-image) pour le look d'un sprite complexe, puis le ramener dans le code — downscaler, quantifier vers une petite palette, et on retrouve un asset éditable, minuscule et animable. L'IA pour la forme, le code pour le détail qu'on veut garder léger.
Essayez-le
- 🕹️ Jouer : https://stark-52.github.io/codequest/
- 💻 Source (MIT), avec chaque prototype dans
/process: https://github.com/Stark-52/codequest
C'est parti d'une question idiote. Ça s'est terminé en méthode. Prochaine étape : iOS.
Version aussi sur Medium. Je construis tout ça en solo, en public — andygarcia.pro.
