This statement cannot be understated enough when it comes to common programming practices, and even more important when undertaking a project as large and complex as a game. Games are a special case in their own due to all the different interacting systems, and keeping track of them can be a nightmare if not implemented properly. This is where modularity comes in.
Some programming languages have modularity built in, or are entirely based on it. Visual basic is a good example, and right now I'm fiddling around with Visual Basic for Applications, a scripting language built for office apps such as excel. It is very explicit in how it defines modularity. Every piece of code is written in a "module", which usually contain a sub or a function (if it returns a value). There are also class modules where you can write a stripped version of a class to call methods from. VBA unfortunately (and it seems contradictory) does not support inheritance which is a major component of modularity, however there is a way to fake it through interfaces involving the implements keyword, but I won't go into that here.
What I will talk about is the many applications of modularity and how it could improve what our last year's codebase looked like (which was a little messy).
One of the our worst transgressions was overuse of a main game class. Although we had separate systems we dumped a lot of code into the class containing the main update loop. In fact we only had one update loop where everything in the game was being called, and it acted as a universal manager. Too much reliance on a module can lead to a unhealthy dependency that can have catastrophic effects when that one class fails. So how do we improve it?
One way is to separate every game system into its own little environment, where it has its own manager classes that handle the data calculation . The physics system can have it's own update that does the calculation for the next frame, and all data is handled in that specific update loop which would be implemented in a manager class for physics. It can then send the final processed data to wherever it needs to go, for example handing it off to the rendering system to be sent of to the graphics card for processing (using pointers of course, we don't wanna waste time with pointless copying of objects). This is also better for collaborating with multiple programmers. If you can have these subsystems isolated as much as possible, then multiple people can be working on different things without interfering with each other (this will benefit especially when it comes to sorting out conflicting commits).
The other alternative is to include scripting to handle your high level game logic, which will change more as you are reaching the end of your development cycle. Because scripting languages are coded at runtime they are essentially "instantly" compiled and can be run immediately. The benefit is that you can make tweaks and even major changes to upper game logic without needing to recompile the entire engine. The scripting engine acts as the brain and the core engine the body (sort of). The drawbacks though are a loss of performance as this(script) code is "outside" the main engine code, and the engine has to go all the way to the script to get the high level instructions, but again you save the time from having to recompile your entire engine. It is a balancing act of time vs. performance depending on how well you implement it.
For this year's title, I think we will be having a go at implementing a scripting language, could be python, lua, especially with the multiplayer requirement in the upcoming semester. We'll just see if we're up to the task.