Index: binaries/data/mods/public/simulation/components/TrainingQueue.js
===================================================================
--- binaries/data/mods/public/simulation/components/TrainingQueue.js	(revision 7866)
+++ binaries/data/mods/public/simulation/components/TrainingQueue.js	(working copy)
@@ -19,7 +19,7 @@
 TrainingQueue.prototype.Init = function()
 {
     this.nextID = 1;
-
+    this.popReserve = 0;
 	this.queue = [];
 	// Queue items are:
 	//   {
@@ -46,6 +46,24 @@
 	return string.split(/\s+/);
 };
 
+TrainingQueue.prototype.GetPlayer = function()
+{
+	var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
+	var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
+	var playerEnt = cmpPlayerMan.GetPlayerByID(cmpOwnership.GetOwner());
+	return Engine.QueryInterface(playerEnt, IID_Player);
+};
+
+TrainingQueue.prototype.ReservePopulationSlots = function(num)
+{
+	this.popReserve += num;
+};
+
+TrainingQueue.prototype.UnReservePopulationSlots = function(num)
+{
+	this.popReserve -= Math.min(num, this.popReserve);
+};
+
 TrainingQueue.prototype.AddBatch = function(player, templateName, count)
 {
 	// TODO: there should probably be a limit on the number of queued batches
@@ -70,11 +88,17 @@
 		else
 			costs[r] = 0;
 	}
+	var population;
+	if(template.Cost.Population)
+	{
+		population = template.Cost.Population * count;
+	}
+	else
+	{
+		population = 0;
+	}
 
-	// Find the player
-	var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
-	var playerEnt = cmpPlayerMan.GetPlayerByID(player);
-	var cmpPlayer = Engine.QueryInterface(playerEnt, IID_Player);
+	var cmpPlayer = this.GetPlayer();
 
 	if (!cmpPlayer.TrySubtractResources(costs))
 	{
@@ -82,11 +106,14 @@
 		return;
 	}
 
+	
 	this.queue.push({
 		"id": this.nextID++,
 		"template": templateName,
 		"count": count,
 		"resources": costs,
+		"population": population,
+		"trainingStarted": false,
 		"timeTotal": time*1000,
 		"timeRemaining": time*1000,
 	});
@@ -109,20 +136,26 @@
 
 		// Now we've found the item to remove
 
-		// Find the player
-		var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
-		var playerEnt = cmpPlayerMan.GetPlayerByID(player);
-		var cmpPlayer = Engine.QueryInterface(playerEnt, IID_Player);
+		var cmpPlayer = this.GetPlayer();
 
 		// Refund the resource cost for this batch
 		cmpPlayer.AddResources(item.resources);
-
+		
+		//Remove reserved population slots
+		if (item.trainingStarted)
+		{
+			//The batch's training has started. It will have 
+			//population slots reserved for it
+			cmpPlayer.UnReservePopulationSlots(item.population);
+			this.UnReservePopulationSlots(item.population);
+		}
+		
 		// Remove from the queue
 		// (We don't need to remove the timer - it'll expire if it discovers the queue is empty)
 		this.queue.splice(i, 1);
 		return;
 	}
-}
+};
 
 TrainingQueue.prototype.GetQueue = function()
 {
@@ -139,12 +172,35 @@
 	return out;
 };
 
+TrainingQueue.prototype.OnOwnershipChanged = function(msg)
+{
+	var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
+	if (msg.from != -1)
+	{
+		//if msg.from==-1, Building has just been created,
+		//so there will be no need to remove reserved slots
+		var fromPlayerEnt = cmpPlayerMan.GetPlayerByID(msg.from);
+		var cmpFromPlayer = Engine.QueryInterface(fromPlayerEnt, IID_Player);
+		//Remove reserved slots from the original owner
+		cmpFromPlayer.UnReservePopulationSlots(this.popReserve);
+	}
+	if (msg.to != -1)
+	{
+		//if msg.to==-1, Building has been destroyed,
+		//so there will be no need to reserve slots
+		var toPlayerEnt = cmpPlayerMan.GetPlayerByID(msg.to);
+		var cmpToPlayer = Engine.QueryInterface(toPlayerEnt, IID_Player);
+		//Reserve slots in new owner
+		cmpToPlayer.ReservePopulationSlots(this.popReserve);
+	}
+	
+};
+
 TrainingQueue.prototype.OnDestroy = function()
 {
 	// If the building is destroyed while it's got a large training queue,
 	// you lose all the resources invested in that queue. That'll teach you
 	// to be so reckless with your buildings.
-
 	if (this.timer)
 	{
 		var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
@@ -163,7 +219,6 @@
 	for (var i = 0; i < count; ++i)
 	{
 		var ent = Engine.AddEntity(templateName);
-
 		var pos = cmpFootprint.PickSpawnPoint(ent);
 		if (pos.y < 0)
 		{
@@ -198,14 +253,30 @@
 	// until we've used up all the time (so that we work accurately
 	// with items that take fractions of a second)
 	var time = g_ProgressInterval;
-
+	var cmpPlayer = this.GetPlayer();
+	
 	time *= 10; // XXX: this is a hack to make testing easier
-
 	while (time > 0 && this.queue.length)
 	{
 		var item = this.queue[0];
-		if (item.timeRemaining > time)
+		if (!item.trainingStarted)
 		{
+			//Batch's training hasn't started yet
+			var popSlotsAvail = cmpPlayer.GetPopulationLimit() - cmpPlayer.GetPopulationCount();
+			if (popSlotsAvail >= item.population)
+			{
+				//Slots available;
+				//Reserve those slots
+				this.ReservePopulationSlots(item.population);
+				cmpPlayer.ReservePopulationSlots(item.population);
+				//Start Training
+				item.timeRemaining -= time;
+				item.trainingStarted = true;
+			}
+			break;
+		}
+		else if (item.timeRemaining > time)
+		{
 			item.timeRemaining -= time;
 			break;
 		}
@@ -213,6 +284,9 @@
 		// This item is finished now
 		time -= item.timeRemaining;
 		this.SpawnUnits(item.template, item.count);
+		//Unit has been created. Remove reserved spots
+		cmpPlayer.UnReservePopulationSlots(item.population);
+		this.UnReservePopulationSlots(item.population);
 		this.queue.shift();
 	}
 
Index: binaries/data/mods/public/simulation/components/Player.js
===================================================================
--- binaries/data/mods/public/simulation/components/Player.js	(revision 7866)
+++ binaries/data/mods/public/simulation/components/Player.js	(working copy)
@@ -10,7 +10,8 @@
 	this.civ = "gaia";
 	this.colour = { "r": 0.0, "g": 0.0, "b": 0.0, "a": 1.0 };
 	this.popCount = 0;
-	this.popLimit = 50;
+	this.popLimit = 0;
+	this.popReserve = 0;
 	this.resourceCount = {
 		"food": 2000,	
 		"wood": 1500,	
@@ -54,9 +55,19 @@
 	return this.colour;
 };
 
+Player.prototype.ReservePopulationSlots = function(num)
+{
+	this.popReserve += num;
+};
+
+Player.prototype.UnReservePopulationSlots = function(num)
+{
+	this.popReserve -= Math.min(num, this.popReserve);
+}
+
 Player.prototype.GetPopulationCount = function()
 {
-	return this.popCount;
+	return this.popCount + this.popReserve;
 };
 
 Player.prototype.GetPopulationLimit = function()

