From 0843c3619923614493bbcbb460ff232da5518aa7 Mon Sep 17 00:00:00 2001
From: Adrian Paschkowski <git@wasdennnoch.me>
Date: Sun, 18 Apr 2021 19:28:24 +0200
Subject: [PATCH] Document Classes

---
 Assets/Scripts/BaseCameraController.cs       |  5 +-
 Assets/Scripts/Fighters/AntiPlayer.cs        | 16 +++--
 Assets/Scripts/Fighters/Archer.cs            | 17 +----
 Assets/Scripts/Fighters/Bandit.cs            |  2 -
 Assets/Scripts/Fighters/Enemy.cs             |  8 ++-
 Assets/Scripts/Fighters/Fighter.cs           | 29 +++++----
 Assets/Scripts/Fighters/Tank.cs              |  2 -
 Assets/Scripts/RoundController.cs            |  7 ++-
 Assets/Scripts/StatsManager.cs               | 19 +++---
 Assets/Scripts/Store/Opponent.cs             |  2 +-
 Assets/Scripts/Store/SpawnEnemy.cs           | 29 ---------
 Assets/Scripts/Store/SpawnEnemy.cs.meta      | 11 ----
 Assets/Scripts/Store/StoreStateHandler.cs    |  2 +-
 Assets/Scripts/UI/CurrentManaText.cs         |  8 +--
 Assets/Scripts/UI/DamageIndicatorCanvas.cs   |  5 +-
 Assets/Scripts/UI/DamageIndicatorText.cs     |  7 ++-
 Assets/Scripts/UI/DragDestroyController.cs   | 19 ++++--
 Assets/Scripts/UI/HealthBarController.cs     |  3 +-
 Assets/Scripts/UI/OpponentDragSpawner.cs     | 14 ++++-
 Assets/Scripts/UI/RoundControllerButton.cs   |  3 +-
 Assets/Scripts/Upgrades/Upgrade.cs           |  4 +-
 Assets/Scripts/Upgrades/UpgradeController.cs | 65 +++++++++++---------
 Assets/Scripts/utils/Box.cs                  |  4 +-
 Assets/Scripts/utils/Interpolator.cs         |  5 +-
 Assets/Scripts/utils/InterpolatorQueue.cs    |  5 +-
 25 files changed, 142 insertions(+), 149 deletions(-)
 delete mode 100644 Assets/Scripts/Store/SpawnEnemy.cs
 delete mode 100644 Assets/Scripts/Store/SpawnEnemy.cs.meta

diff --git a/Assets/Scripts/BaseCameraController.cs b/Assets/Scripts/BaseCameraController.cs
index 3959709..a2eb4db 100644
--- a/Assets/Scripts/BaseCameraController.cs
+++ b/Assets/Scripts/BaseCameraController.cs
@@ -4,6 +4,9 @@ using System;
 using System.Collections.Generic;
 using UnityEngine;
 
+// Controls Camera movement. The user may control the Camera using the Keyboard or by
+// moving the mouse close to the edge of the screen. Scripts may disable user movement
+// and instead smoothly animate the camera to a specific position and a specific zoom.
 public class BaseCameraController : MonoBehaviour
 {
 
@@ -248,7 +251,7 @@ public class BaseCameraController : MonoBehaviour
             Debug.DrawLine(worldEdges.topLeft, worldEdges.bottomLeft, color);
         }
 
-        // Update the size of the bounds
+        // Update the size of the edge bounds
         public void RecalculateBounds(float newInset)
         {
             RecalculateBounds(new Vector2(newInset, newInset));
diff --git a/Assets/Scripts/Fighters/AntiPlayer.cs b/Assets/Scripts/Fighters/AntiPlayer.cs
index 7744a8e..afe1795 100644
--- a/Assets/Scripts/Fighters/AntiPlayer.cs
+++ b/Assets/Scripts/Fighters/AntiPlayer.cs
@@ -1,7 +1,7 @@
-using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
+// The main opponent of yours. Defeat him and you win.
 public class AntiPlayer : Fighter, IFighterCallback
 {
 
@@ -33,17 +33,19 @@ public class AntiPlayer : Fighter, IFighterCallback
 
         var vectorToNextEnemy = currentTargetEnemy.transform.position - transform.position;
         var scale = transform.localScale;
-        // Always face the target Enemy
+        // Always face the target Enemy. Flip the scale to also flip the position of the attack hitbox.
         scale.x = vectorToNextEnemy.x < 0 ? -initalScale.x : initalScale.x;
         transform.localScale = scale;
 
         // Run towards target enemy if too far away
         if (Mathf.Abs(vectorToNextEnemy.x) > maxDistanceToEnemy)
         {
-            animator.SetInteger("AnimState", 1); // Run
+            animator.SetInteger("AnimState", 1); // Run Animation
             rigidbody.velocity = new Vector2(Mathf.Sign(vectorToNextEnemy.x) * movementSpeed, rigidbody.velocity.y);
-        } else
+        }
+        else
         {
+            // No horizontal movement
             animator.SetInteger("AnimState", 0);
             rigidbody.velocity = new Vector2(0, rigidbody.velocity.y);
         }
@@ -54,7 +56,7 @@ public class AntiPlayer : Fighter, IFighterCallback
         {
             return false;
         }
-        // Can only attack when near an Enemy
+        // Can only attack when close enough to the target Enemy
         var vectorToNextEnemy = currentTargetEnemy.transform.position - transform.position;
         return Mathf.Abs(vectorToNextEnemy.x) <= maxDistanceToEnemy;
     }
@@ -66,6 +68,7 @@ public class AntiPlayer : Fighter, IFighterCallback
 
     void CalculateClosestEnemy()
     {
+        // Sort by closest distance
         enemies.Sort((a, b) => (int)Mathf.Sign(Vector3.Distance(transform.position, a.transform.position) - Vector3.Distance(transform.position, b.transform.position)));
         currentTargetEnemy = enemies.Count > 0 ? enemies[0] : null;
     }
@@ -90,6 +93,7 @@ public class AntiPlayer : Fighter, IFighterCallback
     {
         base.OnRoundStart();
 
+        // Listen for Enemy Death events, used for targeting
         foreach (var enemy in GameObject.FindGameObjectsWithTag("Enemy"))
         {
             var fighter = enemy.GetComponent<Fighter>();
@@ -101,7 +105,7 @@ public class AntiPlayer : Fighter, IFighterCallback
 
     public override void OnRoundEnd(bool won)
     {
-        if (!alive)
+        if (!alive) // When the player successfully killed us
         {
             damageIndicator.FlashText("Upgrade!", true);
             StatsManager.instance.UpgradeAntiPlayer();
diff --git a/Assets/Scripts/Fighters/Archer.cs b/Assets/Scripts/Fighters/Archer.cs
index 6b962ec..665f919 100644
--- a/Assets/Scripts/Fighters/Archer.cs
+++ b/Assets/Scripts/Fighters/Archer.cs
@@ -1,21 +1,6 @@
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-
 public class Archer : Enemy
 {
 
-    //[SerializeField, Tooltip("When the AntiPlayer is closer than this value, change to a combat idle anim")]
-    //float playerNearDistance = 50f;
-
-    protected override void Awake()
-    {
-        base.Awake();
-    }
-
-    protected override void Update()
-    {
-        base.Update();
-    }
+    // Archers don't have any special abilities
 
 }
diff --git a/Assets/Scripts/Fighters/Bandit.cs b/Assets/Scripts/Fighters/Bandit.cs
index c5a7979..0896ff3 100644
--- a/Assets/Scripts/Fighters/Bandit.cs
+++ b/Assets/Scripts/Fighters/Bandit.cs
@@ -1,5 +1,3 @@
-using System.Collections;
-using System.Collections.Generic;
 using UnityEngine;
 
 public class Bandit : Enemy
diff --git a/Assets/Scripts/Fighters/Enemy.cs b/Assets/Scripts/Fighters/Enemy.cs
index 7d76013..c72b4fa 100644
--- a/Assets/Scripts/Fighters/Enemy.cs
+++ b/Assets/Scripts/Fighters/Enemy.cs
@@ -1,7 +1,7 @@
-using System.Collections;
-using System.Collections.Generic;
 using UnityEngine;
 
+// Base Enemy class, includes some functionality common to all Enemies, such as a reference
+// to the AntiPlayer and that they always face towards it.
 public abstract class Enemy : Fighter
 {
 
@@ -55,7 +55,9 @@ public abstract class Enemy : Fighter
 
     public override void OnRoundEnd(bool won)
     {
-        // Destroy all dead Enemies after a successful round
+        // Destroy all dead Enemies after a successful round. Otherwise, if either
+        // the round was lost of the Enemy was still alive at the end of the round,
+        // it will be resurrected.
         if (won && !alive)
         {
             Destroy(gameObject);
diff --git a/Assets/Scripts/Fighters/Fighter.cs b/Assets/Scripts/Fighters/Fighter.cs
index 81c4eae..bdff094 100644
--- a/Assets/Scripts/Fighters/Fighter.cs
+++ b/Assets/Scripts/Fighters/Fighter.cs
@@ -1,4 +1,3 @@
-using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
@@ -7,8 +6,9 @@ public interface IFighterCallback
     void OnFighterDeath(Fighter fighter);
 }
 
-// Generic subclass for any Fighter on the field, whether it's an Enemy or the AntiPlayer.
+// Generic class for any Fighter on the field, whether it's an Enemy or the AntiPlayer.
 // Contains stats management such as health, attacks, damage, death, etc.
+// Listens to round start/end events and updates the internal state accordingly.
 public abstract class Fighter : MonoBehaviour, IRoundCallback
 {
 
@@ -16,9 +16,9 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback
     [SerializeField, Tooltip("Attack every x seconds")] float baseAttackSpeed = 1f;
     [SerializeField] int baseAttackDamage = 10;
     [SerializeField] int baseArmor = 1;
-    [SerializeField, Tooltip("Being hurt may cancel the current Attack animation, aborting the current attack. If this Fighter is hurt within x seconds of the last attack, attack again after attackRetryDelayAfterBeingHurt seconds")]
+    [SerializeField, Tooltip("Being hurt may cancel the current Attack animation, aborting the current attack. If this Fighter is hurt within x seconds of the last attack, attack again after attackRetryDelayAfterBeingHurt seconds.")]
     float attackRetryGracePeriod = 0.8f;
-    [SerializeField, Tooltip("If an attack is being retried, how long to wait until to actually attack again. Gives the Hrt animation time to play out.")]
+    [SerializeField, Tooltip("If an attack is being retried, how long to wait until to actually attack again. Gives the Hurt animation time to play out.")]
     float attackRetryDelayAfterBeingHurt = 0.25f;
     [SerializeField] List<AudioClip> attackBarks;
     [SerializeField] List<AudioClip> hurtBarks;
@@ -26,7 +26,7 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback
 
     public List<IFighterCallback> callbacks = new List<IFighterCallback>();
 
-    protected int maxHealth = 100; // Dynamically valculated based on upgrades
+    protected int maxHealth = 100; // Dynamically calculated on round start based on upgrades
     protected int currentHealth = 100;
     protected float currentHealthPercentage { get => (float) currentHealth / maxHealth; }
     protected Animator animator;
@@ -37,9 +37,10 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback
     protected BaseCameraController cameraController;
     protected bool alive { get => currentHealth > 0; }
     protected bool roundRunning = false;
-    protected FighterTypes fighterType;
-    protected string opponentTag;
+    protected FighterTypes fighterType; // Subclasses should set this accordingly. Used for stats retrieval.
+    protected string opponentTag; // Subclasses should set this accordingly. Used for hit detection.
 
+    // Used to reset values on round end
     protected Vector3 initalScale;
     protected Vector3 initalPosition;
     protected int initialLayer;
@@ -74,12 +75,18 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback
         RoundController.instance.roundCallbacks.Add(this);
     }
 
+    protected virtual void OnDestroy()
+    {
+        RoundController.instance.roundCallbacks.Remove(this);
+    }
+
     protected virtual void Update()
     {
         if (alive && roundRunning)
         {
             if (CanAttack())
             {
+                // Attack Timer
                 timeSinceLastAttack += Time.deltaTime;
                 var timeUntilNextAttack = baseAttackSpeed - timeSinceLastAttack;
                 if (timeUntilNextAttack <= 0)
@@ -96,6 +103,7 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback
         }
     }
 
+    // Returns the actual amount of damage dealt, calculated based on armor upgrades.
     public virtual int DealDamage(int dmg)
     {
         if (!alive || !roundRunning)
@@ -142,6 +150,7 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback
 #if false
         Debug.Log(string.Format("'{0}' (tag '{1}') collided with '{2}' (tag '{3}') in parent '{4}' (tag '{5}')", name, tag, other.name, other.tag, other.transform.parent ? other.transform.parent.name : null, other.transform.parent ? other.transform.parent.tag : null));
 #endif
+        // If we hit an opponent, deal them damage
         if (roundRunning && other.CompareTag(opponentTag))
         {
             var damageToDeal = Mathf.RoundToInt(baseAttackDamage * GetStats().damageMultiplier);
@@ -162,6 +171,7 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback
 
     public virtual void OnRoundEnd(bool won)
     {
+        // Reset everything back to its initial state
         roundRunning = false;
         animator.enabled = false;
         timeSinceLastAttack = float.PositiveInfinity;
@@ -174,9 +184,4 @@ public abstract class Fighter : MonoBehaviour, IRoundCallback
         callbacks.Clear();
         healthBarController.SetHealthBarEnabled(false);
     }
-
-    protected virtual void OnDestroy()
-    {
-        RoundController.instance.roundCallbacks.Remove(this);
-    }
 }
diff --git a/Assets/Scripts/Fighters/Tank.cs b/Assets/Scripts/Fighters/Tank.cs
index 0b7da3d..1b833fe 100644
--- a/Assets/Scripts/Fighters/Tank.cs
+++ b/Assets/Scripts/Fighters/Tank.cs
@@ -1,5 +1,3 @@
-using System.Collections;
-using System.Collections.Generic;
 using UnityEngine;
 
 public class Tank : Enemy
diff --git a/Assets/Scripts/RoundController.cs b/Assets/Scripts/RoundController.cs
index e62b921..e2375d8 100644
--- a/Assets/Scripts/RoundController.cs
+++ b/Assets/Scripts/RoundController.cs
@@ -9,6 +9,10 @@ public interface IRoundCallback
     void OnRoundEnd(bool won);
 }
 
+// Controls the state of the current round (whether one is currently running or not)
+// and provides update callbacks. Listens to Fighter events. If a round is won or lost,
+// meaning if the last Fighter of the AntiPlayer died, play the according animation
+// and SFX and end the current round.
 public class RoundController : MonoBehaviour, IFighterCallback
 {
 
@@ -140,11 +144,12 @@ public class RoundController : MonoBehaviour, IFighterCallback
             var targetGameSpeed = 0.2f;
             SetCurrentGameSpeed(targetGameSpeed);
             cameraController.SetUserControlEnabled(false);
-            cameraController.AnimateToPosition(fighter.transform.position + new Vector3(0f, 0.75f), 1.5f, 0.125f * targetGameSpeed);
+            cameraController.AnimateToPosition(fighter.transform.position + new Vector3(0f, 0.75f), 1.5f, 0.25f * targetGameSpeed);
             Invoke(nameof(StopRoundAfterDeath), targetGameSpeed * restartDelayAfterLastFighterDeath);
         }
     }
 
+    // Invoked delayed after the last Fighter died to allow death animations to play out
     void StopRoundAfterDeath()
     {
         cameraController.PlayRandomGlobalAudioClip(hasWonLastRound ? roundWinSfx : roundLooseSfx);
diff --git a/Assets/Scripts/StatsManager.cs b/Assets/Scripts/StatsManager.cs
index 2b78652..c08d3cb 100644
--- a/Assets/Scripts/StatsManager.cs
+++ b/Assets/Scripts/StatsManager.cs
@@ -50,6 +50,8 @@ public interface IManaChangeCallback
     void OnManaChanged(int oldValue, int newValue);
 }
 
+// Provides the current Statistics (buffs) for supported Fighter types as well as
+// Mana storage and management. Allows scripts to buy Upgrade or otherwise spend Mana.
 public class StatsManager : MonoBehaviour, IRoundCallback
 {
 
@@ -66,7 +68,7 @@ public class StatsManager : MonoBehaviour, IRoundCallback
     // The currently active statistics for each fighter type
     public Dictionary<FighterTypes, FighterStats> fighterStats = new Dictionary<FighterTypes, FighterStats>();
 
-    // Information about currently available and purchased upgrades. Should only be read, not modified.
+    // Information about currently available and purchased Enemy upgrades. Should only be read, not modified.
     public Dictionary<UpgradeTypes, UpgradeData> upgrades = new Dictionary<UpgradeTypes, UpgradeData>();
 
     // Want to be notified whenever the current Mana amount changes?
@@ -96,7 +98,7 @@ public class StatsManager : MonoBehaviour, IRoundCallback
             return false;
         }
         upgrades[type].count++;
-        RecalculateStatMultipliers();
+        RecalculateEnemyStats();
         return true;
     }
 
@@ -135,6 +137,12 @@ public class StatsManager : MonoBehaviour, IRoundCallback
         }
     }
 
+    // How much a specific Enemy stat is buffed based on how many Upgrades have already been purchased
+    public float GetTotalEffectMultiplier(UpgradeTypes type)
+    {
+        return upgrades[type].GetTotalEffectMultiplier();
+    }
+
     public void UpgradeAntiPlayer()
     {
         var playerStats = fighterStats[FighterTypes.ANTI_PLAYER];
@@ -144,7 +152,7 @@ public class StatsManager : MonoBehaviour, IRoundCallback
         fighterStats[FighterTypes.ANTI_PLAYER] = playerStats;
     }
 
-    void RecalculateStatMultipliers()
+    void RecalculateEnemyStats()
     {
         var enemyStats = fighterStats[FighterTypes.ENEMY];
         enemyStats.healthMultiplier = upgrades[UpgradeTypes.ENEMY_HEALTH].GetTotalEffectMultiplier();
@@ -153,11 +161,6 @@ public class StatsManager : MonoBehaviour, IRoundCallback
         fighterStats[FighterTypes.ENEMY] = enemyStats;
     }
 
-    public float GetTotalEffectMultiplier(UpgradeTypes type)
-    {
-        return upgrades[type].GetTotalEffectMultiplier();
-    }
-
     void Awake()
     {
         if (instance == null)
diff --git a/Assets/Scripts/Store/Opponent.cs b/Assets/Scripts/Store/Opponent.cs
index ea8d1c9..aba7f88 100644
--- a/Assets/Scripts/Store/Opponent.cs
+++ b/Assets/Scripts/Store/Opponent.cs
@@ -9,6 +9,6 @@ public class Opponent : ScriptableObject
     public GameObject enemyPrefab;
     public int enemyCost;
     public float costMultiplier;
-    public Vector2 dragPivot;
+    public Vector2 dragPivot; // Texture offset used for mouse dragging
 
 }
diff --git a/Assets/Scripts/Store/SpawnEnemy.cs b/Assets/Scripts/Store/SpawnEnemy.cs
deleted file mode 100644
index d18d81e..0000000
--- a/Assets/Scripts/Store/SpawnEnemy.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
-using UnityEngine.EventSystems;
-
-public class SpawnEnemy : MonoBehaviour, IPointerDownHandler, IBeginDragHandler
-{
-    public void OnBeginDrag(PointerEventData eventData)
-    {
-        Debug.Log("Something has happend");
-    }
-
-    public void OnPointerDown(PointerEventData eventData)
-    {
-        Debug.Log("Something has happend");
-    }
-
-    // Start is called before the first frame update
-    void Start()
-    {
-        
-    }
-
-    // Update is called once per frame
-    void Update()
-    {
-        
-    }
-}
diff --git a/Assets/Scripts/Store/SpawnEnemy.cs.meta b/Assets/Scripts/Store/SpawnEnemy.cs.meta
deleted file mode 100644
index 984dcf7..0000000
--- a/Assets/Scripts/Store/SpawnEnemy.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: e1e4776ca1e2ca04b99c32d12ca966bb
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Assets/Scripts/Store/StoreStateHandler.cs b/Assets/Scripts/Store/StoreStateHandler.cs
index 5b8b133..c29f48c 100644
--- a/Assets/Scripts/Store/StoreStateHandler.cs
+++ b/Assets/Scripts/Store/StoreStateHandler.cs
@@ -1,7 +1,7 @@
-using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
+// Responsible for opening/closing the upgradfe store as well as hiding other UI elements.
 public class StoreStateHandler : MonoBehaviour, IRoundCallback
 {
 
diff --git a/Assets/Scripts/UI/CurrentManaText.cs b/Assets/Scripts/UI/CurrentManaText.cs
index 63b277d..8b8520e 100644
--- a/Assets/Scripts/UI/CurrentManaText.cs
+++ b/Assets/Scripts/UI/CurrentManaText.cs
@@ -1,11 +1,9 @@
-using System.Collections;
-using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
 
 // Controls the text displaying the current Mana amount. When the player's amount of
-// Mana changes, this visually interpolates smoothly between old and new value.
-// Additionally, does a color flash effect.
+// Mana changes, this visually interpolates smoothly between old and new value and
+// does a color flash effect.
 public class CurrentManaText : MonoBehaviour, IManaChangeCallback
 {
 
@@ -40,11 +38,11 @@ public class CurrentManaText : MonoBehaviour, IManaChangeCallback
             currentlyDisplayedValue = (int)Mathf.Lerp(previousMana, StatsManager.instance.GetMana(), animationProgress / manaUpdateTime);
             manaText.text = currentlyDisplayedValue.ToString();
         }
-        var flashColor = currentlyDisplayedValue > previousMana ? manaGainColor : manaLossColor;
         if (colorFlashProgress < colorFlashTime)
         {
             // Fade flashed color back to default color
             colorFlashProgress += Time.deltaTime;
+            var flashColor = currentlyDisplayedValue > previousMana ? manaGainColor : manaLossColor;
             manaText.color = Color.Lerp(flashColor, defaultColor, colorFlashProgress / colorFlashTime);
         }
     }
diff --git a/Assets/Scripts/UI/DamageIndicatorCanvas.cs b/Assets/Scripts/UI/DamageIndicatorCanvas.cs
index e7cfa2a..88ea1bd 100644
--- a/Assets/Scripts/UI/DamageIndicatorCanvas.cs
+++ b/Assets/Scripts/UI/DamageIndicatorCanvas.cs
@@ -1,7 +1,7 @@
-using System.Collections;
-using System.Collections.Generic;
 using UnityEngine;
 
+// A Canvas for displaying how much damage was dealt to an enemy.
+// Can also show any kind of other text.
 public class DamageIndicatorCanvas : MonoBehaviour
 {
 
@@ -28,6 +28,7 @@ public class DamageIndicatorCanvas : MonoBehaviour
         transform.localScale = scale;
     }
 
+    // Creates a new, short-lived text element displaying the given text.
     public void FlashText(string text, bool center = false)
     {
         var rect = rectTransform.rect;
diff --git a/Assets/Scripts/UI/DamageIndicatorText.cs b/Assets/Scripts/UI/DamageIndicatorText.cs
index 22177ca..e3d98a1 100644
--- a/Assets/Scripts/UI/DamageIndicatorText.cs
+++ b/Assets/Scripts/UI/DamageIndicatorText.cs
@@ -1,8 +1,9 @@
 using System.Collections;
-using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
 
+// The text element used in DamageIndicatorCanvas. Moves upwards and fades out,
+// destroying itself once the opacity hits 0.
 public class DamageIndicatorText : MonoBehaviour
 {
 
@@ -17,10 +18,10 @@ public class DamageIndicatorText : MonoBehaviour
         textComponent = GetComponent<Text>();
         textComponent.text = text;
 
-        StartCoroutine(DoFade());
+        StartCoroutine(RiseAndFade());
     }
 
-    IEnumerator DoFade()
+    IEnumerator RiseAndFade()
     {
         while (textComponent.color.a > 0)
         {
diff --git a/Assets/Scripts/UI/DragDestroyController.cs b/Assets/Scripts/UI/DragDestroyController.cs
index 8b4c5d9..343bcca 100644
--- a/Assets/Scripts/UI/DragDestroyController.cs
+++ b/Assets/Scripts/UI/DragDestroyController.cs
@@ -1,4 +1,3 @@
-using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
@@ -8,6 +7,10 @@ public interface IDragDropListener
     void OnEnemyDeleted(GameObject enemy, Opponent opponent);
 }
 
+// Allows you to drag and drop existing Enemies around the field. Checks for valid
+// drop positions; resets the dragged Enemy to its previous position of the target
+// position was invalid (occluded by another Fighter). Also allows for deletion of
+// active Enemies.
 public class DragDestroyController : MonoBehaviour
 {
 
@@ -32,6 +35,7 @@ public class DragDestroyController : MonoBehaviour
     int noCollisionLayer;
     BaseCameraController cameraController;
 
+    // Sets the given Enemy to be the active Enemy that can be dragged around and places on the field.
     public void HandoffEnemy(GameObject enemy, bool skipSound = true)
     {
         if (selectedEnemy != null)
@@ -51,6 +55,7 @@ public class DragDestroyController : MonoBehaviour
         }
     }
 
+    // Sets whether Enemies can be dragged around
     public void SetDraggingEnabled(bool enabled)
     {
         draggingEnabled = enabled;
@@ -76,12 +81,13 @@ public class DragDestroyController : MonoBehaviour
         }
     }
 
-    GameObject RayCastForFighter(bool includeAntiHero)
+    // Returns the Fighter at the current mouse position, optionally including the AntiPlayer
+    GameObject RayCastForFighter(bool includeAntiPlayer)
     {
         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
         RaycastHit2D hit = Physics2D.GetRayIntersection(ray, fighterRaycastLength, fighterRaycastLayer);
 
-        if (hit.collider == null || (!includeAntiHero && hit.collider.gameObject.CompareTag("AntiPlayer")))
+        if (hit.collider == null || (!includeAntiPlayer && hit.collider.gameObject.CompareTag("AntiPlayer")))
         {
             return null;
         }
@@ -89,6 +95,7 @@ public class DragDestroyController : MonoBehaviour
         return hit.collider.transform.gameObject;
     }
 
+    // Deletes the Enemy under the mouse cursor
     void DeleteHoveredEnemy()
     {
         GameObject enemy = RayCastForFighter(false);
@@ -101,7 +108,8 @@ public class DragDestroyController : MonoBehaviour
             cameraController.PlayRandomGlobalAudioClip(removeEnemySfx);
         }
     }
-
+    
+    // Selects the Enemy currently under the mouse cursor to be the one being dragged around
     void SelectHoveredEnemy()
     {
         GameObject enemy = RayCastForFighter(false);
@@ -111,6 +119,8 @@ public class DragDestroyController : MonoBehaviour
         }
     }
 
+    // Set the current Enemie's position to the mouse position, accounting for configured texture offsets.
+    // Indicates if the current position is occluded by another Fighter.
     void MoveSelectedEnemy()
     {
         if (selectedEnemy != null)
@@ -123,6 +133,7 @@ public class DragDestroyController : MonoBehaviour
         }
     }
 
+    // Drops the active Enemy at the mouse position.
     void PlaceSelectedEnemy()
     {
         if (selectedEnemy != null)
diff --git a/Assets/Scripts/UI/HealthBarController.cs b/Assets/Scripts/UI/HealthBarController.cs
index c77020c..cbe9066 100644
--- a/Assets/Scripts/UI/HealthBarController.cs
+++ b/Assets/Scripts/UI/HealthBarController.cs
@@ -1,7 +1,6 @@
-using System.Collections;
-using System.Collections.Generic;
 using UnityEngine;
 
+// It's a health bar. You know what it does.
 public class HealthBarController : MonoBehaviour
 {
 
diff --git a/Assets/Scripts/UI/OpponentDragSpawner.cs b/Assets/Scripts/UI/OpponentDragSpawner.cs
index 66c5f72..d8883a3 100644
--- a/Assets/Scripts/UI/OpponentDragSpawner.cs
+++ b/Assets/Scripts/UI/OpponentDragSpawner.cs
@@ -1,9 +1,12 @@
-using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
 using UnityEngine.EventSystems;
 
+// Allows Enemies to be spawned by dragging them out of the Box. Handles and
+// indicates whether the current Enemy can actually be bought, based on price
+// and the current round state. Keeps track of the amount of currently placed
+// Enemies of this type to calculate costs.
 public class OpponentDragSpawner : MonoBehaviour, IRoundCallback, IManaChangeCallback, IDragDropListener
 {
 
@@ -30,6 +33,7 @@ public class OpponentDragSpawner : MonoBehaviour, IRoundCallback, IManaChangeCal
 
         var eventTrigger = GetComponent<EventTrigger>();
 
+        // Listen for BeginDrag events
         var beginDragEvent = new EventTrigger.Entry();
         beginDragEvent.eventID = EventTriggerType.BeginDrag;
         beginDragEvent.callback.AddListener((data) => OnBeginDrag((PointerEventData)data));
@@ -42,6 +46,7 @@ public class OpponentDragSpawner : MonoBehaviour, IRoundCallback, IManaChangeCal
         UpdateDisplayStates();
     }
 
+    // If all conditions are met, buy a new Enemy
     void OnBeginDrag(PointerEventData eventData)
     {
         if (RoundController.instance.roundRunning || !StatsManager.instance.ModifyMana(GetNextOpponentCost()))
@@ -56,6 +61,7 @@ public class OpponentDragSpawner : MonoBehaviour, IRoundCallback, IManaChangeCal
         UpdateDisplayStates();
     }
 
+    // Visually indicate whether this Opponent can be purchased
     void UpdateDisplayStates()
     {
         // Enemies call `OnEnemyDeleted()` when they are destroyed. This also happens
@@ -110,6 +116,7 @@ public class OpponentDragSpawner : MonoBehaviour, IRoundCallback, IManaChangeCal
         if (opponent == this.opponent)
         {
             placedOpponentCount--;
+            // Refund
             StatsManager.instance.ModifyMana(-GetNextOpponentCost());
             UpdateDisplayStates();
         }
@@ -122,7 +129,10 @@ public class OpponentDragSpawner : MonoBehaviour, IRoundCallback, IManaChangeCal
 
     public void OnRoundEnd(bool won)
     {
-        // To make sure this is called _after_ enemies might have destroyed itself in this callback
+        // To make sure this is called _after_ enemies might have destroyed itself
+        // with this same callback. Their OnRoundEnd may be called after this one.
+        // Hey look another hack, it's almost as if we didn't have enough time to
+        // think about a proper code architecture first!
         Invoke(nameof(RecalculatePlacedOpponentsCount), 0.01f);
         UpdateDisplayStates();
     }
diff --git a/Assets/Scripts/UI/RoundControllerButton.cs b/Assets/Scripts/UI/RoundControllerButton.cs
index 431709c..b69294c 100644
--- a/Assets/Scripts/UI/RoundControllerButton.cs
+++ b/Assets/Scripts/UI/RoundControllerButton.cs
@@ -1,8 +1,7 @@
-using System.Collections;
-using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
 
+// The button used to start and stop a round, which also indicates whether a round is currently running.
 public class RoundControllerButton : MonoBehaviour, IRoundCallback
 {
 
diff --git a/Assets/Scripts/Upgrades/Upgrade.cs b/Assets/Scripts/Upgrades/Upgrade.cs
index 162ed72..b2cef55 100644
--- a/Assets/Scripts/Upgrades/Upgrade.cs
+++ b/Assets/Scripts/Upgrades/Upgrade.cs
@@ -7,8 +7,8 @@ public class Upgrade : ScriptableObject
     public UpgradeTypes type;
     public string upgradeName;
     public int baseCost;
-    public float costMultiplier;
+    [Tooltip("How much each additional Upgrade costs")] public float costMultiplier;
     public Sprite shopSprite;
-    [Tooltip("Multiplier of the stat that this Upgrade controls")] public float effectMultiplier;
+    [Tooltip("How much each instance of this Upgrade improves the stat type")] public float effectMultiplier;
 
 }
diff --git a/Assets/Scripts/Upgrades/UpgradeController.cs b/Assets/Scripts/Upgrades/UpgradeController.cs
index 2b668c8..9455397 100644
--- a/Assets/Scripts/Upgrades/UpgradeController.cs
+++ b/Assets/Scripts/Upgrades/UpgradeController.cs
@@ -1,92 +1,97 @@
-using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;
 
-
-
+// Powers the Shop. Allows you to purchase Upgrades. Displays how many of each
+// Upgrade you already own and how much additional Upgrades cost.
 public class UpgradeController : MonoBehaviour
 {
     [SerializeField] Button manaButton;
 
     [Header("Price Texts")]
-    [SerializeField] Text healthText, damageText, armorText, manaText;
+    [SerializeField] Text healthText;
+    [SerializeField] Text damageText;
+    [SerializeField] Text armorText;
+    [SerializeField] Text manaText;
 
     [Header("Multiplier Texts")]
-    [SerializeField] Text healthMultiplierText, damageMultiplierText, armorMultiplierText, manaMultiplierText;
+    [SerializeField] Text healthMultiplierText;
+    [SerializeField] Text damageMultiplierText;
+    [SerializeField] Text armorMultiplierText;
+    [SerializeField] Text manaMultiplierText;
 
-    Dictionary<UpgradeTypes,Text> upgradeTexts = new Dictionary<UpgradeTypes,Text>();
+    Dictionary<UpgradeTypes, Text> upgradeTexts = new Dictionary<UpgradeTypes, Text>();
     Dictionary<UpgradeTypes, Text> multiplierTexts = new Dictionary<UpgradeTypes, Text>();
-    StatsManager statsManager;
 
-    
+
     private void Awake()
     {
-        statsManager = FindObjectOfType<StatsManager>();
-        
-        //initalise upgrade Texts
+        // Display initial values
         upgradeTexts.Add(UpgradeTypes.ENEMY_HEALTH, healthText);
         upgradeTexts.Add(UpgradeTypes.ENEMY_DAMAGE, damageText);
         upgradeTexts.Add(UpgradeTypes.ENEMY_ARMOR, armorText);
         upgradeTexts.Add(UpgradeTypes.MANA_COST, manaText);
-        UpdateAllCosts();
+        UpdateCostTexts();
 
-        //initalize Multiplier
-        multiplierTexts.Add(UpgradeTypes.ENEMY_HEALTH,healthMultiplierText);
+        multiplierTexts.Add(UpgradeTypes.ENEMY_HEALTH, healthMultiplierText);
         multiplierTexts.Add(UpgradeTypes.ENEMY_DAMAGE, damageMultiplierText);
         multiplierTexts.Add(UpgradeTypes.ENEMY_ARMOR, armorMultiplierText);
         multiplierTexts.Add(UpgradeTypes.MANA_COST, manaMultiplierText);
-        foreach (KeyValuePair<UpgradeTypes,Text> multiplierText in multiplierTexts)
+
+        foreach (KeyValuePair<UpgradeTypes, Text> multiplierText in multiplierTexts)
         {
-            multiplierText.Value.text = statsManager.GetTotalEffectMultiplier(multiplierText.Key).ToString("F2");
+            multiplierText.Value.text = StatsManager.instance.GetTotalEffectMultiplier(multiplierText.Key).ToString("F2");
         }
 
     }
+
+    // Called whenever a button to buy an Upgrade is called.
     public void Buy(string upgradeType)
     {
         switch (upgradeType)
         {
             case "Health":
-                UpdateCostText(UpgradeTypes.ENEMY_HEALTH);
+                BuyUpgrade(UpgradeTypes.ENEMY_HEALTH);
                 break;
             case "Damage":
-                UpdateCostText(UpgradeTypes.ENEMY_DAMAGE);
+                BuyUpgrade(UpgradeTypes.ENEMY_DAMAGE);
                 break;
             case "Armor":
-                UpdateCostText(UpgradeTypes.ENEMY_ARMOR);
+                BuyUpgrade(UpgradeTypes.ENEMY_ARMOR);
                 break;
             case "Mana":
-                UpdateCostText(UpgradeTypes.MANA_COST);
+                BuyUpgrade(UpgradeTypes.MANA_COST);
                 break;
         }
     }
 
-    private void UpdateCostText(UpgradeTypes upgradeType)
+    void BuyUpgrade(UpgradeTypes upgradeType)
     {
-        if (statsManager.BuyUpgrade(upgradeType))
+        if (StatsManager.instance.BuyUpgrade(upgradeType))
         {
-            upgradeTexts[upgradeType].text = statsManager.GetNextUpgradeCost(upgradeType).ToString();
-            multiplierTexts[upgradeType].text = statsManager.GetTotalEffectMultiplier(upgradeType).ToString("F2");
+            upgradeTexts[upgradeType].text = StatsManager.instance.GetNextUpgradeCost(upgradeType).ToString();
+            multiplierTexts[upgradeType].text = StatsManager.instance.GetTotalEffectMultiplier(upgradeType).ToString("F2");
             if (upgradeType == UpgradeTypes.MANA_COST)
             {
-                UpdateAllCosts();
-                DeactivateMana();
+                UpdateCostTexts();
+                MaybeDeactivateBuyManaButton();
             }
         }
 
     }
 
-    private void UpdateAllCosts()
+    void UpdateCostTexts()
     {
         foreach (KeyValuePair<UpgradeTypes, Text> upgradeText in upgradeTexts)
         {
-            upgradeText.Value.text = statsManager.GetNextUpgradeCost(upgradeText.Key).ToString();
+            upgradeText.Value.text = StatsManager.instance.GetNextUpgradeCost(upgradeText.Key).ToString();
         }
     }
 
-    private void DeactivateMana()
+    // Don't allow you to buy enough Mana Cost Decrease Upgrades to be able to spend negative Mana, aka gain Mana with purchases
+    void MaybeDeactivateBuyManaButton()
     {
-        if (statsManager.GetTotalEffectMultiplier(UpgradeTypes.MANA_COST) <= 0.1)
+        if (StatsManager.instance.GetTotalEffectMultiplier(UpgradeTypes.MANA_COST) <= 0.1)
         {
             manaButton.interactable = false;
             multiplierTexts[UpgradeTypes.MANA_COST].text = "0.1";
diff --git a/Assets/Scripts/utils/Box.cs b/Assets/Scripts/utils/Box.cs
index 6d6d593..e5433e3 100644
--- a/Assets/Scripts/utils/Box.cs
+++ b/Assets/Scripts/utils/Box.cs
@@ -1,7 +1,9 @@
 using System;
 using UnityEngine;
 
-// A simple struct representing a rectangular box consisting of four edges
+// A simple struct representing a rectangular box consisting of four edges.
+// I could've probably used a Rect or Bounds but when I write this I didn't
+// have much experience with them so, meh.
 [Serializable]
 public struct Box
 {
diff --git a/Assets/Scripts/utils/Interpolator.cs b/Assets/Scripts/utils/Interpolator.cs
index 23b2423..f21883e 100644
--- a/Assets/Scripts/utils/Interpolator.cs
+++ b/Assets/Scripts/utils/Interpolator.cs
@@ -1,8 +1,9 @@
 using System;
 using UnityEngine;
 
-// Fancy wrapper class for `Mathf.SmoothDamp()`. Interpolates between `currentValue` and `targetValue`,
-// which may change rapidly without disturbing the interpolation.
+// Fancy wrapper class for `Mathf.SmoothDamp()`. Interpolates between `currentValue`
+// and `targetValue`, which may change rapidly without disturbing the interpolation.
+// This entire system is completely over-engineered.
 [Serializable]
 public class Interpolator
 {
diff --git a/Assets/Scripts/utils/InterpolatorQueue.cs b/Assets/Scripts/utils/InterpolatorQueue.cs
index ad1aaa8..1afb6a7 100644
--- a/Assets/Scripts/utils/InterpolatorQueue.cs
+++ b/Assets/Scripts/utils/InterpolatorQueue.cs
@@ -5,7 +5,7 @@ using System.Collections.Generic;
 // A LayeredInterpolator consists of one base interpolator as well as an arbitrary
 // amount of interpolators which are stacked on top. Only the interpolator at the
 // top of the queue will be used. Once that interpolator has finished, it will be
-// removed from the queue and the seond-last interpolator takes over.
+// removed from the queue and the new top interpolator takes over.
 [Serializable]
 public class InterpolatorQueue
 {
@@ -43,6 +43,7 @@ public class InterpolatorQueue
         interpolators.Add(baseInterpolator);
     }
 
+    // Adds a new Interpolator to the top of the queue, meaning that it will be the new active one.
     public void PushInterpolator(Interpolator newInterpolator)
     {
         // Only push interpolators that would actually do something
@@ -52,6 +53,7 @@ public class InterpolatorQueue
         }
     }
 
+    // Removes the currently active interpolator, if there is one
     public void PopInterpolator()
     {
         // Always keep the base interpolator
@@ -61,6 +63,7 @@ public class InterpolatorQueue
         }
     }
 
+    // See `Interpolator#Tick()`
     public float Tick()
     {
         Interpolator current = GetCurrentInterpolator();
-- 
GitLab