DEVELOPER_GUIDE
Developer Guide
Complete Reference for Tower Defense Developers
Version: 1.0 Date: December 2025 Project: Procedurally Generated Tower Defense
Table of Contents
1. Getting Started
1.1 Project Setup
Prerequisites
✅ Unity 2022.3 LTS or newer ✅ Universal Render Pipeline (URP) package ✅ Git (for version control) ✅ Visual Studio 2022 or Rider 2024 ✅ Windows 10/11, Mac, or Linux
Setup Steps
Step 1: Clone Repository
Step 2: Open in Unity
Open Unity Hub
Click "Open" → Select project folder
Unity will import assets automatically (5-10 minutes first time)
Step 3: Verify URP Asset
Edit → Project Settings → Graphics
Verify URP Asset is assigned
Check SRP Batcher is enabled ✓
Step 4: First Run Test
Open scene:
Assets/Scenes/MainGame.unityPress Play
Expected: Game runs at 100+ FPS
📝 Note: If FPS is low (<60), check VSync settings: Edit → Project Settings → Quality → VSync Count: Don't Sync
1.2 Required Tools
Unity Profiler
Performance analysis
Window → Analysis → Profiler
Frame Debugger
Rendering optimization
Window → Analysis → Frame Debugger
Stats Window
Real-time FPS/batch monitoring
Game View → Stats
Console
Debug logs, errors, warnings
Window → General → Console
1.3 First Launch Checklist
✅ Game runs without errors ✅ FPS ≥100 in Game View ✅ Console shows system initialization logs:
✅ Towers can be placed on grid ✅ Enemies spawn and move ✅ Towers attack enemies ✅ Projectiles hit targets
1.4 Project Structure Overview
2. Project Structure
2.1 Folder Organization
/Scripts/Systems/ - Core Game Systems
/Scripts/Systems/ - Core Game SystemsPurpose: Centralized logic processors. Each system handles one responsibility.
Files:
GameSystemsManager.cs- Master orchestratorMovementSystem.cs- Batch movement processingAttackSystem.cs- Combat & targetingProjectileSystem.cs- Projectile lifecycleEffectSystem.cs- Status effects (burn, slow, etc.)
Rules:
✅ Systems implement
IGameSystem✅ No Update() - use Tick(deltaTime)
✅ Register/unregister entities via OnEnable/OnDisable
❌ Never directly reference other systems
/Scripts/Entities/ - Game Entities
/Scripts/Entities/ - Game EntitiesPurpose: Data providers. Entities implement interfaces, contain no logic.
Files:
Enemy.cs- Base enemy classTower.cs- Base tower classProjectile.cs- Base projectile classStatusEffect.cs- Base effect class
Rules:
✅ Implement interfaces (IMoveable, IAttacker, etc.)
✅ Register with appropriate system in OnEnable()
❌ No Update() methods allowed
❌ No direct references to other entities
/Scripts/Interfaces/ - Contracts
/Scripts/Interfaces/ - ContractsPurpose: Define contracts for systems and entities.
Files:
IGameSystem.cs- System lifecycle contractIMoveable.cs- Movement capabilityIAttacker.cs- Combat capabilityITargetable.cs- Can be targetedIDamageable.cs- Can take damageIProjectile.cs- Projectile behaviorIEffect.cs- Status effect behaviorIPoolable.cs- Object pooling support
Rules:
✅ Interface segregation (small, focused interfaces)
✅ Properties only (no methods in data interfaces)
❌ No implementation logic in interfaces
/Scripts/Managers/ - Gameplay Managers
/Scripts/Managers/ - Gameplay ManagersPurpose: High-level game flow control.
Files:
WaveManager.cs- Enemy wave spawningBuildManager.cs- Tower placementUIManager.cs- UI updatesGameState.cs- Game state persistencePoolManager.cs- Object pooling
Rules:
✅ Singleton pattern (managed lifetime)
✅ Event-driven communication
❌ No direct entity manipulation (use systems)
2.2 Naming Conventions
Classes
PascalCase
GameSystemsManager, Enemy
Interfaces
IPascalCase
IMoveable, IGameSystem
Public Fields/Props
PascalCase
Speed, AttackRange
Private Fields
camelCase
currentHealth, moveSpeed
Methods
PascalCase
RegisterMoveable(), Tick()
Constants
UPPER_SNAKE_CASE
MAX_ENEMIES, GRID_SIZE
Enums
PascalCase
TargetingMode, EffectType
Events
PascalCase + Event
OnEnemyDied, OnWaveComplete
2.3 Asset Organization
Prefabs
ScriptableObjects
3. Core Scripts Reference
3.1 System Scripts
GameSystemsManager.cs
Location: Assets/Scripts/Systems/GameSystemsManager.cs
Purpose: Master orchestrator that manages all game systems. Handles initialization, execution order, and lifecycle.
Key Responsibilities:
Initialize all systems on scene load
Execute systems in priority order
Manage system lifecycle (Initialize → Tick → Shutdown)
Provide system lookup API
Architecture:
Public API:
GetSystem<T>()
Retrieve specific system by type
T where T : IGameSystem
RegisterSystem(IGameSystem)
Add system to managed list
void
Usage Example:
⚠️ Critical Notes:
✅ GameSystemsManager MUST exist in every gameplay scene!
✅ Systems execute in priority order (0 = first)
❌ Do NOT modify Update() loop - breaks execution order
❌ Do NOT manually call Tick() - let manager handle it
Expected Console Output:
MovementSystem.cs
Location: Assets/Scripts/Systems/MovementSystem.cs
Purpose: Centralized movement processor for all entities implementing IMoveable. Eliminates individual Update() calls.
Priority: 0 (executes first)
Key Responsibilities:
Batch process all moving entities
Update entity positions
Handle waypoint progression
Notify entities on destination reached
Architecture:
Public API:
RegisterMoveable
IMoveable moveable
Add entity to movement processing
void
UnregisterMoveable
IMoveable moveable
Remove entity from processing
void
Tick
float deltaTime
Process all moving entities
void
Usage Example:
Performance Impact:
⚠️ Critical Notes:
✅ Always register in OnEnable(), not Start()
✅ Always unregister in OnDisable()
❌ Never call UpdatePosition() directly
❌ Never implement Update() in IMoveable entities
AttackSystem.cs
Location: Assets/Scripts/Systems/AttackSystem.cs
Purpose: Centralized combat processor. Handles targeting, cooldowns, and attack execution for all towers.
Priority: 1 (after movement)
Key Responsibilities:
Manage attack cooldowns
Target selection (6 strategies)
Focus towers on targets
Execute attacks
Spatial optimization (coroutine-based scanning)
Architecture:
Public API:
RegisterAttacker
IAttacker attacker
Add attacker to system
void
UnregisterAttacker
IAttacker attacker
Remove attacker from system
void
UpdateTargetsInRange
IAttacker attacker, List<ITargetable> targets
Update cached targets for attacker
void
Tick
float deltaTime
Process all attackers
void
Targeting Strategies:
First
Targets enemy closest to goal (highest waypoint index)
Prevent early leaks
Last
Targets enemy furthest from goal (lowest waypoint index)
Clear backlog
Closest
Targets nearest enemy (SqrMagnitude)
Maximize DPS uptime
Furthest
Targets farthest enemy
Sniper towers
Strongest
Targets highest HP enemy
Focus fire tanks
Weakest
Targets lowest HP enemy
Clear low HP quickly
Usage Example:
Performance Impact:
⚠️ Critical Notes:
✅ Target scanning via coroutine, not FixedUpdate!
✅ Use SqrMagnitude for distance checks (avoid sqrt)
✅ Manual iteration, NO LINQ in hot paths
❌ Never call PerformAttack() directly
❌ Never implement Update() in towers
ProjectileSystem.cs
Location: Assets/Scripts/Systems/ProjectileSystem.cs
Purpose: Manages projectile lifecycle, pooling, and collision detection.
Priority: 2 (after attack)
Key Responsibilities:
Batch process projectile movement
Handle collision detection
Manage projectile lifetime
Object pooling integration
Architecture:
⚠️ Critical: Object Pooling Gotcha
Public API:
RegisterProjectile
IProjectile projectile
Add projectile to tracking
void
UnregisterProjectile
IProjectile projectile
Remove projectile
void
Tick
float deltaTime
Process all projectiles
void
Usage Example:
EffectSystem.cs
Location: Assets/Scripts/Systems/EffectSystem.cs
Purpose: Centralized status effect processor (burn, slow, stun, poison, etc.).
Priority: 3 (after projectiles)
Key Responsibilities:
Process DOT (damage over time)
Update effect timers
Manage effect stacking/overrides
Clean up expired effects
Architecture:
Public API:
RegisterEffect
IEffect effect
Add effect to processing
void
UnregisterEffect
IEffect effect
Remove effect
void
ApplyEffect
GameObject target, IEffect effect
Apply effect to entity
void
Tick
float deltaTime
Process all effects
void
Usage Example:
Performance Impact:
3.2 Entity Scripts
Enemy.cs
Location: Assets/Scripts/Entities/Enemy.cs
Purpose: Base class for all enemy types. Implements IMoveable, IDamageable, ITargetable.
Key Responsibilities:
Provide movement data to MovementSystem
Handle damage reception
Track health
Emit death events
Architecture:
How to Extend:
⚠️ Common Mistakes:
Tower.cs
Location: Assets/Scripts/Entities/Towers/Tower.cs
Purpose: Base class for all towers. Implements IAttacker.
Key Responsibilities:
Provide attack data to AttackSystem
Scan for targets (coroutine-based)
Rotate to face targets
Spawn projectiles
Architecture:
Tower Variants:
⚠️ Critical Notes:
✅ Target scanning via coroutine (not FixedUpdate!)
✅ Use WaitForSeconds to control scan frequency
✅ Always register with AttackSystem in Start()
❌ Never implement Update() or FixedUpdate()
❌ Never use LINQ for target sorting
Projectile.cs
Location: Assets/Scripts/Entities/Projectiles/Projectile.cs
Purpose: Base class for projectiles. Implements IProjectile.
Key Responsibilities:
Move towards target
Check collision
Deal damage on hit
Return to pool when expired
Architecture:
Projectile Variants:
⚠️ Critical: Pooling Gotcha
3.3 Manager Scripts
WaveManager.cs
Location: Assets/Scripts/Managers/WaveManager.cs
Purpose: Manages enemy wave spawning, difficulty scaling, and wave progression.
Key Responsibilities:
Spawn waves of enemies
Track wave progression
Scale difficulty
Emit wave events
Usage:
BuildManager.cs
Location: Assets/Scripts/Managers/BuildManager.cs
Purpose: Handles tower placement on grid.
Key Responsibilities:
Validate placement positions
Spend currency
Instantiate towers
Update grid state
Usage:
UIManager.cs
Location: Assets/Scripts/Managers/UIManager.cs
Purpose: Updates UI elements based on game state.
Key Responsibilities:
Display gold, health, wave number
Update tower shop
Show game over screen
Usage:
3.4 Interface Scripts
Complete Interface Reference
3.5 Utility Scripts
PoolManager.cs
Location: Assets/Scripts/Utilities/PoolManager.cs
Purpose: Object pooling to reduce Instantiate/Destroy overhead.
Usage:
GridGenerator.cs
Location: Assets/Scripts/Utilities/GridGenerator.cs
Purpose: Procedurally generate game grid at runtime.
Usage:
4. API Reference
4.1 GameSystemsManager API
Public Methods
GetSystem<T>() where T : IGameSystem
Retrieve specific system by type.
Parameters: None
Returns: T - System instance, or null if not found
Example:
RegisterSystem(IGameSystem system)
Add system to managed list. Systems are automatically sorted by Priority.
Parameters:
system- System to register
Returns: void
Example:
4.2 MovementSystem API
Public Methods
RegisterMoveable(IMoveable moveable)
Add entity to movement processing list.
Parameters:
moveable- Entity implementing IMoveable
Returns: void
Example:
UnregisterMoveable(IMoveable moveable)
Remove entity from movement processing.
Parameters:
moveable- Entity to remove
Returns: void
Example:
4.3 AttackSystem API
Public Methods
RegisterAttacker(IAttacker attacker)
Add attacker to combat processing.
Parameters:
attacker- Entity implementing IAttacker
Returns: void
Example:
UnregisterAttacker(IAttacker attacker)
Remove attacker from processing.
Parameters:
attacker- Entity to remove
Returns: void
UpdateTargetsInRange(IAttacker attacker, List<ITargetable> targets)
Update cached targets for specific attacker. Called by tower's scan coroutine.
Parameters:
attacker- Attacker whose targets to updatetargets- List of targetable entities in range
Returns: void
Example:
4.4 ProjectileSystem API
Public Methods
RegisterProjectile(IProjectile projectile)
Add projectile to lifecycle management.
Parameters:
projectile- Entity implementing IProjectile
Returns: void
UnregisterProjectile(IProjectile projectile)
Remove projectile from processing.
Parameters:
projectile- Entity to remove
Returns: void
4.5 EffectSystem API
Public Methods
RegisterEffect(IEffect effect)
Add status effect to processing.
Parameters:
effect- Entity implementing IEffect
Returns: void
UnregisterEffect(IEffect effect)
Remove effect from processing.
Parameters:
effect- Entity to remove
Returns: void
ApplyEffect(GameObject target, IEffect effect)
Apply status effect to specific target.
Parameters:
target- GameObject to apply effect toeffect- Effect to apply
Returns: void
Example:
5. Development Workflows
5.1 How to Add New Tower Type
Step-by-Step Tutorial: Ice Tower
Goal: Create a tower that slows enemies by 50% for 3 seconds.
Step 1: Create Script
Create file: Assets/Scripts/Entities/Towers/IceTower.cs
Step 2: Create Prefab
Create empty GameObject in scene: "IceTower"
Add components:
IceTowerscriptAdd 3D model (or primitive Cube)
Add RotationPart child (for aiming)
Add ShootAnchor child (projectile spawn point)
Configure Inspector:
Attack Range: 6
Attack Cooldown: 1.5
Damage: 8
Targeting Mode: First
Projectile Prefab: IceProjectile (drag from Prefabs)
Slow Effect Prefab: SlowEffect (drag from Prefabs)
Rotation Part: Assign RotationPart child
Shoot Anchor: Assign ShootAnchor child
Save as prefab:
Assets/Prefabs/Towers/IceTower.prefab
Step 3: Create ScriptableObject
Right-click in Project → Create → Scriptable Objects → Tower Data
Name:
IceTowerSOConfigure:
Name: "Ice Tower"
Prefab: IceTower.prefab
Cost: 150
Description: "Slows enemies by 50%"
Icon: (assign sprite)
Step 4: Register in BuildManager
Open
BuildManagerin InspectorFind "Available Towers" list
Add element → Drag IceTowerSO
Step 5: Test
Play game
Check shop - Ice Tower should appear
Place tower, verify it:
✅ Appears in shop
✅ Can be placed on grid
✅ Attacks enemies
✅ Enemies slow down when hit
✅ Console shows:
[AttackSystem] Registered: IceTower(Clone)
Expected Console Output:
5.2 How to Add New Enemy Type
Step-by-Step Tutorial: Tank Enemy
Goal: High HP, slow movement, high gold reward.
Step 1: Create Script
Create file: Assets/Scripts/Entities/Enemies/TankEnemy.cs
Step 2: Create Prefab
Create GameObject: "TankEnemy"
Add components:
TankEnemyscript3D model (make it look tanky!)
Collider (for targeting)
Health bar UI (optional)
Configure Inspector:
Layer: Enemy
(Stats auto-set in script)
Save as prefab:
Assets/Prefabs/Enemies/TankEnemy.prefab
Step 3: Create Wave Configuration
Open WaveManager
Find wave where you want TankEnemy
Add to enemy spawn list:
Enemy Prefab: TankEnemy
Count: 5
Spawn Interval: 2 seconds
Step 4: Test
Play game
Start wave with TankEnemy
Verify:
✅ Spawns correctly
✅ Moves slowly
✅ Takes lot of damage before dying
✅ Awards 50 gold on death
✅ Console:
[MovementSystem] Registered: TankEnemy(Clone)
5.3 How to Add New System
Step-by-Step Tutorial: AbilitySystem
Goal: Centralize enemy ability processing (remove Update() from EnemyUnit.cs).
Step 1: Create Interface
Add to InterfaceDefinitions.cs:
Step 2: Create System
Create file: Assets/Scripts/Systems/AbilitySystem.cs
Step 3: Register with GameSystemsManager
Modify GameSystemsManager.cs:
Step 4: Update Entities to Use System
Modify EnemyUnit.cs:
Step 5: Test
Play game
Check console:
✅
[AbilitySystem] Initialized✅
[AbilitySystem] Registered: EnemyUnit(Clone)
Verify abilities still work
Check Profiler - Update() calls reduced
5.4 How to Add New Targeting Strategy
Step-by-Step Tutorial: RandomTargetingStrategy
Goal: Target random enemy (for fun/chaos towers).
Step 1: Create Strategy Class
Create file: Assets/Scripts/Systems/Targeting/RandomTargetingStrategy.cs
Step 2: Add to TargetingMode Enum
Modify InterfaceDefinitions.cs:
Step 3: Register in AttackSystem
Modify AttackSystem.Initialize():
Step 4: Use in Tower
Step 5: Test
Place ChaosTower
Watch it attack random enemies
Verify targets change unpredictably
5.5 How to Add New Status Effect
Step-by-Step Tutorial: Poison Effect
Goal: Deal 3 damage per second for 10 seconds.
Step 1: Create Effect Script
Create file: Assets/Scripts/StatusEffects/PoisonEffect.cs
Step 2: Create Prefab
Create GameObject: "PoisonEffect"
Add PoisonEffect script
Configure Inspector:
Damage Per Tick: 3
Tick Interval: 1
Add particle system (green poison cloud)
Save as prefab
Step 3: Use in Projectile/Tower
Step 4: Test
Place PoisonTower
Attack enemy
Verify:
✅ Enemy turns green
✅ Takes 3 damage per second
✅ Effect lasts 10 seconds
✅ Console:
[EffectSystem] Applied PoisonEffect
5.6 Safe Modification Points
✅ What You CAN Safely Change
Entity Stats:
Health, speed, damage values in Inspector
Cooldown timers
Range values
Costs and rewards
Prefabs:
Visual meshes, materials, textures
Particle effects
Audio clips
UI layouts
ScriptableObjects:
Tower/Enemy configurations
Wave setups
Shop items
Constants:
GRID_SIZE,MAX_ENEMIES, etc.Default values in scripts
UI:
Text, colors, fonts
Button positions
HUD elements
Wave Configuration:
Enemy counts
Spawn intervals
Wave progression
❌ What You Should NOT Change
System Architecture:
GameSystemsManager Update() loop
System Priority values (breaks execution order!)
Interface definitions (breaks all implementations)
Registration Logic:
OnEnable/OnDisable patterns
Registration order
Object Pooling:
Pool lifecycle (Start vs OnEnable)
Return to pool logic
Batch Processing:
System Tick() implementations
Iteration patterns (manual, not LINQ)
Performance Critical:
SqrMagnitude vs Distance
Coroutine frequencies
Cache invalidation logic
⚠️ Modify With Caution
Targeting Strategies:
Can add new strategies
Don't modify existing strategy logic without testing
Effect Processing:
Can add new effects
Don't change EffectSystem Tick() logic
Collision Detection:
Can adjust layers
Don't change detection method without profiling
6. Onboarding Timeline
6.1 Day 1: Environment Setup
Time: 2-4 hours
Tasks:
✅ Install Unity 2022.3 LTS ✅ Install Visual Studio 2022 or Rider 2024 ✅ Clone repository ✅ Open project in Unity ✅ Wait for asset import (5-10 minutes) ✅ Run first Play Mode test ✅ Verify FPS ≥100
Reading:
📖 Read README.md (5 minutes) 📖 Skim Architecture Handbook (30 minutes) 📖 Review this document: Chapters 1-2 (30 minutes)
Success Criteria:
✅ Game runs without errors
✅ Console shows system initialization logs
✅ Can place towers and start waves
✅ Understand folder structure
✅ Know where Systems, Entities, Managers are located
6.2 Days 2-3: Code Exploration
Time: 1-2 days
Tasks:
Day 2 Morning: Systems
📖 Read GameSystemsManager.cs - understand orchestration
📖 Read MovementSystem.cs - see batch processing
📖 Read AttackSystem.cs - understand targeting & cooldowns
Exercise: Add Debug.Log to each system's Tick() and watch execution order.
Day 2 Afternoon: Entities
📖 Read Enemy.cs - entity example
📖 Read Tower.cs - interface implementation
📖 Read Projectile.cs - pooling gotcha (OnEnable vs Start!)
Exercise: Create FastEnemy subclass (2x speed, half HP).
Day 3 Morning: Interfaces
📖 Review all interfaces in InterfaceDefinitions.cs
📖 Understand IMoveable, IAttacker, ITargetable, IEffect
Exercise: Implement mock interface for testing:
Day 3 Afternoon: Profiling
🔬 Open Unity Profiler (Window → Analysis → Profiler) 🔬 Run game, observe CPU Usage module 🔬 Look for MovementSystem.Tick, AttackSystem.Tick 🔬 Open Frame Debugger, verify batching
Exercise: Compare FPS with/without VSync enabled.
Success Criteria:
✅ Understand system-based architecture
✅ Can explain batch processing benefits
✅ Know difference between entity/system
✅ Familiar with all interfaces
✅ Can use Profiler to identify bottlenecks
6.3 Week 1: First Task
Time: 5 days
Assignment: Create Freeze Tower
Requirements:
Extends Tower class
Stops enemies for 2 seconds (speed = 0)
Uses
FreezeTowerSOfor configurationRegisters with AttackSystem
Applies FreezeEffect via EffectSystem
Visual: Enemy turns blue when frozen
Steps:
Day 4: Planning & Setup
Read Section 5.1 (How to Add New Tower)
Create
FreezeTower.csscriptCreate
FreezeEffect.csscriptDefine interface requirements
Day 5: Implementation
Implement FreezeTower
Implement FreezeEffect
Register with systems
Day 6-7: Prefabs & Testing
Create tower prefab
Create effect prefab
Create ScriptableObject
Test in game
Day 8: Polish & Documentation
Add visual effects (particles, shader)
Add sound effects
Write documentation (what changed, how to use)
Code review with senior dev
Success Criteria:
✅ Tower appears in shop ✅ Can be placed on grid ✅ Attacks enemies in range ✅ Freeze effect applies (enemy stops moving) ✅ Effect expires after 2 seconds ✅ Console shows:
✅ No errors in console ✅ FPS stable (≥100) ✅ Code follows naming conventions ✅ Documentation complete
6.4 Week 2: Independent Development
Time: 1 week
Assignment: Choose One
Pick one task based on your interests:
Option A: Gameplay Feature
Task: Create Lightning Tower
Chains between enemies (hits up to 3 targets)
Each chain does reduced damage (100%, 50%, 25%)
Uses TargetingMode.Strongest
Adds ChainLightningEffect for visual
Option B: System Enhancement
Task: Upgrade AttackSystem with Range Indicators
Visual range circles around towers
Color-coded by tower type
Toggle on/off with hotkey
Option C: Performance Optimization
Task: Implement Spatial Hashing
Replace Physics.OverlapSphere in towers
Use grid-based spatial hash
Measure FPS improvement
Deliverables:
Code Implementation
Clean, commented code
Follows naming conventions
No warnings in console
Testing Report
Test cases documented
Edge cases handled
Performance metrics (if applicable)
Documentation
README with screenshots
Usage instructions
Known limitations
Code Review
Present to senior developer
Answer questions about design choices
Incorporate feedback
Success Criteria:
✅ Feature complete and working ✅ Zero console errors/warnings ✅ Passes code review ✅ Documentation clear and accurate ✅ Tests written and passing ✅ FPS impact measured (if performance-related)
7. Debugging & Maintenance
7.1 Debugging Techniques
Console Logs to Watch
Expected on Game Start:
Expected on Entity Spawn:
Debugging Tools
Unity Profiler
How to Use:
Window → Analysis → Profiler
Play game
Click slow frame in timeline
Expand CPU Usage module
Look for expensive methods
What to Look For:
AttackSystem.Tick > 1ms = suspicious
MovementSystem.Tick > 0.5ms = check entity count
Any Update() methods = should be removed!
Frame Debugger
How to Use:
Window → Analysis → Frame Debugger
Click "Enable"
Game pauses, shows every draw call
What to Look For:
Batches ~2,000 = good
Batches >5,000 = investigate
Look for "SRP Batch" groups = good!
Separate draw calls for same material = bad
Stats Window
How to Use:
Game View → Stats button (top right)
Displays real-time metrics
What to Monitor:
FPS: Should be 100+ (with VSync off)
Batches: Target ~2,000
Tris: Keep under 1M
Saved by batching: Higher = better
7.2 Common Issues & Solutions
Issue: Enemies don't move
Symptom: Enemies spawn but stand still
Possible Causes:
MovementSystem not in scene
Enemy not implementing IMoveable correctly
Enemy not registering with system
Solution:
Issue: Towers don't attack
Symptom: Towers placed, enemies in range, but no attacks
Possible Causes:
AttackSystem not in scene
Tower not registering
Target scan coroutine not running
Projectile prefab not assigned
Solution:
Issue: Projectiles don't move after first spawn
Symptom: First projectile works, subsequent spawns don't move
Cause: Using Start() instead of OnEnable() for pooled objects
Solution:
Issue: Low FPS (<100)
Symptom: Game runs slowly, FPS below 100
Possible Causes:
VSync enabled
Update() methods in entities
Too many enemies/towers
Shadow casters not optimized
Batching broken
Solutions:
Issue: NullReferenceException in System
Symptom: Error: NullReferenceException: Object reference not set to an instance
Common Cause: Entity destroyed but not unregistered from system
Solution:
Issue: Effects not expiring
Symptom: Burn/slow effects never expire, stay forever
Cause: EffectSystem not ticking, or effect not unregistering
Solution:
7.3 Performance Profiling
Quick Profiling Checklist
CPU Performance
Unity Profiler → CPU Usage
Look for methods taking >1ms
Check GameSystemsManager.Update() time
Verify systems execute in order
Expected Values:
MovementSystem.Tick: 0.1-0.5ms
AttackSystem.Tick: 0.2-0.8ms
ProjectileSystem.Tick: 0.1-0.4ms
EffectSystem.Tick: 0.1-0.3ms
Red Flags:
Any Update() in entity scripts
LINQ operations in Tick()
GetComponent in hot paths
Instantiate/Destroy (should use pooling)
GPU Performance
Frame Debugger
Check batch count (~2,000 is good)
Look for "SRP Batch" groups
Verify static batching working
Stats Window
Batches: ~2,000
Saved by batching: 1,000+
SetPass calls: <500
Tris: <1M
Red Flags:
Batches >5,000
No SRP batching
Each object = separate draw call
Memory Performance
Profiler → Memory
Check GC allocations per frame
Should be <1KB/frame
Red Flags:
GC allocations every frame
Memory growing over time (leak)
Frequent GC.Collect (>1 per second)
Profiling Workflow
7.4 Code Review Checklist
Before Submitting Code
Architecture
Registration
Performance
Error Handling
Code Quality
Testing
8. Testing Guidelines
8.1 Unit Testing Setup
Installing Unity Test Framework
Window → Package Manager
Search "Test Framework"
Install
Creating Test Assembly
Create folder:
Assets/Tests/Right-click → Create → Testing → Tests Assembly Folder
Two assemblies created:
EditMode/- Editor testsPlayMode/- Runtime tests
Example Test: MovementSystem
8.2 Integration Testing
Testing System Integration
8.3 Performance Testing
Automated Performance Tests
Conclusion
This Developer Guide provides comprehensive documentation for all aspects of the tower defense project. For additional resources:
Architecture Handbook - Deep dive into design patterns and principles
Performance Optimization Guide - Advanced profiling and optimization techniques
Project Files -
/mnt/project/contains all phase reports and implementation details
Remember:
🔍 Profile before optimizing
📝 Document as you code
✅ Test early and often
🤝 Ask for help when stuck
🚀 Iterate and improve
Happy Coding! 🎮
Last Updated: December 2025 Version: 1.0 Maintainer: Senior Unity Developer
Last updated