Projet 08 : Persistent system
Dans le Projet 07, ta mission accordait de l'argent via un drapeau en mémoire vive. Dans le Projet 08, tu franchis une étape déterminante vers l'ingénierie logicielle : concevoir un moteur de réputation de factions où ton rang auprès des Families et des Ballas est sauvegardé sur disque, survit à la fermeture du jeu et encaisse les fichiers corrompus sans jamais faire planter le moteur.
La mission
Concevoir un système de persistance disque résilient remplissant six objectifs majeurs :
- Sérialiser et désérialiser des données de profil structurées en JSON via
System.Text.Json. - Créer automatiquement l'arborescence de dossiers cible (
scripts/my_mod/) à la volée sans lever d'exception. - Charger les données au premier tick et afficher une notification confirmant la réputation active et la version du schéma.
- Mettre en œuvre une tolérance aux pannes en deux vagues : créer des valeurs par défaut si le fichier manque, et récupérer proprement un JSON corrompu.
- Protéger le système contre les évolutions de schéma futures grâce à un contrôle de version entier (
Profile.CurrentVersion). - Sauvegarder l'état sur disque lors du déchargement du script dans
OnAborted.
Spécifications, contraintes
- Résilience absolue aux pannes : encapsuler toutes les opérations d'E/S et de parsing JSON dans des blocs
try-catchdéfensifs ; un fichier corrompu doit basculer sur les données par défaut sans faire planter le jeu. - Gestion explicite des versions : maintenir un champ entier
Versiondans le modèle de données afin de repérer les formats obsolètes ou incompatibles. - Journalisation secondaire silencieuse : l'écriture de logs dans
profile.logne doit en aucun cas lever d'exception non gérée ni perturber l'expérience de jeu. - Formatage lisible par un humain : indenter le fichier JSON généré avec
new JsonSerializerOptions { WriteIndented = true }. - Sauvegarde au déchargement : enregistrer les données actives dans
OnAbortedpour prévenir toute perte d'avancement.
Étapes de réalisation
- Définir le modèle de données : crée une classe
ProfilecontenantVersion,Reputationet unDictionary<string, int> FactionStandings. - Déclarer le script de persistance : dans
JsonPersistence, définis le chemin du fichier et un champ privé_profile. - Brancher les événements : dans le constructeur, enregistre des gestionnaires pour
TicketAborted. - Programmer le chargement différé : dans
OnTick, vérifie si_profileest nul. Si oui, initialise-le avecLoadProfile()et affiche un téléscripteur d'information. - Bâtir le chargement défensif dans
LoadProfile:- Vérifier
File.Exists(SavePath). Si absent, instancierDefaultProfile(), l'enregistrer sur disque et le renvoyer. - Lire le texte et désérialiser vers
Profile. - Contrôler la compatibilité de version : si la version diffère de
Profile.CurrentVersion, consigner un avertissement et renvoyer les données par défaut. - Encadrer le tout dans un
try-catchpour récupérer toute erreur de syntaxe JSON et renvoyer le profil par défaut.
- Vérifier
- Programmer la sauvegarde défensive dans
SaveProfile:- S'assurer de l'existence du dossier parent avec
Directory.CreateDirectory. - Sérialiser avec indentation et écrire le fichier.
- S'assurer de l'existence du dossier parent avec
- Créer la journalisation silencieuse : ajouter des lignes horodatées dans
profile.logau sein d'untry-catchmuet. - Sauvegarder à l'arrêt : dans
OnAborted, exécuterSaveProfile(_profile).
APIs, outils à explorer
System.Text.Json.JsonSerializer.Serialize<T>(T value, JsonSerializerOptions options): convertit des objets .NET en texte JSON.System.Text.Json.JsonSerializer.Deserialize<T>(string json): reconstruit des objets C# typés à partir d'une chaîne JSON.System.IO.File.ReadAllText(string path)/File.WriteAllText(string path, string contents): lit et écrit l'intégralité d'un fichier texte.System.IO.Directory.CreateDirectory(string path): crée récursivement tous les répertoires et sous-répertoires du chemin spécifié.System.Collections.Generic.Dictionary<TKey, TValue>: dictionnaire clé-valeur pour stocker les scores des différentes factions.
Critères de validation
Ton mod est validé dès que :
- Premier lancement sans fichier :
profile.jsonest généré avec les valeurs par défaut, et la notification affiche "Reputation chargee : 100 (v1)". - Inspection du fichier
profile.json: le document est indenté et contient la version 1, 100 de réputation et les scores des Families (50) et Ballas (-50). - Corruption du fichier avec du texte incohérent : au rechargement, le script restaure les valeurs par défaut sans planter et consigne l'erreur dans
profile.log. - Modification de
"Version": 99dans le JSON : le script détecte l'incompatibilité, bascule sur les valeurs par défaut et poursuit sa route. - Rechargement avec
Inser: le profil actif est sauvegardé sur disque sans perte de données.
Solution, explications
Partner
Solution vérifiée et explications du code
Le sujet, les contraintes et les étapes de réalisation restent 100% libres pour t'exercer par toi-même. Le code source de référence vérifié et les explications détaillées de production sont réservés aux membres du tier Partner.