Le jeu devient intéressant quand les règles se rencontrent
Mon premier jeu de survie en C# associait déplacements, ressources, inventaire, objets et règles de survie. Pris séparément, ces éléments semblaient abordables. Le vrai changement est arrivé quand ils ont dû fonctionner ensemble : une ressource récupérée devait rejoindre l’inventaire, pouvoir servir au crafting et conserver un état cohérent au fil de la partie.
C’est là que la programmation orientée objet a cessé de ressembler seulement à un chapitre de cours. Une classe devait représenter quelque chose d’utile pour le programme, et sa responsabilité avait des conséquences sur les autres parties. Organiser le code ne servait plus simplement à le ranger ; cela déterminait la difficulté du prochain ajout.
Une responsabilité se voit dans les changements qu’elle attire
L’inventaire se trouvait au croisement de plusieurs fonctionnalités. Une modification pouvait toucher le crafting, l’affichage ou la sauvegarde. Cette dépendance n’est pas automatiquement un défaut : ces parties décrivent la même partie en cours. Le problème apparaît lorsqu’une règle doit être répétée à plusieurs endroits ou qu’une modification impose des exceptions difficiles à relier.
Par exemple, dans un jeu fictif, une recette pourrait demander deux ressources disponibles en quantité suffisante. La vérification devrait avoir un sens clair avant de retirer les objets. Si chaque écran réinvente ce contrôle, les comportements peuvent diverger. Cet exemple résume la question qui m’intéresse : où placer une règle pour que les autres parties puissent s’appuyer dessus ?
L’héritage ne remplace pas la compréhension du domaine
Les classes et l’héritage donnaient des outils pour représenter des objets liés. Mais reconnaître une ressemblance ne suffit pas à choisir une structure. Deux objets peuvent partager des données tout en ayant des comportements différents. Il faut regarder ce que le programme doit réellement faire avec eux, plutôt que chercher immédiatement une hiérarchie qui paraît complète sur papier.
Je n’avais pas toutes ces distinctions au départ. Le projet reste utile pour y revenir : quelles informations décrivent un objet, quelles règles concernent l’inventaire et quelles actions appartiennent au déroulement du jeu ? Poser ces questions permet de comprendre une séparation avant de multiplier les classes. Le nombre de fichiers ne dit pas, à lui seul, si les responsabilités sont claires.
Sauvegarder oblige à nommer l’état de la partie
La sauvegarde JSON a ajouté une autre question : quelles informations permettent de reprendre la partie ? Enregistrer tout ce qui est disponible n’est pas forcément utile. Certaines valeurs représentent un choix ou une progression ; d’autres peuvent être recalculées. Il faut distinguer les données à conserver des éléments qui servent seulement à présenter l’état à un moment donné.
Pour prendre un exemple général, conserver les identifiants et les quantités d’un inventaire pose aussi la question de leur reconstruction. Que se passe-t-il si une donnée attendue manque ou n’a plus le bon sens ? Ces questions méritent déjà une place dans un premier projet, même sans réponse complète pour chaque cas. Elles montrent pourquoi une sauvegarde dépasse la simple production d’un fichier.
Reconnaître plus tôt les endroits qui deviennent difficiles
Une méthode qui s’allonge ou une règle répétée rend la suite moins facile à suivre. Dans ce jeu, j’ai commencé à voir le coût de repousser l’organisation jusqu’à la fin. Quand plusieurs fonctions reposent déjà sur le même mélange de responsabilités, les séparer demande de retrouver davantage de contexte et de vérifier plus de comportements en même temps.
Je regarde aujourd’hui ce projet comme un point de départ, avec ses limites. Il montre comment un programme assez petit peut déjà demander des décisions sur les données, les dépendances et la persistance. La question que je garde n’est pas de trouver une architecture parfaite : c’est de pouvoir expliquer où vit une règle et ce qu’un changement risque de toucher.