Paradise · Control Center
juin 2026 → juillet 202610 min de lecture

J’ai commencé ce projet après avoir regardé Paradise, la série de Dan Fogelman : 25 000 personnes vivent enfermées dans une ville souterraine, trois ans après une catastrophe. L’intrigue est policière, mais ce qui m’a occupé l’esprit après l’épisode, c’est l’intendance. Comment on nourrit une ville fermée, d’où vient son oxygène, ce que ça coûte en électricité d’éclairer des cultures qui ne voient jamais le soleil. La série ne répond pas à ces questions, alors j’ai voulu voir si je pouvais y répondre en chiffres.
Paradise · Control Center, c’est le poste de commandement de cette ville. La simulation tourne en continu sur le serveur, en temps réel, donc une heure dans la ville dure une heure chez moi. On y surveille les réserves, la centrale et chaque habitant, avec son bracelet et les caméras qui le voient, et on peut intervenir : arrêter une serre ou un réacteur, rationner la ville, couper un bracelet, geler une caméra. Il n’y a pas de version en ligne, le projet tourne sur ma machine.
Aucun chiffre posé à la main
C’est la règle que je me suis donnée au départ. Presque tout ce qui s’affiche se calcule à partir d’une dizaine de constantes réelles, comme l’oxygène, l’eau et les calories dont un habitant a besoin chaque jour, ou ce que fournit un petit réacteur nucléaire. Chacune vient de sources comme la NASA ou la FAO, et elle est écrite dans un document du dépôt, avec sa formule, avant d’être codée.
Cette règle demande plus de travail qu’elle n’en a l’air. Je ne peux pas ajuster le modèle pour obtenir un résultat qui me plaît, donc il faut chercher les sources, les écrire, et parfois repousser une fonctionnalité faute de données. En échange, chaque chiffre affiché remonte à une cause, et les comportements les plus intéressants de la ville sont arrivés sans que je les programme.
L’air en est un bon exemple. La surface des serres est dictée par les calories, et il faut beaucoup plus de plantes pour nourrir 25 000 personnes que pour recycler leur air. Du coup, les serres produisent presque trois fois plus d’oxygène que les habitants n’en respirent, comme on le voit sur le tableau du support-vie.

Le vrai souci, c’est le gaz carbonique. Les plantes et les humains n’échangent pas leurs gaz dans les mêmes proportions, donc le gaz carbonique s’épuise peu à peu. Le compost des déchets des serres rattrape ça en rendant leur carbone à l’air. Rien n’entre ni ne sort de la ville, et le carbone total ne bouge pas d’un gramme sur des milliers d’heures, parce que les stocks sont comptés en nombres entiers et pas en nombres à virgule. La vue des stocks suit ce circuit.

L’électricité, la chaleur et l’eau
Les serres prennent à elles seules plus de 80 % de l’électricité, et elles fixent la taille de la centrale : sept petits réacteurs, six en marche et un pour couvrir les rechargements. Quand la centrale perd de la puissance, le support-vie est servi en premier et les serres prennent ce qui reste. Une panne réduit donc les récoltes sans jamais couper l’air, et la faim arrive des semaines plus tard.
Pour la chaleur, si j’arrête un groupe froid, la température monte doucement pendant quelques heures puis se stabilise, parce que plus la ville est chaude, plus la roche autour absorbe. Et comme le froid consomme de l’électricité, une ville plus chaude produit un peu moins de nourriture quand le réseau est déjà juste.
Pour l’eau, la première version était un compte à rebours : une réserve de six mois qui se vidait, et la ville mourait à date. Je ne voulais pas de ça, sans pour autant supprimer la contrainte. J’ai ajouté une usine de récupération, dimensionnée sur la demande comme tout le reste. Tant que la population ne dépasse pas ce qu’elle couvre, la réserve reste stable, et au-delà, la pénurie arrive toute seule.
Des naissances et des morts
La population n’est écrite nulle part non plus. Chaque heure, chaque habitant a un risque de mourir qui double à peu près tous les huit ans d’âge, et les naissances dépendent du nombre de femmes à chaque âge. Même la pyramide des âges du départ vient de cette règle. Le recensement la montre, avec les foyers et les emplois.

Quand une ressource vitale manque, il y a moins de naissances et des morts en plus, seulement pour la part de la population que la ville ne peut plus nourrir, étalées sur environ deux mois, ce qu’un humain tient sans manger. Ça se règle tout seul, puisque les ressources redeviennent suffisantes à mesure que la population baisse.
C’est le résultat que je voulais voir, parce que rien de tout ça n’est programmé. Si je ramène les serres à un peu plus de la moitié de leur production, la population tombe à peu près de moitié, puis se stabilise au lieu de s’éteindre. Si je les arrête toutes, la nourriture tient neuf jours et demi. Avec la ration à 70 %, le minimum retenu par la FAO, elle tient un peu plus de treize jours.
La journée de chacun
Chaque habitant a un métier tiré des besoins de la ville, un foyer et une routine, avec des équipes de jour et de nuit qui tournent chaque semaine. Pourtant, presque rien n’est stocké par habitant : sa naissance, sa mort éventuelle, son sexe, son foyer et un identifiant, dans des tableaux typés où les 25 000 tiennent en moins d’un mégaoctet. Tout le reste est recalculé à la demande à partir de la graine du monde et de l’heure. La fiche de ce bébé, né pendant la simulation, est entièrement reconstruite comme ça.

Sur la carte, chaque habitant est placé dans un vrai bâtiment. Le serveur n’envoie jamais les 25 000 positions d’un coup, seulement un échantillon de ce qui est à l’écran.

Ce niveau de détail a ses pièges. À midi, l’équipe d’un réacteur partait manger, et la salle de commande se retrouvait vide. Le personnel des installations critiques compte maintenant comme présent sur tout son service, pauses comprises.
Le navigateur ne calcule rien
L’état de la ville se déduit de trois choses : la graine du monde, le temps écoulé et la liste de mes interventions. Les sauvegardes ne sont donc qu’un cache, puisque rejouer dix ans depuis la fondation prend moins d’un quart de seconde. Le moteur pourrait même rattraper le temps où le serveur était éteint, mais j’ai préféré que la ville reparte là où elle s’était arrêtée. Après une semaine de coupure, je ne voulais pas retrouver des naissances, des morts et des pénuries arrivées sans que personne les voie.
Côté technique, c’est un monorepo Bun en trois parties. Le serveur, en Elysia, fait tourner le moteur, le sert en REST et en SSE et sauvegarde dans SQLite. Le front, en Vite, React 19 et Tailwind, ne fait qu’afficher. Entre les deux, un paquet partagé porte les types échangés et le calcul de l’heure de la ville. Le navigateur n’a donc ni règle du jeu ni horloge à lui. Quand la liaison se coupe, il fige l’heure sur la dernière valeur reçue et le signale, au lieu de faire défiler des secondes que personne n’a calculées.
Écrit entièrement par Claude
C’est le premier projet que j’ai mené de bout en bout sans écrire le code moi-même. Tout Paradise a été écrit par Claude Code à partir de mes prompts. Moi, je décidais quoi construire et dans quel ordre, je choisissais les technologies, je tranchais la conception avant la première ligne de code, et je fixais les règles. Rien n’était livré sans tests, typage, lint et build au vert, ni sans un essai pour de vrai dans le navigateur. Après chaque module, des agents cherchaient des défauts, d’autres essayaient de les réfuter, et je ne gardais que ce qui tenait.
Au début, l’exercice est très bon pour mettre ses idées au clair. Formuler une intention et la voir revenir sous forme de questions fermées m’a obligé à trancher des choses que j’aurais laissées floues. La recherche est l’autre gros gain : chercher, recouper et documenter des chiffres de physiologie, d’agronomie et de nucléaire aurait été un projet à lui seul. Et puis il y a la vitesse. Quand je disais qu’un flux de mesures noyait les vrais événements dans le journal, il avait disparu dans la demi-heure.
Au bout d’une vingtaine d’itérations, je me suis lassé, et la raison est simple : je ne maîtrisais plus ce qui se passait. À la fin, je ne savais plus dire comment fonctionnait une bonne partie du code, et si je reprenais Paradise aujourd’hui, il me faudrait un vrai temps de relecture avant de toucher à quoi que ce soit. Les tests et les revues vérifiaient des choses que je ne relisais plus, mais ça ne remplace pas le fait de connaître son propre code.
Pour ce projet-là, l’échange reste très favorable. Le but était personnel : voir vivre une ville. Je l’ai regardée évoluer semaine après semaine, avec un niveau de détail que je n’aurais jamais atteint autrement, et c’était franchement divertissant. Sur un projet à maintenir dans la durée, ou à plusieurs, je m’y prendrais autrement. C’est ce que je fais sur Nooki : lui aussi est entièrement écrit avec Claude, mais cette fois je le cadre.
Où en est le projet
Paradise est en pause depuis le 26 juillet 2026, avec tous ses tests au vert et à peu près la moitié des modules prévus. La santé, la gouvernance ou les protocoles d’urgence n’ont jamais été commencés.
Je m’arrête pour une raison que je n’avais pas prévue. À force de construire des leviers, je me suis rendu compte que je préférais regarder la ville vivre plutôt que la piloter. Couper un bracelet, geler une caméra ou rationner la ville, c’était l’idée de départ, celle qui vient de la série. Ce qui me retient devant l’écran, c’est la pyramide des âges qui bouge toute seule.
Si je le reprends un jour, je repartirai de zéro sur une bonne partie du code, et je changerai deux choses dans ma façon de faire. D’abord, découper la logique en morceaux beaucoup plus petits, chacun testable seul, pour garder la main sur un projet de cette taille. Ensuite, relire chaque choix technique un par un, et surtout regarder de près comment chaque chiffre est calculé, parce que c’est là qu’on comprend vraiment le modèle, et c’est ce qui m’a manqué à la fin. Le sujet, lui, m’intéresse toujours, et ce moteur pourra servir de base à d’autres simulations de la vie.