CHAPTER 16
Beginner
Clean Code and Game Architecture
Updated: May 16, 2026
30 min read
# CHAPTER 16
Clean Code and Game Architecture
1. Introduction
When you first start programming, your only goal is to make the game work. You write a 1,000-line script calledPlayer.cs that handles movement, health, shooting, playing sounds, and updating the UI. This is called "Spaghetti Code." It works for a 2-day Game Jam, but if you try to build a commercial indie game this way, the code will become so tangled that adding a single new feature will break five others. In this chapter, we transition from being a programmer to an Architect. We will learn how to write Clean Code using SOLID principles, decouple our scripts using the Observer Pattern (Events), and structure our project using dedicated Game Managers.
2. Learning Objectives
By the end of this chapter, you will be able to:- Understand and apply the Single Responsibility Principle (SRP).
- Transition from deep Inheritance to Component-Based Architecture.
-
Decouple scripts using C#
Actiondelegates (The Observer Pattern).
- Implement the Singleton pattern correctly for Game Managers.
- Organize a scalable, professional game codebase.
3. The Single Responsibility Principle (SRP)
The 'S' in SOLID stands for Single Responsibility. A class should have one, and only one, reason to change.-
*Bad:*
Player.cshandles movement, health, and inventory.
-
*Good:*
PlayerMovement.cshandles walking.HealthComponent.cshandles taking damage.InventoryManager.cshandles items.
4. Component-Based Architecture
Instead of writing anEnemy class, and making an Orc inherit from it, modern engines (like Unity) use Composition.
You create a blank "GameObject" and attach small, reusable Lego blocks (Components) to it.
csharp
5. The Observer Pattern (C# Events)
If the player takes damage, the UI needs to update the health bar.-
*Bad (Tightly Coupled):* The Player script calls
UIManager.Instance.UpdateHealthBar(). The Player now relies on the UI existing.
- *Good (Decoupled):* The Player script simply shouts, "I took damage!" to the void. The UI script is listening and updates itself. The Player doesn't even know the UI exists.
Action delegates.
csharp
6. Managing the Game (Singletons)
A game needs global systems. AGameManager tracks the current level and the score. An AudioManager plays music.
We use the Singleton Pattern to ensure only ONE instance of this manager exists, and it is easily accessible from any script.
csharp
7. Visual Learning: Monolithic vs. Component Architecture
txt
8. Best Practices
-
Avoid "Manager" Bloat: If your
GameManageris handling audio, spawning enemies, saving data, and drawing the UI, it violates the Single Responsibility Principle. Break it down into anAudioManager,SpawnManager,SaveManager, andUIManager.
9. Common Mistakes
-
Overusing Singletons: Beginners learn the Singleton pattern and suddenly make *everything* a Singleton (e.g.,
Player.Instance). This is an "anti-pattern." It creates hidden dependencies and makes the code very hard to test. Only use Singletons for true global systems (Audio, Scene Loading, Game State).
10. Mini Project: Implement the Observer Pattern
Objective: Decouple a coin collection system from the UI using Events.
csharp
11. Practice Exercises
- 1. What does the "S" in SOLID principles stand for, and what does it mean?
-
2.
Why is it dangerous to have the
Player.csscript directly reference theUIManager.csscript to update a health bar?
12. MCQs with Answers
Question 1
You want to create a script that manages background music and sound effects across the entire game. You need to ensure that every other script can access it easily, and that only one copy of it ever exists. Which architectural pattern should you use?
Question 2
In the Observer Pattern example, why is the ? used in OnCoinCollected?.Invoke();?
13. Interview Questions
- Q: Explain the Single Responsibility Principle. Describe a scenario where a massive "God Class" violates this principle and explain how you would refactor it.
-
Q: Contrast Tightly Coupled code with Decoupled code. How does implementing C#
Actiondelegates (Events) achieve decoupling between a Player's health component and the UI Canvas?
- Q: What is a Singleton? While useful for Game Managers, why is the Singleton pattern frequently referred to as an "anti-pattern" when overused by junior developers?
14. FAQs
Q: Should I completely avoid Inheritance? A: No! Inheritance is still highly useful for Data and purely logical structures (e.g., anItem base class, with Weapon and Potion inheriting from it). However, for visual objects that live in the game world (Enemies, Players, Props), favor Component-Based Composition.