This code is intended to train a 10 spearman defense force (the "defenders" role does nothing, it's just there as a placeholder really) as top priority, then cycle round spears then javelins. Depending on a strategy which is chosen at random, it then either counts to ten and sends a raiding force or forty for a full-on assault. Almost needless to say, this does not happen. The defense force is generally larger than it should be, and once it is trained the attack forces are entirely made of javelinmen. It also seems to do a lot more full-scale assaults than probability would dictate. I'm not sure if after it goes onto training javelins it will then go back to training defenders if I kill some, though it should do in theory. Any help much appreciated...   var MilitaryAttackManager = Class({  	_init: function() 	{ 		this.targetSquadSize = 20; 		this.findatype = 1; 		this.squadTypes = [ 			"units/{civ}_infantry_spearman_b", 			"units/{civ}_infantry_javelinist_b", //			"units/{civ}_infantry_archer_b", // TODO: should only include this if hele 		]; 	},  	/** 	 * Returns the unit type we should begin training. 	 * (Currently this is whatever we have least of.) 	 */ 	findBestNewUnit: function(gameState) 	{ 		// Count each type 		var types = []; 		for each (var t in this.squadTypes) 			types.push([t, gameState.countEntitiesAndQueuedWithType(t)]);  		// Sort by increasing count 		types.sort(function (a,  { return a[1] - b[1]; });  		// TODO: we shouldn't return units that we don't have any 		// buildings capable of training 		// Let's make this shizz random... 		var randomiser = Math.floor(Math.random()*types.length); 		return types[0][0]; 	},  	update: function(gameState, planGroups) 	{ 		// Pause for a minute before starting any work, to give the economy a chance 		// to start up 		if (gameState.getTimeElapsed() < 60*1000) 			return;  		Engine.ProfileStart("military update"); 		// Also train up some defenders 		var pendingdefense = gameState.getOwnEntitiesWithRole("defenders"); 		if (pendingdefense.length <= 10){ 			planGroups.economyPersonnel.addPlan(110, 				new UnitTrainingPlan(gameState, 					"units/{civ}_infantry_spearman_b", 5, { "role": "defenders" }) 			); 			} 		// Continually try training new units, in batches of 5 		//planGroups.militaryPersonnel.addPlan(100, 		//	new UnitTrainingPlan(gameState, 		//		this.findBestNewUnit(gameState), 5, { "role": "attack-pending" }) 		//); 		//this.chat("Hmm, let's pick a number. I think " + findatype + " sounds good."); 			if (this.findatype == 1){ 			planGroups.economyPersonnel.addPlan(100, 				new UnitTrainingPlan(gameState, 					"units/{civ}_infantry_spearman_b", 5, { "role": "attack-pending" }) 			); 			this.findatype = 0; 			} 			else { 			planGroups.economyPersonnel.addPlan(100, 				new UnitTrainingPlan(gameState, 					"units/{civ}_infantry_javelinist_b", 5, { "role": "attack-pending" }) 			); 			this.findatype = 1; 			}  		// Find the units ready to join the attack 		var pending = gameState.getOwnEntitiesWithRole("attack-pending"); // Variable for impetuousness, so squads vary in size. 		if (this.killstrat == 1){ 		this.baserate = 41; 		} 		else { 		this.baserate = 11; 		} 		// If we have enough units yet, start the attack 		if (pending.length >= this.baserate) 		{ 			// Find the enemy CCs we could attack 			var targets = gameState.entities.filter(function(ent) { 				return (ent.isEnemy() && ent.hasClass("CivCentre")); 			});  			// If there's no CCs, attack anything else that's critical 			if (targets.length == 0) 			{ 				targets = gameState.entities.filter(function(ent) { 					return (ent.isEnemy() && ent.hasClass("ConquestCritical")); 				}); 			}  			// If we have a target, move to it 			if (targets.length) 			{ 				// Remove the pending role 				pending.forEach(function(ent) { 					ent.setMetadata("role", "attack"); 				});  				var target = targets.toEntityArray()[0]; 				var targetPos = target.position();  				// TODO: this should be an attack-move command 				pending.move(targetPos[0], targetPos[1]); 			} 			//Now set whether to do a raid or full attack next time 			var whatnext = Math.random(); 			if (whatnext > 0.25){ 			this.killstrat = 0; 			} 			else { 			this.killstrat = 1; 			} 		}  		Engine.ProfileStop(); 	},  });