diff --git a/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAbility.cs b/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAbility.cs
index dfc797c2f90ab87607ac90e2f58f1a99e70f2b47..f19870ede3fa73fcfbe58607883c12c150e678e4 100644
--- a/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAbility.cs
+++ b/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAbility.cs
@@ -19,22 +19,22 @@ namespace BigSock {
 		/*
 			The name of the ability.
 		*/
-		public string Name { get; set; }
+		public abstract string Name { get;}
 		
 		/*
 			The description of the ability.
 		*/
-		public string Description { get; set; }
+		public abstract string Description { get; }
 
 		/*
 			The id of the ability.
 		*/
-		public ulong Id { get; set; }
+		public abstract ulong Id { get; }
 
 		/*
 			The next time the ability has cooled down.
 		*/
-		public DateTime NextTimeCanUse { get; set; } = DateTime.Now;
+		public DateTime NextTimeCanUse { get; protected set; } = DateTime.Now;
 
 		/*
 			Whether the ability is ready.
diff --git a/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAttack.cs b/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAttack.cs
index 99de155333fa836e121ffba90869c49a53a354b1..a0c6b44b35538b5b559b2f5edfab75d9361d5769 100644
--- a/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAttack.cs
+++ b/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAttack.cs
@@ -15,7 +15,7 @@ namespace BigSock {
 		/*
 			The attack stats of the ability.
 		*/
-		public IAttackStats AttackStats { get; set; }
+		public IAttackStats AttackStats { get; protected set; }
 
 	}
 
diff --git a/MrBigsock/Assets/Code/Core/Abilities/BasicProjectile1.cs b/MrBigsock/Assets/Code/Core/Abilities/BasicProjectile1.cs
index b7e1e8189da0a411a88414cca0d135d37c661840..15aa963ea6f4f5cf4d0eb06519d677547ee3beb8 100644
--- a/MrBigsock/Assets/Code/Core/Abilities/BasicProjectile1.cs
+++ b/MrBigsock/Assets/Code/Core/Abilities/BasicProjectile1.cs
@@ -16,17 +16,19 @@ namespace BigSock {
 		//protected static readonly GameObject PROJECTILE_BASE = new AttackMovement();
 		public const string PROJECTILE_NAME = "attack";
 
-		/*
-			The attack stats of the ability.
-		*/
-		public IAttackStats AttackStats { get; set; }
-
-
+		
+		public override ulong Id => 101;
+		public override string Name => "Basic Player Projectile Attack";
+		public override string Description => "A basic projectile shooting attack the player has.";
 
 		public BasicProjectile1() {
-			Name = "Basic Player Projectile Attack";
-			Id = 101;
-			Description = "A basic projectile shooting attack the player has.";
+			AttackStats = new AttackStats{
+				Damage = 1f,
+				Knockback = 1f,
+				Range = 10f,
+				ProjectileSpeed = 10f,
+				AttackSpeed = 1f,
+			};
 		}
 
 
@@ -38,8 +40,21 @@ namespace BigSock {
 			This should be overridden in sub-classes for the actual abilities.
 		*/
 		protected override bool Activate(Character actor, Vector3? target) {
+			if(target == null) return false;
+
+			var attack = (AttackStats) AttackStats.Apply(actor.Stats);
+			attack.Actor = actor;
+
+
+			var temp = (target.Value - actor.transform.position);
+			temp.z = 0;
+
 			var bullet = PrefabService.SINGLETON.Instance(PROJECTILE_NAME, actor.transform.position);
-			bullet.GetComponent<AttackMovement>().Actor = actor;
+			var bulletScript = bullet.GetComponent<AttackMovement>();
+			//bulletScript.Actor = actor;
+			bulletScript.Stats = attack;
+			bulletScript.Direction = temp.normalized;
+
 
 			//MonoBehaviour.Instantiate(PROJECTILE_BASE, (Vector3) actor.transform.position, PROJECTILE_BASE.transform.rotation);
 			return true;
diff --git a/MrBigsock/Assets/Code/Core/AttackStats.cs b/MrBigsock/Assets/Code/Core/AttackStats.cs
index 6eac3a66344a0e6096c2d907d505c9bbc5cc2327..39cffac40b372ae2f66944dd8a783f5885cb86d0 100644
--- a/MrBigsock/Assets/Code/Core/AttackStats.cs
+++ b/MrBigsock/Assets/Code/Core/AttackStats.cs
@@ -14,22 +14,27 @@ namespace BigSock {
 		/*
 			The damage of the attack.
 		*/
-		public float Damage { get; set; }
+		public float Damage { get; set; } = 1f;
 
 		/*
 			The knockback of the attack.
 		*/
-		public float Knockback { get; set; }
+		public float Knockback { get; set; } = 1f;
 
 		/*
 			The range of the attack.
 		*/
-		public float Range { get; set; }
+		public float Range { get; set; } = 1f;
+
+		/*
+			The projectile speed of the attack.
+		*/
+		public float ProjectileSpeed { get; set; } = 1f;
 
 		/*
 			The attack speed of the attack.
 		*/
-		public float AttackSpeed { get; set; }
+		public float AttackSpeed { get; set; } = 1f;
 
 		/*
 			The source of the attack.
diff --git a/MrBigsock/Assets/Code/Core/IAttackStats.cs b/MrBigsock/Assets/Code/Core/IAttackStats.cs
index ea103727f1cb17a22798b4392db54908a0772484..7b601071f61bd03241c074645bc7d521aa305268 100644
--- a/MrBigsock/Assets/Code/Core/IAttackStats.cs
+++ b/MrBigsock/Assets/Code/Core/IAttackStats.cs
@@ -26,6 +26,11 @@ namespace BigSock {
 		*/
 		float Range { get; }
 
+		/*
+			The projectile speed of the attack.
+		*/
+		float ProjectileSpeed { get; }
+
 		/*
 			The attack speed of the attack.
 		*/
@@ -41,4 +46,27 @@ namespace BigSock {
 		*/
 		Character Actor { get; }
 	}
+
+
+	/*
+		Holds extension methods for attack stat objects.
+	*/
+	public static class AttackStatsExtension {
+
+
+		/*
+			Applies the character's stats to the attack.
+		*/
+		public static IAttackStats Apply(this IAttackStats a, ICharacterStats b) {
+			return new AttackStats{
+				Damage = a.Damage * b.Damage,
+				Knockback = a.Knockback * b.Knockback,
+				Range = a.Range * b.Range,
+				ProjectileSpeed = a.ProjectileSpeed,
+				AttackSpeed = a.AttackSpeed * b.AttackSpeed,
+				Source = a.Source,
+				Actor = a.Actor,
+			};
+		}
+	}
 }
\ No newline at end of file
diff --git a/MrBigsock/Assets/Code/PlayerController.cs b/MrBigsock/Assets/Code/PlayerController.cs
index d07507999d825f65ae26b8ebbcc9a6858d8fdbf2..300cedfbac1d53a86394b866607ddc3655d53b33 100644
--- a/MrBigsock/Assets/Code/PlayerController.cs
+++ b/MrBigsock/Assets/Code/PlayerController.cs
@@ -32,7 +32,7 @@ namespace BigSock {
 
 
 
-			protected IAttack _testAttack = new BasicProjectile1();
+			protected IAttack _testAttack;// = new BasicProjectile1();
 
 			public DateTime NextTimeCanAttack { get; private set; } = DateTime.Now;
 
@@ -53,6 +53,7 @@ namespace BigSock {
 				TryPickUpItem(ItemService.SINGLETON.Get(201));
 				TryPickUpItem(ItemService.SINGLETON.Get(202));
 				var tmp = PrefabService.SINGLETON;
+				_testAttack = (IAttack) AbilityService.SINGLETON.Get(101);
 			}
 
 
diff --git a/MrBigsock/Assets/Code/Services/AbilityService.cs b/MrBigsock/Assets/Code/Services/AbilityService.cs
new file mode 100644
index 0000000000000000000000000000000000000000..1849ecf96f6096928a9ca3abc4d406f12def88f7
--- /dev/null
+++ b/MrBigsock/Assets/Code/Services/AbilityService.cs
@@ -0,0 +1,85 @@
+using System.Collections;
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using System.Reflection;
+
+using UnityEngine;
+using UnityEngine.InputSystem;
+
+using BigSock.Item;
+
+
+namespace BigSock.Service {
+	
+	/*
+		Service for handling abilities.
+	*/
+	public partial class AbilityService {	
+		/*
+			The instance to use.
+		*/
+		public static readonly AbilityService SINGLETON = new AbilityService();
+
+		/*
+			Get an instance of the ability of the given id.
+		*/
+		public IAbility Get(ulong id) {
+			if(_abilities.TryGetValue(id, out var res)) return _new(res);
+			return null;
+		}
+
+		/*
+			Get a random ability from the ability pool.
+		*/
+		public IAbility GetRandom() {
+			var num = _rnd.Next(_abilityList.Count);
+			return _new(_abilityList[num]);
+		}
+	}
+
+	public partial class AbilityService {	
+		private Dictionary<ulong, IAbility> _abilities = new Dictionary<ulong, IAbility>();
+		private List<IAbility> _abilityList = new List<IAbility>();
+
+		private System.Random _rnd = new System.Random();
+
+		private AbilityService() {
+			_loadItems();
+		}
+
+		/*
+			Load the abilities into the dictionary.
+			Reflection code: https://stackoverflow.com/a/6944605
+		*/
+		private void _loadItems() {
+			// Get the classs that inherit the item base class.
+			var types = Assembly
+				.GetAssembly(typeof(BaseAbility))
+				.GetTypes()
+				.Where(myType => myType.IsClass 
+					&& !myType.IsAbstract 
+					&& myType.IsSubclassOf(typeof(BaseAbility)));
+
+			// Create list of instances.
+			_abilityList = types
+				.Select(t => (IAbility) Activator.CreateInstance(t, new object[0]))
+				.ToList();
+
+			// Map to a dictionary by their ids.
+			_abilities = _abilityList
+				.ToDictionary(t => t.Id);
+
+			foreach(var a in _abilityList) {
+				Debug.Log($"[AbilityService._loadItems()] {a.Id}");
+			}
+		}
+
+		/*
+			Creates a new instance of the object.
+		*/
+		private IAbility _new(IAbility obj) 
+			=> (IAbility) Activator.CreateInstance(obj.GetType(), new object[0]);
+		
+	}
+}
\ No newline at end of file
diff --git a/MrBigsock/Assets/Code/Services/AbilityService.cs.meta b/MrBigsock/Assets/Code/Services/AbilityService.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..ba54c4ef9e433c501d67907a37c029f02b20f6f8
--- /dev/null
+++ b/MrBigsock/Assets/Code/Services/AbilityService.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: accabe59812fa39448d6bd558041692d
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/MrBigsock/Assets/Code/attack/AttackMovement.cs b/MrBigsock/Assets/Code/attack/AttackMovement.cs
index 37b53fa9705d5bfb24c47e4824e351bdf21de880..aa7795a3385fed211ac5008c6d464885cd9634fa 100644
--- a/MrBigsock/Assets/Code/attack/AttackMovement.cs
+++ b/MrBigsock/Assets/Code/attack/AttackMovement.cs
@@ -4,29 +4,44 @@ using UnityEngine;
 using UnityEngine.InputSystem;
 using static UnityEngine.GraphicsBuffer;
 
+using BigSock.Service;
+
+
 namespace BigSock {
 
 	public class AttackMovement : MonoBehaviour
 	{
 		public float speed = 10.0f;
 		bool moved = false;
-		Vector3 direction;
+		//Vector3 direction;
+		Vector3 startingPos;
 
 		/*
 			Damage of the character.
 		*/
-		public float Damage => baseDamage;
-		public float baseDamage = 1;
+		//public float Damage => baseDamage;
+		//public float baseDamage = 1;
 
-		public float KnockbackForce => knockbackForce;
-		public float knockbackForce = 1;
+		//public float KnockbackForce => knockbackForce;
+		//public float knockbackForce = 1;
 
 		/*
 			The character that activated the attack.
 		*/
-		public Character Actor { get; set; }
+		//public Character Actor { get; set; }
+		
+		/*
+			The attack stats of the attack.
+		*/
+		public AttackStats Stats { get; set; }
+
+		/*
+			The direction of the attack.
+		*/
+		public Vector3 Direction { get; set; }
+
 
-		// Start is called before the first frame update
+		// Start is called before the first frame update 
 		void Start()
 		{
 		}
@@ -36,18 +51,26 @@ namespace BigSock {
 		{
 			if (!moved)
 			{
-				var mouse = Camera.main.ScreenToWorldPoint(Input.mousePosition);
-				var pos = transform.position;
-				var temp = (mouse - pos);
-				temp.z = 0;
-				direction = temp.normalized;
+				//var mouse = Camera.main.ScreenToWorldPoint(Input.mousePosition);
+				//var pos = transform.position;
+				//var temp = (mouse - pos);
+				//temp.z = 0;
+				//direction = temp.normalized;
 				//print($"[AttackMovement.Update()] {mouse} - {pos} = {direction}");
+				startingPos = transform.position;
 				moved = true;
 			}
 
 			//transform.Translate(new Vector3(1 * horizontalInput, 1 * verticalInput, 0) * speed * Time.deltaTime);
-			transform.Translate(direction * speed * Time.deltaTime);
-				
+			transform.Translate(Direction * Stats.ProjectileSpeed * Time.deltaTime);
+
+			var traveled = Vector2.Distance(transform.position, startingPos);
+
+			// If we traveled passed our range: destroy this obj.
+			if(traveled > Stats.Range) {
+				PrefabService.SINGLETON.Destroy(gameObject);
+			}
+
 		}
 		
 		
@@ -58,23 +81,24 @@ namespace BigSock {
 
 			if(target != null) {
 
-				var attack = new AttackStats{
-					Damage = Damage,
-					Knockback = KnockbackForce,
-					//Range = 0,
-					//AttackSpeed = AttackSpeed,
-					Source = transform.position,
-					Actor = Actor,
-				};
+				//var attack = new AttackStats{
+				//	Damage = Damage,
+				//	Knockback = KnockbackForce,
+				//	//Range = 0,
+				//	//AttackSpeed = AttackSpeed,
+				//	Source = transform.position,
+				//	Actor = Actor,
+				//};
+				Stats.Source = transform.position;
 
 				// If we have an actor: Apply their stat mods & trigger their OnHit.
-				if(Actor != null) {
-					attack.Damage *= Actor.Damage;
-					attack.Knockback *= Actor.KnockbackForce;
-					//Actor.TargetHit(target, attack);
-				}
+				//if(Actor != null) {
+				//	attack.Damage *= Actor.Damage;
+				//	attack.Knockback *= Actor.KnockbackForce;
+				//	//Actor.TargetHit(target, attack);
+				//}
 
-				if(target.TakeDamage(attack)) {
+				if(target.TakeDamage(Stats)) {
 					
 				}
 			}