Aller au contenu
Blog
Technique23 septembre 2026

La sauvegarde que le joueur ne choisit pas

EREME n'a pas de bouton sauvegarder. Le moteur écrit à l'entrée de chaque nœud, avant de révéler la carte, et refuse d'écrire à mi-décision. Pourtant, pendant dix-neuf jours, la partie jouée à l'écran ne s'écrivait presque jamais, et le gate était vert.

Pas de bouton

EREME n'a aucune sauvegarde manuelle. Pas de bouton, pas d'emplacement, pas de « sauvegarder et quitter » : le menu quitte, c'est tout, parce que la partie est déjà écrite. Le moteur sauvegarde à un seul point canonique : l'entrée d'un nœud du voyage, avant la révélation de la carte d'événement. Deux échos au port complètent la liste : la Reliure d'un voyage et un changement d'équipage s'écrivent aussi. La borne n'est pas cosmétique : révéler la carte tire sur le générateur aléatoire et arme une décision. Sauvegarder après, ce serait figer une partie à mi-choix.

L'interdit est exécutable, pas documentaire : le magasin de sauvegarde inspecte l'état et refuse d'écrire si une décision est en cours. Et le fichier embarque l'état du générateur, sérialisé en chaîne de caractères parce qu'un entier 64 bits au-dessus de 2 puissance 53 se tronque en nombre JSON : recharger redonne exactement le même tirage. Le pari risqué se joue après le point de sauvegarde ; le recharger ne le rejoue pas autrement. C'est une sauvegarde de continuité, pas une machine à retenter.

L'écriture elle-même est paranoïaque à proportion de ce qu'elle protège : fichier temporaire, re-parse du temporaire avant de toucher la cible (une écriture corrompue ne détruit jamais la sauvegarde précédente), suppression puis renommage parce que renommer par-dessus un fichier existant échoue sous Windows, et l'échec remonte : la fonction ne répond jamais « écrit » à tort.

Le paradoxe des dix-neuf jours

Cette architecture datait du 18 juillet, testée par un harnais qui rejouait des sagas entières en comparant le fil du récit à l'octet près. Le 6 août, j'ai fait la mesure honnête : la partie jouée à l'écran, elle, ne s'écrivait presque jamais.

La cause est un ordre inversé. La vue rafraîchissait l'écran avant de sauvegarder ; or lire l'état révèle la carte, ce qui arme une décision, et le magasin refusait alors d'écrire, à juste titre. Le commit chiffre le désastre silencieux : « Douze refus par session, une seule sauvegarde sur le disque et sans voyage dedans. » Le point de sauvegarde existait depuis dix-neuf jours sans un seul appelant du côté où les joueurs jouent.

Et le harnais restait vert. « Le gate ironman était vert quatorze graines durant, parce que sa sonde repassait l'id qu'elle venait de choisir : elle mesurait un chemin que personne ne prend. » La sonde vérifiait le magasin ; personne ne vérifiait la vue.

Le correctif inverse l'ordre, sauvegarder avant de rafraîchir, et surtout il change ce qui est mesuré : un bloc de harnais coupe désormais le processus au seizième écran et exige des écritures en vol et zéro refus ; le bloc suivant reprend littéralement la partie coupée, même dossier, même graine. Le refus, autrefois silencieux, est devenu une métrique surveillée. Le commentaire du code assume : « Une sauvegarde qui échoue en silence est pire qu'une absence de sauvegarde : le joueur croit que sa partie est écrite. »

La zone sans filet

Une exception traverse tout ça : le prologue. Jusqu'à sa Reliure, il n'écrit rien sur le disque ; la première écriture d'une saga est précisément cette Reliure. C'est assumé : à graine égale, le prologue se rejoue à l'identique.

Le 15 août, le playtest du matin meurt en dur, précisément là : en fin de prologue. Pas de fenêtre d'erreur, un log moteur vierge, dix minutes de choix perdues, et surtout rien à diagnostiquer. La zone sans filet de sauvegarde était aussi la zone sans filet de diagnostic.

La boîte noire

Ma réponse n'a pas été d'ajouter une sauvegarde au prologue, mais d'admettre que deux choses différentes méritent de survivre à un crash : la partie, et le diagnostic. La partie a son magasin. Le diagnostic a eu, le jour même, sa boîte noire.

Un journal séparé, où chaque ligne est poussée sur le disque avant de rendre la main : la ligne est chez le système d'exploitation, la mort du processus ne peut plus la reprendre. Le geste s'y note avant d'être exécuté, son résultat après, la carte à sa révélation, la graine au largage. Le titre du commit résume le contrat : « Un processus qui meurt laisse la scène, la graine et le dernier geste. »

Le plus élégant est l'inversion du fardeau de la preuve. Une fermeture propre écrit un marqueur de fin ; une mort n'écrit rien. À l'ouverture suivante, la trace sans marqueur est rangée comme trace de mort, à part des traces propres : l'absence est l'aveu, et le crash d'hier survit aux sessions saines d'aujourd'hui.

Et le harnais prouve la boîte comme la boîte le mérite : la sonde tue un vrai processus, sans fermeture, sans dernier vidage, et c'est un second processus qui lit le fichier. « Une mort réelle ne se mesure pas depuis le processus qui la subit. » J'ai sabordé le gate deux fois pour vérifier que le filet mord, et la mesure du commit est nette : sans la poussée ligne à ligne, le mort laisse zéro octet.

L'instrument, pas la correction

Le crash du 15 août n'est toujours pas reproduit. La boîte noire ne l'a pas corrigé, et c'est le point : elle est l'instrument posé pour l'attraper la prochaine fois, avec la scène, la graine et le dernier geste déjà sur le disque.

Deux invariants valent la peine d'être exécutables : le magasin refuse d'écrire à mi-décision, et la sonde emprunte le chemin du joueur, pas le sien. Un gate vert qui mesure un chemin que personne ne prend est pire qu'un gate rouge : il achète dix-neuf jours de confiance avec de la fausse monnaie.

La leçon

La sauvegarde et le diagnostic sont deux disciplines, avec deux preuves distinctes. La partie se protège par un point d'écriture unique et se prouve par une coupure rejouée ; le diagnostic se protège par des lignes poussées une à une et se prouve par un processus réellement tué. Les confondre, c'est découvrir au premier vrai crash qu'on n'a ni l'une ni l'autre.