This isn’t specific to games. It’s a general software principle called «code/data separation».
I expected it would be easy to find an article on the subject to point you towards, but it wasn’t. I’m not going to try to write a full article on the subject myself, but basically it has two benefits.
-
Code reuse. If you separate the data from the code, you can reuse the code with different data. I once met up with someone I vaguely knew for a coffee, and he offered me a job. He ran a research bureau, and they regularly contracted a certain other company to produce questionnaire software; they would install it on a dozen PDAs and send a dozen people out to the airport or the market to interview people. This guy reckoned that it would be cheaper to have an in-house programmer to produce these questionnaire programs. I explained code/data separation to him, and asked for requirements. It ended up with me working for three months on a program which read the questionnaire from a data file which provided an elementary (non-Turing-complete) language with control flow; I spent three days training one of his employees to use the software and write the data files; and the research bureau could prepare a new questionnaire in a day rather than paying this other company for two or three months’ work to produce a hard-coded one. (To forestall any accusations of stupidity or killing the goose which lays the golden eggs: this is the professional approach. And a couple of weeks after finishing that project, I landed a dream job at Jagex).
If you think that sounds completely unrelated to games, try this on: user-developed content. If you create a game which stores level designs in files, you can allow users to create more levels. It’s a cheap way of expanding the game, and it has the potential to provide your players with much more variety than if all the levels came from one or two minds. If the levels are hard-coded, this is almost impossible to implement.
-
Data reuse. Cero has already talked about this. If your data is stored in a file, it can be used by different programs (in different ways). In particular, for games, you can write tools. Sometimes an in-game level editor is the best way to do things, but even in that case you need a way to save your changes.
To address your specific issue of detailed customisation: that’s still possible if you use files for data storage. The custom behaviour may need to be implemented in code, but the linking between behaviours and items can be stored in a config file. The key thing is to learn about ways of composing behaviour other than subclassing, and apply the OOP principle of favouring composition over inheritance. In particular, the Decorator pattern is one relevant approach (although possibly a bit heavyweight); the Observer pattern can be bastardised slightly to allow registering callbacks which affect behaviour; and the Strategy pattern specifically supports different behaviour for the same task.