The game becomes interesting when the rules meet
My first C# survival game combined movement, resources, inventory, items and survival rules. Each part seemed manageable on its own. The real shift came when they needed to work together: a collected resource had to enter the inventory, become available for crafting and remain consistent as the game continued. Features were becoming relationships as well as individual actions.
Object-oriented programming then became more than a course topic. A class needed to represent something useful, and its responsibility affected other parts of the program. Organisation was no longer just about tidy files. It influenced how difficult the next addition would be and how many places needed attention when a rule changed.
Responsibilities show up in the changes they attract
The inventory sat between several features. Changing it could affect crafting, display or saving. That relationship is not automatically a problem: those features describe the same running game. The difficulty appears when a rule is repeated in different places or when a change requires exceptions whose reasons are hard to connect.
In a fictional game, a recipe might require enough of two resources before removing any items. That check needs a clear home. If every screen invents its own version, behaviour can drift. This example captures the question that interests me: where should a rule live so other parts can depend on it consistently?
Inheritance still requires understanding the problem
Classes and inheritance provided ways to represent related objects. Recognising a similarity, however, does not settle the structure. Two objects can share data while behaving differently. The design needs to follow what the program actually does with them, rather than a hierarchy that looks complete before those behaviours have been examined.
I did not have all those distinctions clear at the start. Revisiting the project makes them practical: which information describes an item, which rules concern the inventory and which actions belong to the game’s progression? Asking those questions helps explain a separation before adding more classes. A larger file count cannot answer them on its own.
Saving makes you define the game state
JSON saves introduced another question: which information makes it possible to resume a game? Saving everything available is not necessarily useful. Some values represent choices or progress, while others can be recalculated. I had to pay closer attention to the difference between information that must persist and details used to present it at one moment.
As a general example, saving inventory identifiers and quantities also raises questions about reconstruction. What happens when an expected value is missing or no longer means the same thing? These are useful questions to bring to a first project, even without a complete answer for every case. They explain why saving involves more than producing a file.
Notice earlier when code is getting harder to change
A growing method or repeated rule makes the next step harder to follow. This game helped me see the cost of leaving organisation until the end. When several features already depend on mixed responsibilities, separating them requires recovering more context and checking more behaviours together. The work grows beyond moving a few lines into another file.
I now see the project as a starting point, including its limitations. A relatively small program can already require decisions about data, dependencies and persistence. The question I keep from it is practical: can I explain where a rule lives and what a change might affect? That is a more useful direction than expecting a perfect architecture immediately.