I try to program as atomically as possible, following the Single Responsibility Principle as best I can (but I don't go extreme nazi on things, in case you panic). This works pretty well in a lot of my work.
But games are complicated. Objects interact with each other and the entire game's state regularly throughout the game. Units collide, one unit attacks another, a building makes units, a unit can create projectiles, and those projectiles can affect a large number of other units, etc. In other words, when programming this, you need a way for one object to be able to affect another object (or the game state itself, possibly by creating other units or projectiles). But it's not just a one-time case; many different units have different affects and interactions, which can result in messy code when trying to make all these possible interactions and events possible.
What's your preferred way of letting various objects (units) affect the game (by creating other units, buildings, projectiles, hurting/healing other units, etc.)?
I'm trying to think of some good ways to let these interactions occur that allows for (generally) clean code. My current solution is to have a Game class that actually runs a single game (by updating units (units update themselves as much as possible, but the Game tells them when to), enforcing game rules (so units can't walk up cliffs, for example), updating scores, etc.), and having each unit (or any other object that needs to interact with the Game itself) hold a reference to the Game to which it belongs. If a unit wants to do something that affects another unit or the Game, it calls the corresponding method on the Game object.
For example, if unit A wants to create a building at x, y, it calls Game's makeBuilding(owning_player, x, y), and the Game either creates the building, or it returns false indicating that was an illegal move (perhaps there's already a building there). Or, for another example, unit B wants to launch a rocket that's aimed at target_x, target_y. Unit B then calls Game's createProjectile(owning_player, unit_pos_x, unit_pos_y, target_x, target_y), and the Game creates the projectile and takes ownership of it. Or, another example, unit C performs a melee attack at position x, y in direction dir, so it calls Game's meleeAttack(owning_player, x, y, dir) and the Game can decide if another (enemy) unit was hit and deal damage as needed.
Is this a sane solution? Is there a better one? I'm afraid Game will grow into a monstrous class and have too much responsibility, but then again I'm not sure this can be avoided, and this solution will hopefully prevent a lot of spaghetti code and unnecessary coupling.
I want to try and explore as many (good) solutions as I can before I get too far down the road with this game I'm working on.