diff --git a/Assets/Scripts/Logic/Data/GameOverview.cs b/Assets/Scripts/Logic/Data/GameOverview.cs
index fdbfa175626982e81ca91d078f7f18024200fe56..85aa3eb5268be0549c1d220ccf11062fc9b1fb9c 100644
--- a/Assets/Scripts/Logic/Data/GameOverview.cs
+++ b/Assets/Scripts/Logic/Data/GameOverview.cs
@@ -94,7 +94,8 @@ public class GameOverview : IGameOverview {
 			TimeLeftFromPhase = Math.Max(OverviewConfig.FightingPhaseDuration,
 				World.GetTileObjectsOfType<Barrack>()
 					.Max(barrack =>
-						barrack.QueuedUnits.Count * World.Config.BarrackSpawnCooldownTime));
+						barrack.QueuedUnits.Count * World.Config.BarrackSpawnCooldownTime
+						+ barrack.Ordinal * World.Config.BarrackSpawnTimeOffset));
 		} else if (CurrentPhase == GamePhase.Fight) {
 			if (Teams.Any(t => t.Castle.IsDestroyed)) {
 				CurrentPhase = GamePhase.Finished;
diff --git a/Assets/Scripts/Logic/Data/GameTeam.cs b/Assets/Scripts/Logic/Data/GameTeam.cs
index ff6bf8fab4d9cb33bd2c5a7c6e42bf4042c7e33e..9cc9214ed179ac762e34c615ca995085da99caf2 100644
--- a/Assets/Scripts/Logic/Data/GameTeam.cs
+++ b/Assets/Scripts/Logic/Data/GameTeam.cs
@@ -55,7 +55,7 @@ public class GameTeam {
 		Overview = overview;
 		TeamColor = color;
 		Castle = castle;
-		Barracks = new List<Barrack>(barracks);
+		Barracks = barracks.OrderBy(barrack => barrack.Ordinal).ToList();
 		Money = overview.EconomyConfig.StartingBalance;
 	}
 
@@ -122,7 +122,7 @@ public class GameTeam {
 		_availableTowerPositionsCache.ExceptWith(world.Units.Select(u => u.TilePosition));
 
 		_availableTowerPositionsCache.RemoveWhere(position => {
-			ISet<TilePosition> blocked = new HashSet<TilePosition> { position };
+			ISet<TilePosition> blocked = new HashSet<TilePosition> {position};
 
 			foreach (GameTeam sourceTeam in Overview.Teams) {
 				TilePosition from = Overview.GetEnemyTeam(sourceTeam).Castle.Position;
diff --git a/Assets/Scripts/Logic/Data/World/Barrack.cs b/Assets/Scripts/Logic/Data/World/Barrack.cs
index 557ec35a5d2c39bf0c1eb9cb765d843242aa3348..713f6008e185ed0a9658f9985146f20986414cb6 100644
--- a/Assets/Scripts/Logic/Data/World/Barrack.cs
+++ b/Assets/Scripts/Logic/Data/World/Barrack.cs
@@ -5,7 +5,6 @@ using Logic.Event.World.Barrack;
 using Logic.Event.World.Unit;
 
 namespace Logic.Data.World {
-
 public class Barrack : Building {
 	#region Fields
 
@@ -25,12 +24,16 @@ public class Barrack : Building {
 
 	public IReadOnlyCollection<IUnitTypeData> QueuedUnits => new List<IUnitTypeData>(_queuedUnits);
 
+	public int Ordinal  { get; }
+
 	#endregion
 
 	#region Methods
 
-	internal Barrack(GameWorld world, TilePosition position, Color owner)
-		: base(world, position, owner) {}
+	internal Barrack(GameWorld world, TilePosition position, Color owner, int ordinal)
+		: base(world, position, owner) {
+		Ordinal  = ordinal;
+	}
 
 	internal void QueueUnit(IUnitTypeData type) {
 		_queuedUnits.Add(type);
@@ -62,7 +65,7 @@ public class Barrack : Building {
 	}
 
 	internal void ResetCooldown() {
-		RemainingCooldownTime = 0;
+		RemainingCooldownTime = Ordinal  * World.Config.BarrackSpawnTimeOffset;
 	}
 
 	internal void Spawn() {
@@ -98,5 +101,4 @@ public class Barrack : Building {
 
 	#endregion
 }
-
 }
diff --git a/Assets/Scripts/Logic/Data/World/GameWorld.cs b/Assets/Scripts/Logic/Data/World/GameWorld.cs
index ffd0340aeb9b2e283dd6e73242fa5ecb8dfeb35c..f32bcb543ab8df5b6a3775ba43b4201bd54476ab 100644
--- a/Assets/Scripts/Logic/Data/World/GameWorld.cs
+++ b/Assets/Scripts/Logic/Data/World/GameWorld.cs
@@ -95,6 +95,7 @@ public class GameWorld {
 	#endregion
 
 	private class TileObjectConstructors : WorldGenerator.ITileObjectConstructors {
+		private readonly IDictionary<Color, int> _barrackCounter = new Dictionary<Color, int>();
 		private readonly GameWorld _world;
 
 		public TileObjectConstructors(GameWorld world) {
@@ -106,7 +107,10 @@ public class GameWorld {
 		}
 
 		public Barrack CreateBarrack(TilePosition position, Color team) {
-			return new Barrack(_world, position, team);
+			_barrackCounter.TryGetValue(team, out int index);
+			Barrack barrack = new Barrack(_world, position, team, index);
+			_barrackCounter[team] = index + 1;
+			return barrack;
 		}
 
 		public Obstacle CreateObstacle(TilePosition position) {
diff --git a/Assets/Scripts/Logic/Data/World/IGameWorldConfig.cs b/Assets/Scripts/Logic/Data/World/IGameWorldConfig.cs
index 6f952f8d0058a97158baafc3c13fd774814476f3..10cf551690b1eb4d4df670fb8c71796619905a1c 100644
--- a/Assets/Scripts/Logic/Data/World/IGameWorldConfig.cs
+++ b/Assets/Scripts/Logic/Data/World/IGameWorldConfig.cs
@@ -1,5 +1,4 @@
 ďťżnamespace Logic.Data.World {
-
 public interface IGameWorldConfig {
 	public int Width { get; }
 	public int Height { get; }
@@ -7,6 +6,6 @@ public interface IGameWorldConfig {
 	public float CastleStartingHealth { get; }
 	public int MaxBuildingDistance { get; }
 	public bool GenerateObstacles { get; }
+	public float BarrackSpawnTimeOffset { get; }
 }
-
 }
diff --git a/Assets/Scripts/Logic/Data/World/WorldGenerator.cs b/Assets/Scripts/Logic/Data/World/WorldGenerator.cs
index fa2f9a091766a2e322d371fea9a2eba0f50fbbe3..7e65c8f5ba4a3d3a9fc3fd0626969740e93810a1 100644
--- a/Assets/Scripts/Logic/Data/World/WorldGenerator.cs
+++ b/Assets/Scripts/Logic/Data/World/WorldGenerator.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
 using System.Linq;
 
 namespace Logic.Data.World {
-
 internal class WorldGenerator {
 	public static TileObject[,] GenerateGrid(int seed, int width, int height,
 		bool generateObstacles, ITileObjectConstructors constructors) {
@@ -51,11 +50,11 @@ internal class WorldGenerator {
 
 		occupiedList.Add(_constructors.CreateBarrack(new TilePosition(x, y), Color.Red));
 
-		int obstacleCount = _generateObstacles ? (_random.Next() % ((_width * _height) / 60)) + 2 : 0;
+		int obstacleCount = _generateObstacles ? (_random.Next() % ((_width * _height) / 40)) + 2 : 0;
 		int i = 0, rep = 0;
 		while (i < obstacleCount && rep < 1000) {
 			++rep;
-			int obstacleSize = _random.Next() % 3 + 1;
+			int obstacleSize = _random.Next() % 2 + 1;
 			x = _random.Next() % (_width - obstacleSize);
 			y = _random.Next() % ((_height / 2) - obstacleSize);
 			bool allGood = true;
@@ -79,6 +78,21 @@ internal class WorldGenerator {
 			}
 		}
 
+		if (i == 0) {
+			List<int> goodIndices = new List<int>();
+			for (int j = 0; j < _width; j++) {
+				tp = new TilePosition(_height / 2, _width);
+				if (!occupiedList.Where(building => !(building is Obstacle))
+					.Any(occupied => occupied.Position.FirstNormDistance(tp) < 4)) {
+					goodIndices.Add(j);
+				}
+			}
+
+			occupiedList.Add(_constructors.CreateObstacle(new TilePosition(
+				goodIndices[_random.Next() % goodIndices.Count],
+				_height / 2)));
+		}
+
 		List<TileObject> otherSide = new List<TileObject>();
 		foreach (TileObject tileObject in occupiedList) {
 			TilePosition newPos = new TilePosition(_width, _height)
@@ -109,5 +123,4 @@ internal class WorldGenerator {
 		public Obstacle CreateObstacle(TilePosition position);
 	}
 }
-
 }
diff --git a/Assets/Scripts/Logic/System/InvalidateCachesSystem.cs b/Assets/Scripts/Logic/System/InvalidateCachesSystem.cs
index 54bf7766638b7d7af06c71bad7779d0299564359..a22e78a6faaea53a4be1b752c5776578da42ab06 100644
--- a/Assets/Scripts/Logic/System/InvalidateCachesSystem.cs
+++ b/Assets/Scripts/Logic/System/InvalidateCachesSystem.cs
@@ -5,7 +5,6 @@ using Logic.Event.World.Tower;
 using Logic.Event.World.Unit;
 
 namespace Logic.System {
-
 /// <summary>
 /// System responsible for clearing/recalculating cached values. These include:
 /// <list type="bullet">
@@ -79,5 +78,4 @@ internal class InvalidateCachesSystem : BaseSystem {
 		}
 	}
 }
-
 }
diff --git a/Assets/Scripts/LogicTests/BarrackUnitIntegrationTest.cs b/Assets/Scripts/LogicTests/BarrackUnitIntegrationTest.cs
index 532157923ae78888026670422a3f243e48e90e43..f91efddb169eb1eb5d178a33ff8100b07be34e27 100644
--- a/Assets/Scripts/LogicTests/BarrackUnitIntegrationTest.cs
+++ b/Assets/Scripts/LogicTests/BarrackUnitIntegrationTest.cs
@@ -6,7 +6,6 @@ using Logic.Data.World;
 using NUnit.Framework;
 
 namespace LogicTests {
-
 /// <summary>
 /// Tests the interaction between the <see cref="Barrack"/> and the <see cref="Unit"/> classes:
 /// unit purchasing causing units to get queued and barracks spawning units.
@@ -34,43 +33,43 @@ public class BarrackUnitIntegrationTest {
 	public void TestBarracksSlowlySpawnUnits() {
 		GameOverview overview = GameTestUtils.CreateOverview();
 		GameTeam team = overview.Teams.First();
-		IUnitTypeData unitType = new GameTestUtils.UnitTypeData { Speed = 0 };
+		IUnitTypeData unitType = new GameTestUtils.UnitTypeData {Speed = 0};
 
-		//Purchase 3 units -> one of the barracks must have at least 2
-		for (int i = 0; i < 3; i++) Assert.IsTrue(overview.Commands.Issue(new PurchaseUnitCommand(team, unitType)));
-		Barrack barrack = team.Barracks.OrderByDescending(b => b.QueuedUnits.Count).First();
+		//Purchase 2 units for the first barrack
+		team.Barracks.First().QueueUnit(unitType);
+		team.Barracks.First().QueueUnit(unitType);
 
 		//Enter fighting phase
 		Assert.IsTrue(overview.Commands.Issue(new AdvancePhaseCommand(overview)));
 		Assert.AreEqual(GamePhase.Fight, overview.CurrentPhase);
 		Assert.AreEqual(0, overview.World.Units.Count);
-		Assert.AreEqual(3, team.Barracks.Sum(b => b.QueuedUnits.Count));
+		Assert.AreEqual(2, team.Barracks.First().QueuedUnits.Count);
 
-		//Spawn the first unit(s)
+		//Spawn the first unit
 		Assert.IsTrue(overview.Commands.Issue(new AdvanceTimeCommand(overview, float.Epsilon)));
-		Assert.AreEqual(3, overview.World.Units.Count + team.Barracks.Sum(b => b.QueuedUnits.Count));
-		Assert.IsTrue(barrack.QueuedUnits.Count > 0);
-		Assert.IsTrue(barrack.IsOnCooldown);
+		Assert.AreEqual(2, overview.World.Units.Count + team.Barracks.Sum(b => b.QueuedUnits.Count));
+		Assert.IsTrue(team.Barracks.First().QueuedUnits.Count > 0);
+		Assert.IsTrue(team.Barracks.First().IsOnCooldown);
 
 		//Assert that cooldown lasts
 		float deltaTime = overview.World.Config.BarrackSpawnCooldownTime / 10;
 		for (int i = 0; i < 9; i++) Assert.IsTrue(overview.Commands.Issue(new AdvanceTimeCommand(overview, deltaTime)));
-		Assert.IsTrue(barrack.QueuedUnits.Count > 0);
-		Assert.IsTrue(barrack.IsOnCooldown);
+		Assert.IsTrue(team.Barracks.First().QueuedUnits.Count > 0);
+		Assert.IsTrue(team.Barracks.First().IsOnCooldown);
 
 		//Assert that the barrack spawn another unit
-		int oldQueued = barrack.QueuedUnits.Count;
+		int oldQueued = team.Barracks.First().QueuedUnits.Count;
 		for (int i = 0; i < 2; i++) Assert.IsTrue(overview.Commands.Issue(new AdvanceTimeCommand(overview, deltaTime)));
-		Assert.AreEqual(3, overview.World.Units.Count + team.Barracks.Sum(b => b.QueuedUnits.Count));
-		Assert.AreEqual(oldQueued - 1, barrack.QueuedUnits.Count);
-		Assert.IsTrue(barrack.IsOnCooldown);
+		Assert.AreEqual(2, overview.World.Units.Count + team.Barracks.Sum(b => b.QueuedUnits.Count));
+		Assert.AreEqual(oldQueued - 1, team.Barracks.First().QueuedUnits.Count);
+		Assert.IsTrue(team.Barracks.First().IsOnCooldown);
 
 		//Assert that the barrack won't be on cooldown after spawning all units
 		deltaTime = overview.World.Config.BarrackSpawnCooldownTime * 1.1f;
 		for (int i = 0; i < 3; i++) Assert.IsTrue(overview.Commands.Issue(new AdvanceTimeCommand(overview, deltaTime)));
-		Assert.AreEqual(3, overview.World.Units.Count);
+		Assert.AreEqual(2, overview.World.Units.Count);
 		Assert.AreEqual(0, team.Barracks.Sum(b => b.QueuedUnits.Count));
-		Assert.IsFalse(barrack.IsOnCooldown);
+		Assert.IsFalse(team.Barracks.First().IsOnCooldown);
 	}
 
 	[Test]
@@ -95,5 +94,4 @@ public class BarrackUnitIntegrationTest {
 		Assert.AreEqual(expectedMoney, team.Money);
 	}
 }
-
 }
diff --git a/Assets/Scripts/LogicTests/GameOverviewTest.cs b/Assets/Scripts/LogicTests/GameOverviewTest.cs
index b56423088a8d05b37287705c2525062b7fd97892..44b07a610c1715dd15a4b7581c2447014a987776 100644
--- a/Assets/Scripts/LogicTests/GameOverviewTest.cs
+++ b/Assets/Scripts/LogicTests/GameOverviewTest.cs
@@ -6,7 +6,6 @@ using Logic.Data;
 using NUnit.Framework;
 
 namespace LogicTests {
-
 /// <summary>
 /// Container of unit tests for the <see cref="GameOverview"/> class.
 /// This class encapsulates almost all other classes in the logic component,
@@ -48,8 +47,8 @@ public class GameOverviewTest {
 		GameOverview overview = GameTestUtils.CreateOverview();
 
 		Assert.AreEqual(GamePhase.Prepare, overview.CurrentPhase);
-		GameTestUtils.UnitTypeData unitType = new GameTestUtils.UnitTypeData { Speed = float.Epsilon };
-		Assert.IsTrue(overview.Commands.Issue(new PurchaseUnitCommand(overview.Teams.First(), unitType)));
+		GameTestUtils.UnitTypeData unitType = new GameTestUtils.UnitTypeData {Speed = float.Epsilon};
+		overview.Teams.First().Barracks.First().QueueUnit(unitType);
 
 		overview.AdvancePhase();
 		Assert.AreEqual(GamePhase.Fight, overview.CurrentPhase);
@@ -80,5 +79,4 @@ public class GameOverviewTest {
 		Assert.AreEqual(GamePhase.Finished, overview.CurrentPhase);
 	}
 }
-
 }
diff --git a/Assets/Scripts/LogicTests/GameTestUtils.cs b/Assets/Scripts/LogicTests/GameTestUtils.cs
index abb554f8e9ea1800661de399bbb2f7652a14cd04..aba6a1dc98280c7c1133d2646d1ed3b6d2ec7510 100644
--- a/Assets/Scripts/LogicTests/GameTestUtils.cs
+++ b/Assets/Scripts/LogicTests/GameTestUtils.cs
@@ -5,7 +5,6 @@ using Logic.Data.World;
 using NUnit.Framework;
 
 namespace LogicTests {
-
 /// <summary>
 /// Utility methods regarding the whole game (<see cref="GameOverview"/>).
 /// </summary>
@@ -121,6 +120,8 @@ public static class GameTestUtils {
 		public float CastleStartingHealth { get; set; } = 10;
 		public int MaxBuildingDistance { get; set; } = 5;
 		public bool GenerateObstacles { get; set; } = true;
+
+		public float BarrackSpawnTimeOffset { get; set; } = 0.1f;
 	}
 
 	/// <summary>
@@ -156,5 +157,4 @@ public static class GameTestUtils {
 		public ITowerTypeData AfterUpgradeType { get; set; } = null;
 	}
 }
-
 }
diff --git a/Assets/Scripts/LogicTests/RandomUtils.cs b/Assets/Scripts/LogicTests/RandomUtils.cs
index 9ef69e2cbf88c401b80297f98fa9425d33b7dde6..1fea40814d40e50dc48799d251a061d3158ff39d 100644
--- a/Assets/Scripts/LogicTests/RandomUtils.cs
+++ b/Assets/Scripts/LogicTests/RandomUtils.cs
@@ -2,7 +2,6 @@
 using NUnit.Framework;
 
 namespace LogicTests {
-
 /// <summary>
 /// Utility methods regarding random number generation.
 /// </summary>
@@ -27,5 +26,4 @@ public static class RandomUtils {
 		}
 	}
 }
-
 }
diff --git a/Assets/Scripts/LogicTests/UnitTowerCastleIntegrationTest.cs b/Assets/Scripts/LogicTests/UnitTowerCastleIntegrationTest.cs
index beaf880a441337cd25bea783dd612584dcde283d..c1d0de961cba38c6cc73c41de1852f5f2836fd91 100644
--- a/Assets/Scripts/LogicTests/UnitTowerCastleIntegrationTest.cs
+++ b/Assets/Scripts/LogicTests/UnitTowerCastleIntegrationTest.cs
@@ -11,7 +11,6 @@ using Logic.Event.World.Unit;
 using NUnit.Framework;
 
 namespace LogicTests {
-
 /// <summary>
 /// Tests the basic interactions between <see cref="Unit"/>, <see cref="Castle"/>
 /// and <see cref="Tower"/> instances: unit damaging castle, unit destroying castle,
@@ -117,8 +116,8 @@ public class UnitTowerCastleIntegrationTest {
 		GameTeam towerTeam = overview.GetEnemyTeam(unitTeam);
 
 		//Purchase a unit with zero speed
-		GameTestUtils.UnitTypeData unitType = new GameTestUtils.UnitTypeData { Speed = 0 };
-		Assert.IsTrue(overview.Commands.Issue(new PurchaseUnitCommand(unitTeam, unitType)));
+		GameTestUtils.UnitTypeData unitType = new GameTestUtils.UnitTypeData {Speed = 0};
+		unitTeam.Barracks.First().QueueUnit(unitType);
 
 		//Build a tower with zero damage and high range
 		GameTestUtils.TowerTypeData towerType = new GameTestUtils.TowerTypeData {
@@ -157,7 +156,7 @@ public class UnitTowerCastleIntegrationTest {
 	[Test]
 	public void TestTowerTargetReachedCastle() {
 		GameOverview overview = CreateTowerTargetTestingGame(10, 10,
-			(towerTeam, _) => new[] { towerTeam.AvailableTowerPositions.First() }, 1, 0, float.PositiveInfinity, 1);
+			(towerTeam, _) => new[] {towerTeam.AvailableTowerPositions.First()}, 1, 0, float.PositiveInfinity, 1);
 
 		//Update the tower's target
 		Assert.IsTrue(overview.Commands.Issue(new AdvanceTimeCommand(overview, float.Epsilon)));
@@ -194,8 +193,8 @@ public class UnitTowerCastleIntegrationTest {
 	[Test]
 	public void TestTowerTargetMovedOutOfRange() {
 		IEnumerable<TilePosition> TowerPositionChooser(GameTeam towerTeam, GameWorld world) {
-			int[] dx = { -1, 0, 0, 1 };
-			int[] dy = { 0, 1, -1, 0 };
+			int[] dx = {-1, 0, 0, 1};
+			int[] dy = {0, 1, -1, 0};
 			foreach (Barrack barrack in world.Overview.GetEnemyTeam(towerTeam).Barracks) {
 				bool any = false;
 				for (int i = 0; i < 4 && !any; i++) {
@@ -244,8 +243,8 @@ public class UnitTowerCastleIntegrationTest {
 		GameTeam towerTeam = overview.GetEnemyTeam(unitTeam);
 
 		//Purchase a unit
-		GameTestUtils.UnitTypeData unitType = new GameTestUtils.UnitTypeData { Health = unitHealth };
-		Assert.IsTrue(overview.Commands.Issue(new PurchaseUnitCommand(unitTeam, unitType)));
+		GameTestUtils.UnitTypeData unitType = new GameTestUtils.UnitTypeData {Health = unitHealth};
+		overview.Teams.First().Barracks.First().QueueUnit(unitType);
 
 		//Build a tower
 		GameTestUtils.TowerTypeData towerType = new GameTestUtils.TowerTypeData {
@@ -265,5 +264,4 @@ public class UnitTowerCastleIntegrationTest {
 		return overview;
 	}
 }
-
 }
diff --git a/Assets/Scripts/Presentation/World/Config/WorldConfig.cs b/Assets/Scripts/Presentation/World/Config/WorldConfig.cs
index b335f127a47aa336e92edd40bb838849d5d56b1d..6468b1ea1a000076bcf86b7a80a6a38b905c16a6 100644
--- a/Assets/Scripts/Presentation/World/Config/WorldConfig.cs
+++ b/Assets/Scripts/Presentation/World/Config/WorldConfig.cs
@@ -41,6 +41,10 @@ public class WorldConfig : ScriptableObject, IGameWorldConfig {
 	[Min(0)]
 	private int maxBuildingDistance;
 
+	[SerializeField]
+	[Min(0.01f)]
+	private float barrackSpawnTimeOffset;
+
 	[NonSerialized]
 	private int _height;
 
@@ -65,5 +69,6 @@ public class WorldConfig : ScriptableObject, IGameWorldConfig {
 	public float CastleStartingHealth => castleStartingHealth;
 	public int MaxBuildingDistance => maxBuildingDistance;
 	public bool GenerateObstacles => true;
+	public float BarrackSpawnTimeOffset => barrackSpawnTimeOffset;
 }
 }
diff --git a/Assets/World/Config/WorldConfig.asset b/Assets/World/Config/WorldConfig.asset
index 7651735645f268ccae500a512ff4d243cce3253c..27342230d020d9e80091f2d1cc8f7e21dc867768 100644
--- a/Assets/World/Config/WorldConfig.asset
+++ b/Assets/World/Config/WorldConfig.asset
@@ -19,3 +19,4 @@ MonoBehaviour:
   barrackSpawnCooldownTime: 0.6
   castleStartingHealth: 10
   maxBuildingDistance: 3
+  barrackSpawnOffset: 0.1