Index: binaries/data/mods/public/simulation/ai/aegis/base-manager.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/base-manager.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/base-manager.js	(Arbeitskopie)
@@ -1,3 +1,5 @@
+var AEGIS = function(m)
+{
 /* Base Manager
  * Handles lower level economic stuffs.
  * Some tasks:
@@ -10,9 +12,10 @@
 	-updating whatever needs updating, keeping track of stuffs (rebuilding needs…)
  */
 
-var BaseManager = function() {
+m.BaseManager = function(Config) {
+	this.Config = Config;
 	this.farmingFields = false;
-	this.ID = uniqueIDBases++;
+	this.ID = m.playerGlobals[PlayerID].uniqueIDBases++;
 	
 	// anchor building: seen as the main building of the base. Needs to have territorial influence
 	this.anchor = undefined;
@@ -31,13 +34,13 @@
 	this.territoryIndices = [];
 };
 
-BaseManager.prototype.init = function(gameState, events, unconstructed){
+m.BaseManager.prototype.init = function(gameState, events, unconstructed){
 	this.constructing = unconstructed;
 	// entitycollections
-	this.units = gameState.getOwnEntities().filter(Filters.and(Filters.byClass("Unit"),Filters.byMetadata(PlayerID, "base", this.ID)));
-	this.buildings = gameState.getOwnEntities().filter(Filters.and(Filters.byClass("Structure"),Filters.byMetadata(PlayerID, "base", this.ID)));
+	this.units = gameState.getOwnEntities().filter(API3.Filters.and(API3.Filters.byClass("Unit"),API3.Filters.byMetadata(PlayerID, "base", this.ID)));
+	this.buildings = gameState.getOwnEntities().filter(API3.Filters.and(API3.Filters.byClass("Structure"),API3.Filters.byMetadata(PlayerID, "base", this.ID)));
 	
-	this.workers = this.units.filter(Filters.byMetadata(PlayerID,"role","worker"));
+	this.workers = this.units.filter(API3.Filters.byMetadata(PlayerID,"role","worker"));
 
 	this.workers.allowQuickIter();
 	this.buildings.allowQuickIter();
@@ -62,7 +65,7 @@
 	this.bigRadius = { 'food':70*70,'wood':200*200,'stone':200*200,'metal':200*200 };
 };
 
-BaseManager.prototype.assignEntity = function(unit){
+m.BaseManager.prototype.assignEntity = function(unit){
 	unit.setMetadata(PlayerID, "base", this.ID);
 	this.units.updateEnt(unit);
 	this.workers.updateEnt(unit);
@@ -73,7 +76,7 @@
 		this.territoryBuildings.push(unit.id());
 };
 
-BaseManager.prototype.setAnchor = function(anchorEntity) {
+m.BaseManager.prototype.setAnchor = function(anchorEntity) {
 	if (!anchorEntity.hasClass("Structure") || !anchorEntity.hasTerritoryInfluence())
 	{
 		warn("Error: Aegis' base " + this.ID + " has been assigned an anchor building that has no territorial influence. Please report this on the forum.")
@@ -90,7 +93,7 @@
 }
 
 // affects the HQ map.
-BaseManager.prototype.initTerritory = function(HQ, gameState) {
+m.BaseManager.prototype.initTerritory = function(HQ, gameState) {
 	if (!this.anchor)
 		warn ("Error: Aegis tried to initialize the territory of base " + this.ID + " without assigning it an anchor building first");
 	var radius = Math.round((this.anchor.territoryInfluenceRadius() / 4.0) * 1.25);
@@ -122,7 +125,7 @@
 			}
 }
 
-BaseManager.prototype.initGatheringFunctions = function(HQ, gameState, specTypes) {
+m.BaseManager.prototype.initGatheringFunctions = function(HQ, gameState, specTypes) {
 	// init our gathering functions.
 	var types = ["food","wood","stone","metal"];
 	if (specTypes !== undefined)
@@ -136,7 +139,7 @@
 		var type = types[i];
 		// TODO: set us as "X" gatherer
 		
-		this.buildings.filter(Filters.isDropsite(type)).forEach(function(ent) { self.initializeDropsite(gameState, ent,type) });
+		this.buildings.filter(API3.Filters.isDropsite(type)).forEach(function(ent) { self.initializeDropsite(gameState, ent,type) });
 
 		if (this.getResourceLevel(gameState, type, "all") > 1000)
 			this.willGather[type] = 1;
@@ -151,13 +154,13 @@
 		if (needFarm)
 			this.willGather["food"] = 1;
 	}
-	debug ("food" + this.willGather["food"]);
-	debug (this.willGather["wood"]);
-	debug (this.willGather["stone"]);
-	debug (this.willGather["metal"]);
+	m.debug ("food" + this.willGather["food"]);
+	m.debug (this.willGather["wood"]);
+	m.debug (this.willGather["stone"]);
+	m.debug (this.willGather["metal"]);
 }
 
-BaseManager.prototype.checkEvents = function (gameState, events, queues) {
+m.BaseManager.prototype.checkEvents = function (gameState, events, queues) {
 	for (i in events)
 	{
 		if (events[i].type == "Destroy")
@@ -185,10 +188,10 @@
 					if (ent.hasClass("CivCentre"))
 					{
 						// TODO: might want to tell the queue manager to pause other stuffs if we are the only base.
-						queues.civilCentre.addItem(new ConstructionPlan(gameState, "structures/{civ}_civil_centre", { "base" : this.ID, "baseAnchor" : true }, 0 , -1,ent.position()));
+						queues.civilCentre.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_civil_centre", { "base" : this.ID, "baseAnchor" : true }, 0 , -1,ent.position()));
 					} else {
 						// TODO
-						queues.civilCentre.addItem(new ConstructionPlan(gameState, "structures/{civ}_civil_centre", { "base" : this.ID, "baseAnchor" : true },0,-1,ent.position()));
+						queues.civilCentre.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_civil_centre", { "base" : this.ID, "baseAnchor" : true },0,-1,ent.position()));
 					}
 				}
 			}
@@ -238,7 +241,7 @@
 };
 
 // If no specific dropsite, it'll assign to the closest
-BaseManager.prototype.assignResourceToDP = function (gameState, supply, specificDP) {
+m.BaseManager.prototype.assignResourceToDP = function (gameState, supply, specificDP) {
 	var type = supply.resourceSupplyType()["generic"];
 	if (type == "treasure")
 		type = supply.resourceSupplyType()["specific"];
@@ -249,7 +252,7 @@
 		for (i in this.dropsites)
 		{
 			var dp = gameState.getEntityById(i);
-			var distance = SquareVectorDistance(supply.position(), dp.position());
+			var distance = API3.SquareVectorDistance(supply.position(), dp.position());
 			if (distance < dist && distance < this.bigRadius[type])
 			{
 				closest = dp.id();
@@ -267,7 +270,7 @@
 	// TODO: ought to recount immediatly.
 }
 
-BaseManager.prototype.initializeDropsite = function (gameState, ent, type) {
+m.BaseManager.prototype.initializeDropsite = function (gameState, ent, type) {
 	var count = 0, farCount = 0;
 	var self = this;
 
@@ -278,7 +281,7 @@
 		resources.filter( function (supply) { //}){
 			if (!supply.position() || !ent.position())
 				return;
-			var distance = SquareVectorDistance(supply.position(), ent.position());
+			var distance = API3.SquareVectorDistance(supply.position(), ent.position());
 			
 			if (supply.getMetadata(PlayerID, "linked-dropsite") == undefined || supply.getMetadata(PlayerID, "linked-dropsite-dist") > distance) {
 				if (distance < self.bigRadius[type]) {
@@ -294,19 +297,19 @@
 			}
 		});
 		// This one is both for the nearby and the linked
-		var filter = Filters.byMetadata(PlayerID, "linked-dropsite", ent.id());
+		var filter = API3.Filters.byMetadata(PlayerID, "linked-dropsite", ent.id());
 		var collection = resources.filter(filter);
 		collection.registerUpdates();
 		
-		filter = Filters.byMetadata(PlayerID, "linked-dropsite-close",true);
+		filter = API3.Filters.byMetadata(PlayerID, "linked-dropsite-close",true);
 		var collection2 = collection.filter(filter);
 		collection2.registerUpdates();
 
-		filter = Filters.byMetadata(PlayerID, "linked-dropsite-nearby",true);
+		filter = API3.Filters.byMetadata(PlayerID, "linked-dropsite-nearby",true);
 		var collection3 = collection.filter(filter);
 		collection3.registerUpdates();
 
-		filter = Filters.byMetadata(PlayerID, "linked-to-dropsite", ent.id());
+		filter = API3.Filters.byMetadata(PlayerID, "linked-to-dropsite", ent.id());
 		var WkCollection = this.workers.filter(filter);
 		WkCollection.registerUpdates();
 		
@@ -318,51 +321,51 @@
 		// TODO: get workers on those resources and do something with them.
 	}
 	
-	if (Config.debug)
+	if (this.Config.debug)
 	{
 		// Make resources glow wildly
 		if (type == "food") {
 			self.dropsites[ent.id()][type][2].forEach(function(ent){ 
-				Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [0.5,0,0]});
+				Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent.id()], "rgb": [0.5,0,0]});
 			});
 			self.dropsites[ent.id()][type][1].forEach(function(ent){
-				Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [2,0,0]});
+				Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent.id()], "rgb": [2,0,0]});
 			});
 			self.dropsites[ent.id()][type][0].forEach(function(ent){
-				Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [10,0,0]});
+				Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent.id()], "rgb": [10,0,0]});
 			});
 		}
 		if (type == "wood") {
 			self.dropsites[ent.id()][type][2].forEach(function(ent){
-				Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,0.5,0]});
+				Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,0.5,0]});
 			});
 			self.dropsites[ent.id()][type][1].forEach(function(ent){
-				Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,2,0]});
+				Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,2,0]});
 			});
 			self.dropsites[ent.id()][type][0].forEach(function(ent){
-				Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,10,0]});
+				Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,10,0]});
 			});
 		}
 		if (type == "stone") {
 			self.dropsites[ent.id()][type][2].forEach(function(ent){
-				Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [0.5,0.5,0]});
+				Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent.id()], "rgb": [0.5,0.5,0]});
 			});
 			self.dropsites[ent.id()][type][1].forEach(function(ent){
-				Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [2,2,0]});
+				Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent.id()], "rgb": [2,2,0]});
 			});
 			self.dropsites[ent.id()][type][0].forEach(function(ent){
-				Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [10,10,0]});
+				Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent.id()], "rgb": [10,10,0]});
 			});
 		}
 		if (type == "metal") {
 			self.dropsites[ent.id()][type][2].forEach(function(ent){
-				Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,0.5,0.5]});
+				Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,0.5,0.5]});
 			});
 			self.dropsites[ent.id()][type][1].forEach(function(ent){
-				Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,2,2]});
+				Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,2,2]});
 			});
 			self.dropsites[ent.id()][type][0].forEach(function(ent){
-				Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,10,10]});
+				Engine.PostCommand(PlayerID,{"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,10,10]});
 			});
 		}
 	}
@@ -371,7 +374,7 @@
 // completely and "safely" remove a dropsite from our list.
 // this also removes any linked resource and so on.
 // TODO: should re-add the resources to another dropsite.
-BaseManager.prototype.scrapDropsite = function (gameState, ent) {
+m.BaseManager.prototype.scrapDropsite = function (gameState, ent) {
 	if (this.dropsites[ent.id()] === undefined)
 		return true;
 	
@@ -398,7 +401,7 @@
 };
 
 // Returns the position of the best place to build a new dropsite for the specified resource
-BaseManager.prototype.findBestDropsiteLocation = function(gameState, resource){
+m.BaseManager.prototype.findBestDropsiteLocation = function(gameState, resource){
 	
 	var storeHousePlate = gameState.getTemplate(gameState.applyCiv("structures/{civ}_storehouse"));
 
@@ -407,15 +410,15 @@
 	// Then checks for a good spot in the territory. If none, and town/city phase, checks outside
 	// The AI will currently not build a CC if it wouldn't connect with an existing CC.
 	
-	var territory = Map.createTerritoryMap(gameState);
+	var territory = m.createTerritoryMap(gameState);
 	
-	var obstructions = Map.createObstructionMap(gameState,this.accessIndex,storeHousePlate);
+	var obstructions = m.createObstructionMap(gameState,this.accessIndex,storeHousePlate);
 	obstructions.expandInfluences();
 	
 	// copy the resource map as initialization.
-	var friendlyTiles = new Map(gameState.sharedScript, gameState.sharedScript.resourceMaps[resource].map, true);
+	var friendlyTiles = new API3.Map(gameState.sharedScript, gameState.sharedScript.resourceMaps[resource].map, true);
 
-	var DPFoundations = gameState.getOwnFoundations().filter(Filters.byType(gameState.applyCiv("foundation|structures/{civ}_storehouse")));
+	var DPFoundations = gameState.getOwnFoundations().filter(API3.Filters.byType(gameState.applyCiv("foundation|structures/{civ}_storehouse")));
 	
 	// TODO: might be better to check dropsites someplace else.
 	// loop over this in this.terrytoryindices. It's usually a little too much, but it's always enough.
@@ -434,25 +437,25 @@
 		{
 			var pos = [j%friendlyTiles.width, Math.floor(j/friendlyTiles.width)];
 			var dpPos = gameState.getEntityById(i).position();
-			if (dpPos && SquareVectorDistance(friendlyTiles.gamePosToMapPos(dpPos), pos) < 250)
+			if (dpPos && API3.SquareVectorDistance(friendlyTiles.gamePosToMapPos(dpPos), pos) < 250)
 			{
 				friendlyTiles.map[j] = 0;
 				continue;
-			} else if (dpPos && SquareVectorDistance(friendlyTiles.gamePosToMapPos(dpPos), pos) < 450)
+			} else if (dpPos && API3.SquareVectorDistance(friendlyTiles.gamePosToMapPos(dpPos), pos) < 450)
 				friendlyTiles.map[j] /= 2;
 		}
 		for (var i in DPFoundations._entities)
 		{
 			var pos = [j%friendlyTiles.width, Math.floor(j/friendlyTiles.width)];
 			var dpPos = gameState.getEntityById(i).position();
-			if (dpPos && SquareVectorDistance(friendlyTiles.gamePosToMapPos(dpPos), pos) < 250)
+			if (dpPos && API3.SquareVectorDistance(friendlyTiles.gamePosToMapPos(dpPos), pos) < 250)
 				friendlyTiles.map[j] = 0;
-			else if (dpPos && SquareVectorDistance(friendlyTiles.gamePosToMapPos(dpPos), pos) < 450)
+			else if (dpPos && API3.SquareVectorDistance(friendlyTiles.gamePosToMapPos(dpPos), pos) < 450)
 				friendlyTiles.map[j] /= 2;
 		}
 	}
 	
-	if (Config.debug)
+	if (this.Config.debug)
 		friendlyTiles.dumpIm("DP_" + resource + "_" + gameState.getTimeElapsed() + ".png");
 	
 	var best = friendlyTiles.findBestTile(2, obstructions);	// try to find a spot to place a DP.
@@ -469,7 +472,7 @@
 };
 
 // update the resource level of a dropsite.
-BaseManager.prototype.updateDropsite = function (gameState, ent, type) {
+m.BaseManager.prototype.updateDropsite = function (gameState, ent, type) {
 	if (this.dropsites[ent.id()] === undefined || this.dropsites[ent.id()][type] === undefined)
 		return undefined;	// should initialize it first.
 
@@ -490,7 +493,7 @@
 };
 
 // Updates dropsites.
-BaseManager.prototype.updateDropsites = function (gameState) {
+m.BaseManager.prototype.updateDropsites = function (gameState) {
 	// for each dropsite, recalculate
 	for (i in this.dropsites)
 	{
@@ -507,7 +510,7 @@
 // we're assuming Max - 3 for metal/stone mines, and 20 for any dropsite that has wood.
 // TODO: for wood might want to count the trees too.
 // TODO: this returns "future" worker capacity, might want to have a current one.
-BaseManager.prototype.getWorkerCapacity = function (gameState, type) {
+m.BaseManager.prototype.getWorkerCapacity = function (gameState, type) {
 	var count = 0;
 	if (type == "food")
 		return 1000000;	// TODO: perhaps return something sensible here.
@@ -530,12 +533,12 @@
 
 // TODO: ought to be cached or something probably
 // Returns the amount of resource left
-BaseManager.prototype.getResourceLevel = function (gameState, type, searchType, threshold) {
+m.BaseManager.prototype.getResourceLevel = function (gameState, type, searchType, threshold) {
 	var count = 0;
 	if (searchType == "all")
 	{
 		// return all resources in the base area.
-		gameState.getResourceSupplies(type).filter(Filters.byTerritory(gameState.ai.HQ.basesMap, this.ID)).forEach( function (ent) { //}){
+		gameState.getResourceSupplies(type).filter(API3.Filters.byTerritory(gameState.ai.HQ.basesMap, this.ID)).forEach( function (ent) { //}){
 			count += ent.resourceSupplyAmount();
 		});
 		return count;
@@ -574,7 +577,7 @@
 };
 
 // check our resource levels and react accordingly
-BaseManager.prototype.checkResourceLevels = function (gameState,queues) {
+m.BaseManager.prototype.checkResourceLevels = function (gameState,queues) {
 	for (type in this.willGather)
 	{
 		if (this.willGather[type] === 0)
@@ -589,9 +592,9 @@
 			if (!this.isFarming && count < 1600 && queues.field.length === 0)
 			{
 				// tell the queue manager we'll be trying to build fields shortly.
-				for (var  i = 0; i < Config.Economy.initialFields;++i)
+				for (var  i = 0; i < this.Config.Economy.initialFields;++i)
 				{
-					var plan = new ConstructionPlan(gameState, "structures/{civ}_field", { "base" : this.ID });
+					var plan = new m.ConstructionPlan(gameState, "structures/{civ}_field", { "base" : this.ID });
 					plan.isGo = function() { return false; };	// don't start right away.
 					queues.field.addItem(plan);
 				}
@@ -604,7 +607,7 @@
 			if (this.isFarming)
 			{
 				var numFarms = 0;
-				this.buildings.filter(Filters.byClass("Field")).forEach(function (field) {
+				this.buildings.filter(API3.Filters.byClass("Field")).forEach(function (field) {
 					if (field.resourceSupplyAmount() > 400)
 						numFarms++;
 				});
@@ -615,7 +618,7 @@
 				// let's see if we need to push new farms.
 				if (numFd < 2)
 					if (numFarms < Math.round(this.gatherersByType(gameState, "food").length / 4.6) || numFarms < Math.round(this.workers.length / 15.0))
-						queues.field.addItem(new ConstructionPlan(gameState, "structures/{civ}_field", { "base" : this.ID }));
+						queues.field.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_field", { "base" : this.ID }));
 				// TODO: refine count to only count my base.
 			}
 		} else if (queues.dropsites.length() === 0 && gameState.countFoundationsWithType(gameState.applyCiv("structures/{civ}_storehouse")) === 0) {
@@ -626,12 +629,12 @@
 				var pos = this.findBestDropsiteLocation(gameState, type);
 				if (!pos)
 				{
-					debug ("Found no right position for a " + type + " dropsite, going into \"noSpot\" mode");
+					m.debug ("Found no right position for a " + type + " dropsite, going into \"noSpot\" mode");
 					this.willGather[type] = 2;	// won't build
 					// TODO: tell the HQ we'll be needing a new base for this resource, or tell it we've ran out of resource Z.
 				} else {
-					debug ("planning new dropsite for " + type);
-					queues.dropsites.addItem(new ConstructionPlan(gameState, "structures/{civ}_storehouse",{ "base" : this.ID }, 0, -1, pos));
+					m.debug ("planning new dropsite for " + type);
+					queues.dropsites.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_storehouse",{ "base" : this.ID }, 0, -1, pos));
 				}
 			}
 		}
@@ -640,13 +643,13 @@
 };
 
 // let's return the estimated gather rates.
-BaseManager.prototype.getGatherRates = function(gameState, currentRates) {
+m.BaseManager.prototype.getGatherRates = function(gameState, currentRates) {
 
 };
 
-BaseManager.prototype.assignRolelessUnits = function(gameState) {
+m.BaseManager.prototype.assignRolelessUnits = function(gameState) {
 	// TODO: make this cleverer.
-	var roleless = this.units.filter(Filters.not(Filters.byHasMetadata(PlayerID, "role")));
+	var roleless = this.units.filter(API3.Filters.not(API3.Filters.byHasMetadata(PlayerID, "role")));
 	var self = this;
 	roleless.forEach(function(ent) {
 		if (ent.hasClass("Worker") || ent.hasClass("CitizenSoldier")) {
@@ -660,7 +663,7 @@
 // If the numbers of workers on the resources is unbalanced then set some of workers to idle so
 // they can be reassigned by reassignIdleWorkers.
 // TODO: actually this probably should be in the HQ.
-BaseManager.prototype.setWorkersIdleByPriority = function(gameState){
+m.BaseManager.prototype.setWorkersIdleByPriority = function(gameState){
 	var self = this;
 	if (gameState.currentPhase() < 2 && gameState.getTimeElapsed() < 360000)
 		return;	// not in the first phase or the first 6 minutes.
@@ -685,7 +688,7 @@
 				this.gatherersByType(gameState,types.types[i]).forEach( function (ent) { //}){
 					if (nb > 0)
 					{
-						//debug ("Moving " +ent.id() + " from " + types.types[i]);
+						//m.debug ("Moving " +ent.id() + " from " + types.types[i]);
 						nb--;
 						// TODO: might want to direct assign.
 						ent.stopMoving();
@@ -693,16 +696,16 @@
 					}
 				});
 			}
-	//debug (currentRates);
+	//m.debug (currentRates);
 };
 
 // TODO: work on this.
-BaseManager.prototype.reassignIdleWorkers = function(gameState) {
+m.BaseManager.prototype.reassignIdleWorkers = function(gameState) {
 	
 	var self = this;
 
 	// Search for idle workers, and tell them to gather resources based on demand
-	var filter = Filters.or(Filters.byMetadata(PlayerID,"subrole","idle"), Filters.not(Filters.byHasMetadata(PlayerID,"subrole")));
+	var filter = API3.Filters.or(API3.Filters.byMetadata(PlayerID,"subrole","idle"), API3.Filters.not(API3.Filters.byHasMetadata(PlayerID,"subrole")));
 	var idleWorkers = gameState.updatingCollection("idle-workers-base-" + this.ID, filter, this.workers);
 
 	if (idleWorkers.length) {
@@ -713,7 +716,7 @@
 			}
 			if (ent.hasClass("Worker")) {
 				var types = gameState.ai.HQ.pickMostNeededResources(gameState);
-				//debug ("assigning " +ent.id() + " to " + types[0]);
+				//m.debug ("assigning " +ent.id() + " to " + types[0]);
 				ent.setMetadata(PlayerID, "subrole", "gatherer");
 				ent.setMetadata(PlayerID, "gather-type", types[0]);
 				
@@ -734,21 +737,21 @@
 	}
 };
 
-BaseManager.prototype.workersBySubrole = function(gameState, subrole) {
-	return gameState.updatingCollection("subrole-" + subrole +"-base-" + this.ID, Filters.byMetadata(PlayerID, "subrole", subrole), this.workers, true);
+m.BaseManager.prototype.workersBySubrole = function(gameState, subrole) {
+	return gameState.updatingCollection("subrole-" + subrole +"-base-" + this.ID, API3.Filters.byMetadata(PlayerID, "subrole", subrole), this.workers, true);
 };
 
-BaseManager.prototype.gatherersByType = function(gameState, type) {
-	return gameState.updatingCollection("workers-gathering-" + type +"-base-" + this.ID, Filters.byMetadata(PlayerID, "gather-type", type), this.workersBySubrole(gameState, "gatherer"));
+m.BaseManager.prototype.gatherersByType = function(gameState, type) {
+	return gameState.updatingCollection("workers-gathering-" + type +"-base-" + this.ID, API3.Filters.byMetadata(PlayerID, "gather-type", type), this.workersBySubrole(gameState, "gatherer"));
 };
 
 
 // returns an entity collection of workers.
 // They are idled immediatly and their subrole set to idle.
-BaseManager.prototype.pickBuilders = function(gameState, number) {
-	var collec = new EntityCollection(gameState.sharedScript);
+m.BaseManager.prototype.pickBuilders = function(gameState, number) {
+	var collec = new API3.EntityCollection(gameState.sharedScript);
 	// TODO: choose better.
-	var workers = this.workers.filter(Filters.not(Filters.byClass("Cavalry"))).toEntityArray();
+	var workers = this.workers.filter(API3.Filters.not(API3.Filters.byClass("Cavalry"))).toEntityArray();
 	workers.sort(function (a,b) {
 		var vala = 0, valb = 0;
 		if (a.getMetadata(PlayerID,"subrole") == "builder")
@@ -770,7 +773,8 @@
 	return collec;
 }
 
-BaseManager.prototype.assignToFoundations = function(gameState, noRepair) {
+m.BaseManager.prototype.assignToFoundations = function(gameState, noRepair) {
+
 	// If we have some foundations, and we don't have enough builder-workers,
 	// try reassigning some other workers who are nearby
 	
@@ -778,21 +782,21 @@
 	
 	var self = this;
 	
-	var foundations = this.buildings.filter(Filters.and(Filters.isFoundation(),Filters.not(Filters.byClass("Field")))).toEntityArray();
+	var foundations = this.buildings.filter(API3.Filters.and(API3.Filters.isFoundation(),API3.Filters.not(API3.Filters.byClass("Field")))).toEntityArray();
 	var damagedBuildings = this.buildings.filter(function (ent) { if (ent.needsRepair() && ent.getMetadata(PlayerID, "plan") == undefined) { return true; } return false; }).toEntityArray();
 	
 	// Check if nothing to build
 	if (!foundations.length && !damagedBuildings.length){
 		return;
 	}
-	var workers = this.workers.filter(Filters.not(Filters.byClass("Cavalry")));
+	var workers = this.workers.filter(API3.Filters.not(API3.Filters.byClass("Cavalry")));
 	var builderWorkers = this.workersBySubrole(gameState, "builder");
-	var idleBuilderWorkers = this.workersBySubrole(gameState, "builder").filter(Filters.isIdle());
+	var idleBuilderWorkers = this.workersBySubrole(gameState, "builder").filter(API3.Filters.isIdle());
 
 	// if we're constructing and we have the foundations to our base anchor, only try building that.
-	if (this.constructing == true && this.buildings.filter(Filters.and(Filters.isFoundation(), Filters.byMetadata(PlayerID, "baseAnchor", true))).length !== 0)
+	if (this.constructing == true && this.buildings.filter(API3.Filters.and(API3.Filters.isFoundation(), API3.Filters.byMetadata(PlayerID, "baseAnchor", true))).length !== 0)
 	{
-		foundations = this.buildings.filter(Filters.byMetadata(PlayerID, "baseAnchor", true)).toEntityArray();
+		foundations = this.buildings.filter(API3.Filters.byMetadata(PlayerID, "baseAnchor", true)).toEntityArray();
 		var tID = foundations[0].id();
 		workers.forEach(function (ent) { //}){
 			var target = ent.getMetadata(PlayerID, "target-foundation");
@@ -832,7 +836,7 @@
 		
 		var assigned = gameState.getOwnEntitiesByMetadata("target-foundation", target.id()).length;
 
-		var targetNB = Config.Economy.targetNumBuilders;	// TODO: dynamic that.
+		var targetNB = this.Config.Economy.targetNumBuilders;	// TODO: dynamic that.
 		if (target.hasClass("CivCentre") || target.buildTime() > 150 || target.hasClass("House"))
 			targetNB *= 2;
 		if (target.getMetadata(PlayerID, "baseAnchor") == true)
@@ -844,7 +848,7 @@
 				var addedToThis = 0;
 				
 				idleBuilderWorkers.forEach(function(ent) {
-					if (ent.position() && SquareVectorDistance(ent.position(), target.position()) < 10000 && assigned + addedToThis < targetNB)
+					if (ent.position() && API3.SquareVectorDistance(ent.position(), target.position()) < 10000 && assigned + addedToThis < targetNB)
 					{
 						addedWorkers++;
 						addedToThis++;
@@ -876,7 +880,7 @@
 		} else if (noRepair && !target.hasClass("CivCentre"))
 			continue;
 		
-		var territory = Map.createTerritoryMap(gameState);
+		var territory = m.createTerritoryMap(gameState);
 		if (territory.getOwner(target.position()) !== PlayerID || territory.getOwner([target.position()[0] + 5, target.position()[1]]) !== PlayerID)
 			continue;
 		
@@ -900,7 +904,7 @@
 	}
 };
 
-BaseManager.prototype.update = function(gameState, queues, events) {
+m.BaseManager.prototype.update = function(gameState, queues, events) {
 	Engine.ProfileStart("Base update - base " + this.ID);
 	var self = this;
 	
@@ -957,10 +961,14 @@
 	Engine.ProfileStart("Run Workers");
 	this.workers.forEach(function(ent) {
 		if (!ent.getMetadata(PlayerID, "worker-object"))
-			ent.setMetadata(PlayerID, "worker-object", new Worker(ent));
+			ent.setMetadata(PlayerID, "worker-object", new m.Worker(ent));
 		ent.getMetadata(PlayerID, "worker-object").update(self, gameState);
 	});
 	Engine.ProfileStop();
 		
 	Engine.ProfileStop();
 };
+
+return m;
+
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/utils-extend.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/utils-extend.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/utils-extend.js	(Arbeitskopie)
@@ -1,4 +1,7 @@
-function AssocArraytoArray(assocArray) {
+var AEGIS = function(m)
+{
+
+m.AssocArraytoArray = function(assocArray) {
 	var endArray = [];
 	for (var i in assocArray)
 		endArray.push(assocArray[i]);
@@ -7,7 +10,7 @@
 
 // A is the reference, B must be in "range" of A
 // this supposes the range is already squared
-function inRange(a, b, range)// checks for X distance
+m.inRange = function(a, b, range)// checks for X distance
 {
 	// will avoid unnecessary checking for position in some rare cases... I'm lazy
 	if (a === undefined || b === undefined || range === undefined)
@@ -18,9 +21,12 @@
 	return ((dx*dx + dz*dz ) < range);
 }
 // slower than SquareVectorDistance, faster than VectorDistance but not exactly accurate.
-function ManhattanDistance(a, b)
+m.ManhattanDistance = function(a, b)
 {
 	var dx = a[0] - b[0];
 	var dz = a[1] - b[1];
 	return Math.abs(dx) + Math.abs(dz);
 }
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/defence.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/defence.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/defence.js	(Arbeitskopie)
@@ -1,6 +1,9 @@
+var AEGIS = function(m)
+{
+
 // directly imported from Marilyn, with slight modifications to work with qBot.
 
-function Defence(){
+m.Defence = function(Config){
 	this.defenceRatio = Config.Defence.defenceRatio;// How many defenders we want per attacker.  Need to balance fewer losses vs. lost economy
 							// note: the choice should be a no-brainer most of the time: better deflect the attack.
 							// This is also sometimes forcebly overcome by the defense manager.
@@ -48,36 +51,36 @@
 // 1: Huge army in the base, outnumbering us.
 
 
-Defence.prototype.update = function(gameState, events, HQ){
+m.Defence.prototype.update = function(gameState, events, HQ){
 	
 	Engine.ProfileStart("Defence Manager");
 	
 	// a litlle cache-ing
 	if (!this.idleDefs) {
-		var filter = Filters.and(Filters.byMetadata(PlayerID, "role", "defence"), Filters.isIdle());
+		var filter = API3.Filters.and(API3.Filters.byMetadata(PlayerID, "role", "defence"), API3.Filters.isIdle());
 		this.idleDefs = gameState.getOwnEntities().filter(filter);
 		this.idleDefs.registerUpdates();
 	}
 	if (!this.defenders) {
-		var filter = Filters.byMetadata(PlayerID, "role", "defence");
+		var filter = API3.Filters.byMetadata(PlayerID, "role", "defence");
 		this.defenders = gameState.getOwnEntities().filter(filter);
 		this.defenders.registerUpdates();
 	}
 	/*if (!this.listedEnemyCollection) {
-		var filter = Filters.byMetadata(PlayerID, "listed-enemy", true);
+		var filter = API3.Filters.byMetadata(PlayerID, "listed-enemy", true);
 		this.listedEnemyCollection = gameState.getEnemyEntities().filter(filter);
 		this.listedEnemyCollection.registerUpdates();
 	}
-	this.myBuildings = gameState.getOwnEntities().filter(Filters.byClass("Structure")).toEntityArray();
-	this.myUnits = gameState.getOwnEntities().filter(Filters.byClass("Unit"));
+	this.myBuildings = gameState.getOwnEntities().filter(API3.Filters.byClass("Structure")).toEntityArray();
+	this.myUnits = gameState.getOwnEntities().filter(API3.Filters.byClass("Unit"));
 	*/
-	var filter = Filters.and(Filters.byClassesOr(["CitizenSoldier", "Hero", "Champion", "Siege"]), Filters.byOwner(PlayerID));
+	var filter = API3.Filters.and(API3.Filters.byClassesOr(["CitizenSoldier", "Hero", "Champion", "Siege"]), API3.Filters.byOwner(PlayerID));
 	this.myUnits = gameState.updatingGlobalCollection("player-" +PlayerID + "-soldiers", filter);
 	
-	filter = Filters.and(Filters.byClass("Structure"), Filters.byOwner(PlayerID));
+	filter = API3.Filters.and(API3.Filters.byClass("Structure"), API3.Filters.byOwner(PlayerID));
 	this.myBuildings = gameState.updatingGlobalCollection("player-" +PlayerID + "-structures", filter);
 
-	this.territoryMap = Map.createTerritoryMap(gameState);	// used by many func
+	this.territoryMap = m.createTerritoryMap(gameState);	// used by many func
 
 	// First step: we deal with enemy armies, those are the highest priority.
 	this.defendFromEnemies(gameState, events, HQ);
@@ -118,7 +121,7 @@
 		}
 		for (var o in this.myBuildings) {
 			// if the armies out of my buildings LOS (with a little more, because we're cheating right now and big armies could go undetected)
-			if (inRange(pos, this.myBuildings[o].position(),this.myBuildings[o].visionRange()*this.myBuildings[o].visionRange() + 2500)) {
+			if (m.inRange(pos, this.myBuildings[o].position(),this.myBuildings[o].visionRange()*this.myBuildings[o].visionRange() + 2500)) {
 				stillDangerousArmies[i] = armies[i];
 				break;
 			}
@@ -138,7 +141,7 @@
 }*/
 // Incorporates an entity in an army. If no army fits, it creates a new one around this one.
 // an army is basically an entity collection.
-Defence.prototype.armify = function(gameState, entity, HQ, minNBForArmy) {
+m.Defence.prototype.armify = function(gameState, entity, HQ, minNBForArmy) {
 	if (entity.position() === undefined)
 		return;
 	if (this.enemyArmy[entity.owner()] === undefined)
@@ -151,7 +154,7 @@
 			if (army.getCentrePosition() === undefined)
 			{
 			} else {
-				if (SquareVectorDistance(army.getCentrePosition(), entity.position()) < this.armyCompactSize)
+				if (API3.SquareVectorDistance(army.getCentrePosition(), entity.position()) < this.armyCompactSize)
 				{
 					entity.setMetadata(PlayerID, "inArmy", armyIndex);
 					army.addEnt(entity);
@@ -163,11 +166,11 @@
 	if (HQ)
 	{
 		var self = this;
-		var close = HQ.enemyWatchers[entity.owner()].enemySoldiers.filter(Filters.byDistance(entity.position(), self.armyCompactSize));
+		var close = HQ.enemyWatchers[entity.owner()].enemySoldiers.filter(API3.Filters.byDistance(entity.position(), self.armyCompactSize));
 		if (!minNBForArmy || close.length >= minNBForArmy)
 		{
 			// if we're here, we need to create an army for it, and freeze it to make sure no unit will be added automatically
-			var newArmy = new EntityCollection(gameState.sharedScript, {}, [Filters.byOwner(entity.owner())]);
+			var newArmy = new API3.EntityCollection(gameState.sharedScript, {}, [API3.Filters.byOwner(entity.owner())]);
 			newArmy.addEnt(entity);
 			newArmy.freeze();
 			newArmy.registerUpdates();
@@ -184,7 +187,7 @@
 		}
 	} else {
 		// if we're here, we need to create an army for it, and freeze it to make sure no unit will be added automatically
-		var newArmy = new EntityCollection(gameState.sharedScript, {}, [Filters.byOwner(entity.owner())]);
+		var newArmy = new API3.EntityCollection(gameState.sharedScript, {}, [API3.Filters.byOwner(entity.owner())]);
 		newArmy.addEnt(entity);
 		newArmy.freeze();
 		newArmy.registerUpdates();
@@ -195,12 +198,12 @@
 	return;
 }
 // Returns if a unit should be seen as dangerous or not.
-Defence.prototype.evaluateRawEntity = function(gameState, entity) {
+m.Defence.prototype.evaluateRawEntity = function(gameState, entity) {
 	if (entity.position && +this.territoryMap.point(entity.position) - 64 === +PlayerID && entity._template.Attack !== undefined)
 		return true;
 	return false;
 }
-Defence.prototype.evaluateEntity = function(gameState, entity) {
+m.Defence.prototype.evaluateEntity = function(gameState, entity) {
 	if (!entity.position())
 		return false;
 	if (this.territoryMap.point(entity.position()) - 64 === entity.owner() || entity.attackTypes() === undefined)
@@ -210,20 +213,20 @@
 	{
 		if (!this.myBuildings._entities[i].hasClass("ConquestCritical"))
 			continue;
-		if (SquareVectorDistance(this.myBuildings._entities[i].position(), entity.position()) < 6000)
+		if (API3.SquareVectorDistance(this.myBuildings._entities[i].position(), entity.position()) < 6000)
 			return true;
 	}
 	return false;
 }
 // returns false if the unit is in its territory
-Defence.prototype.reevaluateEntity = function(gameState, entity) {
+m.Defence.prototype.reevaluateEntity = function(gameState, entity) {
 	if ( (entity.position() && +this.territoryMap.point(entity.position()) - 64 === +entity.owner()) || entity.attackTypes() === undefined)
 		return false;
 	return true;
 }
 // This deals with incoming enemy armies, setting the defcon if needed. It will take new soldiers, and assign them to attack
 // TODO: still is still pretty dumb, it could use improvements.
-Defence.prototype.defendFromEnemies = function(gameState, events, HQ) {
+m.Defence.prototype.defendFromEnemies = function(gameState, events, HQ) {
 	var self = this;
 	
 	// New, faster system will loop for enemy soldiers, and also females on occasions ( TODO )
@@ -313,7 +316,7 @@
 			} else {
 				army.forEach(function (ent) { //}){
 					// check if the unit is a breakaway
-					if (ent.position() && SquareVectorDistance(position, ent.position()) > self.armyBreakawaySize)
+					if (ent.position() && API3.SquareVectorDistance(position, ent.position()) > self.armyBreakawaySize)
 					{
 						ent.setMetadata(PlayerID, "inArmy", undefined);
 						army.removeEnt(ent);
@@ -322,12 +325,12 @@
 					} else {
 						// check if we have registered that unit already.
 						if (self.listOfEnemies[ent.id()] === undefined) {
-							self.listOfEnemies[ent.id()] = new EntityCollection(gameState.sharedScript, {}, [Filters.byOwner(ent.owner())]);
+							self.listOfEnemies[ent.id()] = new API3.EntityCollection(gameState.sharedScript, {}, [API3.Filters.byOwner(ent.owner())]);
 							self.listOfEnemies[ent.id()].freeze();
 							self.listOfEnemies[ent.id()].addEnt(ent);
 							self.listOfEnemies[ent.id()].registerUpdates();
 							
-							self.attackerCache[ent.id()] = self.myUnits.filter(Filters.byTargetedEntity(ent.id()));
+							self.attackerCache[ent.id()] = self.myUnits.filter(API3.Filters.byTargetedEntity(ent.id()));
 							self.attackerCache[ent.id()].registerUpdates();
 							nbOfAttackers++;
 							self.nbAttackers++;
@@ -373,7 +376,7 @@
 	
 	if (this.nbAttackers === 0 && this.nbDefenders === 0) {
 		// Release all our units
-		this.myUnits.filter(Filters.byMetadata(PlayerID, "role","defence")).forEach(function (defender) { //}){
+		this.myUnits.filter(API3.Filters.byMetadata(PlayerID, "role","defence")).forEach(function (defender) { //}){
 			defender.stopMoving();
 			if (defender.getMetadata(PlayerID, "formerrole"))
 				defender.setMetadata(PlayerID, "role", defender.getMetadata(PlayerID, "formerrole") );
@@ -387,7 +390,7 @@
 		return;
 	} else if (this.nbAttackers === 0 && this.nbDefenders !== 0) {
 		// Release all our units
-		this.myUnits.filter(Filters.byMetadata(PlayerID, "role","defence")).forEach(function (defender) { //}){
+		this.myUnits.filter(API3.Filters.byMetadata(PlayerID, "role","defence")).forEach(function (defender) { //}){
 			defender.stopMoving();
 			if (defender.getMetadata(PlayerID, "formerrole"))
 				defender.setMetadata(PlayerID, "role", defender.getMetadata(PlayerID, "formerrole") );
@@ -404,8 +407,8 @@
 		HQ.ungarrisonAll(gameState);
 	}
 	
-	//debug ("total number of attackers:"+ this.nbAttackers);
-	//debug ("total number of defenders:"+ this.nbDefenders);
+	//m.debug ("total number of attackers:"+ this.nbAttackers);
+	//m.debug ("total number of defenders:"+ this.nbDefenders);
 
 	// If I'm here, I have a list of enemy units, and a list of my units attacking it (in absolute terms, I could use a list of any unit attacking it).
 	// now I'll list my idle defenders, then my idle soldiers that could defend.
@@ -419,8 +422,8 @@
 	}
 	
 	// we're having too many. Release those that attack units already dealt with, or idle ones.
-	if (this.myUnits.filter(Filters.byMetadata(PlayerID, "role","defence")).length > nbOfAttackers*this.defenceRatio*1.2) {
-		this.myUnits.filter(Filters.byMetadata(PlayerID, "role","defence")).forEach(function (defender) { //}){
+	if (this.myUnits.filter(API3.Filters.byMetadata(PlayerID, "role","defence")).length > nbOfAttackers*this.defenceRatio*1.2) {
+		this.myUnits.filter(API3.Filters.byMetadata(PlayerID, "role","defence")).forEach(function (defender) { //}){
 			if ( defender.isIdle() || (defender.unitAIOrderData() && defender.unitAIOrderData()["target"])) {
 				if ( defender.isIdle() || (self.attackerCache[defender.unitAIOrderData()["target"]] && self.attackerCache[defender.unitAIOrderData()["target"]].length > 3)) {
 					// okay release me.
@@ -437,9 +440,9 @@
 	}
 	
 
-	var nonDefenders = this.myUnits.filter(Filters.or(Filters.not(Filters.byMetadata(PlayerID, "role","defence")),Filters.isIdle()));
-	nonDefenders = nonDefenders.filter(Filters.not(Filters.byClass("Female")));
-	nonDefenders = nonDefenders.filter(Filters.not(Filters.byMetadata(PlayerID, "subrole","attacking")));
+	var nonDefenders = this.myUnits.filter(API3.Filters.or(API3.Filters.not(API3.Filters.byMetadata(PlayerID, "role","defence")),API3.Filters.isIdle()));
+	nonDefenders = nonDefenders.filter(API3.Filters.not(API3.Filters.byClass("Female")));
+	nonDefenders = nonDefenders.filter(API3.Filters.not(API3.Filters.byMetadata(PlayerID, "subrole","attacking")));
 	var defenceRatio = this.defenceRatio;
 	
 	if (newEnemies.length + this.nbAttackers > (this.nbDefenders + nonDefenders.length) * 0.8 && this.nbAttackers > 9)
@@ -448,8 +451,8 @@
 	if (newEnemies.length + this.nbAttackers > (this.nbDefenders + nonDefenders.length) * 1.5 && this.nbAttackers > 5)
 		gameState.setDefcon(1);
 
-	//debug ("newEnemies.length "+ newEnemies.length);
-	//debug ("nonDefenders.length "+ nonDefenders.length);
+	//m.debug ("newEnemies.length "+ newEnemies.length);
+	//m.debug ("nonDefenders.length "+ nonDefenders.length);
 		
 	if (gameState.defcon() > 3)
 		HQ.unpauseAllPlans(gameState);
@@ -457,7 +460,7 @@
 	if ( (nonDefenders.length + this.nbDefenders > newEnemies.length + this.nbAttackers)
 		|| this.nbDefenders + nonDefenders.length < 4)
 	{
-		var buildings = gameState.getOwnEntities().filter(Filters.byCanGarrison()).toEntityArray();
+		var buildings = gameState.getOwnEntities().filter(API3.Filters.byCanGarrison()).toEntityArray();
 		buildings.forEach( function (struct) {
 			if (struct.garrisoned() && struct.garrisoned().length)
 				struct.unloadAll();
@@ -513,7 +516,7 @@
 		{
 			var ent = nonDefenders._entities[id];
 			if (ent.position())
-				data.push([id, ent, SquareVectorDistance(enemy.position(), ent.position())]);
+				data.push([id, ent, API3.SquareVectorDistance(enemy.position(), ent.position())]);
 		}
 		// refine the defenders we want. Since it's the distance squared, it has the effect
 		// of tending to always prefer closer units, though this refinement should change it slighty.
@@ -547,13 +550,13 @@
 		for each (var val in data.slice(0, Math.min(nonDefenders._length, defRatio - assigned)))
 			ret[val[0]] = val[1];
 		
-		var defs = new EntityCollection(nonDefenders._ai, ret);
+		var defs = new API3.EntityCollection(nonDefenders._ai, ret);
 
 		// successfully sorted
 		defs.forEach(function (defender) { //}){
 			if (defender.getMetadata(PlayerID, "plan") != undefined && (gameState.defcon() < 4 || defender.getMetadata(PlayerID,"subrole") == "walking"))
 				HQ.pausePlan(gameState, defender.getMetadata(PlayerID, "plan"));
-			//debug ("Against " +enemy.id() + " Assigning " + defender.id());
+			//m.debug ("Against " +enemy.id() + " Assigning " + defender.id());
 			if (defender.getMetadata(PlayerID, "role") == "worker" || defender.getMetadata(PlayerID, "role") == "attack")
 				defender.setMetadata(PlayerID, "formerrole", defender.getMetadata(PlayerID, "role"));
 			defender.setMetadata(PlayerID, "role","defence");
@@ -571,8 +574,8 @@
 		/*if (gameState.defcon() <= 3)
 		{
 			// let's try to garrison neighboring females.
-			var buildings = gameState.getOwnEntities().filter(Filters.byCanGarrison()).toEntityArray();
-			var females = gameState.getOwnEntities().filter(Filters.byClass("Support"));
+			var buildings = gameState.getOwnEntities().filter(API3.Filters.byCanGarrison()).toEntityArray();
+			var females = gameState.getOwnEntities().filter(API3.Filters.byClass("Support"));
 				
 			var cache = {};
 			var garrisoned = false;
@@ -580,7 +583,7 @@
 				garrisoned = false;
 				if (ent.position())
 				{
-					if (SquareVectorDistance(ent.position(), enemy.position()) < 3500)
+					if (API3.SquareVectorDistance(ent.position(), enemy.position()) < 3500)
 					{
 						for (var i in buildings)
 						{
@@ -611,7 +614,7 @@
 // this processes the attackmessages
 // So that a unit that gets attacked will not be completely dumb.
 // warning: huge levels of indentation coming.
-Defence.prototype.MessageProcess = function(gameState,events, HQ) {
+m.Defence.prototype.MessageProcess = function(gameState,events, HQ) {
 	var self = this;
 	
 	for (var key in events){
@@ -646,12 +649,12 @@
 						if (territory === PlayerID)
 						{
 							// anyway we'll register the animal as dangerous, and attack it (note: only on our territory. Don't care otherwise).
-							this.listOfWantedUnits[attacker.id()] = new EntityCollection(gameState.sharedScript);
+							this.listOfWantedUnits[attacker.id()] = new API3.EntityCollection(gameState.sharedScript);
 							this.listOfWantedUnits[attacker.id()].addEnt(attacker);
 							this.listOfWantedUnits[attacker.id()].freeze();
 							this.listOfWantedUnits[attacker.id()].registerUpdates();
 
-							var filter = Filters.byTargetedEntity(attacker.id());
+							var filter = API3.Filters.byTargetedEntity(attacker.id());
 							this.WantedUnitsAttacker[attacker.id()] = this.myUnits.filter(filter);
 							this.WantedUnitsAttacker[attacker.id()].registerUpdates();
 						}
@@ -666,7 +669,7 @@
 							
 							// Right now, to make the AI less gameable, we'll mark any surrounding resource as inaccessible.
 							// usual tower range is 80. Be on the safe side.
-							var close = gameState.getResourceSupplies("wood").filter(Filters.byDistance(attacker.position(), 90));
+							var close = gameState.getResourceSupplies("wood").filter(API3.Filters.byDistance(attacker.position(), 90));
 							close.forEach(function (supply) { //}){
 								supply.setMetadata(PlayerID, "inaccessible", true);
 							});
@@ -683,7 +686,7 @@
 									if (this.reevaluateEntity(gameState, attacker))
 									{
 										var position = attacker.position();
-										var close = HQ.enemyWatchers[attacker.owner()].enemySoldiers.filter(Filters.byDistance(position, self.armyCompactSize));
+										var close = HQ.enemyWatchers[attacker.owner()].enemySoldiers.filter(API3.Filters.byDistance(position, self.armyCompactSize));
 										
 										if (close.length > 2 || ourUnit.hasClass("Support") || attacker.hasClass("Siege"))
 										{
@@ -692,7 +695,7 @@
 											armyID = attacker.getMetadata(PlayerID, "inArmy");
 											
 											close.forEach(function (ent) { //}){
-												if (SquareVectorDistance(position, ent.position()) < self.armyCompactSize)
+												if (API3.SquareVectorDistance(position, ent.position()) < self.armyCompactSize)
 												{
 													ent.setMetadata(PlayerID, "inArmy", armyID);
 														  self.enemyArmy[ent.owner()][armyID].addEnt(ent);
@@ -708,7 +711,7 @@
 										// let's try to garrison this support unit.
 										if (ourUnit.position())
 										{
-											var buildings = gameState.getOwnEntities().filter(Filters.byCanGarrison()).filterNearest(ourUnit.position(),4).toEntityArray();
+											var buildings = gameState.getOwnEntities().filter(API3.Filters.byCanGarrison()).filterNearest(ourUnit.position(),4).toEntityArray();
 											var garrisoned = false;
 											for (var i in buildings)
 											{
@@ -742,7 +745,7 @@
 }; // nice sets of closing brackets, isn't it?
 
 // At most, this will put defcon to 4
-Defence.prototype.DealWithWantedUnits = function(gameState, events, HQ) {
+m.Defence.prototype.DealWithWantedUnits = function(gameState, events, HQ) {
 	//if (gameState.defcon() < 3)
 	//	return;
 	
@@ -841,3 +844,6 @@
 	}
 	return;
 }
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/worker.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/worker.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/worker.js	(Arbeitskopie)
@@ -1,3 +1,6 @@
+var AEGIS = function(m)
+{
+
 /**
  * This class makes a worker do as instructed by the economy manager
  */
@@ -2,3 +5,3 @@
 
-var Worker = function(ent) {
+m.Worker = function(ent) {
 	this.ent = ent;
@@ -9,7 +12,7 @@
 	this.baseID = 0;
 };
 
-Worker.prototype.update = function(baseManager, gameState) {
+m.Worker.prototype.update = function(baseManager, gameState) {
 	this.baseID = baseManager.ID;
 	var subrole = this.ent.getMetadata(PlayerID, "subrole");
 
@@ -64,7 +67,7 @@
 				}
 				Engine.ProfileStop();
 			}
-			// debug: show the resource we're gathering from
+			// m.debug: show the resource we're gathering from
 			//Engine.PostCommand({"type": "set-shading-color", "entities": [this.ent.id()], "rgb": [10,0,0]});
 		} else if (this.ent.unitAIState().split(".")[1] === "GATHER") {
 			
@@ -93,9 +96,9 @@
 					&& this.ent.unitAIOrderData()[0]["target"])
 				{
 					var ent = gameState.getEntityById(this.ent.unitAIOrderData()[0]["target"]);
-					debug ("here " + this.startApproachingResourceAmount + "," + ent.resourceSupplyAmount());
+					m.debug ("here " + this.startApproachingResourceAmount + "," + ent.resourceSupplyAmount());
 					if (ent && this.startApproachingResourceAmount == ent.resourceSupplyAmount() && this.startEnt == ent.id()) {
-						debug (ent.toString() + " is inaccessible");
+						m.debug (ent.toString() + " is inaccessible");
 						ent.setMetadata(PlayerID, "inaccessible", true);
 						this.ent.flee(ent);
 						this.ent.setMetadata(PlayerID, "subrole", "idle");
@@ -116,7 +119,7 @@
 					var ent = gameState.getEntityById(this.gatheringFrom);
 					if ((ent && ent.resourceSupplyAmount() == ent.resourceSupplyMax())) {
 						// if someone gathers from it, it's only that the pathfinder sucks.
-						debug (ent.toString() + " is inaccessible");
+						m.debug (ent.toString() + " is inaccessible");
 						ent.setMetadata(PlayerID, "inaccessible", true);
 						this.ent.flee(ent);
 						this.ent.setMetadata(PlayerID, "subrole", "idle");
@@ -129,7 +132,7 @@
 				var ent = gameState.getEntityById(this.ent.unitAIOrderData()[0].target);
 				if (ent && !ent.isHurt()) {
 					// if someone gathers from it, it's only that the pathfinder sucks.
-					debug (ent.toString() + " is inaccessible from Combat");
+					m.debug (ent.toString() + " is inaccessible from Combat");
 					ent.setMetadata(PlayerID, "inaccessible", true);
 					this.ent.flee(ent);
 					this.ent.setMetadata(PlayerID, "subrole", "idle");
@@ -186,7 +189,7 @@
 // this can happen in two ways:
 //		-either we were on an unsatisfactory resource last time we started gathering (this.unsatisfactoryResource)
 //		-Or we auto-moved to a bad resource thanks to the great UnitAI.
-Worker.prototype.checkUnsatisfactoryResource = function(gameState) {
+m.Worker.prototype.checkUnsatisfactoryResource = function(gameState) {
 	if (this.unsatisfactoryResource)
 		return true;
 	if (this.ent.unitAIOrderData().length && this.ent.unitAIState().split(".")[1] === "GATHER" && this.ent.unitAIState().split(".")[2] === "GATHERING" && this.ent.unitAIOrderData()[0]["target"])
@@ -198,7 +201,8 @@
 	return false;
 };
 
-Worker.prototype.startGathering = function(baseManager, gameState) {
+m.Worker.prototype.startGathering = function(baseManager, gameState) {
+
 	var resource = this.ent.getMetadata(PlayerID, "gather-type");
 	var ent = this.ent;
 	var self = this;
@@ -219,10 +223,10 @@
 	// TODO: this is a huge part of multi-base support. Count only those in the same base as the worker.
 	var number = 0;
 	
-	var ourDropsites = EntityCollectionFromIds(gameState,Object.keys(baseManager.dropsites));
+	var ourDropsites = m.EntityCollectionFromIds(gameState,Object.keys(baseManager.dropsites));
 	if (ourDropsites.length === 0)
 	{
-		debug ("We do not have a dropsite for " + resource + ", aborting");
+		m.debug ("We do not have a dropsite for " + resource + ", aborting");
 		return;
 	}
 	
@@ -245,7 +249,7 @@
 				return;
 			if (dropsite.position() && (baseManager.dropsites[dropsite.id()][resource][4] > 1000 || (number === 1 && baseManager.dropsites[dropsite.id()][resource][4] > 200) )
 				&& baseManager.dropsites[dropsite.id()][resource][5].length < maxPerDP) {
-				var dist = SquareVectorDistance(ent.position(), dropsite.position());
+				var dist = API3.SquareVectorDistance(ent.position(), dropsite.position());
 				if (dist < minDropsiteDist){
 					minDropsiteDist = dist;
 					nearestResources = baseManager.dropsites[dropsite.id()][resource][1];
@@ -254,6 +258,7 @@
 			}
 		});
 	}
+	
 	// we've found no fitting dropsites close enough from us.
 	// So'll try with far away.
 	if (!nearestResources || nearestResources.length === 0) {
@@ -262,7 +267,7 @@
 				return;
 			if (dropsite.position() && baseManager.dropsites[dropsite.id()][resource][4] > 400
 				&& baseManager.dropsites[dropsite.id()][resource][5].length < maxPerDP) {
-				var dist = SquareVectorDistance(ent.position(), dropsite.position());
+				var dist = API3.SquareVectorDistance(ent.position(), dropsite.position());
 				if (dist < minDropsiteDist){
 					minDropsiteDist = dist;
 					nearestResources = baseManager.dropsites[dropsite.id()][resource][1];
@@ -271,7 +276,7 @@
 			}
 		});
 	}
-
+	
 	if (!nearestResources || nearestResources.length === 0){
 		if (resource === "food")
 			if (this.buildAnyField(gameState))
@@ -283,7 +288,7 @@
 		if (gameState.ai.HQ.switchWorkerBase(gameState, this.ent, resource))
 			return;
 
-		//debug ("No fitting dropsite for " + resource + " found, iterating the map.");
+		//m.debug ("No fitting dropsite for " + resource + " found, iterating the map.");
 		nearestResources = gameState.getResourceSupplies(resource);
 		this.unsatisfactoryResource = true;
 		// TODO: should try setting up dropsites.
@@ -298,20 +303,20 @@
 				return;
 			if (gameState.ai.HQ.switchWorkerBase(gameState, this.ent, resource))
 				return;
-			debug("No " + resource + " found! (1)");
+			m.debug("No " + resource + " found! (1)");
 		}
 		else
 		{
 			if (gameState.ai.HQ.switchWorkerBase(gameState, this.ent, resource))
 				return;
-			debug("No " + resource + " found! (1)");
+			m.debug("No " + resource + " found! (1)");
 		}
 		return;
 	}
-	//debug("Found " + nearestResources.length + "spots for " + resource);
+	//m.debug("Found " + nearestResources.length + "spots for " + resource);
 	
 	/*if (!nearestDropsite) {
-		debug ("No dropsite for " +resource);
+		m.debug ("No dropsite for " +resource);
 		return;
 	}*/
 	
@@ -324,12 +329,12 @@
 	nearestResources.forEach(function(supply) { //}){
 		// sanity check, perhaps sheep could be garrisoned?
 		if (!supply.position()) {
-			//debug ("noposition");
+			//m.debug ("noposition");
 			return;
 		}
 		
 		if (supply.getMetadata(PlayerID, "inaccessible") === true) {
-			//debug ("inaccessible");
+			//m.debug ("inaccessible");
 			return;
 		}
 
@@ -341,19 +346,19 @@
 							 
 		// Don't gather enemy farms or farms from another base
 		if ((!supply.isOwn(PlayerID) && supply.owner() !== 0) || (supply.isOwn(PlayerID) && supply.getMetadata(PlayerID,"base") !== self.baseID)) {
-			//debug ("enemy");
+			//m.debug ("enemy");
 			return;
 		}
 		
 		// quickscope accessbility check.
 		if (!gameState.ai.accessibility.pathAvailable(gameState, ent.position(), supply.position())) {
-			//debug ("nopath");
+			//m.debug ("nopath");
 			return;
 		}
 		// some simple check for chickens: if they're in a square that's inaccessible, we won't gather from them.
 		if (supply.footprintRadius() < 1)
 		{
-			var fakeMap = new Map(gameState.sharedScript,gameState.getMap().data);
+			var fakeMap = new API3.Map(gameState.sharedScript,gameState.getMap().data);
 			var id = fakeMap.gamePosToMapPos(supply.position())[0] + fakeMap.width*fakeMap.gamePosToMapPos(supply.position())[1];
 			if ( (gameState.sharedScript.passabilityClasses["pathfinderObstruction"] & gameState.getMap().data[id]) )
 			{
@@ -363,18 +368,18 @@
 		}
 
 		// measure the distance to the resource (largely irrelevant)
-		 var dist = SquareVectorDistance(supply.position(), ent.position());
+		 var dist = API3.SquareVectorDistance(supply.position(), ent.position());
 							 
 		if (dist > 4900 && supply.hasClass("Animal"))
 		return;
 
 		// Add on a factor for the nearest dropsite if one exists
 		if (nearestDropsite !== undefined ){
-			dist += 4*SquareVectorDistance(supply.position(), nearestDropsite.position());
+			dist += 4*API3.SquareVectorDistance(supply.position(), nearestDropsite.position());
 			dist /= 5.0;
 		}
 					
-		var territoryOwner = Map.createTerritoryMap(gameState).getOwner(supply.position());
+		var territoryOwner = m.createTerritoryMap(gameState).getOwner(supply.position());
 		if (territoryOwner != PlayerID && territoryOwner != 0) {
 			dist *= 5.0;
 			//return;
@@ -395,7 +400,7 @@
 		if (!nearestDropsite) {
 			ourDropsites.forEach(function (dropsite){ //}){
 				if (dropsite.position()){
-					var dist = SquareVectorDistance(pos, dropsite.position());
+					var dist = API3.SquareVectorDistance(pos, dropsite.position());
 					if (dist < minDropsiteDist){
 						minDropsiteDist = dist;
 						nearestDropsite = dropsite;
@@ -404,17 +409,17 @@
 			});
 			if (!nearestDropsite)
 			{
-				debug ("No dropsite for " +resource);
+				m.debug ("No dropsite for " +resource);
 				return;
 			}
 		}
 
 		// if the resource is far away, try to build a farm instead.
 		var tried = false;
-		if (resource === "food" && SquareVectorDistance(pos,this.ent.position()) > 22500)
+		if (resource === "food" && API3.SquareVectorDistance(pos,this.ent.position()) > 22500)
 		{
 			tried = this.buildAnyField(gameState);
-			if (!tried && SquareVectorDistance(pos,this.ent.position()) > 62500) {
+			if (!tried && API3.SquareVectorDistance(pos,this.ent.position()) > 62500) {
 				// TODO: ought to change behavior here.
 				return; // wait. a farm should appear.
 			}
@@ -429,7 +434,7 @@
 			else
 				gameState.turnCache["ressGathererNB"][nearestSupply.id()]++;
 			
-			this.maxApproachTime = Math.max(30000, VectorDistance(pos,this.ent.position()) * 5000);
+			this.maxApproachTime = Math.max(30000, API3.VectorDistance(pos,this.ent.position()) * 5000);
 			this.startApproachingResourceAmount = ent.resourceSupplyAmount();
 			this.startEnt = ent.id();
 			ent.gather(nearestSupply);
@@ -443,7 +448,7 @@
 			return;
 		
 		if (resource !== "food")
-			debug("No " + resource + " found! (2)");
+			m.debug("No " + resource + " found! (2)");
 		// If we had a fitting closest dropsite with a lot of resources, mark it as not good. It means it's probably full. Then retry.
 		// it'll be resetted next time it's counted anyway.
 		if (nearestDropsite && nearestDropsite.getMetadata(PlayerID, "resource-quantity-" +resource)+nearestDropsite.getMetadata(PlayerID, "resource-quantity-far-" +resource) > 400)
@@ -456,7 +461,7 @@
 };
 
 // Makes the worker deposit the currently carried resources at the closest dropsite
-Worker.prototype.returnResources = function(gameState){
+m.Worker.prototype.returnResources = function(gameState){
 	if (!this.ent.resourceCarrying() || this.ent.resourceCarrying().length === 0){
 		return true;	// assume we're OK.
 	}
@@ -472,7 +477,7 @@
 	var dist = Math.min();
 	gameState.getOwnDropsites(resource).forEach(function(dropsite){
 		if (dropsite.position()){
-			var d = SquareVectorDistance(self.ent.position(), dropsite.position());
+			var d = API3.SquareVectorDistance(self.ent.position(), dropsite.position());
 			if (d < dist){
 				dist = d;
 				closestDropsite = dropsite;
@@ -481,7 +486,7 @@
 	});
 	
 	if (!closestDropsite){
-		debug("No dropsite found to deposit " + resource);
+		m.debug("No dropsite found to deposit " + resource);
 		return false;
 	}
 	
@@ -489,7 +494,7 @@
 	return true;
 };
 
-Worker.prototype.startHunting = function(gameState, baseManager){
+m.Worker.prototype.startHunting = function(gameState, baseManager){
 	var ent = this.ent;
 	
 	if (!ent.position() || !baseManager.isHunting)
@@ -500,7 +505,7 @@
 	var resources = gameState.getResourceSupplies("food");
 	
 	if (resources.length === 0){
-		debug("No food found to hunt!");
+		m.debug("No food found to hunt!");
 		return;
 	}
 	
@@ -522,9 +527,9 @@
 			return;
 					  
 		// measure the distance to the resource
-		var dist = SquareVectorDistance(supply.position(), ent.position());
+		var dist = API3.SquareVectorDistance(supply.position(), ent.position());
 
-		var territoryOwner = Map.createTerritoryMap(gameState).getOwner(supply.position());
+		var territoryOwner = m.createTerritoryMap(gameState).getOwner(supply.position());
 		if (territoryOwner != PlayerID && territoryOwner != 0) {
 			dist *= 3.0;
 		}
@@ -547,7 +552,7 @@
 		// find a fitting dropsites in case we haven't already.
 		gameState.getOwnDropsites("food").forEach(function (dropsite){ //}){
 			if (dropsite.position()){
-				var dist = SquareVectorDistance(pos, dropsite.position());
+				var dist = API3.SquareVectorDistance(pos, dropsite.position());
 				if (dist < minDropsiteDist){
 					minDropsiteDist = dist;
 					nearestDropsite = dropsite;
@@ -558,7 +563,7 @@
 		{
 			baseManager.isHunting = false;
 			ent.setMetadata(PlayerID, "role", undefined);
-			debug ("No dropsite for hunting food");
+			m.debug ("No dropsite for hunting food");
 			return;
 		}
 		if (minDropsiteDist > 35000) {
@@ -571,11 +576,11 @@
 	} else {
 		baseManager.isHunting = false;
 		ent.setMetadata(PlayerID, "role", undefined);
-		debug("No food found for hunting! (2)");
+		m.debug("No food found for hunting! (2)");
 	}
 };
 
-Worker.prototype.getResourceType = function(type){
+m.Worker.prototype.getResourceType = function(type){
 	if (!type || !type.generic){
 		return undefined;
 	}
@@ -587,7 +592,7 @@
 	}
 };
 
-Worker.prototype.getGatherRate = function(gameState) {
+m.Worker.prototype.getGatherRate = function(gameState) {
 	if (this.ent.getMetadata(PlayerID,"subrole") !== "gatherer")
 		return 0;
 	var rates = this.ent.resourceGatherRates();
@@ -601,7 +606,7 @@
 		if (type.generic == "treasure")
 			return 1000;
 		var tstring = type.generic + "." + type.specific;
-		//debug (+rates[tstring] + " for " + tstring + " for " + this.ent._templateName);
+		//m.debug (+rates[tstring] + " for " + tstring + " for " + this.ent._templateName);
 		if (rates[tstring])
 			return rates[tstring];
 		return 0;
@@ -609,10 +614,10 @@
 	return 0;
 };
 
-Worker.prototype.buildAnyField = function(gameState){
+m.Worker.prototype.buildAnyField = function(gameState){
 	var self = this;
 	var okay = false;
-	var foundations = gameState.getOwnFoundations().filter(Filters.byMetadata(PlayerID,"base",this.baseID));
+	var foundations = gameState.getOwnFoundations().filter(API3.Filters.byMetadata(PlayerID,"base",this.baseID));
 	foundations.filterNearest(this.ent.position(), foundations.length);
 	foundations.forEach(function (found) {
 		if (found._template.BuildRestrictions.Category === "Field" && !okay) {
@@ -636,3 +641,6 @@
 	}
 	return okay;
 };
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/attack_plan.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/attack_plan.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/attack_plan.js	(Arbeitskopie)
@@ -1,3 +1,6 @@
+var AEGIS = function(m)
+{
+
 /* This is an attack plan (despite the name, it's a relic of older times).
  * It deals with everything in an attack, from picking a target to picking a path to it
  * To making sure units rae built, and pushing elements to the queue manager otherwise
@@ -6,8 +9,9 @@
  * There is a basic support for naval expeditions here. 
  */
 
-function CityAttack(gameState, HQ, uniqueID, targetEnemy, type , targetFinder) {
+m.CityAttack = function CityAttack(gameState, HQ, Config, uniqueID, targetEnemy, type , targetFinder) {
 	
+	this.Config = Config;
 	//This is the list of IDs of the units in the plan
 	this.idList=[];
 	
@@ -33,14 +37,14 @@
 		return false;
 	}
 	
-	var CCs = gameState.getOwnEntities().filter(Filters.byClass("CivCentre"));
+	var CCs = gameState.getOwnEntities().filter(API3.Filters.byClass("CivCentre"));
 	if (CCs.length === 0)
 	{
 		this.failed = true;
 		return false;
 	}
 
-	debug ("Target (" + PlayerID +") = " +this.targetPlayer);
+	m.debug ("Target (" + PlayerID +") = " +this.targetPlayer);
 	this.targetFinder = targetFinder || this.defaultTargetFinder;
 	this.type = type || "normal";
 	this.name = uniqueID;
@@ -50,7 +54,7 @@
 	
 	this.maxPreparationTime = 210*1000;
 	// in this case we want to have the attack ready by the 13th minute. Countdown. Minimum 2 minutes.
-	if (type !== "superSized" && Config.difficulty >= 1)
+	if (type !== "superSized" && this.Config.difficulty >= 1)
 		this.maxPreparationTime = 780000 - gameState.getTimeElapsed() < 120000 ? 120000 : 780000 - gameState.getTimeElapsed();
 	
 	this.pausingStart = 0;
@@ -120,7 +124,7 @@
 		return (strength[0] > 15 || strength[1] > 15);
 	};*/
 
-	var filter = Filters.and(Filters.byMetadata(PlayerID, "plan",this.name),Filters.byOwner(PlayerID));
+	var filter = API3.Filters.and(API3.Filters.byMetadata(PlayerID, "plan",this.name),API3.Filters.byOwner(PlayerID));
 	this.unitCollection = gameState.getOwnEntities().filter(filter);
 	this.unitCollection.registerUpdates();
 	this.unitCollection.length;
@@ -136,7 +140,7 @@
 		var cat = unitCat;
 		var Unit = this.unitStat[cat];
 
-		filter = Filters.and(Filters.byClassesAnd(Unit["classes"]),Filters.and(Filters.byMetadata(PlayerID, "plan",this.name),Filters.byOwner(PlayerID)));
+		filter = API3.Filters.and(API3.Filters.byClassesAnd(Unit["classes"]),API3.Filters.and(API3.Filters.byMetadata(PlayerID, "plan",this.name),API3.Filters.byOwner(PlayerID)));
 		this.unit[cat] = gameState.getOwnEntities().filter(filter);
 		this.unit[cat].registerUpdates();
 		this.unit[cat].length;
@@ -186,7 +190,7 @@
 	this.anyNotMinimal = true;	// used for support plans
 
 
-	var myFortresses = gameState.getOwnTrainingFacilities().filter(Filters.byClass("GarrisonFortress"));
+	var myFortresses = gameState.getOwnTrainingFacilities().filter(API3.Filters.byClass("GarrisonFortress"));
 	if (myFortresses.length !== 0)
 	{
 		// make this our rallypoint
@@ -237,11 +241,11 @@
 	
 	this.assignUnits(gameState);
 	
-	//debug ("Before");
+	//m.debug ("Before");
 	//Engine.DumpHeap();
 	
 	// get a good path to an estimated target.
-	this.pathFinder = new aStarPath(gameState,false,false, this.targetPlayer);
+	this.pathFinder = new API3.aStarPath(gameState,false,false, this.targetPlayer);
 	//Engine.DumpImage("widthmap.png", this.pathFinder.widthMap, this.pathFinder.width,this.pathFinder.height,255);
 
 	this.pathWidth = 6;	// prefer a path far from entities. This will avoid units getting stuck in trees and also results in less straight paths.
@@ -249,21 +253,21 @@
 	this.onBoat = false;	// tells us if our units are loaded on boats.
 	this.needsShip = false;
 	
-	//debug ("after");
+	//m.debug ("after");
 	//Engine.DumpHeap();
 	return true;
 };
 
-CityAttack.prototype.getName = function(){
+m.CityAttack.prototype.getName = function(){
 	return this.name;
 };
-CityAttack.prototype.getType = function(){
+m.CityAttack.prototype.getType = function(){
 	return this.type;
 };
 // Returns true if the attack can be executed at the current time
 // Basically his checks we have enough units.
 // We run a count of our units.
-CityAttack.prototype.canStart = function(gameState){	
+m.CityAttack.prototype.canStart = function(gameState){	
 	for (var unitCat in this.unitStat) {
 		var Unit = this.unitStat[unitCat];
 		if (this.unit[unitCat].length < Unit["minSize"])
@@ -273,27 +277,27 @@
 
 	// TODO: check if our target is valid and a few other stuffs (good moment to attack?)
 };
-CityAttack.prototype.isStarted = function(){
+m.CityAttack.prototype.isStarted = function(){
 	if ((this.state !== "unexecuted"))
-		debug ("Attack plan already started");
+		m.debug ("Attack plan already started");
 	return !(this.state == "unexecuted");
 };
 
-CityAttack.prototype.isPaused = function(){
+m.CityAttack.prototype.isPaused = function(){
 	return this.paused;
 };
-CityAttack.prototype.setPaused = function(gameState, boolValue){
+m.CityAttack.prototype.setPaused = function(gameState, boolValue){
 	if (!this.paused && boolValue === true) {
 		this.pausingStart = gameState.getTimeElapsed();
 		this.paused = true;
-		debug ("Pausing attack plan " +this.name);
+		m.debug ("Pausing attack plan " +this.name);
 	} else if (this.paused && boolValue === false) {
 		this.totalPausingTime += gameState.getTimeElapsed() - this.pausingStart;
 		this.paused = false;
-		debug ("Unpausing attack plan " +this.name);
+		m.debug ("Unpausing attack plan " +this.name);
 	}
 };
-CityAttack.prototype.mustStart = function(gameState){
+m.CityAttack.prototype.mustStart = function(gameState){
 	if (this.isPaused() || this.path === undefined)
 		return false;
 	var MaxReachedEverywhere = true;
@@ -309,14 +313,14 @@
 };
 
 // Adds a build order. If resetQueue is true, this will reset the queue.
-CityAttack.prototype.addBuildOrder = function(gameState, name, unitStats, resetQueue) {
+m.CityAttack.prototype.addBuildOrder = function(gameState, name, unitStats, resetQueue) {
 	if (!this.isStarted())
 	{
-		debug ("Adding a build order for " + name);
+		m.debug ("Adding a build order for " + name);
 		// no minsize as we don't want the plan to fail at the last minute though.
 		this.unitStat[name] = unitStats;
 		var Unit = this.unitStat[name];
-		var filter = Filters.and(Filters.byClassesAnd(Unit["classes"]),Filters.and(Filters.byMetadata(PlayerID, "plan",this.name),Filters.byOwner(PlayerID)));
+		var filter = API3.Filters.and(API3.Filters.byClassesAnd(Unit["classes"]),API3.Filters.and(API3.Filters.byMetadata(PlayerID, "plan",this.name),API3.Filters.byOwner(PlayerID)));
 		this.unit[name] = gameState.getOwnEntities().filter(filter);
 		this.unit[name].registerUpdates();
 		this.buildOrder.push([0, Unit["classes"], this.unit[name], Unit, name]);
@@ -330,7 +334,7 @@
 
 // Three returns possible: 1 is "keep going", 0 is "failed plan", 2 is "start"
 // 3 is a special case: no valid path returned. Right now I stop attacking alltogether.
-CityAttack.prototype.updatePreparation = function(gameState, HQ,events) {
+m.CityAttack.prototype.updatePreparation = function(gameState, HQ,events) {
 	var self = this;
 	
 	if (this.path == undefined || this.target == undefined || this.path === "toBeContinued") {
@@ -342,14 +346,14 @@
 				targets = this.defaultTargetFinder(gameState, HQ);
 				
 			if (targets.length !== 0) {
-				debug ("Aiming for " + targets);
+				m.debug ("Aiming for " + targets);
 				// picking a target
 				var maxDist = -1;
 				var index = 0;
 				for (var i in targets._entities)
 				{
 					// we're sure it has a position has TargetFinder already checks that.
-					var dist = SquareVectorDistance(targets._entities[i].position(), this.rallyPoint);
+					var dist = API3.SquareVectorDistance(targets._entities[i].position(), this.rallyPoint);
 					if (dist < maxDist || maxDist === -1)
 					{
 						maxDist = dist;
@@ -385,11 +389,11 @@
 			// Basically we'll add it as a new class to train compulsorily, and we'll recompute our path.
 			if (!gameState.ai.HQ.waterMap)
 			{
-				debug ("This is actually a water map.");
+				m.debug ("This is actually a water map.");
 				gameState.ai.HQ.waterMap = true;
 				return 0;
 			}
-			debug ("We need a ship.");
+			m.debug ("We need a ship.");
 			this.needsShip = true;
 			this.pathWidth = 3;
 			this.pathSampling = 3;
@@ -400,7 +404,7 @@
 			{
 				// my pathfinder returns arrays in arrays in arrays.
 				var waypointPos = this.path[i][0];
-				var territory = Map.createTerritoryMap(gameState);
+				var territory = m.createTerritoryMap(gameState);
 				if (territory.getOwner(waypointPos) !== PlayerID || this.path[i][1] === true)
 				{
 					// if we're suddenly out of our territory or this is the point where we change transportation method.
@@ -426,7 +430,7 @@
 			{
 				// my pathfinder returns arrays in arrays in arrays.
 				var waypointPos = this.path[i][0];
-				var territory = Map.createTerritoryMap(gameState);
+				var territory = m.createTerritoryMap(gameState);
 				if (territory.getOwner(waypointPos) !== PlayerID || this.path[i][1] === true)
 				{
 					// if we're suddenly out of our territory or this is the point where we change transportation method.
@@ -511,7 +515,7 @@
 			
 			if (this.buildOrder[0][0] < 1 && queue.length() <= 5) {
 				var template = HQ.findBestTrainableSoldier(gameState, this.buildOrder[0][1], this.buildOrder[0][3]["interests"] );
-				//debug ("tried " + uneval(this.buildOrder[0][1]) +", and " + template);
+				//m.debug ("tried " + uneval(this.buildOrder[0][1]) +", and " + template);
 				// HACK (TODO replace) : if we have no trainable template... Then we'll simply remove the buildOrder, effectively removing the unit from the plan.
 				if (template === undefined) {
 					// TODO: this is a complete hack.
@@ -523,9 +527,9 @@
 					if (gameState.getTimeElapsed() > 1800000)
 						max *= 2;
 					if (gameState.getTemplate(template).hasClass("CitizenSoldier"))
-						queue.addItem( new TrainingPlan(gameState,template, { "role" : "worker", "plan" : this.name, "special" : specialData, "base" : 1 }, this.buildOrder[0][3]["batchSize"],max ) );
+						queue.addItem( new m.TrainingPlan(gameState,template, { "role" : "worker", "plan" : this.name, "special" : specialData, "base" : 1 }, this.buildOrder[0][3]["batchSize"],max ) );
 					else
-						queue.addItem( new TrainingPlan(gameState,template, { "role" : "attack", "plan" : this.name, "special" : specialData, "base" : 1 }, this.buildOrder[0][3]["batchSize"],max ) );
+						queue.addItem( new m.TrainingPlan(gameState,template, { "role" : "attack", "plan" : this.name, "special" : specialData, "base" : 1 }, this.buildOrder[0][3]["batchSize"],max ) );
 				}
 			}
 		}
@@ -546,7 +550,7 @@
 					this.targetPos = target.position();
 					count++;
 					if (count > 1000){
-						debug("No target with a valid position found");
+						m.debug("No target with a valid position found");
 						return false;
 					}
 				}
@@ -559,7 +563,7 @@
 			if (path !== "toBeContinued") {
 				this.startedPathing = false;
 				this.path = path;
-				debug("Pathing ended");
+				m.debug("Pathing ended");
 			}
 		}
 		*/
@@ -567,7 +571,7 @@
 		Engine.ProfileStop();
 		// can happen for now
 		if (this.buildOrder.length === 0) {
-			debug ("Ending plan: no build orders");
+			m.debug ("Ending plan: no build orders");
 			return 0;	// will abort the plan, should return something else
 		}
 		return 1;
@@ -583,7 +587,7 @@
 		return 0;
 	return 0;
 };
-CityAttack.prototype.assignUnits = function(gameState){
+m.CityAttack.prototype.assignUnits = function(gameState){
 	var self = this;
 
 	// TODO: assign myself units that fit only, right now I'm getting anything.
@@ -604,14 +608,14 @@
 
 };
 // this sends a unit by ID back to the "rally point"
-CityAttack.prototype.ToRallyPoint = function(gameState,id)
+m.CityAttack.prototype.ToRallyPoint = function(gameState,id)
 {	
 	// Move back to nearest rallypoint
 	gameState.getEntityById(id).move(this.rallyPoint[0],this.rallyPoint[1]);
 }
 // this sends all units back to the "rally point" by entity collections.
 // It doesn't disturb ones that could be currently defending, even if the plan is not (yet) paused.
-CityAttack.prototype.AllToRallyPoint = function(gameState, evenWorkers) {
+m.CityAttack.prototype.AllToRallyPoint = function(gameState, evenWorkers) {
 	var self = this;
 	if (evenWorkers) {
 		for (var unitCat in this.unit) {
@@ -634,7 +638,7 @@
 }
 
 // Default target finder aims for conquest critical targets
-CityAttack.prototype.defaultTargetFinder = function(gameState, HQ){
+m.CityAttack.prototype.defaultTargetFinder = function(gameState, HQ){
 	var targets = undefined;
 	
 	targets = HQ.enemyWatchers[this.targetPlayer].getEnemyBuildings(gameState, "CivCentre",true);
@@ -650,13 +654,13 @@
 	}
 	// no buildings, attack anything conquest critical, even units (it's assuming it won't move).
 	if (targets.length == 0) {
-		targets = gameState.getEnemyEntities().filter(Filters.and( Filters.byOwner(this.targetPlayer),Filters.byClass("ConquestCritical")));
+		targets = gameState.getEnemyEntities().filter(API3.Filters.and( API3.Filters.byOwner(this.targetPlayer),API3.Filters.byClass("ConquestCritical")));
 	}
 	return targets;
 };
 
 // tupdate
-CityAttack.prototype.raidingTargetFinder = function(gameState, HQ, Target){
+m.CityAttack.prototype.raidingTargetFinder = function(gameState, HQ, Target){
 	var targets = undefined;
 	if (Target == "villager")
 	{
@@ -684,7 +688,7 @@
 // Executes the attack plan, after this is executed the update function will be run every turn
 // If we're here, it's because we have in our IDlist enough units.
 // now the IDlist units are treated turn by turn
-CityAttack.prototype.StartAttack = function(gameState, HQ){
+m.CityAttack.prototype.StartAttack = function(gameState, HQ){
 	
 	// check we have a target and a path.
 	if (this.targetPos && this.path !== undefined) {
@@ -701,19 +705,19 @@
 		
 		this.unitCollection.move(this.path[0][0][0], this.path[0][0][1]);
 		this.unitCollection.setStance("aggressive");
-		this.unitCollection.filter(Filters.byClass("Siege")).setStance("defensive");
+		this.unitCollection.filter(API3.Filters.byClass("Siege")).setStance("defensive");
 
 		this.state = "walking";
 	} else {
 		gameState.ai.gameFinished = true;
-		debug ("I do not have any target. So I'll just assume I won the game.");
+		m.debug ("I do not have any target. So I'll just assume I won the game.");
 		return false;
 	}
 	return true;
 };
 
 // Runs every turn after the attack is executed
-CityAttack.prototype.update = function(gameState, HQ, events){
+m.CityAttack.prototype.update = function(gameState, HQ, events){
 	var self = this;
 		
 	Engine.ProfileStart("Update Attack");
@@ -750,7 +754,7 @@
 
 					if (attacker && attacker.position() && attacker.hasClass("Unit") && attacker.owner() != 0 && attacker.owner() != PlayerID) {
 						
-						var territoryMap = Map.createTerritoryMap(gameState);
+						var territoryMap = m.createTerritoryMap(gameState);
 						if ( +territoryMap.point(attacker.position()) - 64 === +this.targetPlayer)
 						{
 							attackedNB++;
@@ -769,7 +773,7 @@
 			}
 		}
 		if (attackedNB > 4) {
-			debug ("Attack Plan " +this.type +" " +this.name +" has arrived to destination.");
+			m.debug ("Attack Plan " +this.type +" " +this.name +" has arrived to destination.");
 			// we must assume we've arrived at the end of the trail.
 			this.state = "arrived";
 		}
@@ -799,7 +803,7 @@
 								var enemy = enemySoldiers[j];
 								if (enemy.position() === undefined)	// likely garrisoned
 									continue;
-								if (inRange(enemy.position(), attacker.position(), 1000) && this.threatList.indexOf(enemy.id()) === -1)
+								if (m.inRange(enemy.position(), attacker.position(), 1000) && this.threatList.indexOf(enemy.id()) === -1)
 									this.threatList.push(enemy.id());
 							}
 							this.threatList.push(e.msg.attacker);
@@ -844,16 +848,16 @@
 		}
 
 		// basically haven't moved an inch: very likely stuck)
-		if (SquareVectorDistance(this.position, this.position5TurnsAgo) < 10 && this.path.length > 0 && gameState.ai.playedTurn % 5 === 0) {
+		if (API3.SquareVectorDistance(this.position, this.position5TurnsAgo) < 10 && this.path.length > 0 && gameState.ai.playedTurn % 5 === 0) {
 			// check for stuck siege units
 			
-			var sieges = this.unitCollection.filter(Filters.byClass("Siege"));
+			var sieges = this.unitCollection.filter(API3.Filters.byClass("Siege"));
 			var farthest = 0;
 			var farthestEnt = -1;
 			sieges.forEach (function (ent) {
-				if (SquareVectorDistance(ent.position(),self.position) > farthest)
+				if (API3.SquareVectorDistance(ent.position(),self.position) > farthest)
 				{
-					farthest = SquareVectorDistance(ent.position(),self.position);
+					farthest = API3.SquareVectorDistance(ent.position(),self.position);
 					farthestEnt = ent;
 				}
 			});
@@ -863,42 +867,42 @@
 		if (gameState.ai.playedTurn % 5 === 0)
 			this.position5TurnsAgo = this.position;
 		
-		if (this.lastPosition && SquareVectorDistance(this.position, this.lastPosition) < 20 && this.path.length > 0) {
+		if (this.lastPosition && API3.SquareVectorDistance(this.position, this.lastPosition) < 20 && this.path.length > 0) {
 			this.unitCollection.moveIndiv(this.path[0][0][0], this.path[0][0][1]);
 			// We're stuck, presumably. Check if there are no walls just close to us. If so, we're arrived, and we're gonna tear down some serious stone.
-			var walls = gameState.getEnemyEntities().filter(Filters.and(Filters.byOwner(this.targetPlayer), Filters.byClass("StoneWall")));
+			var walls = gameState.getEnemyEntities().filter(API3.Filters.and(API3.Filters.byOwner(this.targetPlayer), API3.Filters.byClass("StoneWall")));
 			var nexttoWalls = false;
 			walls.forEach( function (ent) {
-				if (!nexttoWalls && SquareVectorDistance(self.position, ent.position()) < 800)
+				if (!nexttoWalls && API3.SquareVectorDistance(self.position, ent.position()) < 800)
 					nexttoWalls = true;
 			});
 			// there are walls but we can attack
-			if (nexttoWalls && this.unitCollection.filter(Filters.byCanAttack("StoneWall")).length !== 0)
+			if (nexttoWalls && this.unitCollection.filter(API3.Filters.byCanAttack("StoneWall")).length !== 0)
 			{
-				debug ("Attack Plan " +this.type +" " +this.name +" has met walls and is not happy.");
+				m.debug ("Attack Plan " +this.type +" " +this.name +" has met walls and is not happy.");
 				this.state = "arrived";
 			} else if (nexttoWalls) {
 				// abort plan.
-				debug ("Attack Plan " +this.type +" " +this.name +" has met walls and gives up.");
+				m.debug ("Attack Plan " +this.type +" " +this.name +" has met walls and gives up.");
 				Engine.ProfileStop();
 				return 0;
 			}
 		}
 		
 		// check if our land units are close enough from the next waypoint.
-		if (SquareVectorDistance(this.unitCollection.getCentrePosition(), this.targetPos) < 7500 ||
-			SquareVectorDistance(this.unitCollection.getCentrePosition(), this.path[0][0]) < 650) {
-			if (this.unitCollection.filter(Filters.byClass("Siege")).length !== 0
-				&& SquareVectorDistance(this.unitCollection.getCentrePosition(), this.targetPos) >= 7500
-				&& SquareVectorDistance(this.unitCollection.filter(Filters.byClass("Siege")).getCentrePosition(), this.path[0][0]) >= 650)
+		if (API3.SquareVectorDistance(this.unitCollection.getCentrePosition(), this.targetPos) < 7500 ||
+			API3.SquareVectorDistance(this.unitCollection.getCentrePosition(), this.path[0][0]) < 650) {
+			if (this.unitCollection.filter(API3.Filters.byClass("Siege")).length !== 0
+				&& API3.SquareVectorDistance(this.unitCollection.getCentrePosition(), this.targetPos) >= 7500
+				&& API3.SquareVectorDistance(this.unitCollection.filter(API3.Filters.byClass("Siege")).getCentrePosition(), this.path[0][0]) >= 650)
 			{
 			} else {
 
 				for (var i = 0; i < this.path.length; ++i)
 				{
-					debug ("path waypoint " + i + "," + this.path[i][1] + " at " + uneval(this.path[i][0]));
+					m.debug ("path waypoint " + i + "," + this.path[i][1] + " at " + uneval(this.path[i][0]));
 				}
-				debug ("position is " + this.unitCollection.getCentrePosition());
+				m.debug ("position is " + this.unitCollection.getCentrePosition());
 
 				// okay so here basically two cases. The first one is "we need a boat at this point".
 				// the second one is "we need to unload at this point". The third is "normal".
@@ -908,7 +912,7 @@
 					if (this.path.length > 0){
 						this.unitCollection.move(this.path[0][0][0], this.path[0][0][1]);
 					} else {
-						debug ("Attack Plan " +this.type +" " +this.name +" has arrived to destination.");
+						m.debug ("Attack Plan " +this.type +" " +this.name +" has arrived to destination.");
 						// we must assume we've arrived at the end of the trail.
 						this.state = "arrived";
 					}
@@ -917,7 +921,7 @@
 					// TODO: make this require an escort later on.
 					this.path.shift();
 					if (this.path.length === 0) {
-						debug ("Attack Plan " +this.type +" " +this.name +" has arrived to destination.");
+						m.debug ("Attack Plan " +this.type +" " +this.name +" has arrived to destination.");
 						// we must assume we've arrived at the end of the trail.
 						this.state = "arrived";
 					} else {
@@ -925,7 +929,7 @@
 						var plan = new TransportPlan(gameState, this.unitCollection.toIdArray(), this.path[0][0], false);
 						this.tpPlanID = plan.ID;
 						HQ.navalManager.transportPlans.push(plan);
-						debug ("Transporting over sea");
+						m.debug ("Transporting over sea");
 						this.state = "transporting";
 					*/
 						// TODO: fix this above
@@ -962,7 +966,7 @@
 				});
 			var targetList = [];
 			enemyCitizens.forEach( function (enemy) {
-				if (inRange(enemy.position(), units.getCentrePosition(), 2500) && targetList.indexOf(enemy.id()) === -1)
+				if (m.inRange(enemy.position(), units.getCentrePosition(), 2500) && targetList.indexOf(enemy.id()) === -1)
 					targetList.push(enemy.id());
 			});
 			if (targetList.length > 0)
@@ -989,7 +993,7 @@
 					if (attacker && attacker.position() && attacker.hasClass("Unit") && attacker.owner() != 0 && attacker.owner() != PlayerID) {
 						if (ourUnit.hasClass("Siege"))
 						{
-							var collec = this.unitCollection.filterNearest(ourUnit.position(), 8).filter(Filters.not(Filters.byClass("Siege"))).toEntityArray();
+							var collec = this.unitCollection.filterNearest(ourUnit.position(), 8).filter(API3.Filters.not(API3.Filters.byClass("Siege"))).toEntityArray();
 							if (collec.length !== 0)
 							{
 								collec[0].attack(attacker.id());
@@ -1018,7 +1022,7 @@
 			this.unitCollUpdateArray = this.unitCollection.toIdArray();
 		} else {
 			// some stuffs for locality and speed
-			var territoryMap = Map.createTerritoryMap(gameState);
+			var territoryMap = m.createTerritoryMap(gameState);
 			var timeElapsed = gameState.getTimeElapsed();
 			
 			// Let's check a few units each time we update. Currently 10
@@ -1057,7 +1061,7 @@
 						if (!enemy.position() || (enemy.hasClass("StoneWall") && ent.canAttackClass("StoneWall"))) {
 							return false;
 						}
-						if (SquareVectorDistance(enemy.position(),ent.position()) > 3000) {
+						if (API3.SquareVectorDistance(enemy.position(),ent.position()) > 3000) {
 							return false;
 						}
 						return true;
@@ -1070,7 +1074,7 @@
 							}
 							if (!enemy.hasClass("Support"))
 								return false;
-							if (SquareVectorDistance(enemy.position(),ent.position()) > 10000) {
+							if (API3.SquareVectorDistance(enemy.position(),ent.position()) > 10000) {
 								return false;
 							}
 							return true;
@@ -1081,7 +1085,7 @@
 							if (!enemy.position()) {
 								return false;
 							}
-							if (SquareVectorDistance(enemy.position(),ent.position()) > 10000) {
+							if (API3.SquareVectorDistance(enemy.position(),ent.position()) > 10000) {
 								return false;
 							}
 							return true;
@@ -1118,19 +1122,19 @@
 							{
 								var rand = Math.floor(Math.random() * mStruct.length*0.1);
 								ent.attack(mStruct[+rand].id());
-								//debug ("Siege units attacking a structure from " +mStruct[+rand].owner() + " , " +mStruct[+rand].templateName());
+								//m.debug ("Siege units attacking a structure from " +mStruct[+rand].owner() + " , " +mStruct[+rand].templateName());
 							}
-						} else if (SquareVectorDistance(self.targetPos, ent.position()) > 900 ){
-							//debug ("Siege units moving to " + uneval(self.targetPos));
+						} else if (API3.SquareVectorDistance(self.targetPos, ent.position()) > 900 ){
+							//m.debug ("Siege units moving to " + uneval(self.targetPos));
 							ent.move(self.targetPos[0],self.targetPos[1]);
 						}
 					} else {
 						if (mUnit.length !== 0) {
 							var rand = Math.floor(Math.random() * mUnit.length*0.99);
 							ent.attack(mUnit[(+rand)].id());
-							//debug ("Units attacking a unit from " +mUnit[+rand].owner() + " , " +mUnit[+rand].templateName());
-						} else if (SquareVectorDistance(self.targetPos, ent.position()) > 900 ){
-							//debug ("Units moving to " + uneval(self.targetPos));
+							//m.debug ("Units attacking a unit from " +mUnit[+rand].owner() + " , " +mUnit[+rand].templateName());
+						} else if (API3.SquareVectorDistance(self.targetPos, ent.position()) > 900 ){
+							//m.debug ("Units moving to " + uneval(self.targetPos));
 							ent.move(self.targetPos[0],self.targetPos[1]);
 						} else if (mStruct.length !== 0) {
 							mStruct.sort(function (structa,structb) { //}){
@@ -1156,7 +1160,7 @@
 							{
 								var rand = Math.floor(Math.random() * mStruct.length*0.1);
 								ent.attack(mStruct[+rand].id());
-								//debug ("Units attacking a structure from " +mStruct[+rand].owner() + " , " +mStruct[+rand].templateName());
+								//m.debug ("Units attacking a structure from " +mStruct[+rand].owner() + " , " +mStruct[+rand].templateName());
 							}
 						}
 					}
@@ -1172,8 +1176,8 @@
 				targets = this.defaultTargetFinder(gameState, HQ);
 			}
 			if (targets.length) {
-				debug ("Seems like our target has been destroyed. Switching.");
-				debug ("Aiming for " + targets);
+				m.debug ("Seems like our target has been destroyed. Switching.");
+				m.debug ("Aiming for " + targets);
 				// picking a target
 				this.targetPos = undefined;
 				var count = 0;
@@ -1183,7 +1187,7 @@
 					this.targetPos = this.target.position();
 					count++;
 					if (count > 1000){
-						debug("No target with a valid position found");
+						m.debug("No target with a valid position found");
 						Engine.ProfileStop();
 						return false;
 					}
@@ -1215,7 +1219,7 @@
 	
 	return this.unitCollection.length;
 };
-CityAttack.prototype.totalCountUnits = function(gameState){
+m.CityAttack.prototype.totalCountUnits = function(gameState){
 	var totalcount = 0;
 	for (var i in this.idList)
 	{
@@ -1224,7 +1228,7 @@
 	return totalcount;
 };
 // reset any units
-CityAttack.prototype.Abort = function(gameState){	
+m.CityAttack.prototype.Abort = function(gameState){	
 	this.unitCollection.forEach(function(ent) {
 		ent.setMetadata(PlayerID, "role",undefined);
 		ent.setMetadata(PlayerID, "subrole",undefined);
@@ -1238,3 +1242,6 @@
 	gameState.ai.queueManager.removeQueue("plan_" + this.name);
 	gameState.ai.queueManager.removeQueue("plan_" + this.name + "_champ");
 };
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/plan-transport.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/plan-transport.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/plan-transport.js	(Arbeitskopie)
@@ -1,3 +1,6 @@
+var AEGIS = function(m)
+{
+
 /*
  Describes a transport plan
  Constructor assign units (units is an ID array, or an ID), a destionation (position, ingame), and a wanted escort size.
@@ -15,10 +18,10 @@
 // TODO: finish the support of multiple accessibility indexes.
 // TODO: this doesn't check we can actually reach in the init, which we might want?
 
-var TransportPlan = function(gameState, units, destination, allAtOnce, escortSize, onlyIfOK) {
+m.TransportPlan = function(gameState, units, destination, allAtOnce, escortSize, onlyIfOK) {
 	var self = this;
 
-	this.ID = uniqueIDTPlans++;
+	this.ID = m.playerGlobals[PlayerID].uniqueIDTPlans++;
 	
 	var unitsID = [];
 	if (units.length !== undefined)
@@ -26,7 +29,7 @@
 	else
 		unitsID = [units];
 	
-	this.units = EntityCollectionFromIds(gameState, unitsID);
+	this.units = m.EntityCollectionFromIds(gameState, unitsID);
 	this.units.forEach(function (ent) { //}){
 		ent.setMetadata(PlayerID, "tpplan", self.ID);
 		ent.setMetadata(PlayerID, "formerRole", ent.getMetadata(PlayerID, "role"));
@@ -36,8 +39,8 @@
 	this.units.freeze();
 	this.units.registerUpdates();
 
-	debug ("Starting a new plan with ID " +  this.ID + " to " + destination);
-	debug ("units are " + uneval (units));
+	m.debug ("Starting a new plan with ID " +  this.ID + " to " + destination);
+	m.debug ("units are " + uneval (units));
 	
 	this.destination = destination;
 	this.destinationIndex = gameState.ai.accessibility.getAccessValue(destination);
@@ -70,7 +73,7 @@
 };
 
 // count available slots
-TransportPlan.prototype.countFreeSlots = function(onlyTrulyFree)
+m.TransportPlan.prototype.countFreeSlots = function(onlyTrulyFree)
 {
 	var slots = 0;
 	this.transportShips.forEach(function (ent) { //}){
@@ -80,12 +83,12 @@
 	});
 }
 
-TransportPlan.prototype.assignShip = function(gameState, ship)
+m.TransportPlan.prototype.assignShip = function(gameState, ship)
 {
 	ship.setMetadata(PlayerID,"tpplan", this.ID);
 }
 
-TransportPlan.prototype.releaseAll = function(gameState)
+m.TransportPlan.prototype.releaseAll = function(gameState)
 {
 	this.ships.forEach(function (ent) { ent.setMetadata(PlayerID,"tpplan", undefined) });
 	this.units.forEach(function (ent) {
@@ -96,25 +99,25 @@
 	});
 }
 
-TransportPlan.prototype.releaseAllShips = function(gameState)
+m.TransportPlan.prototype.releaseAllShips = function(gameState)
 {
 	this.ships.forEach(function (ent) { ent.setMetadata(PlayerID,"tpplan", undefined) });
 }
 
-TransportPlan.prototype.needTpShips = function()
+m.TransportPlan.prototype.needTpShips = function()
 {
 	if ((this.allAtOnce && this.countFreeSlots() >= this.units.length) || this.transportShips.length > 0)
 		return false;
 	return true;
 }
 
-TransportPlan.prototype.needEscortShips = function()
+m.TransportPlan.prototype.needEscortShips = function()
 {
 	return !((this.onlyIfOK && this.escortShips.length < this.escortSize) || !this.onlyIfOK);
 }
 
 // returns the zone for which we are needing our ships
-TransportPlan.prototype.neededShipsZone = function()
+m.TransportPlan.prototype.neededShipsZone = function()
 {
 	if (!this.seaZone)
 		return false;
@@ -134,7 +137,7 @@
 	> there is the possibility that we'll be moving units on land, but that's basically a restart too, with more clearing.
  Grouping Path is basically the same with "grouping" and we never unboard (unless there is a need to)
  */
-TransportPlan.prototype.carryOn = function(gameState, navalManager)
+m.TransportPlan.prototype.carryOn = function(gameState, navalManager)
 {
 	if (this.state === "unstarted")
 	{
@@ -171,7 +174,7 @@
 		// let's get our index this turn.
 		this.startIndex = unitIndexes[0];
 
-		debug ("plan " +  this.ID + " from " + this.startIndex);
+		m.debug ("plan " +  this.ID + " from " + this.startIndex);
 
 		return true;
 	}
@@ -190,7 +193,7 @@
 			}
 			// we have a path, register the first sea zone.
 			this.seaZone = this.path[1];
-			debug ("Plan " + this.ID + " over seazone " + this.seaZone);
+			m.debug ("Plan " + this.ID + " over seazone " + this.seaZone);
 		}
 		// if we currently have no baoarding spot, try and find one.
 		if (!this.boardingSpot)
@@ -206,10 +209,10 @@
 			var passabilityMap = gameState.getMap();
 			var territoryMap = gameState.ai.territoryMap;
 			var obstructionMask = gameState.getPassabilityClassMask("foundationObstruction") | gameState.getPassabilityClassMask("building-shore");
-			var obstructions = new Map(gameState.sharedScript);
+			var obstructions = new API3.Map(gameState.sharedScript);
 			
 			// wanted map.
-			var friendlyTiles = new Map(gameState.sharedScript);
+			var friendlyTiles = new API3.Map(gameState.sharedScript);
 			
 			for (var j = 0; j < friendlyTiles.length; ++j)
 			{
@@ -248,7 +251,7 @@
 			
 			// we have the spot we want to board at.
 			this.boardingSpot = [x,z];
-			debug ("Plan " + this.ID + " new boarding spot is  " + this.boardingSpot);
+			m.debug ("Plan " + this.ID + " new boarding spot is  " + this.boardingSpot);
 		}
 
 		// if all at once we need to be full, else we just need enough escort ships.
@@ -262,7 +265,7 @@
 			
 			this.garrisonShipID = -1;
 			
-			debug ("Boarding");
+			m.debug ("Boarding");
 			this.state = "boarding";
 		}
 		return true;
@@ -300,12 +303,12 @@
 
 		// check if we need to move our units and ships closer together
 		var stillMoving = false;
-		if (SquareVectorDistance(this.ships.getCentrePosition(),this.boardingSpot) > 1600)
+		if (API3.SquareVectorDistance(this.ships.getCentrePosition(),this.boardingSpot) > 1600)
 		{
 			this.ships.move(this.boardingSpot[0],this.boardingSpot[1]);
 			stillMoving = true;	// wait till ships are in position
 		}
-		if (SquareVectorDistance(this.units.getCentrePosition(),this.boardingSpot) > 1600)
+		if (API3.SquareVectorDistance(this.units.getCentrePosition(),this.boardingSpot) > 1600)
 		{
 			this.units.move(this.boardingSpot[0],this.boardingSpot[1]);
 			stillMoving = true;	// wait till units are in position
@@ -365,10 +368,10 @@
 			var passabilityMap = gameState.getMap();
 			var territoryMap = gameState.ai.territoryMap;
 			var obstructionMask = gameState.getPassabilityClassMask("foundationObstruction") | gameState.getPassabilityClassMask("building-shore");
-			var obstructions = new Map(gameState.sharedScript);
+			var obstructions = new API3.Map(gameState.sharedScript);
 			
 			// wanted map.
-			var friendlyTiles = new Map(gameState.sharedScript);
+			var friendlyTiles = new API3.Map(gameState.sharedScript);
 			
 			var wantedIndex = -1;
 			
@@ -377,7 +380,7 @@
 				this.path.splice(0,2);
 				wantedIndex = this.path[0];
 			} else {
-				debug ("too short at " +uneval(this.path));
+				m.debug ("too short at " +uneval(this.path));
 				return false; // Incomputable
 			}
 			
@@ -431,7 +434,7 @@
 			return false;
 		
 		// check if we need to move ships
-		if (SquareVectorDistance(this.ships.getCentrePosition(),this.unboardingSpot) > 400)
+		if (API3.SquareVectorDistance(this.ships.getCentrePosition(),this.unboardingSpot) > 400)
 		{
 			this.ships.move(this.unboardingSpot[0],this.unboardingSpot[1]);
 		} else {
@@ -447,7 +450,7 @@
 			return false;
 		
 		// check if we need to move ships
-		if (SquareVectorDistance(this.ships.getCentrePosition(),this.unboardingSpot) > 400)
+		if (API3.SquareVectorDistance(this.ships.getCentrePosition(),this.unboardingSpot) > 400)
 		{
 			this.ships.move(this.unboardingSpot[0],this.unboardingSpot[1]);
 		} else {
@@ -455,7 +458,7 @@
 			// TODO: improve on this.
 			if (this.path.length > 1)
 			{
-				debug ("plan " +  this.ID + " going back for more");
+				m.debug ("plan " +  this.ID + " going back for more");
 				// basically reset.
 				delete this.boardingSpot;
 				delete this.unboardingSpot;
@@ -463,10 +466,13 @@
 				this.releaseAllShips();
 				return true;
 			}
-			debug ("plan " +  this.ID + " is finished");
+			m.m.debug ("plan " +  this.ID + " is finished");
 			return false;
 		}
 	}
 
 	return true;
 }
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/aegis.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/aegis.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/aegis.js	(Arbeitskopie)
@@ -1,28 +1,33 @@
+
+var AEGIS = (function() {
+var m = {};
+
 // "local" global variables for stuffs that will need a unique ID
 // Note that since order of loading is alphabetic, this means this file must go before any other file using them.
-var uniqueIDBOPlans = 0;	// training/building/research plans
-var uniqueIDBases = 1;	// base manager ID. Starts at one because "0" means "no base" on the map
-var uniqueIDTPlans = 1;	// transport plans. starts at 1 because 0 might be used as none.
+m.playerGlobals = [];
+m.g_debugEnabled = false;
 
-function AegisBot(settings) {
-	BaseAI.call(this, settings);
+m.AegisBot = function AegisBot(settings) {
+	API3.BaseAI.call(this, settings);
 
-	Config.updateDifficulty(settings.difficulty);
+	this.Config = new m.Config();
+
+	this.Config.updateDifficulty(settings.difficulty);
 	
 	this.turn = 0;
 
 	this.playedTurn = 0;
-		
-	this.priorities = Config.priorities;
+	
+	this.priorities = this.Config.priorities;
 
 	// this.queues can only be modified by the queue manager or things will go awry.
 	this.queues = {};
 	for (i in this.priorities)
-		this.queues[i] = new Queue();
+		this.queues[i] = new m.Queue();
 
-	this.queueManager = new QueueManager(this.queues, this.priorities);
+	this.queueManager = new m.QueueManager(this.Config, this.queues, this.priorities);
 
-	this.HQ = new HQ();
+	this.HQ = new m.HQ(this.Config);
 
 	this.firstTime = true;
 
@@ -30,34 +35,39 @@
 	
 	this.defcon = 5;
 	this.defconChangeTime = -10000000;
-}
+};
 
-AegisBot.prototype = new BaseAI();
+m.AegisBot.prototype = new API3.BaseAI();
 
-AegisBot.prototype.CustomInit = function(gameState, sharedScript) {
-	
+m.AegisBot.prototype.CustomInit = function(gameState, sharedScript) {
+
+	m.playerGlobals[PlayerID] = {};
+	m.playerGlobals[PlayerID].uniqueIDBOPlans = 0;	// training/building/research plans
+	m.playerGlobals[PlayerID].uniqueIDBases = 1;	// base manager ID. Starts at one because "0" means "no base" on the map
+	m.playerGlobals[PlayerID].uniqueIDTPlans = 1;	// transport plans. starts at 1 because 0 might be used as none.	
+
 	this.HQ.init(gameState,sharedScript.events,this.queues);
-	debug ("Initialized with the difficulty " + Config.difficulty);
+	m.debug ("Initialized with the difficulty " + this.Config.difficulty);
 
-	var ents = gameState.getEntities().filter(Filters.byOwner(PlayerID));
+	var ents = gameState.getEntities().filter(API3.Filters.byOwner(this.player));
 	var myKeyEntities = ents.filter(function(ent) {
 			return ent.hasClass("CivCentre");
 	});
 
 	if (myKeyEntities.length == 0){
-		myKeyEntities = gameState.getEntities().filter(Filters.byOwner(PlayerID));
+		myKeyEntities = gameState.getEntities().filter(API3.Filters.byOwner(this.player));
 	}
 	
-	var filter = Filters.byClass("CivCentre");
-	var enemyKeyEntities = gameState.getEntities().filter(Filters.not(Filters.byOwner(PlayerID))).filter(filter);
+	var filter = API3.Filters.byClass("CivCentre");
+	var enemyKeyEntities = gameState.getEntities().filter(API3.Filters.not(API3.Filters.byOwner(this.player))).filter(filter);
 	
 	if (enemyKeyEntities.length == 0){
-		enemyKeyEntities = gameState.getEntities().filter(Filters.not(Filters.byOwner(PlayerID)));
+		enemyKeyEntities = gameState.getEntities().filter(API3.Filters.not(API3.Filters.byOwner(this.player)));
 	}
 
 	this.myIndex = this.accessibility.getAccessValue(myKeyEntities.toEntityArray()[0].position());
 	
-	this.pathFinder = new aStarPath(gameState, false, true);
+	this.pathFinder = new API3.aStarPath(gameState, false, true);
 	this.pathsToMe = [];
 	this.pathInfo = { "angle" : 0, "needboat" : true, "mkeyPos" : myKeyEntities.toEntityArray()[0].position(), "ekeyPos" : enemyKeyEntities.toEntityArray()[0].position() };
 	
@@ -65,7 +75,7 @@
 	var pos = [this.pathInfo.mkeyPos[0] + 150*Math.cos(this.pathInfo.angle),this.pathInfo.mkeyPos[1] + 150*Math.sin(this.pathInfo.angle)];
 	var path = this.pathFinder.getPath(this.pathInfo.ekeyPos, pos, 2, 2);// uncomment for debug:*/, 300000, gameState);
 
-	//Engine.DumpImage("initialPath" + PlayerID + ".png", this.pathFinder.TotorMap.map, this.pathFinder.TotorMap.width,this.pathFinder.TotorMap.height,255);
+	//Engine.DumpImage("initialPath" + this.player + ".png", this.pathFinder.TotorMap.map, this.pathFinder.TotorMap.width,this.pathFinder.TotorMap.height,255);
 	
 	if (path !== undefined && path[1] !== undefined && path[1] == false) {
 		// path is viable and doesn't require boating.
@@ -80,7 +90,8 @@
 	this.chooseRandomStrategy();
 }
 
-AegisBot.prototype.OnUpdate = function(sharedScript) {
+m.AegisBot.prototype.OnUpdate = function(sharedScript) {
+
 	if (this.gameFinished){
 		return;
 	}
@@ -120,7 +131,7 @@
 			{
 				if (this.pathInfo.needboat)
 				{
-					debug ("Assuming this is a water map");
+					m.debug ("Assuming this is a water map");
 					this.HQ.waterMap = true;
 				}
 				delete this.pathFinder;
@@ -132,27 +143,27 @@
 		var cityPhase = this.gameState.cityPhase();
 		// try going up phases.
 		// TODO: softcode this.
-		if (this.gameState.canResearch(townPhase,true) && this.gameState.getTimeElapsed() > (Config.Economy.townPhase*1000) && this.gameState.getPopulation() > 40
+		if (this.gameState.canResearch(townPhase,true) && this.gameState.getTimeElapsed() > (this.Config.Economy.townPhase*1000) && this.gameState.getPopulation() > 40
 			&& this.gameState.findResearchers(townPhase,true).length != 0 && this.queues.majorTech.length() === 0
-			&& this.gameState.getOwnEntities().filter(Filters.byClass("Village")).length > 5)
+			&& this.gameState.getOwnEntities().filter(API3.Filters.byClass("Village")).length > 5)
 		{
 			this.queueManager.pauseQueue("villager", true);
 			this.queueManager.pauseQueue("citizenSoldier", true);
 			this.queueManager.pauseQueue("house", true);
-			this.queues.majorTech.addItem(new ResearchPlan(this.gameState, townPhase,0,-1,true));	// we rush the town phase.
-			debug ("Trying to reach town phase");
+			this.queues.majorTech.addItem(new m.ResearchPlan(this.gameState, townPhase,0,-1,true));	// we rush the town phase.
+			m.debug ("Trying to reach town phase");
 		}
-		else if (this.gameState.canResearch(cityPhase,true) && this.gameState.getTimeElapsed() > (Config.Economy.cityPhase*1000)
+		else if (this.gameState.canResearch(cityPhase,true) && this.gameState.getTimeElapsed() > (this.Config.Economy.cityPhase*1000)
 				&& this.gameState.getOwnEntitiesByRole("worker").length > 85
 				&& this.gameState.findResearchers(cityPhase, true).length != 0 && this.queues.majorTech.length() === 0) {
-			debug ("Trying to reach city phase");
-			this.queues.majorTech.addItem(new ResearchPlan(this.gameState, cityPhase));
+			m.debug ("Trying to reach city phase");
+			this.queues.majorTech.addItem(new m.ResearchPlan(this.gameState, cityPhase));
 		}
 		// defcon cooldown
 		if (this.defcon < 5 && this.gameState.timeSinceDefconChange() > 20000)
 		{
 			this.defcon++;
-			debug ("updefconing to " +this.defcon);
+			m.debug ("updefconing to " +this.defcon);
 			if (this.defcon >= 4 && this.HQ.hasGarrisonedFemales)
 				this.HQ.ungarrisonAll(this.gameState);
 		}
@@ -210,24 +221,24 @@
 	this.turn++;
 };
 
-AegisBot.prototype.chooseRandomStrategy = function()
+m.AegisBot.prototype.chooseRandomStrategy = function()
 {
 	// deactivated for now.
 	this.strategy = "normal";
 	// rarely and if we can assume it's not a water map.
-	if (!this.pathInfo.needboat && 0)//Math.random() < 0.2 && Config.difficulty == 2)
+	if (!this.pathInfo.needboat && 0)//Math.random() < 0.2 && this.Config.difficulty == 2)
 	{
 		this.strategy = "rush";
 		// going to rush.
 		this.HQ.targetNumWorkers = 0;
-		Config.Economy.townPhase = 480;
-		Config.Economy.cityPhase = 900;
-		Config.Economy.farmsteadStartTime = 600;
-		Config.Economy.femaleRatio = 0;	// raise it since we'll want to rush age 2.
+		this.Config.Economy.townPhase = 480;
+		this.Config.Economy.cityPhase = 900;
+		this.Config.Economy.farmsteadStartTime = 600;
+		this.Config.Economy.femaleRatio = 0;	// raise it since we'll want to rush age 2.
 	}
 };
 
-/*AegisBot.prototype.Deserialize = function(data, sharedScript)
+/*m.AegisBot.prototype.Deserialize = function(data, sharedScript)
 {
 };
 
@@ -237,21 +248,24 @@
 	return {};
 };*/
 
-function debug(output){
-	if (Config.debug){
+m.debug = function(output){
+	if (m.g_debugEnabled){
 		if (typeof output === "string"){
 			warn(output);
 		}else{
 			warn(uneval(output));
 		}
 	}
-}
+};
 
-function copyPrototype(descendant, parent) {
+m.copyPrototype = function(descendant, parent) {
     var sConstructor = parent.toString();
     var aMatch = sConstructor.match( /\s*function (.*)\(/ );
     if ( aMatch != null ) { descendant.prototype[aMatch[1]] = parent; }
     for (var m in parent.prototype) {
         descendant.prototype[m] = parent.prototype[m];
     }
-}
+};
+
+return m;
+}());
Index: binaries/data/mods/public/simulation/ai/aegis/queueplan-building.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/queueplan-building.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/queueplan-building.js	(Arbeitskopie)
@@ -1,10 +1,13 @@
-var ConstructionPlan = function(gameState, type, metadata, startTime, expectedTime, position) {
+var AEGIS = function(m)
+{
+
+m.ConstructionPlan = function(gameState, type, metadata, startTime, expectedTime, position) {
 	this.type = gameState.applyCiv(type);
 	this.position = position;
 
 	this.metadata = metadata;
 
-	this.ID = uniqueIDBOPlans++;
+	this.ID = m.playerGlobals[PlayerID].uniqueIDBOPlans++;
 
 	this.template = gameState.getTemplate(this.type);
 	if (!this.template) {
@@ -12,7 +15,7 @@
 	}
 	
 	this.category = "building";
-	this.cost = new Resources(this.template.cost());
+	this.cost = new API3.Resources(this.template.cost());
 	this.number = 1; // The number of buildings to build
 	
 	if (!startTime)
@@ -28,13 +31,13 @@
 };
 
 // return true if we willstart amassing resource for this plan
-ConstructionPlan.prototype.isGo = function(gameState) {
+m.ConstructionPlan.prototype.isGo = function(gameState) {
 	return (gameState.getTimeElapsed() > this.startTime);
 };
 
 // checks other than resource ones.
 // TODO: change this.
-ConstructionPlan.prototype.canStart = function(gameState) {
+m.ConstructionPlan.prototype.canStart = function(gameState) {
 	if (gameState.buildingsBuilt > 0)
 		return false;
 	
@@ -51,7 +54,7 @@
 	return (builders.length != 0);
 };
 
-ConstructionPlan.prototype.start = function(gameState) {
+m.ConstructionPlan.prototype.start = function(gameState) {
 	
 	var builders = gameState.findBuilders(this.type).toEntityArray();
 
@@ -63,11 +66,11 @@
 	if (!pos){
 		if (this.template.hasClass("Naval"))
 			gameState.ai.HQ.dockFailed = true;
-		debug("No room to place " + this.type);
+		m.debug("No room to place " + this.type);
 		return;
 	}
 	if (this.template.hasClass("Naval"))
-		debug (pos);
+		m.debug (pos);
 	gameState.buildingsBuilt++;
 
 	if (gameState.getTemplate(this.type).buildCategory() === "Dock")
@@ -80,20 +83,20 @@
 		builders[0].construct(this.type, pos.x, pos.z, pos.angle, this.metadata);
 };
 
-ConstructionPlan.prototype.getCost = function() {
-	var costs = new Resources();
+m.ConstructionPlan.prototype.getCost = function() {
+	var costs = new API3.Resources();
 	costs.add(this.cost);
 	return costs;
 };
 
-ConstructionPlan.prototype.findGoodPosition = function(gameState) {
+m.ConstructionPlan.prototype.findGoodPosition = function(gameState) {
 	var template = gameState.getTemplate(this.type);
 
 	var cellSize = gameState.cellSize; // size of each tile
 
 	// First, find all tiles that are far enough away from obstructions:
 
-	var obstructionMap = Map.createObstructionMap(gameState,0, template);
+	var obstructionMap = m.createObstructionMap(gameState,0, template);
 	
 	//obstructionMap.dumpIm(template.buildCategory() + "_obstructions_pre.png");
 
@@ -104,7 +107,7 @@
 
 	// Compute each tile's closeness to friendly structures:
 
-	var friendlyTiles = new Map(gameState.sharedScript);
+	var friendlyTiles = new API3.Map(gameState.sharedScript);
 	
 	var alreadyHasHouses = false;
 
@@ -229,3 +232,7 @@
 		"angle" : angle
 	};
 };
+
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/entity-extend.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/entity-extend.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/entity-extend.js	(Arbeitskopie)
@@ -1,5 +1,8 @@
+var AEGIS = function(m)
+{
+
 // returns some sort of DPS * health factor. If you specify a class, it'll use the modifiers against that class too.
-function getMaxStrength(ent, againstClass)
+m.getMaxStrength = function(ent, againstClass)
 {
 	var strength = 0.0;
 	var attackTypes = ent.attackTypes();
@@ -61,3 +64,6 @@
 	}
 	return strength * hp;
 };
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/config.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/config.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/config.js	(Arbeitskopie)
@@ -1,6 +1,11 @@
-// Baseconfig is the highest difficulty.
-var baseConfig = {
-	"Military" : {
+var AEGIS = function(m)
+{
+
+m.Config = function() {
+	this.debug = false;	// 0 is sandbox, 1 is easy, 2 is medium, 3 is hard, 4 is very hard.
+	this.difficulty = 2;	// overriden by the GUI
+
+	this.Military = {
 		"fortressLapseTime" : 540, // Time to wait between building 2 fortresses
 		"defenceBuildingTime" : 600, // Time to wait before building towers or fortresses
 		"attackPlansStartTime" : 0,	// time to wait before attacking. Start as soon as possible (first barracks)
@@ -8,8 +13,8 @@
 		"popForBarracks1" : 15,
 		"popForBarracks2" : 95,
 		"timeForBlacksmith" : 900,
-	},
-	"Economy" : {
+	};
+	this.Economy = {
 		"townPhase" : 180,	// time to start trying to reach town phase (might be a while after. Still need the requirements + ress )
 		"cityPhase" : 840,	// time to start trying to reach city phase
 		"popForMarket" : 80,
@@ -19,19 +24,21 @@
 		"targetNumBuilders" : 1.5, // Base number of builders per foundation.
 		"femaleRatio" : 0.4, // percent of females among the workforce.
 		"initialFields" : 2
-	},
+	};
 	
 	// Note: attack settings are set directly in attack_plan.js
 	
 	// defence
-	"Defence" : {
+	this.Defence =
+	{
 		"defenceRatio" : 5,	// see defence.js for more info.
 		"armyCompactSize" : 700,	// squared. Half-diameter of an army.
 		"armyBreakawaySize" : 900  // squared.
-	},
+	};
 	
 	// military
-	"buildings" : {
+	this.buildings = 
+	{
 		"moderate" : {
 			"default" : [ "structures/{civ}_barracks" ]
 		},
@@ -51,10 +58,11 @@
 			"default" : [ "structures/{civ}_fortress" ],
 			"celt" : [ "structures/{civ}_fortress_b", "structures/{civ}_fortress_g" ]
 		}
-	},
+	};
 
 	// qbot
-	"priorities" : {  // Note these are dynamic, you are only setting the initial values
+	this.priorities = 
+	{  // Note these are dynamic, you are only setting the initial values
 		"house" : 350,
 		"villager" : 40,
 		"citizenSoldier" : 60,
@@ -67,49 +75,46 @@
 		"majorTech" : 700,
 		"minorTech" : 50,
 		"civilCentre" : 400
-	},
-	"difficulty" : 2,	// 0 is sandbox, 1 is easy, 2 is medium, 3 is hard, 4 is very hard.
-	"debug" : false
+	};
 };
 
-var Config = {
-	"debug": false,
-	"difficulty" : 2,	// overriden by the GUI
-	updateDifficulty: function(difficulty)
+//Config.prototype = new BaseConfig();
+
+m.Config.prototype.updateDifficulty = function(difficulty)
+{
+	this.difficulty = difficulty;
+	// changing settings based on difficulty.
+	if (this.difficulty === 1)
 	{
-		Config.difficulty = difficulty;
-		// changing settings based on difficulty.
-		if (Config.difficulty === 1)
-		{
-			Config.Military.defenceBuildingTime = 1200;
-			Config.Military.attackPlansStartTime = 960;
-			Config.Military.popForBarracks1 = 35;
-			Config.Military.popForBarracks2 = 150;	// shouldn't reach it
-			Config.Military.popForBlacksmith = 150;	// shouldn't reach it
+		this.Military.defenceBuildingTime = 1200;
+		this.Military.attackPlansStartTime = 960;
+		this.Military.popForBarracks1 = 35;
+		this.Military.popForBarracks2 = 150;	// shouldn't reach it
+		this.Military.popForBlacksmith = 150;	// shouldn't reach it
 
-			Config.Economy.cityPhase = 1800;
-			Config.Economy.popForMarket = 80;
-			Config.Economy.techStartTime = 600;
-			Config.Economy.femaleRatio = 0.6;
-			Config.Economy.initialFields = 1;
-			// Config.Economy.targetNumWorkers will be set by AI scripts.
-		}
-		else if (Config.difficulty === 0)
-		{
-			Config.Military.defenceBuildingTime = 450;
-			Config.Military.attackPlansStartTime = 9600000;	// never
-			Config.Military.popForBarracks1 = 60;
-			Config.Military.popForBarracks2 = 150;	// shouldn't reach it
-			Config.Military.popForBlacksmith = 150;	// shouldn't reach it
+		this.Economy.cityPhase = 1800;
+		this.Economy.popForMarket = 80;
+		this.Economy.techStartTime = 600;
+		this.Economy.femaleRatio = 0.6;
+		this.Economy.initialFields = 1;
+		// Config.Economy.targetNumWorkers will be set by AI scripts.
+	}
+	else if (this.difficulty === 0)
+	{
+		this.Military.defenceBuildingTime = 450;
+		this.Military.attackPlansStartTime = 9600000;	// never
+		this.Military.popForBarracks1 = 60;
+		this.Military.popForBarracks2 = 150;	// shouldn't reach it
+		this.Military.popForBlacksmith = 150;	// shouldn't reach it
 
-			Config.Economy.cityPhase = 240000;
-			Config.Economy.popForMarket = 200;
-			Config.Economy.techStartTime = 1800;
-			Config.Economy.femaleRatio = 0.2;
-			Config.Economy.initialFields = 1;
-			// Config.Economy.targetNumWorkers will be set by AI scripts.
-		}
+		this.Economy.cityPhase = 240000;
+		this.Economy.popForMarket = 200;
+		this.Economy.techStartTime = 1800;
+		this.Economy.femaleRatio = 0.2;
+		this.Economy.initialFields = 1;
+		// Config.Economy.targetNumWorkers will be set by AI scripts.
 	}
 };
 
-Config.__proto__ = baseConfig;
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/queueplan-training.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/queueplan-training.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/queueplan-training.js	(Arbeitskopie)
@@ -1,15 +1,18 @@
-var TrainingPlan = function(gameState, type, metadata, number, startTime, expectedTime, maxMerge) {
+var AEGIS = function(m)
+{
+
+m.TrainingPlan = function(gameState, type, metadata, number, startTime, expectedTime, maxMerge) {
 	this.type = gameState.applyCiv(type);
 	this.metadata = metadata;
 
-	this.ID = uniqueIDBOPlans++;
+	this.ID = m.playerGlobals[PlayerID].uniqueIDBOPlans++;
 	
 	this.template = gameState.getTemplate(this.type);
 	if (!this.template)
 		return false;
 
 	this.category = "unit";
-	this.cost = new Resources(this.template.cost(), this.template._template.Cost.Population);
+	this.cost = new API3.Resources(this.template.cost(), this.template._template.Cost.Population);
 	if (!number)
 		this.number = 1;
 	else
@@ -33,11 +36,11 @@
 };
 
 // return true if we willstart amassing resource for this plan
-TrainingPlan.prototype.isGo = function(gameState) {
+m.TrainingPlan.prototype.isGo = function(gameState) {
 	return (gameState.getTimeElapsed() > this.startTime);
 };
 
-TrainingPlan.prototype.canStart = function(gameState) {
+m.TrainingPlan.prototype.canStart = function(gameState) {
 	if (this.invalidTemplate)
 		return false;
 
@@ -48,7 +51,7 @@
 	return (trainers.length != 0);
 };
 
-TrainingPlan.prototype.start = function(gameState) {
+m.TrainingPlan.prototype.start = function(gameState) {
 	//warn("Executing TrainingPlan " + uneval(this));
 	var self = this;
 	var trainers = gameState.findTrainers(this.type).toEntityArray();
@@ -72,15 +75,19 @@
 	}
 };
 
-TrainingPlan.prototype.getCost = function(){
-	var multCost = new Resources();
+m.TrainingPlan.prototype.getCost = function(){
+	var multCost = new API3.Resources();
 	multCost.add(this.cost);
 	multCost.multiply(this.number);
 	return multCost;
 };
 
-TrainingPlan.prototype.addItem = function(amount){
+m.TrainingPlan.prototype.addItem = function(amount){
 	if (amount === undefined)
 		amount = 1;
 	this.number += amount;
 };
+
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/enemy-watcher.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/enemy-watcher.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/enemy-watcher.js	(Arbeitskopie)
@@ -1,3 +1,6 @@
+var AEGIS = function(m)
+{
+
 /*
  * A class that keeps track of enemy buildings, units, and pretty much anything I can think of (still a LOT TODO here)
  * Only watches one enemy, you'll need one per enemy.
@@ -4,29 +7,29 @@
  * Note: pretty much unused in the current version.
  */
 
-var enemyWatcher = function(gameState, playerToWatch) {
+m.enemyWatcher = function(gameState, playerToWatch) {
 	
 	this.watched = playerToWatch;
 	
 	// using global entity collections, shared by any AI that knows the name of this.
 	
-	var filter = Filters.and(Filters.byClass("Structure"), Filters.byOwner(this.watched));
+	var filter = API3.Filters.and(API3.Filters.byClass("Structure"), API3.Filters.byOwner(this.watched));
 	this.enemyBuildings = gameState.updatingGlobalCollection("player-" +this.watched + "-structures", filter);
 
-	filter = Filters.and(Filters.byClass("Unit"), Filters.byOwner(this.watched));
+	filter = API3.Filters.and(API3.Filters.byClass("Unit"), API3.Filters.byOwner(this.watched));
 	this.enemyUnits = gameState.updatingGlobalCollection("player-" +this.watched + "-units", filter);
 
-	filter = Filters.and(Filters.byClass("Worker"), Filters.byOwner(this.watched));
+	filter = API3.Filters.and(API3.Filters.byClass("Worker"), API3.Filters.byOwner(this.watched));
 	this.enemyCivilians = gameState.updatingGlobalCollection("player-" +this.watched + "-civilians", filter);
 							 
-	filter = Filters.and(Filters.byClassesOr(["CitizenSoldier", "Hero", "Champion", "Siege"]), Filters.byOwner(this.watched));
+	filter = API3.Filters.and(API3.Filters.byClassesOr(["CitizenSoldier", "Hero", "Champion", "Siege"]), API3.Filters.byOwner(this.watched));
 	this.enemySoldiers = gameState.updatingGlobalCollection("player-" +this.watched + "-soldiers", filter);
 	
-	filter = Filters.and(Filters.byClass("Worker"), Filters.byOwner(this.watched));
+	filter = API3.Filters.and(API3.Filters.byClass("Worker"), API3.Filters.byOwner(this.watched));
 	this.enemyCivilians = gameState.getEnemyEntities().filter(filter);
 	this.enemyCivilians.registerUpdates();
 
-	filter = Filters.and(Filters.byClassesOr(["CitizenSoldier", "Hero", "Champion", "Siege"]), Filters.byOwner(this.watched));
+	filter = API3.Filters.and(API3.Filters.byClassesOr(["CitizenSoldier", "Hero", "Champion", "Siege"]), API3.Filters.byOwner(this.watched));
 	this.enemySoldiers = gameState.getEnemyEntities().filter(filter);
 	this.enemySoldiers.registerUpdates();
 
@@ -40,15 +43,15 @@
 	this.dangerousArmies = [];
 	
 };
-enemyWatcher.prototype.getAllEnemySoldiers = function() {
+m.enemyWatcher.prototype.getAllEnemySoldiers = function() {
 	return this.enemySoldiers;
 };
-enemyWatcher.prototype.getAllEnemyBuildings = function() {
+m.enemyWatcher.prototype.getAllEnemyBuildings = function() {
 	return this.enemyBuildings;
 };
 
-enemyWatcher.prototype.getEnemyBuildings = function(gameState, specialClass, OneTime) {
-	var filter = Filters.byClass(specialClass);
+m.enemyWatcher.prototype.getEnemyBuildings = function(gameState, specialClass, OneTime) {
+	var filter = API3.Filters.byClass(specialClass);
 	
 	if (OneTime && gameState.getGEC("player-" +this.watched + "-structures-" +specialClass))
 		return gameState.getGEC("player-" +this.watched + "-structures-" +specialClass);
@@ -57,55 +60,55 @@
 	
 	return gameState.updatingGlobalCollection("player-" +this.watched + "-structures-" +specialClass, filter, gameState.getGEC("player-" +this.watched + "-structures"));
 };
-enemyWatcher.prototype.getDangerousArmies = function() {
+m.enemyWatcher.prototype.getDangerousArmies = function() {
 	var toreturn = {};
 	for (var i in this.dangerousArmies)
 		toreturn[this.dangerousArmies[i]] = this.armies[this.dangerousArmies[i]];
 	return toreturn;
 };
-enemyWatcher.prototype.getSafeArmies = function() {
+m.enemyWatcher.prototype.getSafeArmies = function() {
 	var toreturn = {};
 	for (var i in this.armies)
 		if (this.dangerousArmies.indexOf(i) == -1)
 			toreturn[i] = this.armies[i];
 	return toreturn;
 };
-enemyWatcher.prototype.resetDangerousArmies = function() {
+m.enemyWatcher.prototype.resetDangerousArmies = function() {
 	this.dangerousArmies = [];
 };
-enemyWatcher.prototype.setAsDangerous = function(armyID) {
+m.enemyWatcher.prototype.setAsDangerous = function(armyID) {
 	if (this.dangerousArmies.indexOf(armyID) === -1)
 		this.dangerousArmies.push(armyID);
 };
-enemyWatcher.prototype.isDangerous = function(armyID) {
+m.enemyWatcher.prototype.isDangerous = function(armyID) {
 	if (this.dangerousArmies.indexOf(armyID) === -1)
 		return false;
 	return true;
 };
 // returns [id, army]
-enemyWatcher.prototype.getArmyFromMember = function(memberID) {
+m.enemyWatcher.prototype.getArmyFromMember = function(memberID) {
 	for (var i in this.armies) {
 		if (this.armies[i].toIdArray().indexOf(memberID) !== -1)
 			return [i,this.armies[i]];
 	}
 	return undefined;
 };
-enemyWatcher.prototype.isPartOfDangerousArmy = function(memberID) {
+m.enemyWatcher.prototype.isPartOfDangerousArmy = function(memberID) {
 	var armyID = this.getArmyFromMember(memberID)[0];
 	if (this.isDangerous(armyID))
 		return true;
 	return false;
 };
-enemyWatcher.prototype.cleanDebug = function() {
+m.enemyWatcher.prototype.cleanDebug = function() {
 	for (var armyID in this.armies) {
 		var army = this.armies[armyID];
-		debug ("Army " +armyID);
-		debug (army.length +" members, centered around " +army.getCentrePosition());
+		m.debug ("Army " +armyID);
+		m.debug (army.length +" members, centered around " +army.getCentrePosition());
 	}
 }
 
 // this will monitor any unmonitored soldier.
-enemyWatcher.prototype.detectArmies = function(gameState){
+m.enemyWatcher.prototype.detectArmies = function(gameState){
 	//this.cleanDebug();
 	
 	var self = this;
@@ -121,7 +124,7 @@
 			var armyID = gameState.player + "" + self.totalNBofArmies;
 			self.totalNBofArmies++,
 			enemy.setMetadata(PlayerID, "EnemyWatcherArmy",armyID);
-			var filter = Filters.byMetadata(PlayerID, "EnemyWatcherArmy",armyID);
+			var filter = API3.Filters.byMetadata(PlayerID, "EnemyWatcherArmy",armyID);
 			var army = self.enemySoldiers.filter(filter);
 			self.armies[armyID] = army;
 			self.armies[armyID].registerUpdates();
@@ -140,7 +143,7 @@
 };
 // this will merge any two army who are too close together. The distance for "army" is fairly big.
 // note: this doesn't actually merge two entity collections... It simply changes the unit metadatas, and will clear the empty entity collection
-enemyWatcher.prototype.mergeArmies = function(){
+m.enemyWatcher.prototype.mergeArmies = function(){
 	for (var army in this.armies) {
 		var firstArmy = this.armies[army];
 		if (firstArmy.length !== 0) {
@@ -149,7 +152,7 @@
 				if (otherArmy !== army && this.armies[otherArmy].length !== 0) {
 					var secondArmy = this.armies[otherArmy];
 					// we're not self merging, so we check if the two armies are close together
-					if (inRange(firstAPos,secondArmy.getApproximatePosition(4), 4000 ) ) {
+					if (m.inRange(firstAPos,secondArmy.getApproximatePosition(4), 4000 ) ) {
 						// okay so we merge the two together
 						
 						// if the other one was dangerous and we weren't, we're now.
@@ -166,7 +169,7 @@
 	}
 	this.ScrapEmptyArmies();
 };
-enemyWatcher.prototype.ScrapEmptyArmies = function(){
+m.enemyWatcher.prototype.ScrapEmptyArmies = function(){
 	var removelist = [];
 	for (var army in this.armies) {
 		if (this.armies[army].length === 0) {
@@ -181,10 +184,10 @@
 	}
 };
 // splits any unit too far from the centerposition
-enemyWatcher.prototype.splitArmies = function(gameState){
+m.enemyWatcher.prototype.splitArmies = function(gameState){
 	var self = this;
 	
-	var map = Map.createTerritoryMap(gameState);
+	var map = m.createTerritoryMap(gameState);
 	
 	for (var armyID in this.armies) {
 		var army = this.armies[armyID];
@@ -197,14 +200,14 @@
 			if (enemy.position() === undefined)
 				return;
 					 
-			if (!inRange(enemy.position(),centre, 3500) ) {
+			if (!m.inRange(enemy.position(),centre, 3500) ) {
 				var newArmyID = gameState.player + "" + self.totalNBofArmies;
 				if (self.dangerousArmies.indexOf(armyID) !== -1)
 					 self.dangerousArmies.push(newArmyID);
 				
 				self.totalNBofArmies++,
 				enemy.setMetadata(PlayerID, "EnemyWatcherArmy",newArmyID);
-				var filter = Filters.byMetadata(PlayerID, "EnemyWatcherArmy",newArmyID);
+				var filter = API3.Filters.byMetadata(PlayerID, "EnemyWatcherArmy",newArmyID);
 				var newArmy = self.enemySoldiers.filter(filter);
 				self.armies[newArmyID] = newArmy;
 				self.armies[newArmyID].registerUpdates();
@@ -213,3 +216,7 @@
 		});
 	}
 };
+
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/entitycollection-extend.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/entitycollection-extend.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/entitycollection-extend.js	(Arbeitskopie)
@@ -1,4 +1,7 @@
-function EntityCollectionFromIds(gameState, idList){
+var AEGIS = function(m)
+{
+
+m.EntityCollectionFromIds = function(gameState, idList){
 	var ents = {};
 	for (var i in idList){
 		var id = idList[i];
@@ -6,5 +9,8 @@
 			ents[id] = gameState.entities._entities[id];
 		}
 	}
-	return new EntityCollection(gameState.sharedScript, ents);
+	return new API3.EntityCollection(gameState.sharedScript, ents);
 }
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/timer.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/timer.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/timer.js	(Arbeitskopie)
@@ -1,3 +1,6 @@
+var AEGIS = function(m)
+{
+
 //The Timer class // The instance of this class is created in the qBot object under the name 'timer'
 //The methods that are available to call from this instance are:
 //timer.setTimer           : Creates a new timer with the given interval (miliseconds).
@@ -11,7 +14,7 @@
 
 
 //-EmjeR-// Timer class //
-var Timer = function() {
+m.Timer = function() {
 	///Private array.
 	var alarmList = [];
 	
@@ -94,7 +97,7 @@
 
 
 //-EmjeR-// Alarm class //
-function alarm(gameState, id, interval, delay, repeat) {
+m.alarm = function(gameState, id, interval, delay, repeat) {
 	this.id = id;
 	this.interval = interval;
 	this.delay = delay;
@@ -104,3 +107,6 @@
 	this.active = true;
 	this.counter = 0;
 };
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/template-manager.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/template-manager.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/template-manager.js	(Arbeitskopie)
@@ -1,3 +1,6 @@
+var AEGIS = function(m)
+{
+
 /*
  * Used to know which templates I have, which templates I know I can train, things like that.
  * Mostly unused.
@@ -3,5 +6,5 @@
  */
 
-var TemplateManager = function(gameState) {
+m.TemplateManager = function(gameState) {
 	var self = this;
 	
@@ -23,7 +26,7 @@
 	this.getTemplateCounters(gameState);
 	
 };
-TemplateManager.prototype.AcknowledgeTemplates = function(gameState)
+m.TemplateManager.prototype.AcknowledgeTemplates = function(gameState)
 {
 	var self = this;
 	var myEntities = gameState.getOwnEntities();
@@ -39,7 +42,7 @@
 
 	});
 }
-TemplateManager.prototype.getBuildableSubtemplates = function(gameState)
+m.TemplateManager.prototype.getBuildableSubtemplates = function(gameState)
 {
 	for each (var templateName in this.knownTemplatesList) {
 		var template = gameState.getTemplate(templateName);
@@ -59,7 +62,7 @@
 		}
 	}
 }
-TemplateManager.prototype.getTrainableSubtemplates = function(gameState)
+m.TemplateManager.prototype.getTrainableSubtemplates = function(gameState)
 {
 	for each (var templateName in this.knownTemplatesList) {
 		var template = gameState.getTemplate(templateName);
@@ -79,7 +82,7 @@
 		}
 	}
 }
-TemplateManager.prototype.getTemplateCounters = function(gameState)
+m.TemplateManager.prototype.getTemplateCounters = function(gameState)
 {
 	for (var i in this.unitTemplates)
 	{
@@ -89,7 +92,7 @@
 	}
 }
 // features auto-caching
-TemplateManager.prototype.getCountersToClasses = function(gameState,classes,templateName)
+m.TemplateManager.prototype.getCountersToClasses = function(gameState,classes,templateName)
 {
 	if (templateName !== undefined && this.templateCounteredBy[templateName])
 		return this.templateCounteredBy[templateName];
@@ -114,3 +117,6 @@
 	return templates;
 }
 
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/queue.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/queue.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/queue.js	(Arbeitskopie)
@@ -1,3 +1,6 @@
+var AEGIS = function(m)
+{
+
 /*
  * Holds a list of wanted items to train or construct
  */
@@ -2,12 +5,12 @@
 
-var Queue = function() {
+m.Queue = function() {
 	this.queue = [];
 	this.paused = false;
 };
 
-Queue.prototype.empty = function() {
+m.Queue.prototype.empty = function() {
 	this.queue = [];
 };
 
-Queue.prototype.addItem = function(plan) {
+m.Queue.prototype.addItem = function(plan) {
 	for (var i in this.queue)
@@ -23,7 +26,7 @@
 	this.queue.push(plan);
 };
 
-Queue.prototype.getNext = function() {
+m.Queue.prototype.getNext = function() {
 	if (this.queue.length > 0) {
 		return this.queue[0];
 	} else {
@@ -31,7 +34,7 @@
 	}
 };
 
-Queue.prototype.startNext = function(gameState) {
+m.Queue.prototype.startNext = function(gameState) {
 	if (this.queue.length > 0) {
 		this.queue.shift().start(gameState);
 		return true;
@@ -42,8 +45,8 @@
 
 // returns the maximal account we'll accept for this queue.
 // Currently 100% of the cost of the first element and 80% of that of the second
-Queue.prototype.maxAccountWanted = function(gameState) {
-	var cost = new Resources();
+m.Queue.prototype.maxAccountWanted = function(gameState) {
+	var cost = new API3.Resources();
 	if (this.queue.length > 0 && this.queue[0].isGo(gameState))
 		cost.add(this.queue[0].getCost());
 	if (this.queue.length > 1 && this.queue[1].isGo(gameState))
@@ -55,19 +58,19 @@
 	return cost;
 };
 
-Queue.prototype.queueCost = function(){
-	var cost = new Resources();
+m.Queue.prototype.queueCost = function(){
+	var cost = new API3.Resources();
 	for (var key in this.queue){
 		cost.add(this.queue[key].getCost());
 	}
 	return cost;
 };
 
-Queue.prototype.length = function() {
+m.Queue.prototype.length = function() {
 	return this.queue.length;
 };
 
-Queue.prototype.countQueuedUnits = function(){
+m.Queue.prototype.countQueuedUnits = function(){
 	var count = 0;
 	for (var i in this.queue){
 		count += this.queue[i].number;
@@ -75,7 +78,7 @@
 	return count;
 };
 
-Queue.prototype.countQueuedUnitsWithClass = function(classe){
+m.Queue.prototype.countQueuedUnitsWithClass = function(classe){
 	var count = 0;
 	for (var i in this.queue){
 		if (this.queue[i].template && this.queue[i].template.hasClass(classe))
@@ -83,7 +86,7 @@
 	}
 	return count;
 };
-Queue.prototype.countQueuedUnitsWithMetadata = function(data,value){
+m.Queue.prototype.countQueuedUnitsWithMetadata = function(data,value){
 	var count = 0;
 	for (var i in this.queue){
 		if (this.queue[i].metadata[data] && this.queue[i].metadata[data] == value)
@@ -92,7 +95,7 @@
 	return count;
 };
 
-Queue.prototype.countAllByType = function(t){
+m.Queue.prototype.countAllByType = function(t){
 	var count = 0;
 	
 	for (var i = 0; i < this.queue.length; i++){
@@ -102,3 +105,6 @@
 	}
 	return count;
 };
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/headquarters.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/headquarters.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/headquarters.js	(Arbeitskopie)
@@ -1,3 +1,5 @@
+var AEGIS = function(m)
+{
 /* Headquarters
  * Deal with high level logic for the AI. Most of the interesting stuff gets done here.
  * Some tasks:
@@ -12,12 +14,14 @@
 	-picking new CC locations.
  */
 
-var HQ = function() {
-	this.targetNumBuilders = Config.Economy.targetNumBuilders; // number of workers we want building stuff
+m.HQ = function(Config) {
 	
-	this.dockStartTime =  Config.Economy.dockStartTime * 1000;
-	this.techStartTime = Config.Economy.techStartTime * 1000;
+	this.Config = Config;
+	this.targetNumBuilders = this.Config.Economy.targetNumBuilders; // number of workers we want building stuff
 	
+	this.dockStartTime =  this.Config.Economy.dockStartTime * 1000;
+	this.techStartTime = this.Config.Economy.techStartTime * 1000;
+	
 	this.dockFailed = false;	// sanity check
 	this.waterMap = false;	// set by the aegis.js file.
 	
@@ -27,15 +31,15 @@
 	this.baseManagers = {};
 	
 	// this means we'll have about a big third of women, and thus we can maximize resource gathering rates.
-	this.femaleRatio = Config.Economy.femaleRatio;
+	this.femaleRatio = this.Config.Economy.femaleRatio;
 	
 	this.fortressStartTime = 0;
-	this.fortressLapseTime = Config.Military.fortressLapseTime * 1000;
-	this.defenceBuildingTime = Config.Military.defenceBuildingTime * 1000;
-	this.attackPlansStartTime = Config.Military.attackPlansStartTime * 1000;
-	this.defenceManager = new Defence();
+	this.fortressLapseTime = this.Config.Military.fortressLapseTime * 1000;
+	this.defenceBuildingTime = this.Config.Military.defenceBuildingTime * 1000;
+	this.attackPlansStartTime = this.Config.Military.attackPlansStartTime * 1000;
+	this.defenceManager = new m.Defence(this.Config);
 	
-	this.navalManager = new NavalManager();
+	this.navalManager = new m.NavalManager();
 	
 	this.TotalAttackNumber = 0;
 	this.upcomingAttacks = { "CityAttack" : [] };
@@ -43,49 +47,49 @@
 };
 
 // More initialisation for stuff that needs the gameState
-HQ.prototype.init = function(gameState, events, queues){
+m.HQ.prototype.init = function(gameState, events, queues){
 	// initialize base map. Each pixel is a base ID, or 0 if none
-	this.basesMap = new Map(gameState.sharedScript, new Uint8Array(gameState.getMap().data.length));
+	this.basesMap = new API3.Map(gameState.sharedScript, new Uint8Array(gameState.getMap().data.length));
 	this.basesMap.setMaxVal(255);
 
-	if (Config.Economy.targetNumWorkers)
-		this.targetNumWorkers = Config.Economy.targetNumWorkers;
+	if (this.Config.Economy.targetNumWorkers)
+		this.targetNumWorkers = this.Config.Economy.targetNumWorkers;
 	else if (this.targetNumWorkers === undefined)
-		this.targetNumWorkers = Math.max(Math.floor(gameState.getPopulationMax()*(0.2 + Math.min(+(Config.difficulty)*0.125,0.3))), 1);
+		this.targetNumWorkers = Math.max(Math.floor(gameState.getPopulationMax()*(0.2 + Math.min(+(this.Config.difficulty)*0.125,0.3))), 1);
 
 
 	// Let's get our initial situation here.
 	// TODO: improve on this.
 	// TODO: aknowledge bases, assign workers already.
-	var ents = gameState.getEntities().filter(Filters.byOwner(PlayerID));
+	var ents = gameState.getEntities().filter(API3.Filters.byOwner(PlayerID));
 	
 	var workersNB = 0;
 	var hasScout = false;
 	var treasureAmount = { 'food': 0, 'wood': 0, 'stone': 0, 'metal': 0 };
 	var hasCC = false;
 	
-	if (ents.filter(Filters.byClass("CivCentre")).length > 0)
+	if (ents.filter(API3.Filters.byClass("CivCentre")).length > 0)
 		hasCC = true;
-	workersNB = ents.filter(Filters.byClass("Worker")).length;
-	if (ents.filter(Filters.byClass("Cavalry")).length > 0)
+	workersNB = ents.filter(API3.Filters.byClass("Worker")).length;
+	if (ents.filter(API3.Filters.byClass("Cavalry")).length > 0)
 		hasScout = true;
 	
 	// tODO: take multiple CCs into account.
 	if (hasCC)
 	{
-		var CC = ents.filter(Filters.byClass("CivCentre")).toEntityArray()[0];
+		var CC = ents.filter(API3.Filters.byClass("CivCentre")).toEntityArray()[0];
 		for (i in treasureAmount)
 			gameState.getResourceSupplies(i).forEach( function (ent) {
-				if (ent.resourceSupplyType().generic === "treasure" && SquareVectorDistance(ent.position(), CC.position()) < 5000)
+				if (ent.resourceSupplyType().generic === "treasure" && API3.SquareVectorDistance(ent.position(), CC.position()) < 5000)
 					treasureAmount[i] += ent.resourceSupplyMax();
 			});
-		this.baseManagers[1] = new BaseManager();
+		this.baseManagers[1] = new m.BaseManager(this.Config);
 		this.baseManagers[1].init(gameState, events);
 		this.baseManagers[1].setAnchor(CC);
 		this.baseManagers[1].initTerritory(this, gameState);
 		this.baseManagers[1].initGatheringFunctions(this, gameState);
 		
-		if (Config.debug)
+		if (this.Config.debug)
 			this.basesMap.dumpIm("basesMap.png");
 		var self = this;
 
@@ -105,14 +109,14 @@
 			var pos = this.baseManagers[1].findBestDropsiteLocation(gameState, "wood");
 			if (pos)
 			{
-				queues.dropsites.addItem(new ConstructionPlan(gameState, "structures/{civ}_storehouse",{ "base" : 1 }, 0, -1, pos));
-				queues.minorTech.addItem(new ResearchPlan(gameState, "gather_capacity_wheelbarrow"));
+				queues.dropsites.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_storehouse",{ "base" : 1 }, 0, -1, pos));
+				queues.minorTech.addItem(new m.ResearchPlan(gameState, "gather_capacity_wheelbarrow"));
 			}
 		}
 	}
 	
-	var map = new Map(gameState.sharedScript, gameState.sharedScript.CCResourceMaps["wood"].map);
-	if (Config.debug)
+	var map = new API3.Map(gameState.sharedScript, gameState.sharedScript.CCResourceMaps["wood"].map);
+	if (this.Config.debug)
 		map.dumpIm("map_CC_Wood.png");
 	
 	//this.reassignIdleWorkers(gameState);
@@ -125,22 +129,22 @@
 	
 	// load units and buildings from the config files
 	
-	if (civ in Config.buildings.moderate){
-		this.bModerate = Config.buildings.moderate[civ];
+	if (civ in this.Config.buildings.moderate){
+		this.bModerate = this.Config.buildings.moderate[civ];
 	}else{
-		this.bModerate = Config.buildings.moderate['default'];
+		this.bModerate = this.Config.buildings.moderate['default'];
 	}
 	
-	if (civ in Config.buildings.advanced){
-		this.bAdvanced = Config.buildings.advanced[civ];
+	if (civ in this.Config.buildings.advanced){
+		this.bAdvanced = this.Config.buildings.advanced[civ];
 	}else{
-		this.bAdvanced = Config.buildings.advanced['default'];
+		this.bAdvanced = this.Config.buildings.advanced['default'];
 	}
 	
-	if (civ in Config.buildings.fort){
-		this.bFort = Config.buildings.fort[civ];
+	if (civ in this.Config.buildings.fort){
+		this.bFort = this.Config.buildings.fort[civ];
 	}else{
-		this.bFort = Config.buildings.fort['default'];
+		this.bFort = this.Config.buildings.fort['default'];
 	}
 	
 	for (var i in this.bAdvanced){
@@ -156,7 +160,7 @@
 	}
 	
 	var enemies = gameState.getEnemyEntities();
-	var filter = Filters.byClassesOr(["CitizenSoldier", "Champion", "Hero", "Siege"]);
+	var filter = API3.Filters.byClassesOr(["CitizenSoldier", "Champion", "Hero", "Siege"]);
 	this.enemySoldiers = enemies.filter(filter); // TODO: cope with diplomacy changes
 	this.enemySoldiers.registerUpdates();
 	
@@ -167,13 +171,13 @@
 	this.ennWatcherIndex = [];
 	for (var i = 1; i <= 8; i++)
 		if (PlayerID != i && gameState.isPlayerEnemy(i)) {
-			this.enemyWatchers[i] = new enemyWatcher(gameState, i);
+			this.enemyWatchers[i] = new m.enemyWatcher(gameState, i);
 			this.ennWatcherIndex.push(i);
 			this.defenceManager.enemyArmy[i] = [];
 		}
 };
 
-HQ.prototype.checkEvents = function (gameState, events, queues) {
+m.HQ.prototype.checkEvents = function (gameState, events, queues) {
 	for (i in events)
 	{
 		if (events[i].type == "Destroy")
@@ -193,8 +197,8 @@
 				if (ent.isOwn(PlayerID) && ent.getMetadata(PlayerID, "base") === -1)
 				{
 					// Okay so let's try to create a new base around this.
-					var bID = uniqueIDBases;
-					this.baseManagers[bID] = new BaseManager();
+					var bID = m.playerGlobals[PlayerID].uniqueIDBases;
+					this.baseManagers[bID] = new m.BaseManager(this.Config);
 					this.baseManagers[bID].init(gameState, events, true);
 					this.baseManagers[bID].setAnchor(ent);
 					this.baseManagers[bID].initTerritory(this, gameState);
@@ -243,7 +247,7 @@
 // TODO: This should probably be changed to favor a more mixed approach for better defense.
 //		(or even to adapt based on estimated enemy strategy).
 // TODO: this should probably set which base it wants them in.
-HQ.prototype.trainMoreWorkers = function(gameState, queues) {
+m.HQ.prototype.trainMoreWorkers = function(gameState, queues) {
 	// Count the workers in the world and in progress
 	var numFemales = gameState.countEntitiesAndQueuedByType(gameState.applyCiv("units/{civ}_support_female_citizen"));
 	numFemales += queues.villager.countQueuedUnitsWithClass("Support");
@@ -293,14 +297,14 @@
 		
 		// base "0" means "auto"
 		if (template === gameState.applyCiv("units/{civ}_support_female_citizen"))
-			queues.villager.addItem(new TrainingPlan(gameState, template, { "role" : "worker", "base" : 0 }, size, 0, -1, size ));
+			queues.villager.addItem(new m.TrainingPlan(gameState, template, { "role" : "worker", "base" : 0 }, size, 0, -1, size ));
 		else
-			queues.citizenSoldier.addItem(new TrainingPlan(gameState, template, { "role" : "worker", "base" : 0 }, size, 0, -1, size));
+			queues.citizenSoldier.addItem(new m.TrainingPlan(gameState, template, { "role" : "worker", "base" : 0 }, size, 0, -1, size));
 	}
 };
 
 // picks the best template based on parameters and classes
-HQ.prototype.findBestTrainableUnit = function(gameState, classes, parameters) {
+m.HQ.prototype.findBestTrainableUnit = function(gameState, classes, parameters) {
 	var units = gameState.findTrainableUnits(classes);
 	
 	if (units.length === 0)
@@ -317,8 +321,8 @@
 				bTopParam = param[1];
 			}
 			if (param[0] == "strength") {
-				aTopParam += getMaxStrength(a[1]) * param[1];
-				bTopParam += getMaxStrength(b[1]) * param[1];
+				aTopParam += m.getMaxStrength(a[1]) * param[1];
+				bTopParam += m.getMaxStrength(b[1]) * param[1];
 			}
 			if (param[0] == "speed") {
 				aTopParam += a[1].walkSpeed() * param[1];
@@ -343,7 +347,7 @@
 };
 
 // picks the best template based on parameters and classes
-HQ.prototype.findBestTrainableSoldier = function(gameState, classes, parameters) {
+m.HQ.prototype.findBestTrainableSoldier = function(gameState, classes, parameters) {
 	var units = gameState.findTrainableUnits(classes);
 	
 	if (units.length === 0)
@@ -361,12 +365,12 @@
 				bTopParam = param[1];
 			}
 			if (param[0] == "strength") {
-				aTopParam += getMaxStrength(a[1]) * param[1];
-				bTopParam += getMaxStrength(b[1]) * param[1];
+				aTopParam += m.getMaxStrength(a[1]) * param[1];
+				bTopParam += m.getMaxStrength(b[1]) * param[1];
 			}
 			if (param[0] == "siegeStrength") {
-				aTopParam += getMaxStrength(a[1], "Structure") * param[1];
-				bTopParam += getMaxStrength(b[1], "Structure") * param[1];
+				aTopParam += m.getMaxStrength(a[1], "Structure") * param[1];
+				bTopParam += m.getMaxStrength(b[1], "Structure") * param[1];
 			}
 			if (param[0] == "speed") {
 				aTopParam += a[1].walkSpeed() * param[1];
@@ -394,7 +398,7 @@
 // Tries to research any available tech
 // Only one at once. Also does military tech (selection is completely random atm)
 // TODO: Lots, lots, lots here.
-HQ.prototype.tryResearchTechs = function(gameState, queues) {
+m.HQ.prototype.tryResearchTechs = function(gameState, queues) {
 	if (queues.minorTech.length() === 0)
 	{
 		var possibilities = gameState.findAvailableTech();
@@ -402,15 +406,16 @@
 			return;
 		// randomly pick one. No worries about pairs in that case.
 		var p = Math.floor((Math.random()*possibilities.length));
-		queues.minorTech.addItem(new ResearchPlan(gameState, possibilities[p][0]));
+		queues.minorTech.addItem(new m.ResearchPlan(gameState, possibilities[p][0]));
 	}
 }
 
 // We're given a worker and a resource type
 // We'll assign the worker for the best base for that resource type.
 // TODO: improve choice alogrithm
-HQ.prototype.switchWorkerBase = function(gameState, worker, type) {
+m.HQ.prototype.switchWorkerBase = function(gameState, worker, type) {
 	var bestBase = 0;
+
 	for (var i in this.baseManagers)
 	{
 		if (this.baseManagers[i].willGather[type] >= 1)
@@ -435,12 +440,12 @@
 // returns an entity collection of workers through BaseManager.pickBuilders
 // TODO: better the choice algo.
 // TODO: also can't get over multiple bases right now.
-HQ.prototype.bulkPickWorkers = function(gameState, newBaseID, number) {
+m.HQ.prototype.bulkPickWorkers = function(gameState, newBaseID, number) {
 	var accessIndex = this.baseManagers[newBaseID].accessIndex;
 	if (!accessIndex)
 		return false;
 	// sorting bases by whether they are on the same accessindex or not.
-	var baseBest = AssocArraytoArray(this.baseManagers).sort(function (a,b) {
+	var baseBest = m.AssocArraytoArray(this.baseManagers).sort(function (a,b) {
 		if (a.accessIndex === accessIndex && b.accessIndex !== accessIndex)
 			return -1;
 		else if (b.accessIndex === accessIndex && a.accessIndex !== accessIndex)
@@ -459,7 +464,7 @@
 
 // returns the current gather rate
 // This is not per-se exact, it performs a few adjustments ad-hoc to account for travel distance, stuffs like that.
-HQ.prototype.GetCurrentGatherRates = function(gameState) {
+m.HQ.prototype.GetCurrentGatherRates = function(gameState) {
 	var self = this;
 
 	var currentRates = {};
@@ -474,7 +479,7 @@
 
 
 // Pick the resource which most needs another worker
-HQ.prototype.pickMostNeededResources = function(gameState) {
+m.HQ.prototype.pickMostNeededResources = function(gameState) {
 	var self = this;
 	
 	this.wantedRates = gameState.ai.queueManager.wantedGatherRates(gameState);
@@ -517,7 +522,7 @@
 
 // If all the CC's are destroyed then build a new one
 // TODO: rehabilitate.
-HQ.prototype.buildNewCC= function(gameState, queues) {
+m.HQ.prototype.buildNewCC= function(gameState, queues) {
 	var numCCs = gameState.countEntitiesAndQueuedByType(gameState.applyCiv("structures/{civ}_civil_centre"));
 	numCCs += queues.civilCentre.length();
 
@@ -529,14 +534,14 @@
 			this.baseNeed["wood"] = 50;
 			this.baseNeed["stone"] = 50;
 			this.baseNeed["metal"] = 50;
-			queues.civilCentre.addItem(new ConstructionPlan(gameState, "structures/{civ}_civil_centre"));
+			queues.civilCentre.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_civil_centre"));
 		}
 	return (gameState.countEntitiesByType(gameState.applyCiv("structures/{civ}_civil_centre"), true) == 0 && gameState.currentPhase() > 1);
 };
 
 // Returns the best position to build a new Civil Centre
 // Whose primary function would be to reach new resources of type "resource".
-HQ.prototype.findBestEcoCCLocation = function(gameState, resource){
+m.HQ.prototype.findBestEcoCCLocation = function(gameState, resource){
 	
 	var CCPlate = gameState.getTemplate("structures/{civ}_civil_centre");
 
@@ -545,16 +550,16 @@
 	// Then checks for a good spot in the territory. If none, and town/city phase, checks outside
 	// The AI will currently not build a CC if it wouldn't connect with an existing CC.
 	
-	var territory = Map.createTerritoryMap(gameState);
+	var territory = m.createTerritoryMap(gameState);
 	
-	var obstructions = Map.createObstructionMap(gameState, 0);
+	var obstructions = m.createObstructionMap(gameState, 0);
 	obstructions.expandInfluences();
 
 	// copy the resource map as initialization.
-	var friendlyTiles = new Map(gameState.sharedScript, gameState.sharedScript.CCResourceMaps[resource].map, true);
+	var friendlyTiles = new API3.Map(gameState.sharedScript, gameState.sharedScript.CCResourceMaps[resource].map, true);
 	friendlyTiles.setMaxVal(255);
-	var ents = gameState.getOwnEntities().filter(Filters.byClass("CivCentre")).toEntityArray();
-	var eEnts = gameState.getEnemyEntities().filter(Filters.byClass("CivCentre")).toEntityArray();
+	var ents = gameState.getOwnEntities().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
+	var eEnts = gameState.getEnemyEntities().filter(API3.Filters.byClass("CivCentre")).toEntityArray();
 
 	var dps = gameState.getOwnDropsites().toEntityArray();
 
@@ -576,7 +581,7 @@
 			var entPos = ents[i].position();
 			entPos = [entPos[0]/4.0,entPos[1]/4.0];
 			
-			var dist = SquareVectorDistance(entPos, pos);
+			var dist = API3.SquareVectorDistance(entPos, pos);
 			if (dist < 2120)
 			{
 				canBuild = false;
@@ -598,7 +603,7 @@
 				var entPos = eEnts[i].position();
 				entPos = [entPos[0]/4.0,entPos[1]/4.0];
 				// 7100 works well as a limit.
-				if (SquareVectorDistance(entPos, pos) < 2500)
+				if (API3.SquareVectorDistance(entPos, pos) < 2500)
 				{
 					canBuild = false;
 					continue;
@@ -620,11 +625,11 @@
 				continue;
 			}
 			dpPos = [dpPos[0]/4.0,dpPos[1]/4.0];
-			if (SquareVectorDistance(dpPos, pos) < 100)
+			if (API3.SquareVectorDistance(dpPos, pos) < 100)
 			{
 				friendlyTiles.map[j] = 0;
 				continue;
-			} else if (SquareVectorDistance(dpPos, pos) < 400)
+			} else if (API3.SquareVectorDistance(dpPos, pos) < 400)
 				friendlyTiles.map[j] /= 2;
 		}
 
@@ -645,7 +650,7 @@
 	var best = friendlyTiles.findBestTile(6, obstructions);
 	var bestIdx = best[0];
 
-	if (Config.debug)
+	if (this.Config.debug)
 	{
 		friendlyTiles.map[bestIdx] = 270;
 		friendlyTiles.dumpIm("cc_placement_base_" + gameState.getTimeElapsed() + "_" + resource + "_" + best[1] + ".png",301);
@@ -659,44 +664,44 @@
 	var x = ((bestIdx % friendlyTiles.width) + 0.5) * gameState.cellSize;
 	var z = (Math.floor(bestIdx / friendlyTiles.width) + 0.5) * gameState.cellSize;
 
-	debug ("Best for value " + best[1] + " at " + uneval([x,z]));
+	m.debug ("Best for value " + best[1] + " at " + uneval([x,z]));
 
 	return [x,z];
 };
 
-HQ.prototype.buildTemple = function(gameState, queues){
+m.HQ.prototype.buildTemple = function(gameState, queues){
 	if (gameState.currentPhase() >= 2 ) {
 		if (queues.economicBuilding.countQueuedUnits() === 0 &&
 			gameState.countEntitiesAndQueuedByType(gameState.applyCiv("structures/{civ}_temple")) === 0){
-			queues.economicBuilding.addItem(new ConstructionPlan(gameState, "structures/{civ}_temple", { "base" : 1 }));
+			queues.economicBuilding.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_temple", { "base" : 1 }));
 		}
 	}
 };
 
-HQ.prototype.buildMarket = function(gameState, queues){
-	if (gameState.getPopulation() > Config.Economy.popForMarket && gameState.currentPhase() >= 2 ) {
+m.HQ.prototype.buildMarket = function(gameState, queues){
+	if (gameState.getPopulation() > this.Config.Economy.popForMarket && gameState.currentPhase() >= 2 ) {
 		if (queues.economicBuilding.countQueuedUnitsWithClass("BarterMarket") === 0 &&
 			gameState.countEntitiesAndQueuedByType(gameState.applyCiv("structures/{civ}_market")) === 0){
 			//only ever build one storehouse/CC/market at a time
-			queues.economicBuilding.addItem(new ConstructionPlan(gameState, "structures/{civ}_market", { "base" : 1 }));
+			queues.economicBuilding.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_market", { "base" : 1 }));
 		}
 	}
 };
 
 // Build a farmstead to go to town phase faster and prepare for research. Only really active on higher diff mode.
-HQ.prototype.buildFarmstead = function(gameState, queues){
-	if (gameState.getPopulation() > Config.Economy.popForFarmstead) {
+m.HQ.prototype.buildFarmstead = function(gameState, queues){
+	if (gameState.getPopulation() > this.Config.Economy.popForFarmstead) {
 		// achtung: "DropsiteFood" does not refer to CCs.
 		if (queues.economicBuilding.countQueuedUnitsWithClass("DropsiteFood") === 0 &&
 			gameState.countEntitiesAndQueuedByType(gameState.applyCiv("structures/{civ}_farmstead")) === 0){
 			//only ever build one storehouse/CC/market at a time
-			queues.economicBuilding.addItem(new ConstructionPlan(gameState, "structures/{civ}_farmstead", { "base" : 1 }));
+			queues.economicBuilding.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_farmstead", { "base" : 1 }));
 		}
 	}
 };
 
 // TODO: generic this, probably per-base
-HQ.prototype.buildDock = function(gameState, queues){
+m.HQ.prototype.buildDock = function(gameState, queues){
 	if (!this.waterMap || this.dockFailed)
 		return;
 	if (gameState.getTimeElapsed() > this.dockStartTime) {
@@ -710,7 +715,7 @@
 			if (tp !== "")
 			{
 				var remaining = this.navalManager.getUnconnectedSeas(gameState, this.baseManagers[1].accessIndex);
-				queues.economicBuilding.addItem(new ConstructionPlan(gameState, tp, { "base" : 1, "sea" : remaining[0] }));
+				queues.economicBuilding.addItem(new m.ConstructionPlan(gameState, tp, { "base" : 1, "sea" : remaining[0] }));
 			}
 		}
 	}
@@ -719,7 +724,7 @@
 // if Aegis has resources it doesn't need, it'll try to barter it for resources it needs
 // once per turn because the info doesn't update between a turn and I don't want to fix it.
 // Not sure how efficient it is but it seems to be sane, at least.
-HQ.prototype.tryBartering = function(gameState){
+m.HQ.prototype.tryBartering = function(gameState){
 	var done = false;
 	if (gameState.countEntitiesByType(gameState.applyCiv("structures/{civ}_market"), true) >= 1) {
 		
@@ -732,7 +737,7 @@
 					if ( (ress[buy] < 400) || needs[buy] > 0) {	// if we need that other resource/ have too little of it
 						var markets = gameState.getOwnEntitiesByType(gameState.applyCiv("structures/{civ}_market"), true).toEntityArray();
 						markets[0].barter(buy,sell,100);
-						//debug ("bartered " +sell +" for " + buy + ", value 100");
+						//m.debug ("bartered " +sell +" for " + buy + ", value 100");
 						done = true;
 					}
 				}
@@ -743,7 +748,7 @@
 
 // build more houses if needed.
 // kinda ugly, lots of special cases to both build enough houses but not tooo many…
-HQ.prototype.buildMoreHouses = function(gameState,queues) {
+m.HQ.prototype.buildMoreHouses = function(gameState,queues) {
 
 	if (gameState.getPopulationLimit() < gameState.getPopulationMax()) {
 
@@ -751,7 +756,9 @@
 
 		if (numPlanned < 3 || (numPlanned < 5 && gameState.getPopulation() > 80))
 		{
-			var plan = new ConstructionPlan(gameState, "structures/{civ}_house", { "base" : 1 });
+			var plan = new m.ConstructionPlan(gameState, "structures/{civ}_house", { "base" : 1 });
+			// make the difficulty available to the isGo function without having to pass it as argument
+			var difficulty = this.Config.difficulty;
 			// change the starting condition to "less than 15 slots left".
 			plan.isGo = function (gameState) {
 				var HouseNb = gameState.countEntitiesByType(gameState.applyCiv("foundation|structures/{civ}_house"), true);
@@ -761,9 +768,9 @@
 					freeSlots = gameState.getPopulationLimit() + HouseNb*5 - gameState.getPopulation();
 				else
 					freeSlots = gameState.getPopulationLimit() + HouseNb*10 - gameState.getPopulation();
-				if (gameState.getPopulation() > 55 && Config.difficulty > 1)
+				if (gameState.getPopulation() > 55 && difficulty > 1)
 					return (freeSlots <= 21);
-				else if (gameState.getPopulation() >= 20 && Config.difficulty !== 0)
+				else if (gameState.getPopulation() >= 20 && difficulty !== 0)
 					return (freeSlots <= 16);
 				else
 					return (freeSlots <= 10);
@@ -774,19 +781,20 @@
 };
 
 // checks if we have bases for all resource types (bar food for now) or if we need to expand.
-HQ.prototype.checkBasesRessLevel = function(gameState,queues) {
+m.HQ.prototype.checkBasesRessLevel = function(gameState,queues) {
 	if (gameState.currentPhase() === 1 && !gameState.isResearching(gameState.townPhase()))
 		return;
 	var count = { "wood" : 0, "stone" : 0, "metal" : 0 }
 	var capacity = { "wood" : 0, "stone" : 0, "metal" : 0 }
 	var need = { "wood" : true, "stone" : true, "metal" : true };
 	var posss = [];
+
 	for (i in this.baseManagers)
 	{
 		var base = this.baseManagers[i];
 		for (type in count)
 		{
-			if (base.getResourceLevel(gameState, type, "all") > 1500*Math.max(Config.difficulty,2))
+			if (base.getResourceLevel(gameState, type, "all") > 1500*Math.max(this.Config.difficulty,2))
 				count[type]++;
 			capacity[type] += base.getWorkerCapacity(gameState, type);
 			if (base.willGather[type] !== 2)
@@ -796,7 +804,7 @@
 	for (type in count)
 	{
 		if (count[type] === 0 || need[type]
-			|| capacity[type] < gameState.getOwnEntities().filter(Filters.and(Filters.byMetadata(PlayerID, "subrole", "gatherer"), Filters.byMetadata(PlayerID, "gather-type", type))).length * 1.05)
+			|| capacity[type] < gameState.getOwnEntities().filter(API3.Filters.and(API3.Filters.byMetadata(PlayerID, "subrole", "gatherer"), API3.Filters.byMetadata(PlayerID, "gather-type", type))).length * 1.05)
 		{
 			// plan a new base.
 			if (gameState.countFoundationsWithType(gameState.applyCiv("structures/{civ}_civil_centre")) === 0 && queues.civilCentre.length() === 0) {
@@ -809,7 +817,7 @@
 					this.outOf[type] = true;
 				} else {
 					// base "-1" means new base.
-					queues.civilCentre.addItem(new ConstructionPlan(gameState, "structures/{civ}_civil_centre",{ "base" : -1 }, 0, -1, pos));
+					queues.civilCentre.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_civil_centre",{ "base" : -1 }, 0, -1, pos));
 				}
 			}
 		}
@@ -819,9 +827,9 @@
 // Deals with building fortresses and towers.
 // Currently build towers next to every useful dropsites.
 // TODO: Fortresses are placed randomly atm.
-HQ.prototype.buildDefences = function(gameState, queues){
+m.HQ.prototype.buildDefences = function(gameState, queues){
 	
-	var workersNumber = gameState.getOwnEntitiesByRole("worker").filter(Filters.not(Filters.byHasMetadata(PlayerID,"plan"))).length;
+	var workersNumber = gameState.getOwnEntitiesByRole("worker").filter(API3.Filters.not(API3.Filters.byHasMetadata(PlayerID,"plan"))).length;
 	
 	if (gameState.countEntitiesAndQueuedByType(gameState.applyCiv('structures/{civ}_defense_tower'))
 		+ queues.defenceBuilding.length() < gameState.getEntityLimits()["DefenseTower"] && queues.defenceBuilding.length() < 4 && gameState.currentPhase() > 1) {
@@ -836,7 +844,7 @@
 					{
 						var position = dpEnt.position();
 						if (position) {
-							queues.defenceBuilding.addItem(new ConstructionPlan(gameState, 'structures/{civ}_defense_tower', { "base" : i }, 0 , -1, position));
+							queues.defenceBuilding.addItem(new m.ConstructionPlan(gameState, 'structures/{civ}_defense_tower', { "base" : i }, 0 , -1, position));
 						}
 						dpEnt.setMetadata(PlayerID, "defenseTower", true);
 					}
@@ -855,8 +863,8 @@
 		{
 			if (!this.fortressStartTime)
 				this.fortressStartTime = gameState.getTimeElapsed();
-			queues.defenceBuilding.addItem(new ConstructionPlan(gameState, this.bFort[0], { "base" : 1 }));
-			debug ("Building a fortress");
+			queues.defenceBuilding.addItem(new m.ConstructionPlan(gameState, this.bFort[0], { "base" : 1 }));
+			m.debug ("Building a fortress");
 		}
 	}
 	if (gameState.countEntitiesByType(gameState.applyCiv(this.bFort[i]), true) >= 1) {
@@ -877,13 +885,13 @@
 	}
 };
 
-HQ.prototype.buildBlacksmith = function(gameState, queues){
-	if (gameState.getTimeElapsed() > Config.Military.timeForBlacksmith*1000) {
+m.HQ.prototype.buildBlacksmith = function(gameState, queues){
+	if (gameState.getTimeElapsed() > this.Config.Military.timeForBlacksmith*1000) {
 		if (queues.militaryBuilding.length() === 0 &&
 			gameState.countEntitiesAndQueuedByType(gameState.applyCiv("structures/{civ}_blacksmith")) === 0) {
 			var tp = gameState.getTemplate(gameState.applyCiv("structures/{civ}_blacksmith"));
 			if (tp.available(gameState))
-				queues.militaryBuilding.addItem(new ConstructionPlan(gameState, "structures/{civ}_blacksmith", { "base" : 1 }));
+				queues.militaryBuilding.addItem(new m.ConstructionPlan(gameState, "structures/{civ}_blacksmith", { "base" : 1 }));
 		}
 	}
 };
@@ -892,32 +900,32 @@
 // They are mostly defined by Config.js. This is unreliable since changes could be done easily.
 // TODO: We need to determine these dynamically. Also doesn't build fortresses since the above function does that.
 // TODO: building placement is bad. Choice of buildings is also fairly dumb.
-HQ.prototype.constructTrainingBuildings = function(gameState, queues) {
+m.HQ.prototype.constructTrainingBuildings = function(gameState, queues) {
 	Engine.ProfileStart("Build buildings");
-	var workersNumber = gameState.getOwnEntitiesByRole("worker").filter(Filters.not(Filters.byHasMetadata(PlayerID, "plan"))).length;
+	var workersNumber = gameState.getOwnEntitiesByRole("worker").filter(API3.Filters.not(API3.Filters.byHasMetadata(PlayerID, "plan"))).length;
 
-	if (workersNumber > Config.Military.popForBarracks1) {
+	if (workersNumber > this.Config.Military.popForBarracks1) {
 		if (gameState.countEntitiesAndQueuedByType(gameState.applyCiv(this.bModerate[0])) + queues.militaryBuilding.length() < 1) {
-			debug ("Trying to build barracks");
-			queues.militaryBuilding.addItem(new ConstructionPlan(gameState, this.bModerate[0], { "base" : 1 }));
+			m.debug ("Trying to build barracks");
+			queues.militaryBuilding.addItem(new m.ConstructionPlan(gameState, this.bModerate[0], { "base" : 1 }));
 		}
 	}
 	
-	if (gameState.countEntitiesAndQueuedByType(gameState.applyCiv(this.bModerate[0])) < 2 && workersNumber > Config.Military.popForBarracks2)
+	if (gameState.countEntitiesAndQueuedByType(gameState.applyCiv(this.bModerate[0])) < 2 && workersNumber > this.Config.Military.popForBarracks2)
 		if (queues.militaryBuilding.length() < 1)
-			queues.militaryBuilding.addItem(new ConstructionPlan(gameState, this.bModerate[0], { "base" : 1 }));
+			queues.militaryBuilding.addItem(new m.ConstructionPlan(gameState, this.bModerate[0], { "base" : 1 }));
 	
 	if (gameState.countEntitiesByType(gameState.applyCiv(this.bModerate[0]), true) === 2 && gameState.countEntitiesAndQueuedByType(gameState.applyCiv(this.bModerate[0])) < 3 && workersNumber > 125)
 		if (queues.militaryBuilding.length() < 1)
 		{
-			queues.militaryBuilding.addItem(new ConstructionPlan(gameState, this.bModerate[0], { "base" : 1 }));
+			queues.militaryBuilding.addItem(new m.ConstructionPlan(gameState, this.bModerate[0], { "base" : 1 }));
 			if (gameState.civ() == "gaul" || gameState.civ() == "brit" || gameState.civ() == "iber") {
-				queues.militaryBuilding.addItem(new ConstructionPlan(gameState, this.bModerate[0], { "base" : 1 }));
-				queues.militaryBuilding.addItem(new ConstructionPlan(gameState, this.bModerate[0], { "base" : 1 }));
+				queues.militaryBuilding.addItem(new m.ConstructionPlan(gameState, this.bModerate[0], { "base" : 1 }));
+				queues.militaryBuilding.addItem(new m.ConstructionPlan(gameState, this.bModerate[0], { "base" : 1 }));
 			}
 		}
 	//build advanced military buildings
-	if (workersNumber >= Config.Military.popForBarracks2 - 15 && gameState.currentPhase() > 2){
+	if (workersNumber >= this.Config.Military.popForBarracks2 - 15 && gameState.currentPhase() > 2){
 		if (queues.militaryBuilding.length() === 0){
 			var inConst = 0;
 			for (var i in this.bAdvanced)
@@ -925,7 +933,7 @@
 			if (inConst == 0 && this.bAdvanced && this.bAdvanced.length !== 0) {
 				var i = Math.floor(Math.random() * this.bAdvanced.length);
 				if (gameState.countEntitiesAndQueuedByType(gameState.applyCiv(this.bAdvanced[i])) < 1){
-					queues.militaryBuilding.addItem(new ConstructionPlan(gameState, this.bAdvanced[i], { "base" : 1 }));
+					queues.militaryBuilding.addItem(new m.ConstructionPlan(gameState, this.bAdvanced[i], { "base" : 1 }));
 				}
 			}
 		}
@@ -939,8 +947,8 @@
 		if (inConst == 1) {
 			var i = Math.floor(Math.random() * this.bAdvanced.length);
 			if (gameState.countEntitiesAndQueuedByType(gameState.applyCiv(this.bAdvanced[i])) < 1){
-				queues.militaryBuilding.addItem(new ConstructionPlan(gameState, this.bAdvanced[i], { "base" : 1 }));
-				queues.militaryBuilding.addItem(new ConstructionPlan(gameState, this.bAdvanced[i], { "base" : 1 }));
+				queues.militaryBuilding.addItem(new m.ConstructionPlan(gameState, this.bAdvanced[i], { "base" : 1 }));
+				queues.militaryBuilding.addItem(new m.ConstructionPlan(gameState, this.bAdvanced[i], { "base" : 1 }));
 			}
 		}
 	}
@@ -949,9 +957,9 @@
 };
 
 // TODO: use pop(). Currently unused as this is too gameable.
-HQ.prototype.garrisonAllFemales = function(gameState) {
-	var buildings = gameState.getOwnEntities().filter(Filters.byCanGarrison()).toEntityArray();
-	var females = gameState.getOwnEntities().filter(Filters.byClass("Support"));
+m.HQ.prototype.garrisonAllFemales = function(gameState) {
+	var buildings = gameState.getOwnEntities().filter(API3.Filters.byCanGarrison()).toEntityArray();
+	var females = gameState.getOwnEntities().filter(API3.Filters.byClass("Support"));
 	
 	var cache = {};
 	
@@ -974,16 +982,16 @@
 	});
 	this.hasGarrisonedFemales = true;
 };
-HQ.prototype.ungarrisonAll = function(gameState) {
+m.HQ.prototype.ungarrisonAll = function(gameState) {
 	this.hasGarrisonedFemales = false;
-	var buildings = gameState.getOwnEntities().filter(Filters.and(Filters.byClass("Structure"),Filters.byCanGarrison())).toEntityArray();
+	var buildings = gameState.getOwnEntities().filter(API3.Filters.and(API3.Filters.byClass("Structure"),API3.Filters.byCanGarrison())).toEntityArray();
 	buildings.forEach( function (struct) {
 		if (struct.garrisoned() && struct.garrisoned().length)
 			struct.unloadAll();
 		});
 };
 
-HQ.prototype.pausePlan = function(gameState, planName) {
+m.HQ.prototype.pausePlan = function(gameState, planName) {
 	for (var attackType in this.upcomingAttacks) {
 		for (var i in this.upcomingAttacks[attackType]) {
 			var attack = this.upcomingAttacks[attackType][i];
@@ -999,7 +1007,7 @@
 		}
 	}
 }
-HQ.prototype.unpausePlan = function(gameState, planName) {
+m.HQ.prototype.unpausePlan = function(gameState, planName) {
 	for (var attackType in this.upcomingAttacks) {
 		for (var i in this.upcomingAttacks[attackType]) {
 			var attack = this.upcomingAttacks[attackType][i];
@@ -1015,7 +1023,7 @@
 		}
 	}
 }
-HQ.prototype.pauseAllPlans = function(gameState) {
+m.HQ.prototype.pauseAllPlans = function(gameState) {
 	for (var attackType in this.upcomingAttacks) {
 		for (var i in this.upcomingAttacks[attackType]) {
 			var attack = this.upcomingAttacks[attackType][i];
@@ -1029,7 +1037,7 @@
 		}
 	}
 }
-HQ.prototype.unpauseAllPlans = function(gameState) {
+m.HQ.prototype.unpauseAllPlans = function(gameState) {
 	for (var attackType in this.upcomingAttacks) {
 		for (var i in this.upcomingAttacks[attackType]) {
 			var attack = this.upcomingAttacks[attackType][i];
@@ -1047,7 +1055,7 @@
 
 // Some functions are run every turn
 // Others once in a while
-HQ.prototype.update = function(gameState, queues, events) {
+m.HQ.prototype.update = function(gameState, queues, events) {	
 	Engine.ProfileStart("Headquarters update");
 	
 	this.checkEvents(gameState,events,queues);
@@ -1057,7 +1065,7 @@
 	this.trainMoreWorkers(gameState, queues);
 	
 	// sandbox doesn't expand.
-	if (Config.difficulty !== 0)
+	if (this.Config.difficulty !== 0)
 		this.checkBasesRessLevel(gameState, queues);
 
 	this.buildMoreHouses(gameState,queues);
@@ -1065,7 +1073,7 @@
 	if (gameState.getTimeElapsed() > this.techStartTime && gameState.currentPhase() > 2)
 		this.tryResearchTechs(gameState,queues);
 	
-	if (Config.difficulty > 1)
+	if (this.Config.difficulty > 1)
 		this.tryBartering(gameState);
 	
 	this.buildFarmstead(gameState, queues);
@@ -1087,7 +1095,7 @@
 	for (i in this.baseManagers)
 	{
 		this.baseManagers[i].checkEvents(gameState, events, queues)
-		if ( ( (+i + gameState.ai.playedTurn) % (uniqueIDBases - 1)) === 0)
+		if ( ( (+i + gameState.ai.playedTurn) % (m.playerGlobals[PlayerID].uniqueIDBases - 1)) === 0)
 			this.baseManagers[i].update(gameState, queues, events);
 	}
 
@@ -1113,10 +1121,10 @@
 					if (updateStep === 1 || attack.isPaused() ) {
 						// just chillin'
 					} else if (updateStep === 0 || updateStep === 3) {
-						debug ("Military Manager: " +attack.getType() +" plan " +attack.getName() +" aborted.");
+						m.debug ("Military Manager: " +attack.getType() +" plan " +attack.getName() +" aborted.");
 						if (updateStep === 3) {
 							this.attackPlansEncounteredWater = true;
-							debug("No attack path found. Aborting.");
+							m.debug("No attack path found. Aborting.");
 						}
 						attack.Abort(gameState, this);
 						this.upcomingAttacks[attackType].splice(i--,1);
@@ -1130,7 +1138,7 @@
 							chatText = "I'm starting an attack against " + gameState.sharedScript.playersData[attack.targetPlayer].name + ".";
 						gameState.ai.chatTeam(chatText);
 						
-						debug ("Military Manager: Starting " +attack.getType() +" plan " +attack.getName());
+						m.debug ("Military Manager: Starting " +attack.getType() +" plan " +attack.getName());
 						attack.StartAttack(gameState,this);
 						this.startedAttacks[attackType].push(attack);
 						this.upcomingAttacks[attackType].splice(i--,1);
@@ -1145,7 +1153,7 @@
 						chatText = "I'm starting an attack against " + gameState.sharedScript.playersData[attack.targetPlayer].name + ".";
 					gameState.ai.chatTeam(chatText);
 					
-					debug ("Military Manager: Starting " +attack.getType() +" plan " +attack.getName());
+					m.debug ("Military Manager: Starting " +attack.getType() +" plan " +attack.getName());
 					this.startedAttacks[attackType].push(attack);
 					this.upcomingAttacks[attackType].splice(i--,1);
 				}
@@ -1160,7 +1168,7 @@
 			{
 				var remaining = attack.update(gameState,this,events);
 				if (remaining == 0 || remaining == undefined) {
-					debug ("Military Manager: " +attack.getType() +" plan " +attack.getName() +" is now finished.");
+					m.debug ("Military Manager: " +attack.getType() +" plan " +attack.getName() +" is now finished.");
 					attack.Abort(gameState);
 					this.startedAttacks[attackType].splice(i--,1);
 				}
@@ -1174,14 +1182,14 @@
 	if (gameState.ai.strategy === "rush" && this.startedAttacks["CityAttack"].length !== 0) {
 		// and then we revert.
 		gameState.ai.strategy = "normal";
-		Config.Economy.femaleRatio = 0.4;
+		this.Config.Economy.femaleRatio = 0.4;
 		gameState.ai.modules.economy.targetNumWorkers = Math.max(Math.floor(gameState.getPopulationMax()*0.55), 1);
 	} else if (gameState.ai.strategy === "rush" && this.upcomingAttacks["CityAttack"].length === 0)
 	{
-		Lalala = new CityAttack(gameState, this,this.TotalAttackNumber, -1, "rush")
+		Lalala = new m.CityAttack(gameState, this, this.Config, this.TotalAttackNumber, -1, "rush")
 		this.TotalAttackNumber++;
 		this.upcomingAttacks["CityAttack"].push(Lalala);
-		debug ("Starting a little something");
+		m.debug ("Starting a little something");
 	} else if (gameState.ai.strategy !== "rush" && !this.waterMap)
 	{
 		// creating plans after updating because an aborted plan might be reused in that case.
@@ -1193,22 +1201,22 @@
 			} else {
 				// basically only the first plan, really.
 				if (this.upcomingAttacks["CityAttack"].length == 0 && gameState.getTimeElapsed() < 12*60000) {
-					var Lalala = new CityAttack(gameState, this,this.TotalAttackNumber, -1);
+					var Lalala = new m.CityAttack(gameState, this, this.Config, this.TotalAttackNumber, -1);
 					if (Lalala.failed)
 					{
 						this.attackPlansEncounteredWater = true; // hack
 					} else {
-						debug ("Military Manager: Creating the plan " +this.TotalAttackNumber);
+						m.debug ("Military Manager: Creating the plan " +this.TotalAttackNumber);
 						this.TotalAttackNumber++;
 						this.upcomingAttacks["CityAttack"].push(Lalala);
 					}
-				} else if (this.upcomingAttacks["CityAttack"].length == 0 && Config.difficulty !== 0) {
-					var Lalala = new CityAttack(gameState, this,this.TotalAttackNumber, -1, "superSized");
+				} else if (this.upcomingAttacks["CityAttack"].length == 0 && this.Config.difficulty !== 0) {
+					var Lalala = new m.CityAttack(gameState, this, this.Config, this.TotalAttackNumber, -1, "superSized");
 					if (Lalala.failed)
 					{
 						this.attackPlansEncounteredWater = true; // hack
 					} else {
-						debug ("Military Manager: Creating the super sized plan " +this.TotalAttackNumber);
+						m.debug ("Military Manager: Creating the super sized plan " +this.TotalAttackNumber);
 						this.TotalAttackNumber++;
 						this.upcomingAttacks["CityAttack"].push(Lalala);
 					}
@@ -1221,12 +1229,12 @@
 	 // very old relic. This should be reimplemented someday so the code stays here.
 	 
 	 if (this.HarassRaiding && this.preparingRaidNumber + this.startedRaidNumber < 1 && gameState.getTimeElapsed() < 780000) {
-	 var Lalala = new CityAttack(gameState, this,this.totalStartedAttackNumber, -1, "harass_raid");
+	 var Lalala = new m.CityAttack(gameState, this,this.totalStartedAttackNumber, -1, "harass_raid");
 	 if (!Lalala.createSupportPlans(gameState, this, )) {
-	 debug ("Military Manager: harrassing plan not a valid option");
+	 m.debug ("Military Manager: harrassing plan not a valid option");
 	 this.HarassRaiding = false;
 	 } else {
-	 debug ("Military Manager: Creating the harass raid plan " +this.totalStartedAttackNumber);
+	 m.debug ("Military Manager: Creating the harass raid plan " +this.totalStartedAttackNumber);
 	 
 	 this.totalStartedAttackNumber++;
 	 this.preparingRaidNumber++;
@@ -1243,7 +1251,7 @@
 	this.buildDropsites(gameState, queues);
 	Engine.ProfileStop();
 
-	if (Config.difficulty !== 0)
+	if (this.Config.difficulty !== 0)
 		this.tryBartering(gameState);
 		
 	this.buildFarmstead(gameState, queues);
@@ -1255,3 +1263,7 @@
 */
 	Engine.ProfileStop();	// Heaquarters update
 };
+
+return m;
+
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/queueplan-research.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/queueplan-research.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/queueplan-research.js	(Arbeitskopie)
@@ -1,14 +1,17 @@
-var ResearchPlan = function(gameState, type, startTime, expectedTime, rush) {
+var AEGIS = function(m)
+{
+
+m.ResearchPlan = function(gameState, type, startTime, expectedTime, rush) {
 	this.type = type;
 
-	this.ID = uniqueIDBOPlans++;
+	this.ID = m.playerGlobals[PlayerID].uniqueIDBOPlans++;
 
 	this.template = gameState.getTemplate(this.type);
 	if (!this.template || this.template.researchTime === undefined) {
 		return false;
 	}
 	this.category = "technology";
-	this.cost = new Resources(this.template.cost(),0);
+	this.cost = new API3.Resources(this.template.cost(),0);
 	this.number = 1; // Obligatory for compatibility
 	
 	if (!startTime)
@@ -30,23 +33,23 @@
 };
 
 // return true if we willstart amassing resource for this plan
-ResearchPlan.prototype.isGo = function(gameState) {
+m.ResearchPlan.prototype.isGo = function(gameState) {
 	return (gameState.getTimeElapsed() > this.startTime);
 };
 
-ResearchPlan.prototype.canStart = function(gameState) {
+m.ResearchPlan.prototype.canStart = function(gameState) {
 	// also checks canResearch
 	return (gameState.findResearchers(this.type).length !== 0);
 };
 
-ResearchPlan.prototype.start = function(gameState) {
+m.ResearchPlan.prototype.start = function(gameState) {
 	var self = this;
 	
 	// TODO: this is special cased for "rush" technologies, ie the town phase
 	// which currently is a 100% focus.
 	gameState.ai.queueManager.unpauseAll();
 	
-	//debug ("Starting the research plan for " + this.type);
+	//m.debug ("Starting the research plan for " + this.type);
 	var trainers = gameState.findResearchers(this.type).toEntityArray();
 
 	//for (var i in trainers)
@@ -66,9 +69,12 @@
 	}
 };
 
-ResearchPlan.prototype.getCost = function(){
-	var costs = new Resources();
+m.ResearchPlan.prototype.getCost = function(){
+	var costs = new API3.Resources();
 	costs.add(this.cost);
 	return costs;
 };
 
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/queue-manager.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/queue-manager.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/queue-manager.js	(Arbeitskopie)
@@ -1,3 +1,6 @@
+var AEGIS = function(m)
+{
+
 // This takes the input queues and picks which items to fund with resources until no more resources are left to distribute.
 //
 // Currently this manager keeps accounts for each queue, split between the 4 main resources
@@ -17,7 +20,8 @@
 //
 // This system should be improved. It's probably not flexible enough.
 
-var QueueManager = function(queues, priorities) {
+m.QueueManager = function(Config, queues, priorities) {
+	this.Config = Config;
 	this.queues = queues;
 	this.priorities = priorities;
 	this.account = {};
@@ -28,7 +32,7 @@
 	this.queueArrays = [];
 	for (var p in this.queues) {
 		this.account[p] = 0;
-		this.accounts[p] = new Resources();
+		this.accounts[p] = new API3.Resources();
 		this.queueArrays.push([p,this.queues[p]]);
 	}
 	this.queueArrays.sort(function (a,b) { return (self.priorities[b[0]] - self.priorities[a[0]]) });
@@ -36,7 +40,7 @@
 	this.curItemQueue = [];
 };
 
-QueueManager.prototype.getAvailableResources = function(gameState, noAccounts) {
+m.QueueManager.prototype.getAvailableResources = function(gameState, noAccounts) {
 	var resources = gameState.getResources();
 	if (noAccounts)
 		return resources;
@@ -46,16 +50,16 @@
 	return resources;
 };
 
-QueueManager.prototype.getTotalAccountedResources = function(gameState) {
-	var resources = new Resources();
+m.QueueManager.prototype.getTotalAccountedResources = function(gameState) {
+	var resources = new API3.Resources();
 	for (var key in this.queues) {
 		resources.add(this.accounts[key]);
 	}
 	return resources;
 };
 
-QueueManager.prototype.currentNeeds = function(gameState) {
-	var needs = new Resources();
+m.QueueManager.prototype.currentNeeds = function(gameState) {
+	var needs = new API3.Resources();
 	// get out current resources, not removing accounts.
 	var current = this.getAvailableResources(gameState, true);
 	//queueArrays because it's faster.
@@ -82,8 +86,8 @@
 	};
 };
 
-QueueManager.prototype.futureNeeds = function(gameState) {
-	var needs = new Resources();
+m.QueueManager.prototype.futureNeeds = function(gameState) {
+	var needs = new API3.Resources();
 	// get out current resources, not removing accounts.
 	var current = this.getAvailableResources(gameState, true);
 	//queueArrays because it's faster.
@@ -108,7 +112,7 @@
 };
 
 // calculate the gather rates we'd want to be able to use all elements in our queues
-QueueManager.prototype.wantedGatherRates = function(gameState) {
+m.QueueManager.prototype.wantedGatherRates = function(gameState) {
 	var rates = { "food" : 0, "wood" : 0, "stone" : 0, "metal" : 0 };
 	var qTime = gameState.getTimeElapsed();
 	var qCosts = { "food" : 0, "wood" : 0, "stone" : 0, "metal" : 0 };
@@ -143,7 +147,9 @@
 				// estimate time based on priority + cost + nb
 				// TODO: work on this.
 				for (type in qCosts)
+				{
 					qCosts[type] += (cost[type] + Math.min(cost[type],this.priorities[name]));
+				}
 				qTime += 30000;
 			} else {
 				// TODO: work on this.
@@ -165,7 +171,7 @@
 	return rates;
 };
 
-/*QueueManager.prototype.logNeeds = function(gameState) {
+/*m.QueueManager.prototype.logNeeds = function(gameState) {
  if (!this.totor)
  {
  this.totor = [];
@@ -255,34 +261,34 @@
 };
 */
 
-QueueManager.prototype.printQueues = function(gameState){
-	debug("QUEUES");
+m.QueueManager.prototype.printQueues = function(gameState){
+	m.debug("QUEUES");
 	for (var i in this.queues){
 		var qStr = "";
 		var q = this.queues[i];
 		if (q.queue.length > 0)
-			debug((i + ":"));
+			m.debug((i + ":"));
 		for (var j in q.queue){
 			qStr = "     " + q.queue[j].type + " ";
 			if (q.queue[j].number)
 				qStr += "x" + q.queue[j].number;
-			debug (qStr);
+			m.debug (qStr);
 		}
 	}
-	debug ("Accounts");
+	m.debug ("Accounts");
 	for (var p in this.accounts)
 	{
-		debug(p + ": " + uneval(this.accounts[p]));
+		m.debug(p + ": " + uneval(this.accounts[p]));
 	}
-	debug("Needed Resources:" + uneval(this.futureNeeds(gameState,false)));
-	debug ("Wanted Gather Rates:" + uneval(this.wantedGatherRates(gameState)));
-	debug ("Current Resources:" + uneval(gameState.getResources()));
-	debug ("Available Resources:" + uneval(this.getAvailableResources(gameState)));
+	m.debug("Needed Resources:" + uneval(this.futureNeeds(gameState,false)));
+	m.debug ("Wanted Gather Rates:" + uneval(this.wantedGatherRates(gameState)));
+	m.debug ("Current Resources:" + uneval(gameState.getResources()));
+	m.debug ("Available Resources:" + uneval(this.getAvailableResources(gameState)));
 };
 
 // nice readable HTML version.
-QueueManager.prototype.HTMLprintQueues = function(gameState){
-	if (!Config.debug)
+m.QueueManager.prototype.HTMLprintQueues = function(gameState){
+	if (!this.Config.debug)
 		return;
 	log("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"> <html> <head> <title>Aegis Queue Manager</title> <link rel=\"stylesheet\" href=\"table.css\">  </head> <body> <table> <caption>Aegis Build Order</caption> ");
 	for (var i in this.queues){
@@ -325,13 +331,13 @@
 	log("</body></html>");
 };
 
-QueueManager.prototype.clear = function(){
+m.QueueManager.prototype.clear = function(){
 	this.curItemQueue = [];
 	for (var i in this.queues)
 		this.queues[i].empty();
 };
 
-QueueManager.prototype.update = function(gameState) {
+m.QueueManager.prototype.update = function(gameState) {
 	var self = this;
 	
 	for (var i in this.priorities){
@@ -430,7 +436,7 @@
 							this.accounts[queues[under]] -= amnt;
 							this.accounts[queues[over]] += amnt;
 							--over;
-							debug ("Shifting " + amnt + " from " + queues[under] + " to " +queues[over]);
+							m.debug ("Shifting " + amnt + " from " + queues[under] + " to " +queues[over]);
 							continue;
 						} else {
 							++under;
@@ -447,8 +453,8 @@
 	
 	Engine.ProfileStart("Pick items from queues");
 
-	//debug ("start");
-	//debug (uneval(this.accounts));
+	//m.debug ("start");
+	//m.debug (uneval(this.accounts));
 	// Start the next item in the queue if we can afford it.
 	for (var i in this.queueArrays)
 	{
@@ -457,7 +463,7 @@
 		if (queue.length() > 0 && !queue.paused)
 		{
 			var item = queue.getNext();
-			var total = new Resources();
+			var total = new API3.Resources();
 			total.add(this.accounts[name]);
 			if (total.canAfford(item.getCost()))
 			{
@@ -471,7 +477,7 @@
 			this.accounts[name].reset();
 		}
 	}
-	//debug (uneval(this.accounts));
+	//m.debug (uneval(this.accounts));
 	
 	Engine.ProfileStop();
 	
@@ -481,7 +487,7 @@
 	Engine.ProfileStop();
 };
 
-QueueManager.prototype.pauseQueue = function(queue, scrapAccounts) {
+m.QueueManager.prototype.pauseQueue = function(queue, scrapAccounts) {
 	if (this.queues[queue])
 	{
 		this.queues[queue].paused = true;
@@ -490,12 +496,12 @@
 	}
 }
 
-QueueManager.prototype.unpauseQueue = function(queue) {
+m.QueueManager.prototype.unpauseQueue = function(queue) {
 	if (this.queues[queue])
 		this.queues[queue].paused = false;
 }
 
-QueueManager.prototype.pauseAll = function(scrapAccounts, but) {
+m.QueueManager.prototype.pauseAll = function(scrapAccounts, but) {
 	for (var p in this.queues)
 		if (p != but)
 		{
@@ -505,28 +511,30 @@
 		}
 }
 
-QueueManager.prototype.unpauseAll = function(but) {
+m.QueueManager.prototype.unpauseAll = function(but) {
 	for (var p in this.queues)
 		if (p != but)
 			this.queues[p].paused = false;
 }
 
 
-QueueManager.prototype.addQueue = function(queueName, priority) {
+m.QueueManager.prototype.addQueue = function(queueName, priority) {
 	if (this.queues[queueName] == undefined) {
-		this.queues[queueName] = new Queue();
+		this.queues[queueName] = new m.Queue();
 		this.priorities[queueName] = priority;
 		this.account[queueName] = 0;
-		this.accounts[queueName] = new Resources();
+		this.accounts[queueName] = new API3.Resources();
 
 		var self = this;
 		this.queueArrays = [];
 		for (var p in this.queues)
+		{
 			this.queueArrays.push([p,this.queues[p]]);
+		}
 		this.queueArrays.sort(function (a,b) { return (self.priorities[b[0]] - self.priorities[a[0]]) });
 	}
 }
-QueueManager.prototype.removeQueue = function(queueName) {
+m.QueueManager.prototype.removeQueue = function(queueName) {
 	if (this.queues[queueName] !== undefined) {
 		if ( this.curItemQueue.indexOf(queueName) !== -1) {
 			this.curItemQueue.splice(this.curItemQueue.indexOf(queueName),1);
@@ -539,18 +547,23 @@
 		var self = this;
 		this.queueArrays = [];
 		for (var p in this.queues)
+		{
 			this.queueArrays.push([p,this.queues[p]]);
+		}
 		this.queueArrays.sort(function (a,b) { return (self.priorities[b[0]] - self.priorities[a[0]]) });
 	}
 }
-QueueManager.prototype.changePriority = function(queueName, newPriority) {
+m.QueueManager.prototype.changePriority = function(queueName, newPriority) {
 	var self = this;
 	if (this.queues[queueName] !== undefined)
 		this.priorities[queueName] = newPriority;
 	this.queueArrays = [];
-	for (var p in this.queues) {
+	for (var p in this.queues)
+	{
 		this.queueArrays.push([p,this.queues[p]]);
 	}
 	this.queueArrays.sort(function (a,b) { return (self.priorities[b[0]] - self.priorities[a[0]]) });
 }
 
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/map-module.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/map-module.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/map-module.js	(Arbeitskopie)
@@ -1,6 +1,9 @@
+var AEGIS = function(m)
+{
+
 // other map functions
 
-Map.createObstructionMap = function(gameState, accessIndex, template){
+m.createObstructionMap = function(gameState, accessIndex, template){
 	var passabilityMap = gameState.getMap();
 	var territoryMap = gameState.ai.territoryMap;
 	
@@ -31,7 +34,7 @@
 			for (var y = 0; y < passabilityMap.height; ++y)
 			{
 				var i = x + y*passabilityMap.width;
-				var tilePlayer = (territoryMap.data[i] & TERRITORY_PLAYER_MASK);
+				var tilePlayer = (territoryMap.data[i] & 0x3F);
 				
 				if (gameState.ai.myIndex !== gameState.ai.accessibility.landPassMap[i])
 				{
@@ -88,7 +91,7 @@
 		var obstructionTiles = new Uint8Array(passabilityMap.data.length);
 		for (var i = 0; i < passabilityMap.data.length; ++i)
 		{
-			var tilePlayer = (territoryMap.data[i] & TERRITORY_PLAYER_MASK);
+			var tilePlayer = (territoryMap.data[i] & 0x3F);
 			var invalidTerritory = (
 									(!buildOwn && tilePlayer == playerID) ||
 									(!buildAlly && gameState.isPlayerAlly(tilePlayer) && tilePlayer != playerID) ||
@@ -105,7 +108,7 @@
 		}
 	}
 	
-	var map = new Map(gameState.sharedScript, obstructionTiles);
+	var map = new API3.Map(gameState.sharedScript, obstructionTiles);
 	map.setMaxVal(255);
 	
 	if (template && template.buildDistance()){
@@ -126,17 +129,19 @@
 };
 
 
-
-Map.createTerritoryMap = function(gameState) {
+m.createTerritoryMap = function(gameState) {
 	var map = gameState.ai.territoryMap;
 	
-	var ret = new Map(gameState.sharedScript, map.data);
+	var ret = new API3.Map(gameState.sharedScript, map.data);
 	
 	ret.getOwner = function(p) {
-		return this.point(p) & TERRITORY_PLAYER_MASK;
+		return this.point(p) & 0x3F;
 	}
 	ret.getOwnerIndex = function(p) {
-		return this.map[p] & TERRITORY_PLAYER_MASK;
+		return this.map[p] & 0x3F;
 	}
 	return ret;
 };
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/aegis/data.json
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/data.json	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/data.json	(Arbeitskopie)
@@ -1,6 +1,7 @@
 {
   "name": "Aegis Bot",
   "description": "Wraitii's improvement of qBot. It is more reliable and generally a better player. Note that it doesn't support saved games yet, and there may be other bugs. Please report issues to Wildfire Games (see the link in the main menu).",
+  "moduleName" : "AEGIS",
   "constructor": "AegisBot",
   "useShared": true
 }
Index: binaries/data/mods/public/simulation/ai/aegis/naval-manager.js
===================================================================
--- binaries/data/mods/public/simulation/ai/aegis/naval-manager.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/aegis/naval-manager.js	(Arbeitskopie)
@@ -1,3 +1,6 @@
+var AEGIS = function(m)
+{
+
 /* Naval Manager
  Will deal with anything ships.
  -Basically trade over water (with fleets and goals commissioned by the economy manager)
@@ -9,7 +12,7 @@
  Does not build them though, that's for the base manager to handle.
  */
 
-var NavalManager = function() {
+m.NavalManager = function() {
 	// accessibility zones for which we have a dock.
 	// Connexion is described as [landindex] = [seaIndexes];
 	// technically they also exist for sea zones but I don't care.
@@ -32,16 +35,16 @@
 };
 
 // More initialisation for stuff that needs the gameState
-NavalManager.prototype.init = function(gameState, events, queues) {
+m.NavalManager.prototype.init = function(gameState, events, queues) {
 	// finished docks
-	this.docks = gameState.getOwnEntities().filter(Filters.and(Filters.byClass("Dock"), Filters.not(Filters.isFoundation())));
+	this.docks = gameState.getOwnEntities().filter(API3.Filters.and(API3.Filters.byClass("Dock"), API3.Filters.not(API3.Filters.isFoundation())));
 	this.docks.allowQuickIter();
 	this.docks.registerUpdates();
 	
-	this.ships = gameState.getOwnEntities().filter(Filters.byClass("Ship"));
+	this.ships = gameState.getOwnEntities().filter(API3.Filters.byClass("Ship"));
 	// note: those two can overlap (some transport ships are warships too and vice-versa).
-	this.tpShips = this.ships.filter(Filters.byCanGarrison());
-	this.warships = this.ships.filter(Filters.byClass("Warship"));
+	this.tpShips = this.ships.filter(API3.Filters.byCanGarrison());
+	this.warships = this.ships.filter(API3.Filters.byClass("Warship"));
 
 	this.ships.registerUpdates();
 	this.tpShips.registerUpdates();
@@ -52,19 +55,19 @@
 		if (gameState.ai.accessibility.regionType[i] !== "water")
 		{
 			// push dummies
-			this.seaShips.push(new EntityCollection(gameState.sharedScript));
-			this.seaTpShips.push(new EntityCollection(gameState.sharedScript));
-			this.seaWarships.push(new EntityCollection(gameState.sharedScript));
+			this.seaShips.push(new API3.EntityCollection(gameState.sharedScript));
+			this.seaTpShips.push(new API3.EntityCollection(gameState.sharedScript));
+			this.seaWarships.push(new API3.EntityCollection(gameState.sharedScript));
 			this.wantedTpShips.push(0);
 			this.wantedWarships.push(0);
 		} else {
-			var collec = this.ships.filter(Filters.byStaticMetadata(PlayerID, "sea", i));
+			var collec = this.ships.filter(API3.Filters.byStaticMetadata(PlayerID, "sea", i));
 			collec.registerUpdates();
 			this.seaShips.push(collec);
-			collec = this.tpShips.filter(Filters.byStaticMetadata(PlayerID, "sea", i));
+			collec = this.tpShips.filter(API3.Filters.byStaticMetadata(PlayerID, "sea", i));
 			collec.registerUpdates();
 			this.seaTpShips.push(collec);
-			var collec = this.warships.filter(Filters.byStaticMetadata(PlayerID, "sea", i));
+			var collec = this.warships.filter(API3.Filters.byStaticMetadata(PlayerID, "sea", i));
 			collec.registerUpdates();
 			this.seaWarships.push(collec);
 			
@@ -76,7 +79,7 @@
 	}
 };
 
-NavalManager.prototype.getUnconnectedSeas = function (gameState, region) {
+m.NavalManager.prototype.getUnconnectedSeas = function (gameState, region) {
 	var seas = gameState.ai.accessibility.regionLinks[region]
 	if (seas.length === 0)
 		return [];
@@ -89,7 +92,7 @@
 };
 
 // returns true if there is a path from A to B and we have docks.
-NavalManager.prototype.canReach = function (gameState, regionA, regionB) {
+m.NavalManager.prototype.canReach = function (gameState, regionA, regionB) {
 	var path = gameState.ai.accessibility.getTrajectToIndex(regionA, regionB);
 	if (!path)
 	{
@@ -100,7 +103,7 @@
 		if (gameState.ai.accessibility.regionType[path[i]] == "land")
 			if (this.accessibleSeas.indexOf(path[i+1]) === -1)
 			{
-				debug ("cannot reach because of " + path[i+1]);
+				m.debug ("cannot reach because of " + path[i+1]);
 				return false;	// we wn't be able to board on that sea
 			}
 	}
@@ -108,7 +111,7 @@
 };
 
 
-NavalManager.prototype.checkEvents = function (gameState, queues, events) {
+m.NavalManager.prototype.checkEvents = function (gameState, queues, events) {
 	for (i in events)
 	{
 		if (events[i].type == "Destroy")
@@ -137,19 +140,19 @@
 	}
 };
 
-NavalManager.prototype.addPlan = function(plan) {
+m.NavalManager.prototype.addPlan = function(plan) {
 	this.transportPlans.push(plan);
 };
 
 // will create a plan at the end of the turn.
 // many units can call this separately and end up in the same plan
 // which can be useful.
-NavalManager.prototype.askForTransport = function(entity, startPos, endPos) {
+m.NavalManager.prototype.askForTransport = function(entity, startPos, endPos) {
 	this.askedPlans.push([entity, startPos, endPos]);
 };
 
 // creates aforementionned plans
-NavalManager.prototype.createPlans = function(gameState) {
+m.NavalManager.prototype.createPlans = function(gameState) {
 	var startID = {};
 
 	for (i in this.askedPlans)
@@ -178,7 +181,7 @@
 };
 
 // TODO: work on this.
-NavalManager.prototype.maintainFleet = function(gameState, queues, events) {
+m.NavalManager.prototype.maintainFleet = function(gameState, queues, events) {
 	// check if we have enough transport ships.
 	// check per region.
 	for (var i = 0; i < this.seaShips.length; ++i)
@@ -188,13 +191,13 @@
 			&& tpNb + queues.ships.length() === 0 && gameState.getTemplate(gameState.applyCiv("units/{civ}_ship_bireme")).available(gameState))
 		{
 			// TODO: check our dock can build the wanted ship types, for Carthage.
-			queues.ships.addItem(new TrainingPlan(gameState, "units/{civ}_ship_bireme", { "sea" : i }, 1, 0, -1, 1 ));
+			queues.ships.addItem(new m.TrainingPlan(gameState, "units/{civ}_ship_bireme", { "sea" : i }, 1, 0, -1, 1 ));
 		}
 	}
 };
 
 // bumps up the number of ships we want if we need more.
-NavalManager.prototype.checkLevels = function(gameState, queues) {
+m.NavalManager.prototype.checkLevels = function(gameState, queues) {
 	if (queues.ships.length() !== 0)
 		return;
 	for (var i = 0; i < this.transportPlans.length; ++i)
@@ -214,7 +217,7 @@
 };
 
 // assigns free ships to plans that need some
-NavalManager.prototype.assignToPlans = function(gameState, queues, events) {
+m.NavalManager.prototype.assignToPlans = function(gameState, queues, events) {
 	for (var i = 0; i < this.transportPlans.length; ++i)
 	{
 		var plan = this.transportPlans[i];
@@ -228,7 +231,7 @@
 				{
 					if (!ship.getMetadata(PlayerID, "tpplan"))
 					{
-						debug ("Assigning ship " + ship.id() + " to plan" + plan.ID);
+						m.debug ("Assigning ship " + ship.id() + " to plan" + plan.ID);
 						plan.assignShip(gameState, ship);
 						return true;
 					}
@@ -239,7 +242,7 @@
 	return false;
 };
 
-NavalManager.prototype.checkActivePlan = function(ID) {
+m.NavalManager.prototype.checkActivePlan = function(ID) {
 	for (var i = 0; i < this.transportPlans.length; ++i)
 		if (this.transportPlans[i].ID === ID)
 			return true;
@@ -249,7 +252,7 @@
 
 // Some functions are run every turn
 // Others once in a while
-NavalManager.prototype.update = function(gameState, queues, events) {
+m.NavalManager.prototype.update = function(gameState, queues, events) {
 	Engine.ProfileStart("Naval Manager update");
 	
 	this.checkEvents(gameState, queues, events);
@@ -286,3 +289,6 @@
 	}
 	Engine.ProfileStop();
 };
+
+return m;
+}(AEGIS);
Index: binaries/data/mods/public/simulation/ai/qbot/attackMoveToLocation.js
===================================================================
--- binaries/data/mods/public/simulation/ai/qbot/attackMoveToLocation.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/qbot/attackMoveToLocation.js	(Arbeitskopie)
@@ -1,4 +1,6 @@
-function AttackMoveToLocation(gameState, militaryManager, minAttackSize, maxAttackSize, targetFinder){
+function AttackMoveToLocation(gameState, Config, militaryManager, minAttackSize, maxAttackSize, targetFinder){
+	
+	this.Config = Config;	
 	this.minAttackSize = minAttackSize || Config.attack.minAttackSize;
 	this.maxAttackSize = maxAttackSize || Config.attack.maxAttackSize;
 	this.idList=[];
@@ -17,7 +19,7 @@
 	var enemyCount = militaryManager.measureEnemyCount(gameState);
 	
 	// We require our army to be >= this strength
-	var targetStrength = enemyStrength * Config.attack.enemyRatio;
+	var targetStrength = enemyStrength * this.Config.attack.enemyRatio;
 	
 	var availableCount = militaryManager.countAvailableUnits();
 	var availableStrength = militaryManager.measureAvailableStrength();
Index: binaries/data/mods/public/simulation/ai/qbot/worker.js
===================================================================
--- binaries/data/mods/public/simulation/ai/qbot/worker.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/qbot/worker.js	(Arbeitskopie)
@@ -34,7 +34,7 @@
 			
 			this.startApproachingResourceTime = gameState.getTimeElapsed();
 			
-			//Engine.PostCommand({"type": "set-shading-color", "entities": [this.ent.id()], "rgb": [10,0,0]});
+			//Engine.PostCommand(PlayerID, {"type": "set-shading-color", "entities": [this.ent.id()], "rgb": [10,0,0]});
 		}else{
 			// If we haven't reached the resource in 2 minutes twice in a row and none of the resource has been 
 			// gathered then mark it as inaccessible.
@@ -61,7 +61,7 @@
 			this.ent.repair(target);
 		}
 		
-		//Engine.PostCommand({"type": "set-shading-color", "entities": [this.ent.id()], "rgb": [0,10,0]});
+		//Engine.PostCommand(PlayerID, {"type": "set-shading-color", "entities": [this.ent.id()], "rgb": [0,10,0]});
 	}
 	
 	Engine.ProfileStart("Update Gatherer Counts");
@@ -248,4 +248,4 @@
 	}else{
 		return type.generic;
 	}
-};
\ Kein Zeilenumbruch am Ende der Datei
+};
Index: binaries/data/mods/public/simulation/ai/qbot/defence.js
===================================================================
--- binaries/data/mods/public/simulation/ai/qbot/defence.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/qbot/defence.js	(Arbeitskopie)
@@ -1,4 +1,4 @@
-function Defence(){
+function Defence(Config){
 	this.ACQUIRE_DIST = Config.defence.acquireDistance;
 	this.RELEASE_DIST = Config.defence.releaseDistance;
 	
Index: binaries/data/mods/public/simulation/ai/qbot/military.js
===================================================================
--- binaries/data/mods/public/simulation/ai/qbot/military.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/qbot/military.js	(Arbeitskopie)
@@ -6,7 +6,9 @@
  *
  */
 
-var MilitaryAttackManager = function() {
+var MilitaryAttackManager = function(Config) {
+
+	this.Config = Config
 	// these use the structure soldiers[unitId] = true|false to register the units
 	this.attackManagers = [AttackMoveToLocation];
 	this.availableAttacks = [];
@@ -16,7 +18,7 @@
 	this.attackCount = 0;
 	this.lastAttackTime = 0;
 	
-	this.defenceManager = new Defence();
+	this.defenceManager = new Defence(Config);
 };
 
 MilitaryAttackManager.prototype.init = function(gameState) {
@@ -24,22 +26,22 @@
 	
 	// load units and buildings from the config files
 	
-	if (civ in Config.buildings.moderate){
-		this.bModerate = Config.buildings.moderate[civ];
+	if (civ in this.Config.buildings.moderate){
+		this.bModerate = this.Config.buildings.moderate[civ];
 	}else{
-		this.bModerate = Config.buildings.moderate['default'];
+		this.bModerate = this.Config.buildings.moderate['default'];
 	}
 	
-	if (civ in Config.buildings.advanced){
-		this.bAdvanced = Config.buildings.advanced[civ];
+	if (civ in this.Config.buildings.advanced){
+		this.bAdvanced = this.Config.buildings.advanced[civ];
 	}else{
-		this.bAdvanced = Config.buildings.advanced['default'];
+		this.bAdvanced = this.Config.buildings.advanced['default'];
 	}
 	
-	if (civ in Config.buildings.fort){
-		this.bFort = Config.buildings.fort[civ];
+	if (civ in this.Config.buildings.fort){
+		this.bFort = this.Config.buildings.fort[civ];
 	}else{
-		this.bFort = Config.buildings.fort['default'];
+		this.bFort = this.Config.buildings.fort['default'];
 	}
 
 	for (var i in this.bAdvanced){
@@ -54,7 +56,7 @@
 	};
 	// TODO: figure out how to make this generic
 	for (var i in this.attackManagers){
-		this.availableAttacks[i] = new this.attackManagers[i](gameState, this);
+		this.availableAttacks[i] = new this.attackManagers[i](gameState, this.Config, this);
 	}
 	
 	var enemies = gameState.getEnemyEntities();
@@ -435,7 +437,7 @@
 			this.currentAttacks.push(this.availableAttacks[i]);
 			//debug("Attacking!");
 		}
-		this.availableAttacks.splice(i, 1, new this.attackManagers[i](gameState, this));
+		this.availableAttacks.splice(i, 1, new this.attackManagers[i](gameState, this.Config, this));
 	}
 	Engine.ProfileStop();
 	
Index: binaries/data/mods/public/simulation/ai/qbot/entity-extend.js
===================================================================
--- binaries/data/mods/public/simulation/ai/qbot/entity-extend.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/qbot/entity-extend.js	(Arbeitskopie)
@@ -3,12 +3,12 @@
 };
 
 Entity.prototype.garrison = function(target) {
-	Engine.PostCommand({"type": "garrison", "entities": [this.id()], "target": target.id(),"queued": false});
+	Engine.PostCommand(PlayerID, {"type": "garrison", "entities": [this.id()], "target": target.id(),"queued": false});
 	return this;
 };
 
 Entity.prototype.attack = function(unitId)
 {
-	Engine.PostCommand({"type": "attack", "entities": [this.id()], "target": unitId, "queued": false});
+	Engine.PostCommand(PlayerID, {"type": "attack", "entities": [this.id()], "target": unitId, "queued": false});
 	return this;
-};
\ Kein Zeilenumbruch am Ende der Datei
+};
Index: binaries/data/mods/public/simulation/ai/qbot/config.js
===================================================================
--- binaries/data/mods/public/simulation/ai/qbot/config.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/qbot/config.js	(Arbeitskopie)
@@ -1,23 +1,25 @@
-var baseConfig = {
-	"attack" : {
+function Config() {
+	this.debug = false
+
+	this.attack = {
 		"minAttackSize" : 20, // attackMoveToLocation
 		"maxAttackSize" : 60, // attackMoveToLocation
 		"enemyRatio" : 1.5, // attackMoveToLocation
 		"groupSize" : 10 // military
-	},
+	};
 	
 	// defence
-	"defence" : {
+	this.defence = {
 		"acquireDistance" : 220,
 		"releaseDistance" : 250,
 		"groupRadius" : 20,
 		"groupBreakRadius" : 40,
 		"groupMergeRadius" : 10,
 		"defenderRatio" : 2
-	},
+	};
 	
 	// military
-	"buildings" : {
+	this.buildings = {
 		"moderate" : {
 			"default" : [ "structures/{civ}_barracks" ]
 		},
@@ -37,10 +39,10 @@
 			"default" : [ "structures/{civ}_fortress" ],
 			"celt" : [ "structures/{civ}_fortress_b", "structures/{civ}_fortress_g" ]
 		}
-	},
+	};
 
 	// qbot
-	"priorities" : {  // Note these are dynamic, you are only setting the initial values
+	this.priorities = {  // Note these are dynamic, you are only setting the initial values
 		"house" : 500,
 		"citizenSoldier" : 100,
 		"villager" : 100,
@@ -51,13 +53,6 @@
 		"militaryBuilding" : 50,
 		"defenceBuilding" : 17,
 		"civilCentre" : 1000
-	},
-	
-	"debug" : false
+	};
 };
 
-var Config = {
-		"debug": false
-};
-
-Config.__proto__ = baseConfig;
\ Kein Zeilenumbruch am Ende der Datei
Index: binaries/data/mods/public/simulation/ai/qbot/qbot.js
===================================================================
--- binaries/data/mods/public/simulation/ai/qbot/qbot.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/qbot/qbot.js	(Arbeitskopie)
@@ -1,3 +1,4 @@
+var g_debugEnabled = false;
 
 function QBotAI(settings) {
 	BaseAI.call(this, settings);
@@ -4,12 +5,15 @@
 
 	this.turn = 0;
 
+	this.Config = new Config();
+
 	this.modules = {
 			"economy": new EconomyManager(), 
-			"military": new MilitaryAttackManager(), 
+			"military": new MilitaryAttackManager(this.Config), 
 			"housing": new HousingManager()
 	};
 
+
 	// this.queues cannot be modified past initialisation or queue-manager will break
 	this.queues = {
 		house : new Queue(),
@@ -26,7 +30,7 @@
 
 	this.productionQueues = [];
 	
-	this.priorities = Config.priorities;
+	this.priorities = this.Config.priorities;
 	
 	this.queueManager = new QueueManager(this.queues, this.priorities);
 	
@@ -161,7 +165,7 @@
 };
 
 function debug(output){
-	if (Config.debug){
+	if (g_debugEnabled){
 		if (typeof output === "string"){
 			warn(output);
 		}else{
Index: binaries/data/mods/public/simulation/ai/qbot/economy.js
===================================================================
--- binaries/data/mods/public/simulation/ai/qbot/economy.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/qbot/economy.js	(Arbeitskopie)
@@ -357,17 +357,17 @@
 			// Make resources glow wildly 
 			if (resource == "food"){
 				ent.getMetadata("nearby-resources-" + resource).forEach(function(ent){
-					Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [10,0,0]});
+					Engine.PostCommand(PlayerID, {"type": "set-shading-color", "entities": [ent.id()], "rgb": [10,0,0]});
 				});
 			}
 			if (resource == "wood"){
 				ent.getMetadata("nearby-resources-" + resource).forEach(function(ent){
-					Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,10,0]});
+					Engine.PostCommand(PlayerID, {"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,10,0]});
 				});
 			}
 			if (resource == "metal"){
 				ent.getMetadata("nearby-resources-" + resource).forEach(function(ent){
-					Engine.PostCommand({"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,0,10]});
+					Engine.PostCommand(PlayerID, {"type": "set-shading-color", "entities": [ent.id()], "rgb": [0,0,10]});
 				});
 			}*/
 		});
Index: binaries/data/mods/public/simulation/ai/qbot/entitycollection-extend.js
===================================================================
--- binaries/data/mods/public/simulation/ai/qbot/entitycollection-extend.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/qbot/entitycollection-extend.js	(Arbeitskopie)
@@ -7,7 +7,7 @@
 		unitId = unit;
 	}
 	
-	Engine.PostCommand({"type": "attack", "entities": this.toIdArray(), "target": unitId, "queued": false});
+	Engine.PostCommand(PlayerID, {"type": "attack", "entities": this.toIdArray(), "target": unitId, "queued": false});
 	return this;
 };
 
@@ -37,4 +37,4 @@
 	}else{
 		return [sumPos[0]/count, sumPos[1]/count];
 	}
-};
\ Kein Zeilenumbruch am Ende der Datei
+};
Index: binaries/data/mods/public/simulation/ai/common-api-v2/entitycollection.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v2/entitycollection.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v2/entitycollection.js	(Arbeitskopie)
@@ -109,13 +109,13 @@
 EntityCollection.prototype.move = function(x, z, queued)
 {
 	queued = queued || false;
-	Engine.PostCommand({"type": "walk", "entities": this.toIdArray(), "x": x, "z": z, "queued": queued});
+	Engine.PostCommand(PlayerID, {"type": "walk", "entities": this.toIdArray(), "x": x, "z": z, "queued": queued});
 	return this;
 };
 
 EntityCollection.prototype.destroy = function()
 {
-	Engine.PostCommand({"type": "delete-entities", "entities": this.toIdArray()});
+	Engine.PostCommand(PlayerID, {"type": "delete-entities", "entities": this.toIdArray()});
 	return this;
 };
 
Index: binaries/data/mods/public/simulation/ai/common-api-v2/base.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v2/base.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v2/base.js	(Arbeitskopie)
@@ -1,3 +1,5 @@
+var PlayerID = -1;
+
 function BaseAI(settings)
 {
 	if (!settings)
@@ -112,8 +114,9 @@
 	return null;
 };
 
-BaseAI.prototype.HandleMessage = function(state)
+BaseAI.prototype.HandleMessage = function(state, playerID)
 {
+	PlayerID = playerID;
 	if (!this._entities)
 	{
 		// Do a (shallow) clone of all the initial entity properties (in order
@@ -237,7 +240,7 @@
 
 BaseAI.prototype.chat = function(message)
 {
-	Engine.PostCommand({"type": "chat", "message": message});
+	Engine.PostCommand(PlayerID, {"type": "chat", "message": message});
 };
 
 BaseAI.prototype.registerUpdatingEntityCollection = function(entCollection)
Index: binaries/data/mods/public/simulation/ai/common-api-v2/entity.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v2/entity.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v2/entity.js	(Arbeitskopie)
@@ -372,40 +372,40 @@
 
 	move: function(x, z, queued) {
 		queued = queued || false;
-		Engine.PostCommand({"type": "walk", "entities": [this.id()], "x": x, "z": z, "queued": queued});
+		Engine.PostCommand(PlayerID, {"type": "walk", "entities": [this.id()], "x": x, "z": z, "queued": queued});
 		return this;
 	},
 
 	garrison: function(target) {
-		Engine.PostCommand({"type": "garrison", "entities": [this.id()], "target": target.id(),"queued": false});
+		Engine.PostCommand(PlayerID, {"type": "garrison", "entities": [this.id()], "target": target.id(),"queued": false});
 		return this;
 	},
 
 	attack: function(unitId) {
-		Engine.PostCommand({"type": "attack", "entities": [this.id()], "target": unitId, "queued": false});
+		Engine.PostCommand(PlayerID, {"type": "attack", "entities": [this.id()], "target": unitId, "queued": false});
 		return this;
 	},
 
 	gather: function(target, queued) {
 		queued = queued || false;
-		Engine.PostCommand({"type": "gather", "entities": [this.id()], "target": target.id(), "queued": queued});
+		Engine.PostCommand(PlayerID, {"type": "gather", "entities": [this.id()], "target": target.id(), "queued": queued});
 		return this;
 	},
 
 	repair: function(target, queued) {
 		queued = queued || false;
-		Engine.PostCommand({"type": "repair", "entities": [this.id()], "target": target.id(), "autocontinue": false, "queued": queued});
+		Engine.PostCommand(PlayerID, {"type": "repair", "entities": [this.id()], "target": target.id(), "autocontinue": false, "queued": queued});
 		return this;
 	},
 	
 	returnResources: function(target, queued) {
 		queued = queued || false;
-		Engine.PostCommand({"type": "returnresource", "entities": [this.id()], "target": target.id(), "queued": queued});
+		Engine.PostCommand(PlayerID, {"type": "returnresource", "entities": [this.id()], "target": target.id(), "queued": queued});
 		return this;
 	},
 
 	destroy: function() {
-		Engine.PostCommand({"type": "delete-entities", "entities": [this.id()]});
+		Engine.PostCommand(PlayerID, {"type": "delete-entities", "entities": [this.id()]});
 		return this;
 	},
 
@@ -423,7 +423,7 @@
 			return this;
 		}
 
-		Engine.PostCommand({
+		Engine.PostCommand(PlayerID, {
 			"type": "train",
 			"entities": [this.id()],
 			"template": type,
@@ -437,7 +437,7 @@
 		// TODO: verify this unit can construct this, just for internal
 		// sanity-checking and error reporting
 
-		Engine.PostCommand({
+		Engine.PostCommand(PlayerID, {
 			"type": "construct",
 			"entities": [this.id()],
 			"template": template,
Index: binaries/data/mods/public/simulation/ai/common-api-v3/terrain-analysis-pathfinder.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v3/terrain-analysis-pathfinder.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v3/terrain-analysis-pathfinder.js	(Arbeitskopie)
@@ -1,3 +1,6 @@
+var API3 = function(m)
+{
+
 // An implementation of A* as a pathfinder.
 // It's oversamplable, and has a specific "distance from block"
 // variable to avoid narrow passages if wanted.
@@ -11,7 +14,7 @@
 
 // The initializer creates an expanded influence map for checking.
 // It's not extraordinarily slow, but it might be.
-function aStarPath(gameState, onWater, disregardEntities, targetTerritory) {
+m.aStarPath = function(gameState, onWater, disregardEntities, targetTerritory) {
 	var self = this;
 	
 	// get the terrain analyzer map as a reference.
@@ -52,10 +55,10 @@
 	}
 	this.expandInfluences(255,this.widthMap);
 }
-copyPrototype(aStarPath, Map);
+m.copyPrototype(m.aStarPath, m.Map);
 
 // marks some points of the map as impassable. This can be used to create different paths, or to avoid going through some areas.
-aStarPath.prototype.markImpassableArea = function(cx, cy, Distance) {
+m.aStarPath.prototype.markImpassableArea = function(cx, cy, Distance) {
 	[cx,cy] = this.gamePosToMapPos([cx,cy]);
 	var x0 = Math.max(0, cx - Distance);
 	var y0 = Math.max(0, cy - Distance);
@@ -78,7 +81,7 @@
 
 // sending gamestate creates a map
 // (you run the risk of "jumping" over obstacles or weird behavior.
-aStarPath.prototype.getPath = function(start, end, Sampling, preferredWidth, iterationLimit, gamestate)
+m.aStarPath.prototype.getPath = function(start, end, Sampling, preferredWidth, iterationLimit, gamestate)
 {
 	this.Sampling = Sampling >= 1 ? Sampling : 1;
 	this.minWidth = 1;
@@ -97,7 +100,7 @@
 	}
 	if (gamestate !== undefined)
 	{
-		this.TotorMap = new Map(gamestate);
+		this.TotorMap = new m.Map(gamestate);
 		this.TotorMap.addInfluence(s[0],s[1],1,200,'constant');
 		this.TotorMap.addInfluence(e[0],e[1],1,200,'constant');
 	}
@@ -135,7 +138,7 @@
 	
 	this.isOpened[this.s] = true;
 	this.openList.push(this.s);
-	this.fCostArray[this.s] = SquareVectorDistance([this.s%w, Math.floor(this.s/w)], [this.e%w, Math.floor(this.e/w)]);
+	this.fCostArray[this.s] = m.SquareVectorDistance([this.s%w, Math.floor(this.s/w)], [this.e%w, Math.floor(this.e/w)]);
 	this.gCostArray[this.s] = 0;
 	this.parentSquare[this.s] = this.s;
 	
@@ -143,7 +146,7 @@
 	
 }
 // in case it's not over yet, this can carry on the calculation of a path over multiple turn until it's over
-aStarPath.prototype.continuePath = function(gamestate)
+m.aStarPath.prototype.continuePath = function(gamestate)
 {
 	var w = this.width;
 	var h = this.height;
@@ -208,7 +211,7 @@
 				{
 					this.parentSquare[index] = this.currentSquare;
 					
-					this.fCostArray[index] = SquareVectorDistance([index%w, Math.floor(index/w)], target);// * cost[i];
+					this.fCostArray[index] = m.SquareVectorDistance([index%w, Math.floor(index/w)], target);// * cost[i];
 					this.gCostArray[index] = this.gCostArray[this.currentSquare] + cost[i] * this.Sampling;// - this.map[index];
 					
 					if (!this.onWater && this.map[index] === 200) {
@@ -231,7 +234,7 @@
 						this.openList.push(index);
 					}
 					this.isOpened[index] = true;
-					if (SquareVectorDistance( [index%w, Math.floor(index/w)] , target) <= this.Sampling*this.Sampling-1) {
+					if (m.SquareVectorDistance( [index%w, Math.floor(index/w)] , target) <= this.Sampling*this.Sampling-1) {
 						if (this.e != index)
 							this.parentSquare[this.e] = index;
 						found = true;
@@ -294,7 +297,7 @@
 			if (gamestate !== undefined)
 				this.TotorMap.addInfluence(this.currentSquare % w, Math.floor(this.currentSquare / w),1,50,'constant');
 			
-			if (SquareVectorDistance([lastPosx,lastPosy],[this.currentSquare % w, Math.floor(this.currentSquare / w)]) > 300 || changes[this.currentSquare])
+			if (m.SquareVectorDistance([lastPosx,lastPosy],[this.currentSquare % w, Math.floor(this.currentSquare / w)]) > 300 || changes[this.currentSquare])
 			{
 				lastPosx = (this.currentSquare % w);
 				lastPosy = Math.floor(this.currentSquare / w);
@@ -325,3 +328,7 @@
 	}
 	
 }
+
+return m;
+
+}(API3);
Index: binaries/data/mods/public/simulation/ai/common-api-v3/gamestate.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v3/gamestate.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v3/gamestate.js	(Arbeitskopie)
@@ -1,3 +1,7 @@
+var API3 = function(m)
+{
+
+
 /**
  * Provides an API for the rest of the AI scripts to query the world state at a
  * higher level than the raw data.
@@ -2,3 +6,3 @@
  */
-var GameState = function() {
+m.GameState = function() {
 	this.ai = null; // must be updated by the AIs.
@@ -10,7 +14,7 @@
 	this.turnCache = {};
 };
 
-GameState.prototype.init = function(SharedScript, state, player) {
+m.GameState.prototype.init = function(SharedScript, state, player) {
 	this.sharedScript = SharedScript;
 	this.EntCollecNames = SharedScript._entityCollectionsName;
 	this.EntCollec = SharedScript._entityCollections;
@@ -23,7 +27,7 @@
 	this.techModifications = SharedScript._techModifications[this.player];
 };
 
-GameState.prototype.update = function(SharedScript, state) {
+m.GameState.prototype.update = function(SharedScript, state) {
 	this.sharedScript = SharedScript;
 	this.EntCollecNames = SharedScript._entityCollectionsName;
 	this.EntCollec = SharedScript._entityCollections;
@@ -39,7 +43,7 @@
 	this.turnCache = {};
 };
 
-GameState.prototype.updatingCollection = function(id, filter, collection, allowQuick){
+m.GameState.prototype.updatingCollection = function(id, filter, collection, allowQuick){
 	// automatically add the player ID
 	id = this.player + "-" + id;
 	if (!this.EntCollecNames[id]){
@@ -56,7 +60,7 @@
 	
 	return this.EntCollecNames[id];
 };
-GameState.prototype.destroyCollection = function(id){
+m.GameState.prototype.destroyCollection = function(id){
 	// automatically add the player ID
 	id = this.player + "-" + id;
 	
@@ -65,7 +69,7 @@
 		delete this.EntCollecNames[id];
 	}
 };
-GameState.prototype.getEC = function(id){
+m.GameState.prototype.getEC = function(id){
 	// automatically add the player ID
 	id = this.player + "-" + id;
 
@@ -74,7 +78,7 @@
 	return undefined;
 };
 
-GameState.prototype.updatingGlobalCollection = function(id, filter, collection, allowQuick) {
+m.GameState.prototype.updatingGlobalCollection = function(id, filter, collection, allowQuick) {
 	if (!this.EntCollecNames[id]){
 		if (collection !== undefined)
 			this.EntCollecNames[id] = collection.filter(filter);
@@ -88,21 +92,21 @@
 	
 	return this.EntCollecNames[id];
 };
-GameState.prototype.destroyGlobalCollection = function(id)
+m.GameState.prototype.destroyGlobalCollection = function(id)
 {
 	if (this.EntCollecNames[id] !== undefined){
 		this.sharedScript.removeUpdatingEntityCollection(this.EntCollecNames[id]);
 		delete this.EntCollecNames[id];
 	}
 };
-GameState.prototype.getGEC = function(id)
+m.GameState.prototype.getGEC = function(id)
 {
 	if (this.EntCollecNames[id] !== undefined)
 		return this.EntCollecNames[id];
 	return undefined;
 };
 
-GameState.prototype.currentPhase = function()
+m.GameState.prototype.currentPhase = function()
 {
 	if (this.isResearched("phase_city"))
 		return 3;
@@ -113,30 +117,30 @@
 	return 0;
 };
 
-GameState.prototype.townPhase = function()
+m.GameState.prototype.townPhase = function()
 {
 	if (this.playerData.civ == "athen")
 		return "phase_town_athen";
 	return "phase_town_generic";
 };
 
-GameState.prototype.cityPhase = function()
+m.GameState.prototype.cityPhase = function()
 {
 	return "phase_city_generic";
 };
 
-GameState.prototype.isResearched = function(template)
+m.GameState.prototype.isResearched = function(template)
 {
 	return this.playerData.researchedTechs[template] !== undefined;
 };
 // true if started or queued
-GameState.prototype.isResearching = function(template)
+m.GameState.prototype.isResearching = function(template)
 {
 	return (this.playerData.researchStarted[template] !== undefined || this.playerData.researchQueued[template] !== undefined);
 };
 
 // this is an absolute check that doesn't check if we have a building to research from.
-GameState.prototype.canResearch = function(techTemplateName, noRequirementCheck)
+m.GameState.prototype.canResearch = function(techTemplateName, noRequirementCheck)
 {
 	var template = this.getTemplate(techTemplateName);
 	if (!template)
@@ -170,7 +174,7 @@
 
 // Private function for checking a set of requirements is met
 // basically copies TechnologyManager's
-GameState.prototype.checkTechRequirements = function (reqs)
+m.GameState.prototype.checkTechRequirements = function (reqs)
 {
 	// If there are no requirements then all requirements are met
 	if (!reqs)
@@ -229,73 +233,73 @@
 };
 
 
-GameState.prototype.getTimeElapsed = function()
+m.GameState.prototype.getTimeElapsed = function()
 {
 	return this.timeElapsed;
 };
 
-GameState.prototype.getTemplate = function(type)
+m.GameState.prototype.getTemplate = function(type)
 {
 	if (this.techTemplates[type] !== undefined)
-		return new Technology(this.techTemplates, type);
+		return new m.Technology(this.techTemplates, type);
 	
 	if (!this.templates[type])
 		return null;
 	
-	return new EntityTemplate(this.templates[type], this.techModifications);
+	return new m.EntityTemplate(this.templates[type], this.techModifications);
 };
 
-GameState.prototype.applyCiv = function(str) {
+m.GameState.prototype.applyCiv = function(str) {
 	return str.replace(/\{civ\}/g, this.playerData.civ);
 };
 
-GameState.prototype.civ = function() {
+m.GameState.prototype.civ = function() {
 	return this.playerData.civ;
 };
 
 /**
  * @returns {Resources}
  */
-GameState.prototype.getResources = function() {
-	return new Resources(this.playerData.resourceCounts);
+m.GameState.prototype.getResources = function() {
+	return new m.Resources(this.playerData.resourceCounts);
 };
 
-GameState.prototype.getMap = function() {
+m.GameState.prototype.getMap = function() {
 	return this.sharedScript.passabilityMap;
 };
 
-GameState.prototype.getPopulation = function() {
+m.GameState.prototype.getPopulation = function() {
 	return this.playerData.popCount;
 };
 
-GameState.prototype.getPopulationLimit = function() {
+m.GameState.prototype.getPopulationLimit = function() {
 	return this.playerData.popLimit;
 };
 
-GameState.prototype.getPopulationMax = function() {
+m.GameState.prototype.getPopulationMax = function() {
 	return this.playerData.popMax;
 };
 
-GameState.prototype.getPassabilityClassMask = function(name) {
+m.GameState.prototype.getPassabilityClassMask = function(name) {
 	if (!(name in this.sharedScript.passabilityClasses)){
 		error("Tried to use invalid passability class name '" + name + "'");
 	}
 	return this.sharedScript.passabilityClasses[name];
 };
 
-GameState.prototype.getPlayerID = function() {
+m.GameState.prototype.getPlayerID = function() {
 	return this.player;
 };
 
-GameState.prototype.isPlayerAlly = function(id) {
+m.GameState.prototype.isPlayerAlly = function(id) {
 	return this.playerData.isAlly[id];
 };
 
-GameState.prototype.isPlayerEnemy = function(id) {
+m.GameState.prototype.isPlayerEnemy = function(id) {
 	return this.playerData.isEnemy[id];
 };
 
-GameState.prototype.getEnemies = function(){
+m.GameState.prototype.getEnemies = function(){
 	var ret = [];
 	for (var i in this.playerData.isEnemy){
 		if (this.playerData.isEnemy[i]){
@@ -305,7 +309,7 @@
 	return ret;
 };
 
-GameState.prototype.isEntityAlly = function(ent) {
+m.GameState.prototype.isEntityAlly = function(ent) {
 	if (ent && ent.owner && (typeof ent.owner) === "function"){
 		return this.playerData.isAlly[ent.owner()];
 	} else if (ent && ent.owner){
@@ -314,7 +318,7 @@
 	return false;
 };
 
-GameState.prototype.isEntityEnemy = function(ent) {
+m.GameState.prototype.isEntityEnemy = function(ent) {
 	if (ent && ent.owner && (typeof ent.owner) === "function"){
 		return this.playerData.isEnemy[ent.owner()];
 	} else if (ent && ent.owner){
@@ -323,7 +327,7 @@
 	return false;
 };
  
-GameState.prototype.isEntityOwn = function(ent) {
+m.GameState.prototype.isEntityOwn = function(ent) {
 	if (ent && ent.owner && (typeof ent.owner) === "function"){
 		return ent.owner() == this.player;
 	} else if (ent && ent.owner){
@@ -332,11 +336,11 @@
 	return false;
 };
 
-GameState.prototype.getOwnEntities = function() {
-	return this.updatingCollection("own-entities", Filters.byOwner(this.player));
+m.GameState.prototype.getOwnEntities = function() {
+	return this.updatingCollection("own-entities", m.Filters.byOwner(this.player));
 };
 
-GameState.prototype.getEnemyEntities = function() {
+m.GameState.prototype.getEnemyEntities = function() {
 	var diplomacyChange = false;
 	var enemies = this.getEnemies();
 	if (this.enemies){
@@ -351,17 +355,17 @@
 		}
 	}
 	if (diplomacyChange || !this.enemies){
-		return this.updatingCollection("enemy-entities", Filters.byOwners(enemies));
+		return this.updatingCollection("enemy-entities", m.Filters.byOwners(enemies));
 		this.enemies = enemies;
 	}
 	return this.getEC("enemy-entities");
 };
 
-GameState.prototype.getEntities = function() {
+m.GameState.prototype.getEntities = function() {
 	return this.entities;
 };
 
-GameState.prototype.getEntityById = function(id){
+m.GameState.prototype.getEntityById = function(id){
 	if (this.entities._entities[id]) {
 		return this.entities._entities[id];
 	}else{
@@ -370,37 +374,37 @@
 	return undefined;
 };
 
-GameState.prototype.getOwnEntitiesByMetadata = function(key, value, maintain){
+m.GameState.prototype.getOwnEntitiesByMetadata = function(key, value, maintain){
 	if (maintain === true)
-		return this.updatingCollection(key + "-" + value, Filters.byMetadata(this.player, key, value),this.getOwnEntities());
-	return this.getOwnEntities().filter(Filters.byMetadata(this.player, key, value));
+		return this.updatingCollection(key + "-" + value, m.Filters.byMetadata(this.player, key, value),this.getOwnEntities());
+	return this.getOwnEntities().filter(m.Filters.byMetadata(this.player, key, value));
 };
 
-GameState.prototype.getOwnEntitiesByRole = function(role){
+m.GameState.prototype.getOwnEntitiesByRole = function(role){
 	return this.getOwnEntitiesByMetadata("role", role, true);
 };
 
-GameState.prototype.getOwnTrainingFacilities = function(){
-	return this.updatingCollection("own-training-facilities", Filters.byTrainingQueue(), this.getOwnEntities(), true);
+m.GameState.prototype.getOwnTrainingFacilities = function(){
+	return this.updatingCollection("own-training-facilities", m.Filters.byTrainingQueue(), this.getOwnEntities(), true);
 };
 
-GameState.prototype.getOwnResearchFacilities = function(){
-	return this.updatingCollection("own-research-facilities", Filters.byResearchAvailable(), this.getOwnEntities(), true);
+m.GameState.prototype.getOwnResearchFacilities = function(){
+	return this.updatingCollection("own-research-facilities", m.Filters.byResearchAvailable(), this.getOwnEntities(), true);
 };
 
-GameState.prototype.getOwnEntitiesByType = function(type, maintain){
-	var filter = Filters.byType(type);
+m.GameState.prototype.getOwnEntitiesByType = function(type, maintain){
+	var filter = m.Filters.byType(type);
 	if (maintain === true)
 		return this.updatingCollection("own-by-type-" + type, filter, this.getOwnEntities());
 	return this.getOwnEntities().filter(filter);
 
 };
 
-GameState.prototype.countEntitiesByType = function(type, maintain) {
+m.GameState.prototype.countEntitiesByType = function(type, maintain) {
 	return this.getOwnEntitiesByType(type, maintain).length;
 };
 
-GameState.prototype.countEntitiesAndQueuedByType = function(type) {
+m.GameState.prototype.countEntitiesAndQueuedByType = function(type) {
 	var count = this.countEntitiesByType(type, true);
 	
 	// Count building foundations
@@ -424,7 +428,7 @@
 	return count;
 };
 
-GameState.prototype.countFoundationsWithType = function(type) {
+m.GameState.prototype.countFoundationsWithType = function(type) {
 	var foundationType = "foundation|" + type;
 	var count = 0;
 	this.getOwnEntities().forEach(function(ent) {
@@ -435,11 +439,11 @@
 	return count;
 };
 
-GameState.prototype.countOwnEntitiesByRole = function(role) {
+m.GameState.prototype.countOwnEntitiesByRole = function(role) {
 	return this.getOwnEntitiesByRole(role).length;
 };
 
-GameState.prototype.countOwnEntitiesAndQueuedWithRole = function(role) {
+m.GameState.prototype.countOwnEntitiesAndQueuedWithRole = function(role) {
 	var count = this.countOwnEntitiesByRole(role);
 	
 	// Count entities in building production queues
@@ -452,7 +456,7 @@
 	return count;
 };
 
-GameState.prototype.countOwnQueuedEntitiesWithMetadata = function(data, value) {
+m.GameState.prototype.countOwnQueuedEntitiesWithMetadata = function(data, value) {
 	// Count entities in building production queues
 	var count = 0;
 	this.getOwnTrainingFacilities().forEach(function(ent) {
@@ -468,7 +472,7 @@
  * Find buildings that are capable of training the given unit type, and aren't
  * already too busy.
  */
-GameState.prototype.findTrainers = function(template) {
+m.GameState.prototype.findTrainers = function(template) {
 	var maxQueueLength = 3; // avoid tying up resources in giant training queues
 	
 	return this.getOwnTrainingFacilities().filter(function(ent) {
@@ -490,7 +494,7 @@
 /**
  * Find units that are capable of constructing the given building type.
  */
-GameState.prototype.findBuilders = function(template) {
+m.GameState.prototype.findBuilders = function(template) {
 	return this.getOwnEntities().filter(function(ent) {
 
 		var buildable = ent.buildableEntities();
@@ -505,7 +509,7 @@
  * Find buildings that are capable of researching the given tech, and aren't
  * already too busy.
  */
-GameState.prototype.findResearchers = function(templateName, noRequirementCheck) {
+m.GameState.prototype.findResearchers = function(templateName, noRequirementCheck) {
 	// let's check we can research the tech.
 	if (!this.canResearch(templateName, noRequirementCheck))
 		return [];
@@ -532,36 +536,36 @@
 	});
 };
 
-GameState.prototype.getOwnFoundations = function() {
-	return this.updatingCollection("ownFoundations", Filters.isFoundation(), this.getOwnEntities());
+m.GameState.prototype.getOwnFoundations = function() {
+	return this.updatingCollection("ownFoundations", m.Filters.isFoundation(), this.getOwnEntities());
 };
 
-GameState.prototype.getOwnDropsites = function(resource){
+m.GameState.prototype.getOwnDropsites = function(resource){
 	if (resource !== undefined)
-		return this.updatingCollection("dropsite-own-" + resource, Filters.isDropsite(resource), this.getOwnEntities(), true);
-	return this.updatingCollection("dropsite-own", Filters.isDropsite(), this.getOwnEntities(), true);
+		return this.updatingCollection("dropsite-own-" + resource, m.Filters.isDropsite(resource), this.getOwnEntities(), true);
+	return this.updatingCollection("dropsite-own", m.Filters.isDropsite(), this.getOwnEntities(), true);
 };
 
-GameState.prototype.getResourceSupplies = function(resource){
-	return this.updatingGlobalCollection("resource-" + resource, Filters.byResource(resource), this.getEntities(), true);
+m.GameState.prototype.getResourceSupplies = function(resource){
+	return this.updatingGlobalCollection("resource-" + resource, m.Filters.byResource(resource), this.getEntities(), true);
 };
 
-GameState.prototype.getEntityLimits = function() {
+m.GameState.prototype.getEntityLimits = function() {
 	return this.playerData.entityLimits;
 };
 
-GameState.prototype.getEntityCounts = function() {
+m.GameState.prototype.getEntityCounts = function() {
 	return this.playerData.entityCounts;
 };
 
 // Checks whether the maximum number of buildings have been cnstructed for a certain catergory
-GameState.prototype.isEntityLimitReached = function(category) {
+m.GameState.prototype.isEntityLimitReached = function(category) {
 	if(this.playerData.entityLimits[category] === undefined || this.playerData.entityCounts[category] === undefined)
 		return false;
 	return (this.playerData.entityCounts[category] >= this.playerData.entityLimits[category]);
 };
 
-GameState.prototype.findTrainableUnits = function(classes){
+m.GameState.prototype.findTrainableUnits = function(classes){
 	var allTrainable = [];
 	this.getOwnEntities().forEach(function(ent) {
 		var trainable = ent.trainableEntities();
@@ -593,7 +597,7 @@
 // Return all techs which can currently be researched
 // Does not factor cost.
 // If there are pairs, both techs are returned.
-GameState.prototype.findAvailableTech = function() {
+m.GameState.prototype.findAvailableTech = function() {
 	
 	var allResearchable = [];
 	this.getOwnEntities().forEach(function(ent) {
@@ -625,16 +629,20 @@
 };
 
 // defcon utilities
-GameState.prototype.timeSinceDefconChange = function() {
+m.GameState.prototype.timeSinceDefconChange = function() {
 	return this.getTimeElapsed()-this.ai.defconChangeTime;
 };
-GameState.prototype.setDefcon = function(level,force) {
+m.GameState.prototype.setDefcon = function(level,force) {
 	if (this.ai.defcon >= level || force) {
 		this.ai.defcon = level;
 		this.ai.defconChangeTime = this.getTimeElapsed();
 	}
 };
-GameState.prototype.defcon = function() {
+m.GameState.prototype.defcon = function() {
 	return this.ai.defcon;
 };
 
+return m;
+
+}(API3);
+
Index: binaries/data/mods/public/simulation/ai/common-api-v3/resources.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v3/resources.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v3/resources.js	(Arbeitskopie)
@@ -1,4 +1,7 @@
-function Resources(amounts, population) {
+var API3 = function(m)
+{
+
+m.Resources = function(amounts, population) {
 	if (amounts === undefined) {
 		amounts = {
 			food : 0,
@@ -19,9 +22,9 @@
 	}
 }
 
-Resources.prototype.types = [ "food", "wood", "stone", "metal" ];
+m.Resources.prototype.types = [ "food", "wood", "stone", "metal" ];
 
-Resources.prototype.reset = function() {
+m.Resources.prototype.reset = function() {
 	for ( var tKey in this.types) {
 		var t = this.types[tKey];
 		this[t] = 0;
@@ -29,7 +32,7 @@
 	this.population = 0;
 };
 
-Resources.prototype.canAfford = function(that) {
+m.Resources.prototype.canAfford = function(that) {
 	for ( var tKey in this.types) {
 		var t = this.types[tKey];
 		if (this[t] < that[t]) {
@@ -39,7 +42,7 @@
 	return true;
 };
 
-Resources.prototype.add = function(that) {
+m.Resources.prototype.add = function(that) {
 	for ( var tKey in this.types) {
 		var t = this.types[tKey];
 		this[t] += that[t];
@@ -47,7 +50,7 @@
 	this.population += that.population;
 };
 
-Resources.prototype.subtract = function(that) {
+m.Resources.prototype.subtract = function(that) {
 	for ( var tKey in this.types) {
 		var t = this.types[tKey];
 		this[t] -= that[t];
@@ -55,7 +58,7 @@
 	this.population += that.population;
 };
 
-Resources.prototype.multiply = function(n) {
+m.Resources.prototype.multiply = function(n) {
 	for ( var tKey in this.types) {
 		var t = this.types[tKey];
 		this[t] *= n;
@@ -63,7 +66,7 @@
 	this.population *= n;
 };
 
-Resources.prototype.toInt = function() {
+m.Resources.prototype.toInt = function() {
 	var sum = 0;
 	for ( var tKey in this.types) {
 		var t = this.types[tKey];
@@ -72,3 +75,7 @@
 	sum += this.population * 50; // based on typical unit costs
 	return sum;
 };
+
+return m;
+
+}(API3);
Index: binaries/data/mods/public/simulation/ai/common-api-v3/technology.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v3/technology.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v3/technology.js	(Arbeitskopie)
@@ -1,6 +1,9 @@
+var API3 = function(m)
+{
+
 // Wrapper around a technology template
 
-function Technology(allTemplates, templateName)
+m.Technology = function(allTemplates, templateName)
 {
 	this._templateName = templateName;
 	var template = allTemplates[templateName];
@@ -20,7 +23,7 @@
 	this._techTemplates = allTemplates;
 }
 // returns generic, or specific if civ provided.
-Technology.prototype.name = function(civ)
+m.Technology.prototype.name = function(civ)
 {
 	if (civ === undefined)
 	{
@@ -34,37 +37,37 @@
 	}
 };
 
-Technology.prototype.pairDef = function()
+m.Technology.prototype.pairDef = function()
 {
 	return this._definesPair;
 };
 // in case this defines a pair only, returns the two paired technologies.
-Technology.prototype.getPairedTechs = function()
+m.Technology.prototype.getPairedTechs = function()
 {
 	if (!this._definesPair)
 		return undefined;
 	
-	var techOne = new Technology(this._techTemplates, this._template.top);
-	var techTwo = new Technology(this._techTemplates, this._template.bottom);
+	var techOne = new m.Technology(this._techTemplates, this._template.top);
+	var techTwo = new m.Technology(this._techTemplates, this._template.bottom);
 	
 	return [techOne,techTwo];
 };
 
-Technology.prototype.pair = function()
+m.Technology.prototype.pair = function()
 {
 	if (!this._isPair)
 		return undefined;
 	return this._template.pair;
 };
 
-Technology.prototype.pairedWith = function()
+m.Technology.prototype.pairedWith = function()
 {
 	if (!this._isPair)
 		return undefined;
 	return this._pairedWith;
 };
 
-Technology.prototype.cost = function()
+m.Technology.prototype.cost = function()
 {
 	if (!this._template.cost)
 		return undefined;
@@ -72,49 +75,49 @@
 };
 
 // seconds
-Technology.prototype.researchTime = function()
+m.Technology.prototype.researchTime = function()
 {
 	if (!this._template.researchTime)
 		return undefined;
 	return this._template.researchTime;
 };
 
-Technology.prototype.requirements = function()
+m.Technology.prototype.requirements = function()
 {
 	if (!this._template.requirements)
 		return undefined;
 	return this._template.requirements;
 };
 
-Technology.prototype.autoResearch = function()
+m.Technology.prototype.autoResearch = function()
 {
 	if (!this._template.autoResearch)
 		return undefined;
 	return this._template.autoResearch;
 };
 
-Technology.prototype.supersedes = function()
+m.Technology.prototype.supersedes = function()
 {
 	if (!this._template.supersedes)
 		return undefined;
 	return this._template.supersedes;
 };
 
-Technology.prototype.modifications = function()
+m.Technology.prototype.modifications = function()
 {
 	if (!this._template.modifications)
 		return undefined;
 	return this._template.modifications;
 };
 
-Technology.prototype.affects = function()
+m.Technology.prototype.affects = function()
 {
 	if (!this._template.affects)
 		return undefined;
 	return this._template.affects;
 };
 
-Technology.prototype.isAffected = function(classes)
+m.Technology.prototype.isAffected = function(classes)
 {
 	if (!this._template.affects)
 		return false;
@@ -136,3 +139,7 @@
 	}
 	return false;
 };
+
+return m;
+
+}(API3);
Index: binaries/data/mods/public/simulation/ai/common-api-v3/baseAI.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v3/baseAI.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v3/baseAI.js	(Arbeitskopie)
@@ -1,19 +1,22 @@
 var PlayerID = -1;
 
-function BaseAI(settings)
+var API3 = (function() {
+
+var m = {};
+
+m.BaseAI = function(settings)
 {
 	if (!settings)
 		return;
 
 	this.player = settings.player;
-	PlayerID = this.player;
 
 	// played turn, in case you don't want the AI to play every turn.
 	this.turn = 0;
-}
+};
 
 //Return a simple object (using no classes etc) that will be serialized into saved games
-BaseAI.prototype.Serialize = function()
+m.BaseAI.prototype.Serialize = function()
 {
 	// TODO: ought to get the AI script subclass to serialize its own state
 	// TODO: actually this is part of a larger reflection on wether AIs should or not.
@@ -22,15 +25,16 @@
 
 //Called after the constructor when loading a saved game, with 'data' being
 //whatever Serialize() returned
-BaseAI.prototype.Deserialize = function(data, sharedScript)
+m.BaseAI.prototype.Deserialize = function(data, sharedScript)
 {
 	// TODO: ought to get the AI script subclass to deserialize its own state
 	// TODO: actually this is part of a larger reflection on wether AIs should or not.
 	this.isDeserialized = true;
 };
 
-BaseAI.prototype.Init = function(state, sharedAI)
+m.BaseAI.prototype.Init = function(state, playerID, sharedAI)
 {
+	PlayerID = playerID;
 	// define some references
 	this.entities = sharedAI.entities;
 	this.templates = sharedAI.templates;
@@ -43,7 +47,7 @@
 	this.techModifications = sharedAI._techModifications[this.player];
 	this.playerData = sharedAI.playersData[this.player];
 	
-	this.gameState = sharedAI.gameState[PlayerID];
+	this.gameState = sharedAI.gameState[this.player];
 	this.gameState.ai = this;
 	this.sharedScript = sharedAI;
 	
@@ -52,13 +56,14 @@
 	this.CustomInit(this.gameState, this.sharedScript);
 }
 
-BaseAI.prototype.CustomInit = function()
+m.BaseAI.prototype.CustomInit = function()
 {	// AIs override this function
 };
 
-BaseAI.prototype.HandleMessage = function(state, sharedAI)
+m.BaseAI.prototype.HandleMessage = function(state, playerID, sharedAI)
 {
 	this.events = sharedAI.events;
+	PlayerID = playerID;
 	
 	if (this.isDeserialized && this.turn !== 0)
 	{
@@ -70,20 +75,24 @@
 	this.OnUpdate(sharedAI);
 };
 
-BaseAI.prototype.OnUpdate = function()
+m.BaseAI.prototype.OnUpdate = function()
 {	// AIs override this function
 };
 
-BaseAI.prototype.chat = function(message)
+m.BaseAI.prototype.chat = function(message)
 {
-	Engine.PostCommand({"type": "chat", "message": message});
+	Engine.PostCommand(PlayerID,{"type": "chat", "message": message});
 };
-BaseAI.prototype.chatTeam = function(message)
+m.BaseAI.prototype.chatTeam = function(message)
 {
-	Engine.PostCommand({"type": "chat", "message": "/team " +message});
+	Engine.PostCommand(PlayerID,{"type": "chat", "message": "/team " +message});
 };
-BaseAI.prototype.chatEnemies = function(message)
+m.BaseAI.prototype.chatEnemies = function(message)
 {
-	Engine.PostCommand({"type": "chat", "message": "/enemy " +message});
+	Engine.PostCommand(PlayerID,{"type": "chat", "message": "/enemy " +message});
 };
 
+return m;
+
+}());
+
Index: binaries/data/mods/public/simulation/ai/common-api-v3/map-module.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v3/map-module.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v3/map-module.js	(Arbeitskopie)
@@ -1,3 +1,6 @@
+var API3 = function(m)
+{
+
 /* The map module.
  * Copied with changes from QuantumState's original for qBot, it's a component for storing 8 bit values.
  */
@@ -2,5 +5,4 @@
 
-const TERRITORY_PLAYER_MASK = 0x3F;
-
-function Map(sharedScript, originalMap, actualCopy){
+// The function needs to be named too because of the copyConstructor functionality
+m.Map = function Map(sharedScript, originalMap, actualCopy){
 	// get the map to find out the correct dimensions
@@ -25,19 +27,19 @@
 	this.cellSize = 4;
 }
 
-Map.prototype.setMaxVal = function(val){
+m.Map.prototype.setMaxVal = function(val){
 	this.maxVal = val;
 };
 
-Map.prototype.gamePosToMapPos = function(p){
+m.Map.prototype.gamePosToMapPos = function(p){
 	return [Math.floor(p[0]/this.cellSize), Math.floor(p[1]/this.cellSize)];
 };
 
-Map.prototype.point = function(p){
+m.Map.prototype.point = function(p){
 	var q = this.gamePosToMapPos(p);
 	return this.map[q[0] + this.width * q[1]];
 };
-Map.prototype.addInfluence = function(cx, cy, maxDist, strength, type) {
+m.Map.prototype.addInfluence = function(cx, cy, maxDist, strength, type) {
 	strength = strength ? +strength : +maxDist;
 	type = type ? type : 'linear';
 	
@@ -90,7 +92,7 @@
 	}
 };
 
-Map.prototype.multiplyInfluence = function(cx, cy, maxDist, strength, type) {
+m.Map.prototype.multiplyInfluence = function(cx, cy, maxDist, strength, type) {
 	strength = strength ? +strength : +maxDist;
 	type = type ? type : 'constant';
 	
@@ -145,7 +147,7 @@
 };
 
 // doesn't check for overflow.
-Map.prototype.setInfluence = function(cx, cy, maxDist, value) {
+m.Map.prototype.setInfluence = function(cx, cy, maxDist, value) {
 	value = value ? value : 0;
 	
 	var x0 = Math.max(0, cx - maxDist);
@@ -166,7 +168,7 @@
 	}
 };
 
-Map.prototype.sumInfluence = function(cx, cy, radius){
+m.Map.prototype.sumInfluence = function(cx, cy, radius){
 	var x0 = Math.max(0, cx - radius);
 	var y0 = Math.max(0, cy - radius);
 	var x1 = Math.min(this.width, cx + radius);
@@ -192,7 +194,7 @@
  * neighbours' values. (If the grid is initialised with 0s and 65535s or 255s, the
  * result of each cell is its Manhattan distance to the nearest 0.)
  */
-Map.prototype.expandInfluences = function(maximum, map) {
+m.Map.prototype.expandInfluences = function(maximum, map) {
 	var grid = this.map;
 	if (map !== undefined)
 		grid = map;
@@ -252,7 +254,7 @@
 	}
 };
 
-Map.prototype.findBestTile = function(radius, obstructionTiles){
+m.Map.prototype.findBestTile = function(radius, obstructionTiles){
 	// Find the best non-obstructed tile
 	var bestIdx = 0;
 	var bestVal = -1;
@@ -269,14 +271,14 @@
 	return [bestIdx, bestVal];
 };
 // Multiplies current map by the parameter map pixelwise
-Map.prototype.multiply = function(map, onlyBetter, divider, maxMultiplier){
+m.Map.prototype.multiply = function(map, onlyBetter, divider, maxMultiplier){
 	for (var i = 0; i < this.length; ++i){
 		if (map.map[i]/divider > 1)
 			this.map[i] = Math.min(maxMultiplier*this.map[i], this.map[i] * (map.map[i]/divider));
 	}
 };
 // add to current map by the parameter map pixelwise
-Map.prototype.add = function(map){
+m.Map.prototype.add = function(map){
 	for (var i = 0; i < this.length; ++i) {
 		if (this.map[i] + map.map[i] < 0)
 			this.map[i] = 0;
@@ -287,8 +289,12 @@
 	}
 };
 
-Map.prototype.dumpIm = function(name, threshold){
+m.Map.prototype.dumpIm = function(name, threshold){
 	name = name ? name : "default.png";
 	threshold = threshold ? threshold : this.maxVal;
 	Engine.DumpImage(name, this.map, this.width, this.height, threshold);
 };
+
+return m;
+
+}(API3);
Index: binaries/data/mods/public/simulation/ai/common-api-v3/class.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v3/class.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v3/class.js	(Arbeitskopie)
@@ -1,3 +1,5 @@
+var API3 = function(m)
+{
 /**
  * Provides a nicer syntax for defining classes,
  * with support for OO-style inheritance.
@@ -2,3 +4,3 @@
  */
-function Class(data)
+m.Class = function(data)
 {
@@ -34,3 +36,7 @@
 print((new B).foo+" "+(new B).bar+"\n");
 print((new C).foo+" "+(new C).bar+"\n");
 //*/
+
+return m;
+
+}(API3);
Index: binaries/data/mods/public/simulation/ai/common-api-v3/filters.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v3/filters.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v3/filters.js	(Arbeitskopie)
@@ -1,4 +1,7 @@
-var Filters = {
+var API3 = function(m)
+{
+
+m.Filters = {
 	byType: function(type){
 		return {"func" : function(ent){
 			return ent.templateName() === type;
@@ -169,7 +172,7 @@
 			if (ent.position() === undefined){
 				return false;
 			}else{
-				return (SquareVectorDistance(startPoint, ent.position()) < dist*dist);
+				return (m.SquareVectorDistance(startPoint, ent.position()) < dist*dist);
 			}
 		},
 		"dynamicProperties": ['position']};
@@ -181,7 +184,7 @@
 			if (!ent.position()){
 				return false;
 			}else{
-				return (SquareVectorDistance(startPoint, ent.position()) < dist*dist);
+				return (m.SquareVectorDistance(startPoint, ent.position()) < dist*dist);
 			}
 		},
 		"dynamicProperties": []};
@@ -238,3 +241,8 @@
 		"dynamicProperties": []};
 	}
 };
+
+return m;
+
+}(API3);
+
Index: binaries/data/mods/public/simulation/ai/common-api-v3/entity.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v3/entity.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v3/entity.js	(Arbeitskopie)
@@ -1,5 +1,8 @@
-var EntityTemplate = Class({
+var API3 = function(m)
+{
 
+m.EntityTemplate = m.Class({
+
 	// techModifications should be the tech modifications of only one player.
 	// gamestates handle "GetTemplate" and should push the player's
 	// while entities should push the owner's
@@ -447,8 +450,8 @@
 
 
 
-var Entity = Class({
-	_super: EntityTemplate,
+m.Entity = m.Class({
+	_super: m.EntityTemplate,
 
 	_init: function(sharedAI, entity)
 	{
@@ -576,7 +579,7 @@
 		return this._entity.resourceCarrying; 
 	},
 
-	garrisoned: function() { return new EntityCollection(this._ai, this._entity.garrisoned); },
+	garrisoned: function() { return new m.EntityCollection(this._ai, this._entity.garrisoned); },
 	
 	canGarrisonInside: function() { return this._entity.garrisoned.length < this.garrisonMax(); },
 
@@ -584,32 +587,32 @@
 
 	move: function(x, z, queued) {
 		queued = queued || false;
-		Engine.PostCommand({"type": "walk", "entities": [this.id()], "x": x, "z": z, "queued": queued });
+		Engine.PostCommand(PlayerID,{"type": "walk", "entities": [this.id()], "x": x, "z": z, "queued": queued });
 		return this;
 	},
 	
 	attackMove: function(x, z, queued) {
 		queued = queued || false;
-		Engine.PostCommand({"type": "attack-walk", "entities": [this.id()], "x": x, "z": z, "queued": queued });
+		Engine.PostCommand(PlayerID,{"type": "attack-walk", "entities": [this.id()], "x": x, "z": z, "queued": queued });
 		return this;
 	},
 
 	// violent, aggressive, defensive, passive, standground
 	setStance: function(stance,queued){
-		Engine.PostCommand({"type": "stance", "entities": [this.id()], "name" : stance, "queued": queued });
+		Engine.PostCommand(PlayerID,{"type": "stance", "entities": [this.id()], "name" : stance, "queued": queued });
 		return this;
 	},
 
 	// TODO: replace this with the proper "STOP" command
 	stopMoving: function() {
 		if (this.position() !== undefined)
-			Engine.PostCommand({"type": "walk", "entities": [this.id()], "x": this.position()[0], "z": this.position()[1], "queued": false});
+			Engine.PostCommand(PlayerID,{"type": "walk", "entities": [this.id()], "x": this.position()[0], "z": this.position()[1], "queued": false});
 	},
 
 	unload: function(id) {
 		if (!this._template.GarrisonHolder)
 			return undefined;
-		Engine.PostCommand({"type": "unload", "garrisonHolder": this.id(), "entities": [id]});
+		Engine.PostCommand(PlayerID,{"type": "unload", "garrisonHolder": this.id(), "entities": [id]});
 		return this;
 	},
 
@@ -617,17 +620,17 @@
 	unloadAll: function() {
 		if (!this._template.GarrisonHolder)
 			return undefined;
-		Engine.PostCommand({"type": "unload-all-own", "garrisonHolders": [this.id()]});
+		Engine.PostCommand(PlayerID,{"type": "unload-all-own", "garrisonHolders": [this.id()]});
 		return this;
 	},
 
 	garrison: function(target) {
-		Engine.PostCommand({"type": "garrison", "entities": [this.id()], "target": target.id(),"queued": false});
+		Engine.PostCommand(PlayerID,{"type": "garrison", "entities": [this.id()], "target": target.id(),"queued": false});
 		return this;
 	},
 
 	attack: function(unitId) {
-		Engine.PostCommand({"type": "attack", "entities": [this.id()], "target": unitId, "queued": false});
+		Engine.PostCommand(PlayerID,{"type": "attack", "entities": [this.id()], "target": unitId, "queued": false});
 		return this;
 	},
 	
@@ -635,40 +638,40 @@
 	flee: function(unitToFleeFrom) {
 		if (this.position() !== undefined && unitToFleeFrom.position() !== undefined) {
 			var FleeDirection = [this.position()[0] - unitToFleeFrom.position()[0],this.position()[1] - unitToFleeFrom.position()[1]];
-			var dist = VectorDistance(unitToFleeFrom.position(), this.position() );
+			var dist = m.VectorDistance(unitToFleeFrom.position(), this.position() );
 			FleeDirection[0] = (FleeDirection[0]/dist) * 8;
 			FleeDirection[1] = (FleeDirection[1]/dist) * 8;
 			
-			Engine.PostCommand({"type": "walk", "entities": [this.id()], "x": this.position()[0] + FleeDirection[0]*5, "z": this.position()[1] + FleeDirection[1]*5, "queued": false});
+			Engine.PostCommand(PlayerID,{"type": "walk", "entities": [this.id()], "x": this.position()[0] + FleeDirection[0]*5, "z": this.position()[1] + FleeDirection[1]*5, "queued": false});
 		}
 		return this;
 	},
 
 	gather: function(target, queued) {
 		queued = queued || false;
-		Engine.PostCommand({"type": "gather", "entities": [this.id()], "target": target.id(), "queued": queued});
+		Engine.PostCommand(PlayerID,{"type": "gather", "entities": [this.id()], "target": target.id(), "queued": queued});
 		return this;
 	},
 
 	repair: function(target, queued) {
 		queued = queued || false;
-		Engine.PostCommand({"type": "repair", "entities": [this.id()], "target": target.id(), "autocontinue": false, "queued": queued});
+		Engine.PostCommand(PlayerID,{"type": "repair", "entities": [this.id()], "target": target.id(), "autocontinue": false, "queued": queued});
 		return this;
 	},
 	
 	returnResources: function(target, queued) {
 		queued = queued || false;
-		Engine.PostCommand({"type": "returnresource", "entities": [this.id()], "target": target.id(), "queued": queued});
+		Engine.PostCommand(PlayerID,{"type": "returnresource", "entities": [this.id()], "target": target.id(), "queued": queued});
 		return this;
 	},
 
 	destroy: function() {
-		Engine.PostCommand({"type": "delete-entities", "entities": [this.id()] });
+		Engine.PostCommand(PlayerID,{"type": "delete-entities", "entities": [this.id()] });
 		return this;
 	},
 	
 	barter: function(buyType, sellType, amount) {
-		Engine.PostCommand({"type": "barter", "sell" : sellType, "buy" : buyType, "amount" : amount });
+		Engine.PostCommand(PlayerID,{"type": "barter", "sell" : sellType, "buy" : buyType, "amount" : amount });
 		return this;
 	},
 	
@@ -686,7 +689,7 @@
 			return this;
 		}
 
-		Engine.PostCommand({
+		Engine.PostCommand(PlayerID,{
 			"type": "train",
 			"entities": [this.id()],
 			"template": type,
@@ -699,8 +702,7 @@
 	construct: function(template, x, z, angle, metadata) {
 		// TODO: verify this unit can construct this, just for internal
 		// sanity-checking and error reporting
-
-		Engine.PostCommand({
+		Engine.PostCommand(PlayerID,{
 			"type": "construct",
 			"entities": [this.id()],
 			"template": template,
@@ -716,12 +718,12 @@
 	},
 				   
 	 research: function(template) {
-		Engine.PostCommand({ "type": "research", "entity": this.id(), "template": template });
+		Engine.PostCommand(PlayerID,{ "type": "research", "entity": this.id(), "template": template });
 		return this;
 	},
 
 	stopProduction: function(id) {
-		Engine.PostCommand({ "type": "stop-production", "entity": this.id(), "id": id });
+		Engine.PostCommand(PlayerID,{ "type": "stop-production", "entity": this.id(), "id": id });
 		return this;
 	},
 	
@@ -732,9 +734,12 @@
 		for (var i in queue)
 		{
 			if (queue[i].progress < percentToStopAt)
-				Engine.PostCommand({ "type": "stop-production", "entity": this.id(), "id": queue[i].id });
+				Engine.PostCommand(PlayerID,{ "type": "stop-production", "entity": this.id(), "id": queue[i].id });
 		}
 		return this;
 	}
 });
 
+return m;
+
+}(API3);
Index: binaries/data/mods/public/simulation/ai/common-api-v3/terrain-analysis.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v3/terrain-analysis.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v3/terrain-analysis.js	(Arbeitskopie)
@@ -1,3 +1,6 @@
+var API3 = function(m)
+{
+
 /*
  * TerrainAnalysis, inheriting from the Map Component.
  * 
@@ -12,13 +15,13 @@
  * But truly separating optimizes.
  */
 
-function TerrainAnalysis() {
+m.TerrainAnalysis = function() {
 	this.cellSize = 4;
 }
 
-copyPrototype(TerrainAnalysis, Map);
+m.copyPrototype(m.TerrainAnalysis, m.Map);
 
-TerrainAnalysis.prototype.init = function(sharedScript,rawState) {
+m.TerrainAnalysis.prototype.init = function(sharedScript,rawState) {
 	var self = this;
 
 	var passabilityMap = rawState.passabilityMap;
@@ -108,7 +111,7 @@
 };
 
 // Returns the (approximately) closest point which is passable by searching in a spiral pattern 
-TerrainAnalysis.prototype.findClosestPassablePoint = function(startPoint, onLand, limitDistance, quickscope){
+m.TerrainAnalysis.prototype.findClosestPassablePoint = function(startPoint, onLand, limitDistance, quickscope){
 	var w = this.width;
 	var p = startPoint;
 	var direction = 1;
@@ -150,7 +153,7 @@
 
 // Returns an estimate of a tile accessibility. It checks neighboring cells over two levels.
 // returns a count. It's not integer. About 2 should be fairly accessible already.
-TerrainAnalysis.prototype.countConnected = function(startIndex, byLand){
+m.TerrainAnalysis.prototype.countConnected = function(startIndex, byLand){
 	var count = 0.0;
 	
 	var w = this.width;
@@ -181,7 +184,7 @@
 };
 
 // TODO: for now this resets to 255.
-TerrainAnalysis.prototype.updateMapWithEvents = function(sharedAI) {
+m.TerrainAnalysis.prototype.updateMapWithEvents = function(sharedAI) {
 	var self = this;
 	
 	var events = sharedAI.events;
@@ -243,13 +246,13 @@
  * so this can use the land regions already.
 
  */
-function Accessibility() {
+m.Accessibility = function() {
 	
 }
 
-copyPrototype(Accessibility, TerrainAnalysis);
+m.copyPrototype(m.Accessibility, m.TerrainAnalysis);
 
-Accessibility.prototype.init = function(rawState, terrainAnalyser){
+m.Accessibility.prototype.init = function(rawState, terrainAnalyser){
 	var self = this;
 	
 	this.Map(rawState, terrainAnalyser.map);
@@ -322,7 +325,7 @@
 	//Engine.DumpImage("NavalPassMap.png", this.navalPassMap, this.width, this.height, 255);
 }
 
-Accessibility.prototype.getAccessValue = function(position, onWater) {
+m.Accessibility.prototype.getAccessValue = function(position, onWater) {
 	var gamePos = this.gamePosToMapPos(position);
 	if (onWater === true)
 		return this.navalPassMap[gamePos[0] + this.width*gamePos[1]];
@@ -343,7 +346,7 @@
 
 // Returns true if a point is deemed currently accessible (is not blocked by surrounding trees...)
 // NB: accessible means that you can reach it from one side, not necessariliy that you can go ON it.
-Accessibility.prototype.isAccessible = function(gameState, position, onLand){
+m.Accessibility.prototype.isAccessible = function(gameState, position, onLand){
 	var gamePos = this.gamePosToMapPos(position);
 	
 	// quick check
@@ -356,7 +359,7 @@
 // Return true if you can go from a point to a point without switching means of transport
 // Hardcore means is also checks for isAccessible at the end (it checks for either water or land though, beware).
 // This is a blind check and not a pathfinder: for all it knows there is a huge block of trees in the middle.
-Accessibility.prototype.pathAvailable = function(gameState, start, end, onWater, hardcore){
+m.Accessibility.prototype.pathAvailable = function(gameState, start, end, onWater, hardcore){
 	var pstart = this.gamePosToMapPos(start);
 	var istart = pstart[0] + pstart[1]*this.width;
 	var pend = this.gamePosToMapPos(end);
@@ -382,7 +385,7 @@
 	return false;
 };
 
-Accessibility.prototype.getTrajectTo = function(start, end, noBound) {
+m.Accessibility.prototype.getTrajectTo = function(start, end, noBound) {
 	var pstart = this.gamePosToMapPos(start);
 	var istart = pstart[0] + pstart[1]*this.width;
 	var pend = this.gamePosToMapPos(end);
@@ -413,7 +416,7 @@
 // assumes a land unit unless start point is over deep water.
 // if the path is more complicated than "land->sea->land" (or "sea->land->sea"), it will run A* to try and figure it out
 // Thus it can handle arbitrarily complicated paths (theoretically).
-Accessibility.prototype.getTrajectToIndex = function(istart, iend, noBound){
+m.Accessibility.prototype.getTrajectToIndex = function(istart, iend, noBound){
 	var startRegion = istart;
 	var currentRegion = istart;
 	
@@ -530,7 +533,7 @@
 	return path;
 };
 
-Accessibility.prototype.getRegionSize = function(position, onWater){
+m.Accessibility.prototype.getRegionSize = function(position, onWater){
 	var pos = this.gamePosToMapPos(position);
 	var index = pos[0] + pos[1]*this.width;
 	var ID = (onWater === true) ? this.navalPassMap[index] : this.landPassMap[index];
@@ -539,7 +542,7 @@
 	return this.regionSize[ID];
 };
 
-Accessibility.prototype.getRegionSizei = function(index, onWater) {
+m.Accessibility.prototype.getRegionSizei = function(index, onWater) {
 	if (this.regionSize[this.landPassMap[index]] === undefined && (!onWater || this.regionSize[this.navalPassMap[index]] === undefined))
 		return 0;
 	if (onWater && this.regionSize[this.navalPassMap[index]] > this.regionSize[this.landPassMap[index]])
@@ -549,7 +552,7 @@
 
 // Implementation of a fast flood fill. Reasonably good performances for JS.
 // TODO: take big zones of impassable trees into account?
-Accessibility.prototype.floodFill = function(startIndex, value, onWater)
+m.Accessibility.prototype.floodFill = function(startIndex, value, onWater)
 {
 	this.s = startIndex;
 	if ((!onWater && this.landPassMap[this.s] !== 0) || (onWater && this.navalPassMap[this.s] !== 0) ) {
@@ -668,16 +671,16 @@
 }
 
 // creates a map of resource density
-SharedScript.prototype.createResourceMaps = function(sharedScript) {
+m.SharedScript.prototype.createResourceMaps = function(sharedScript) {
 	
 	for (var resource in this.decreaseFactor){
 		// if there is no resourceMap create one with an influence for everything with that resource
 		if (! this.resourceMaps[resource]){
 			// We're creting them 8-bit. Things could go above 255 if there are really tons of resources
 			// But at that point the precision is not really important anyway. And it saves memory.
-			this.resourceMaps[resource] = new Map(sharedScript, new Uint8Array(sharedScript.passabilityMap.data.length));
+			this.resourceMaps[resource] = new m.Map(sharedScript, new Uint8Array(sharedScript.passabilityMap.data.length));
 			this.resourceMaps[resource].setMaxVal(255);
-			this.CCResourceMaps[resource] = new Map(sharedScript, new Uint8Array(sharedScript.passabilityMap.data.length));
+			this.CCResourceMaps[resource] = new m.Map(sharedScript, new Uint8Array(sharedScript.passabilityMap.data.length));
 			this.CCResourceMaps[resource].setMaxVal(255);
 		}
 	}
@@ -711,16 +714,16 @@
 // creates and maintains a map of unused resource density
 // this also takes dropsites into account.
 // resources that are "part" of a dropsite are not counted.
-SharedScript.prototype.updateResourceMaps = function(sharedScript, events) {
+m.SharedScript.prototype.updateResourceMaps = function(sharedScript, events) {
 	
 	for (var resource in this.decreaseFactor){
 		// if there is no resourceMap create one with an influence for everything with that resource
 		if (! this.resourceMaps[resource]){
 			// We're creting them 8-bit. Things could go above 255 if there are really tons of resources
 			// But at that point the precision is not really important anyway. And it saves memory.
-			this.resourceMaps[resource] = new Map(sharedScript, new Uint8Array(sharedScript.passabilityMap.data.length));
+			this.resourceMaps[resource] = new m.Map(sharedScript, new Uint8Array(sharedScript.passabilityMap.data.length));
 			this.resourceMaps[resource].setMaxVal(255);
-			this.CCResourceMaps[resource] = new Map(sharedScript, new Uint8Array(sharedScript.passabilityMap.data.length));
+			this.CCResourceMaps[resource] = new m.Map(sharedScript, new Uint8Array(sharedScript.passabilityMap.data.length));
 			this.CCResourceMaps[resource].setMaxVal(255);
 		}
 	}
@@ -780,3 +783,7 @@
 		}
 	}
 };
+
+return m;
+
+}(API3);
Index: binaries/data/mods/public/simulation/ai/common-api-v3/entitycollection.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v3/entitycollection.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v3/entitycollection.js	(Arbeitskopie)
@@ -1,5 +1,8 @@
-function EntityCollection(sharedAI, entities, filters)
+var API3 = function(m)
 {
+
+m.EntityCollection = function(sharedAI, entities, filters)
+{
 	this._ai = sharedAI;
 	this._entities = entities || {};
 	this._filters = filters || [];
@@ -22,22 +25,22 @@
 		}
 	});
 	this.frozen = false;
-}
+};
 
 // If an entitycollection is frozen, it will never automatically add a unit.
 // But can remove one.
 // this makes it easy to create entity collection that will auto-remove dead units
 // but never add new ones.
-EntityCollection.prototype.freeze = function()
+m.EntityCollection.prototype.freeze = function()
 {
 	this.frozen = true;
 };
-EntityCollection.prototype.defreeze = function()
+m.EntityCollection.prototype.defreeze = function()
 {
 	this.frozen = false;
 };
 
-EntityCollection.prototype.allowQuickIter = function()
+m.EntityCollection.prototype.allowQuickIter = function()
 {
 	this._quickIter = true;
 	this._entitiesArray = [];
@@ -45,7 +48,7 @@
 		this._entitiesArray.push(ent);
 };
 
-EntityCollection.prototype.toIdArray = function()
+m.EntityCollection.prototype.toIdArray = function()
 {
 	var ret = [];
 	for (var id in this._entities)
@@ -53,7 +56,7 @@
 	return ret;
 };
 
-EntityCollection.prototype.toEntityArray = function()
+m.EntityCollection.prototype.toEntityArray = function()
 {
 	if (this._quickIter === true)
 		return this._entitiesArray;
@@ -63,7 +66,7 @@
 	return ret;
 };
 
-EntityCollection.prototype.toString = function()
+m.EntityCollection.prototype.toString = function()
 {
 	return "[EntityCollection " + this.toEntityArray().join(" ") + "]";
 };
@@ -71,7 +74,7 @@
 /**
  * Returns the (at most) n entities nearest to targetPos.
  */
-EntityCollection.prototype.filterNearest = function(targetPos, n)
+m.EntityCollection.prototype.filterNearest = function(targetPos, n)
 {
 	// Compute the distance of each entity
 	var data = []; // [id, ent, distance]
@@ -82,14 +85,14 @@
 		{
 			var ent = this._entitiesArray[i];
 			if (ent.position() !== -1)
-				data.push([ent.id(), ent, SquareVectorDistance(targetPos, ent.position())]);
+				data.push([ent.id(), ent, m.SquareVectorDistance(targetPos, ent.position())]);
 		}
 	} else {
 		for (var id in this._entities)
 		{
 			var ent = this._entities[id];
 			if (ent.position() !== -1)
-				data.push([id, ent, SquareVectorDistance(targetPos, ent.position())]);
+				data.push([id, ent, m.SquareVectorDistance(targetPos, ent.position())]);
 		}
 	}
 
@@ -102,10 +105,10 @@
 	for (var i = 0; i < length; ++i)
 		ret[data[i][0]] = data[i][1];
 
-	return new EntityCollection(this._ai, ret);
+	return new m.EntityCollection(this._ai, ret);
 };
 
-EntityCollection.prototype.filter = function(filter, thisp)
+m.EntityCollection.prototype.filter = function(filter, thisp)
 {
 	if (typeof(filter) == "function")
 		filter = {"func": filter, "dynamicProperties": []};
@@ -129,10 +132,10 @@
 		}
 	}
 	
-	return new EntityCollection(this._ai, ret, this._filters.concat([filter]));
+	return new m.EntityCollection(this._ai, ret, this._filters.concat([filter]));
 };
 
-EntityCollection.prototype.filter_raw = function(callback, thisp)
+m.EntityCollection.prototype.filter_raw = function(callback, thisp)
 {
 	var ret = {};
 	for (var id in this._entities)
@@ -142,10 +145,10 @@
 		if (callback.call(thisp, val, id, this))
 			ret[id] = ent;
 	}
-	return new EntityCollection(this._ai, ret);
+	return new m.EntityCollection(this._ai, ret);
 };
 
-EntityCollection.prototype.forEach = function(callback)
+m.EntityCollection.prototype.forEach = function(callback)
 {
 	if (this._quickIter === true)
 	{
@@ -162,7 +165,7 @@
 	return this;
 };
 
-EntityCollection.prototype.filterNearest = function(targetPos, n)
+m.EntityCollection.prototype.filterNearest = function(targetPos, n)
 {
 	// Compute the distance of each entity
 	var data = []; // [ [id, ent, distance], ... ]
@@ -170,7 +173,7 @@
 	{
 		var ent = this._entities[id];
 		if (ent.position())
-			data.push([id, ent, SquareVectorDistance(targetPos, ent.position())]);
+			data.push([id, ent, m.SquareVectorDistance(targetPos, ent.position())]);
 	}
 	
 	// Sort by increasing distance
@@ -182,22 +185,22 @@
 	for each (var val in data.slice(0, n))
 		ret[val[0]] = val[1];
 	
-	return new EntityCollection(this._ai, ret);
+	return new m.EntityCollection(this._ai, ret);
 };
 
-EntityCollection.prototype.move = function(x, z, queued)
+m.EntityCollection.prototype.move = function(x, z, queued)
 {
 	queued = queued || false;
-	Engine.PostCommand({"type": "walk", "entities": this.toIdArray(), "x": x, "z": z, "queued": queued});
+	Engine.PostCommand(PlayerID,{"type": "walk", "entities": this.toIdArray(), "x": x, "z": z, "queued": queued});
 	return this;
 };
-EntityCollection.prototype.attackMove = function(x, z, queued)
+m.EntityCollection.prototype.attackMove = function(x, z, queued)
 {
 	queued = queued || false;
 	Engine.PostCommand({"type": "attack-walk", "entities": this.toIdArray(), "x": x, "z": z, "queued": queued});
 	return this;
 };
-EntityCollection.prototype.moveIndiv = function(x, z, queued)
+m.EntityCollection.prototype.moveIndiv = function(x, z, queued)
 {
 	queued = queued || false;
 	for (var id in this._entities)
@@ -206,16 +209,16 @@
 		// It disables JIT compiling of this loop. Don't remove it unless you are sure that the underlying issue has been resolved!
 		// TODO: Check this again after the SpiderMonkey upgrade.
 		try {} finally {}
-		Engine.PostCommand({"type": "walk", "entities": [this._entities[id].id()], "x": x, "z": z, "queued": queued});
+		Engine.PostCommand(PlayerID,{"type": "walk", "entities": [this._entities[id].id()], "x": x, "z": z, "queued": queued});
 	}
 	return this;
 };
-EntityCollection.prototype.destroy = function()
+m.EntityCollection.prototype.destroy = function()
 {
-	Engine.PostCommand({"type": "delete-entities", "entities": this.toIdArray()});
+	Engine.PostCommand(PlayerID,{"type": "delete-entities", "entities": this.toIdArray()});
 	return this;
 };
-EntityCollection.prototype.attack = function(unit)
+m.EntityCollection.prototype.attack = function(unit)
 {
 	var unitId;
 	if (typeof(unit) === "Entity")
@@ -226,18 +229,18 @@
 	{
 		unitId = unit;
 	}	
-	Engine.PostCommand({"type": "attack", "entities": this.toIdArray(), "target": unitId, "queued": false});
+	Engine.PostCommand(PlayerID,{"type": "attack", "entities": this.toIdArray(), "target": unitId, "queued": false});
 	return this;
 };
 // violent, aggressive, defensive, passive, standground
-EntityCollection.prototype.setStance = function(stance)
+m.EntityCollection.prototype.setStance = function(stance)
 {
-	Engine.PostCommand({"type": "stance", "entities": this.toIdArray(), "name" : stance, "queued": false});
+	Engine.PostCommand(PlayerID,{"type": "stance", "entities": this.toIdArray(), "name" : stance, "queued": false});
 	return this;
 };
 
 // Returns the average position of all units
-EntityCollection.prototype.getCentrePosition = function()
+m.EntityCollection.prototype.getCentrePosition = function()
 {
 	var sumPos = [0, 0];
 	var count = 0;
@@ -263,7 +266,7 @@
 // returns the average position from the sample first units.
 // This might be faster for huge collections, but there's
 // always a risk that it'll be unprecise.
-EntityCollection.prototype.getApproximatePosition = function(sample)
+m.EntityCollection.prototype.getApproximatePosition = function(sample)
 {
 	var sumPos = [0, 0];
 	var i = 0;
@@ -291,7 +294,7 @@
 
 
 // Removes an entity from the collection, returns true if the entity was a member, false otherwise
-EntityCollection.prototype.removeEnt = function(ent)
+m.EntityCollection.prototype.removeEnt = function(ent)
 {
 	if (this._entities[ent.id()])
 	{
@@ -310,7 +313,7 @@
 };
 
 // Adds an entity to the collection, returns true if the entity was not member, false otherwise
-EntityCollection.prototype.addEnt = function(ent)
+m.EntityCollection.prototype.addEnt = function(ent)
 {
 	if (this._entities[ent.id()])
 	{
@@ -333,7 +336,7 @@
 // Force can add a unit despite a freezing.
 // If an entitycollection is frozen, it will never automatically add a unit.
 // But can remove one.
-EntityCollection.prototype.updateEnt = function(ent, force)
+m.EntityCollection.prototype.updateEnt = function(ent, force)
 {	
 	var passesFilters = true;
 	for each (var filter in this._filters)
@@ -353,17 +356,17 @@
 	}
 };
 
-EntityCollection.prototype.registerUpdates = function(noPush)
+m.EntityCollection.prototype.registerUpdates = function(noPush)
 {
 	this._ai.registerUpdatingEntityCollection(this,noPush);
 };
 
-EntityCollection.prototype.unregister = function()
+m.EntityCollection.prototype.unregister = function()
 {
 	this._ai.removeUpdatingEntityCollection(this);
 };
 
-EntityCollection.prototype.dynamicProperties = function()
+m.EntityCollection.prototype.dynamicProperties = function()
 {
 	var ret = [];
 	for each (var filter in this._filters)
@@ -374,12 +377,16 @@
 	return ret;
 };
 
-EntityCollection.prototype.setUID = function(id)
+m.EntityCollection.prototype.setUID = function(id)
 {
 	this._UID = id;
 };
 
-EntityCollection.prototype.getUID = function()
+m.EntityCollection.prototype.getUID = function()
 {
 	return this._UID;
 };
+
+return m;
+
+}(API3);
Index: binaries/data/mods/public/simulation/ai/common-api-v3/utils.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v3/utils.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v3/utils.js	(Arbeitskopie)
@@ -1,11 +1,14 @@
-function VectorDistance(a, b)
+var API3 = function(m)
 {
+
+m.VectorDistance = function(a, b)
+{
 	var dx = a[0] - b[0];
 	var dz = a[1] - b[1];
 	return Math.sqrt(dx*dx + dz*dz);
 }
 
-function SquareVectorDistance(a, b)
+m.SquareVectorDistance = function(a, b)
 {
 	var dx = a[0] - b[0];
 	var dz = a[1] - b[1];
@@ -13,7 +16,7 @@
 }
 // A is the reference, B must be in "range" of A
 // this supposes the range is already squared
-function inRange(a, b, range)// checks for X distance
+m.inRange = function(a, b, range)// checks for X distance
 {
 	// will avoid unnecessary checking for position in some rare cases... I'm lazy
 	if (a === undefined || b === undefined || range === undefined)
@@ -24,26 +27,26 @@
 	return ((dx*dx + dz*dz ) < range);
 }
 // slower than SquareVectorDistance, faster than VectorDistance but not exactly accurate.
-function ManhattanDistance(a, b)
+m.ManhattanDistance = function(a, b)
 {
 	var dx = a[0] - b[0];
 	var dz = a[1] - b[1];
 	return Math.abs(dx) + Math.abs(dz);
 }
 
-function AssocArraytoArray(assocArray) {
+m.AssocArraytoArray = function(assocArray) {
 	var endArray = [];
 	for (var i in assocArray)
 		endArray.push(assocArray[i]);
 	return endArray;
 };
 
-function MemoizeInit(obj)
+m.MemoizeInit = function(obj)
 {
 	obj._memoizeCache = {};
 }
 
-function Memoize(funcname, func)
+m.Memoize = function(funcname, func)
 {
 	return function() {
 		var args = funcname + '|' + Array.prototype.join.call(arguments, '|');
@@ -56,7 +59,7 @@
 	};
 }
 
-function ShallowClone(obj)
+m.ShallowClone = function(obj)
 {
 	var ret = {};
 	for (var k in obj)
@@ -65,7 +68,7 @@
 }
 
 // Picks a random element from an array
-function PickRandom(list){
+m.PickRandom = function(list){
 	if (list.length === 0)
 	{
 		return undefined;
@@ -75,3 +78,7 @@
 		return list[Math.floor(Math.random()*list.length)];
 	}
 }
+
+return m;
+
+}(API3);
Index: binaries/data/mods/public/simulation/ai/common-api-v3/shared.js
===================================================================
--- binaries/data/mods/public/simulation/ai/common-api-v3/shared.js	(Revision 14386)
+++ binaries/data/mods/public/simulation/ai/common-api-v3/shared.js	(Arbeitskopie)
@@ -1,5 +1,8 @@
+var API3 = function(m)
+{
+
 // Shared script handling templates and basic terrain analysis
-function SharedScript(settings)
+m.SharedScript = function(settings)
 {
 	if (!settings)
 		return;
@@ -37,14 +40,14 @@
 //Return a simple object (using no classes etc) that will be serialized
 //into saved games
 //TODO: that
-SharedScript.prototype.Serialize = function()
+m.SharedScript.prototype.Serialize = function()
 {
 	return { "players" : this._players, "templates" : this._templates, "techTp" : this._techTemplates };
 };
 
 // Called after the constructor when loading a saved game, with 'data' being
 // whatever Serialize() returned
-SharedScript.prototype.Deserialize = function(data)
+m.SharedScript.prototype.Deserialize = function(data)
 {
 	this._players = data.players;
 	this._templates = data.templates;
@@ -56,7 +59,7 @@
 // (This is a bit yucky and fragile since it's the inverse of
 // CCmpTemplateManager::CopyFoundationSubset and only includes components
 // that our EntityTemplate class currently uses.)
-var g_FoundationForbiddenComponents = {
+m.g_FoundationForbiddenComponents = {
 	"ProductionQueue": 1,
 	"ResourceSupply": 1,
 	"ResourceDropsite": 1,
@@ -65,7 +68,7 @@
 
 // Components that will be disabled in resource entity templates.
 // Roughly the inverse of CCmpTemplateManager::CopyResourceSubset.
-var g_ResourceForbiddenComponents = {
+m.g_ResourceForbiddenComponents = {
 	"Cost": 1,
 	"Decay": 1,
 	"Health": 1,
@@ -74,7 +77,7 @@
 	"Vision": 1
 };
 
-SharedScript.prototype.GetTemplate = function(name)
+m.SharedScript.prototype.GetTemplate = function(name)
 {	
 	if (this._templates[name])
 		return this._templates[name];
@@ -89,7 +92,7 @@
 		
 		var foundation = {};
 		for (var key in base)
-			if (!g_FoundationForbiddenComponents[key])
+			if (!m.g_FoundationForbiddenComponents[key])
 				foundation[key] = base[key];
 		
 		this._derivedTemplates[name] = foundation;
@@ -101,7 +104,7 @@
 		
 		var resource = {};
 		for (var key in base)
-			if (!g_ResourceForbiddenComponents[key])
+			if (!m.g_ResourceForbiddenComponents[key])
 				resource[key] = base[key];
 		
 		this._derivedTemplates[name] = resource;
@@ -115,7 +118,7 @@
 // Initialize the shared component.
 // We need to now the initial state of the game for this, as we will use it.
 // This is called right at the end of the map generation.
-SharedScript.prototype.init = function(state) {
+m.SharedScript.prototype.init = function(state) {
 	this.passabilityClasses = state.passabilityClasses;
 	this.passabilityMap = state.passabilityMap;
 	this.players = this._players;
@@ -128,15 +131,15 @@
 	
 	this._entities = {};
 	for (var id in state.entities)
-		this._entities[id] = new Entity(this, state.entities[id]);
+		this._entities[id] = new m.Entity(this, state.entities[id]);
 
 	// entity collection updated on create/destroy event.
-	this.entities = new EntityCollection(this, this._entities);
+	this.entities = new m.EntityCollection(this, this._entities);
 	
 	// create the terrain analyzer
-	this.terrainAnalyzer = new TerrainAnalysis();
+	this.terrainAnalyzer = new m.TerrainAnalysis();
 	this.terrainAnalyzer.init(this, state);
-	this.accessibility = new Accessibility();
+	this.accessibility = new m.Accessibility();
 	this.accessibility.init(state, this.terrainAnalyzer);
 	
 	// defined in TerrainAnalysis.js
@@ -145,14 +148,14 @@
 	this.gameState = {};
 	for (var i in this._players)
 	{
-		this.gameState[this._players[i]] = new GameState();
+		this.gameState[this._players[i]] = new m.GameState();
 		this.gameState[this._players[i]].init(this,state,this._players[i]);
 	}
 };
 
 // General update of the shared script, before each AI's update
 // applies entity deltas, and each gamestate.
-SharedScript.prototype.onUpdate = function(state)
+m.SharedScript.prototype.onUpdate = function(state)
 {
 	if (this.isDeserialized && this.turn !== 0)
 	{
@@ -188,7 +191,7 @@
 	Engine.ProfileStop();
 };
 
-SharedScript.prototype.ApplyEntitiesDelta = function(state)
+m.SharedScript.prototype.ApplyEntitiesDelta = function(state)
 {
 	Engine.ProfileStart("Shared ApplyEntitiesDelta");
 
@@ -202,7 +205,7 @@
 			{
 				continue; // Sometimes there are things like foundations which get destroyed too fast
 			}
-			this._entities[evt.msg.entity] = new Entity(this, state.entities[evt.msg.entity]);
+			this._entities[evt.msg.entity] = new m.Entity(this, state.entities[evt.msg.entity]);
 			this.entities.addEnt(this._entities[evt.msg.entity]);
 
 			// Update all the entity collections since the create operation affects static properties as well as dynamic
@@ -302,7 +305,7 @@
 	Engine.ProfileStop();
 };
 
-SharedScript.prototype.registerUpdatingEntityCollection = function(entCollection, noPush)
+m.SharedScript.prototype.registerUpdatingEntityCollection = function(entCollection, noPush)
 {
 	if (!noPush) {
 		this._entityCollections.push(entCollection);
@@ -316,7 +319,7 @@
 	this._entityCollectionsUID++;
 };
 
-SharedScript.prototype.removeUpdatingEntityCollection = function(entCollection)
+m.SharedScript.prototype.removeUpdatingEntityCollection = function(entCollection)
 {
 	for (var i in this._entityCollections)
 	{
@@ -338,7 +341,7 @@
 	}
 };
 
-SharedScript.prototype.updateEntityCollections = function(property, ent)
+m.SharedScript.prototype.updateEntityCollections = function(property, ent)
 {
 	if (this._entityCollectionsByDynProp[property] !== undefined)
 	{
@@ -349,7 +352,7 @@
 	}
 }
 
-SharedScript.prototype.setMetadata = function(player, ent, key, value)
+m.SharedScript.prototype.setMetadata = function(player, ent, key, value)
 {
 	var metadata = this._entityMetadata[player][ent.id()];
 	if (!metadata)
@@ -359,7 +362,7 @@
 	this.updateEntityCollections('metadata', ent);
 	this.updateEntityCollections('metadata.' + key, ent);
 };
-SharedScript.prototype.getMetadata = function(player, ent, key)
+m.SharedScript.prototype.getMetadata = function(player, ent, key)
 {
 	var metadata = this._entityMetadata[player][ent.id()];
 	
@@ -367,7 +370,7 @@
 		return undefined;
 	return metadata[key];
 };
-SharedScript.prototype.deleteMetadata = function(player, ent, key)
+m.SharedScript.prototype.deleteMetadata = function(player, ent, key)
 {
 	var metadata = this._entityMetadata[player][ent.id()];
 	
@@ -378,7 +381,7 @@
 	return true;
 };
 
-function copyPrototype(descendant, parent) {
+m.copyPrototype = function(descendant, parent) {
     var sConstructor = parent.toString();
     var aMatch = sConstructor.match( /\s*function (.*)\(/ );
 	if ( aMatch != null ) { descendant.prototype[aMatch[1]] = parent; }
@@ -387,3 +390,7 @@
 	}
 };
 
+return m;
+
+}(API3);
+
Index: source/simulation2/components/CCmpAIManager.cpp
===================================================================
--- source/simulation2/components/CCmpAIManager.cpp	(Revision 14386)
+++ source/simulation2/components/CCmpAIManager.cpp	(Arbeitskopie)
@@ -78,22 +78,9 @@
 		NONCOPYABLE(CAIPlayer);
 	public:
 		CAIPlayer(CAIWorker& worker, const std::wstring& aiName, player_id_t player, uint8_t difficulty,
-				const shared_ptr<ScriptRuntime>& runtime, boost::rand48& rng) :
-			m_Worker(worker), m_AIName(aiName), m_Player(player), m_Difficulty(difficulty), m_ScriptInterface("Engine", "AI", runtime)
+				shared_ptr<ScriptInterface> scriptInterface) :
+			m_Worker(worker), m_AIName(aiName), m_Player(player), m_Difficulty(difficulty), m_ScriptInterface(scriptInterface)
 		{
-			m_ScriptInterface.SetCallbackData(static_cast<void*> (this));
-
-			m_ScriptInterface.ReplaceNondeterministicRNG(rng);
-			m_ScriptInterface.LoadGlobalScripts();
-
-			m_ScriptInterface.RegisterFunction<void, std::wstring, CAIPlayer::IncludeModule>("IncludeModule");
-			m_ScriptInterface.RegisterFunction<void, CAIPlayer::DumpHeap>("DumpHeap");
-			m_ScriptInterface.RegisterFunction<void, CAIPlayer::ForceGC>("ForceGC");
-			m_ScriptInterface.RegisterFunction<void, CScriptValRooted, CAIPlayer::PostCommand>("PostCommand");
-
-			m_ScriptInterface.RegisterFunction<void, std::wstring, std::vector<u32>, u32, u32, u32, CAIPlayer::DumpImage>("DumpImage");
-
-			m_ScriptInterface.RegisterFunction<void, std::wstring, CScriptVal, CAIPlayer::RegisterSerializablePrototype>("RegisterSerializablePrototype");
 		}
 
 		~CAIPlayer()
@@ -103,112 +90,10 @@
 			m_Commands.clear();
 		}
 
-		static void IncludeModule(void* cbdata, std::wstring name)
-		{
-			CAIPlayer* self = static_cast<CAIPlayer*> (cbdata);
-
-			self->LoadScripts(name);
-		}
-		static void DumpHeap(void* cbdata)
-		{
-			CAIPlayer* self = static_cast<CAIPlayer*> (cbdata);
-			
-			//std::cout << JS_GetGCParameter(self->m_ScriptInterface.GetRuntime(), JSGC_BYTES) << std::endl;
-			self->m_ScriptInterface.DumpHeap();
-		}
-		static void ForceGC(void* cbdata)
-		{
-			CAIPlayer* self = static_cast<CAIPlayer*> (cbdata);
-			
-			JS_GC(self->m_ScriptInterface.GetContext());
-		}		
-		static void PostCommand(void* cbdata, CScriptValRooted cmd)
-		{
-			CAIPlayer* self = static_cast<CAIPlayer*> (cbdata);
-
-			self->m_Commands.push_back(self->m_ScriptInterface.WriteStructuredClone(cmd.get()));
-		}
-
-		/**
-		 * Debug function for AI scripts to dump 2D array data (e.g. terrain tile weights).
-		 * TODO: check if this needs to be here too.
-		 */
-		static void DumpImage(void* UNUSED(cbdata), std::wstring name, std::vector<u32> data, u32 w, u32 h, u32 max)
-		{
-			// TODO: this is totally not threadsafe.
-
-			VfsPath filename = L"screenshots/aidump/" + name;
-
-			if (data.size() != w*h)
-			{
-				debug_warn(L"DumpImage: data size doesn't match w*h");
-				return;
-			}
-
-			if (max == 0)
-			{
-				debug_warn(L"DumpImage: max must not be 0");
-				return;
-			}
-
-			const size_t bpp = 8;
-			int flags = TEX_BOTTOM_UP|TEX_GREY;
-
-			const size_t img_size = w * h * bpp/8;
-			const size_t hdr_size = tex_hdr_size(filename);
-			shared_ptr<u8> buf;
-			AllocateAligned(buf, hdr_size+img_size, maxSectorSize);
-			Tex t;
-			if (tex_wrap(w, h, bpp, flags, buf, hdr_size, &t) < 0)
-				return;
-
-			u8* img = buf.get() + hdr_size;
-			for (size_t i = 0; i < data.size(); ++i)
-				img[i] = (u8)((data[i] * 255) / max);
-
-			tex_write(&t, filename);
-			tex_free(&t);
-		}
-
-		static void RegisterSerializablePrototype(void* cbdata, std::wstring name, CScriptVal proto)
-		{
-			CAIPlayer* self = static_cast<CAIPlayer*> (cbdata);
-			// Add our player number to avoid name conflicts with other prototypes
-			// TODO: it would be better if serializable prototypes were stored in ScriptInterfaces
-			//	and then each serializer would access those matching its own context, but that's
-			//	not possible with AIs sharing data across contexts
-			std::wstringstream protoID;
-			protoID << self->m_Player << L"." << name.c_str();
-			self->m_Worker.RegisterSerializablePrototype(protoID.str(), proto);
-		}
-
-		bool LoadScripts(const std::wstring& moduleName)
-		{
-			// Ignore modules that are already loaded
-			if (m_LoadedModules.find(moduleName) != m_LoadedModules.end())
-				return true;
-
-			// Mark this as loaded, to prevent it recursively loading itself
-			m_LoadedModules.insert(moduleName);
-
-			// Load and execute *.js
-			VfsPaths pathnames;
-			vfs::GetPathnames(g_VFS, L"simulation/ai/" + moduleName + L"/", L"*.js", pathnames);
-			for (VfsPaths::iterator it = pathnames.begin(); it != pathnames.end(); ++it)
-			{
-				if (!m_ScriptInterface.LoadGlobalScriptFile(*it))
-				{
-					LOGERROR(L"Failed to load script %ls", it->string().c_str());
-					return false;
-				}
-			}
-
-			return true;
-		}
-
 		bool Initialise(bool callConstructor)
 		{
-			if (!LoadScripts(m_AIName))
+			// LoadScripts will only load each script once even though we call it for each player
+			if (!m_Worker.LoadScripts(m_AIName))
 				return false;
 
 			OsPath path = L"simulation/ai/" + m_AIName + L"/data.json";
@@ -220,23 +105,39 @@
 			}
 
 			// Get the constructor name from the metadata
+			// If the AI doesn't use modules, we look for the constructor in the global object
+			// TODO: All AIs should use modules. Remove the condition if this requirement is met.
+			std::string moduleName;
 			std::string constructor;
-			if (!m_ScriptInterface.GetProperty(metadata.get(), "constructor", constructor))
+			CScriptVal objectWithConstructor; // object that should contain the cosntructor fucntion
+			CScriptVal ctor;
+			if (!m_ScriptInterface->GetProperty(metadata.get(), "moduleName", moduleName))
 			{
+				objectWithConstructor = m_ScriptInterface->GetGlobalObject();
+			}
+			else
+			{
+				if(!m_ScriptInterface->GetProperty(m_ScriptInterface->GetGlobalObject(), moduleName.c_str(), objectWithConstructor) || objectWithConstructor.undefined())
+				{
+					LOGERROR(L"Failed to create AI player: %ls: can't find the module that should contain the constructor: '%hs'", path.string().c_str(), moduleName.c_str());
+					return false;
+				}
+			}
+			if (!m_ScriptInterface->GetProperty(metadata.get(), "constructor", constructor))
+			{
 				LOGERROR(L"Failed to create AI player: %ls: missing 'constructor'", path.string().c_str());
 				return false;
 			}
 
 			// Get the constructor function from the loaded scripts
-			CScriptVal ctor;
-			if (!m_ScriptInterface.GetProperty(m_ScriptInterface.GetGlobalObject(), constructor.c_str(), ctor)
+			if (!m_ScriptInterface->GetProperty(objectWithConstructor.get(), constructor.c_str(), ctor)
 				|| ctor.undefined())
 			{
 				LOGERROR(L"Failed to create AI player: %ls: can't find constructor '%hs'", path.string().c_str(), constructor.c_str());
 				return false;
 			}
 
-			m_ScriptInterface.GetProperty(metadata.get(), "useShared", m_UseSharedComponent);
+			m_ScriptInterface->GetProperty(metadata.get(), "useShared", m_UseSharedComponent);
 			
 			CScriptVal obj;
 
@@ -244,20 +145,20 @@
 			{
 				// Set up the data to pass as the constructor argument
 				CScriptVal settings;
-				m_ScriptInterface.Eval(L"({})", settings);
-				m_ScriptInterface.SetProperty(settings.get(), "player", m_Player, false);
-				m_ScriptInterface.SetProperty(settings.get(), "difficulty", m_Difficulty, false);
+				m_ScriptInterface->Eval(L"({})", settings);
+				m_ScriptInterface->SetProperty(settings.get(), "player", m_Player, false);
+				m_ScriptInterface->SetProperty(settings.get(), "difficulty", m_Difficulty, false);
 				ENSURE(m_Worker.m_HasLoadedEntityTemplates);
-				m_ScriptInterface.SetProperty(settings.get(), "templates", m_Worker.m_EntityTemplates, false);
+				m_ScriptInterface->SetProperty(settings.get(), "templates", m_Worker.m_EntityTemplates, false);
 
-				obj = m_ScriptInterface.CallConstructor(ctor.get(), settings.get());
+				obj = m_ScriptInterface->CallConstructor(ctor.get(), settings.get());
 			}
 			else
 			{
 				// For deserialization, we want to create the object with the correct prototype
 				// but don't want to actually run the constructor again
 				// XXX: actually we don't currently use this path for deserialization - maybe delete it?
-				obj = m_ScriptInterface.NewObjectFromConstructor(ctor.get());
+				obj = m_ScriptInterface->NewObjectFromConstructor(ctor.get());
 			}
 
 			if (obj.undefined())
@@ -266,26 +167,26 @@
 				return false;
 			}
 
-			m_Obj = CScriptValRooted(m_ScriptInterface.GetContext(), obj);
+			m_Obj = CScriptValRooted(m_ScriptInterface->GetContext(), obj);
 			return true;
 		}
 
-		void Run(CScriptVal state)
+		void Run(CScriptVal state, int playerID)
 		{
 			m_Commands.clear();
-			m_ScriptInterface.CallFunctionVoid(m_Obj.get(), "HandleMessage", state);
+			m_ScriptInterface->CallFunctionVoid(m_Obj.get(), "HandleMessage", state, playerID);
 		}
 		// overloaded with a sharedAI part.
 		// javascript can handle both natively on the same function.
-		void Run(CScriptVal state, CScriptValRooted SharedAI)
+		void Run(CScriptVal state, int playerID, CScriptValRooted SharedAI)
 		{
 			m_Commands.clear();
-			m_ScriptInterface.CallFunctionVoid(m_Obj.get(), "HandleMessage", state, SharedAI);
+			m_ScriptInterface->CallFunctionVoid(m_Obj.get(), "HandleMessage", state, playerID, SharedAI);
 		}
 		void InitAI(CScriptVal state, CScriptValRooted SharedAI)
 		{
 			m_Commands.clear();
-			m_ScriptInterface.CallFunctionVoid(m_Obj.get(), "Init", state, SharedAI);
+			m_ScriptInterface->CallFunctionVoid(m_Obj.get(), "Init", state, m_Player, SharedAI);
 		}
 
 		CAIWorker& m_Worker;
@@ -294,10 +195,9 @@
 		uint8_t m_Difficulty;
 		bool m_UseSharedComponent;
 		
-		ScriptInterface m_ScriptInterface;
+		shared_ptr<ScriptInterface> m_ScriptInterface;
 		CScriptValRooted m_Obj;
 		std::vector<shared_ptr<ScriptInterface::StructuredClone> > m_Commands;
-		std::set<std::wstring> m_LoadedModules;
 	};
 
 public:
@@ -313,7 +213,7 @@
 		// removed as soon whenever the new pathfinder is committed
 		// And the AIs can stop relying on their own little hands.
 		m_ScriptRuntime(ScriptInterface::CreateRuntime(33554432)),
-		m_ScriptInterface("Engine", "AI", m_ScriptRuntime),
+		m_ScriptInterface(new ScriptInterface("Engine", "AI", m_ScriptRuntime)),
 		m_TurnNum(0),
 		m_CommandsComputed(true),
 		m_HasLoadedEntityTemplates(false),
@@ -321,16 +221,17 @@
 	{
 
 		// TODO: ought to seed the RNG (in a network-synchronised way) before we use it
-		m_ScriptInterface.ReplaceNondeterministicRNG(m_RNG);
-		m_ScriptInterface.LoadGlobalScripts();
+		m_ScriptInterface->ReplaceNondeterministicRNG(m_RNG);
+		m_ScriptInterface->LoadGlobalScripts();
 
-		m_ScriptInterface.SetCallbackData(NULL);
+		m_ScriptInterface->SetCallbackData(static_cast<void*> (this));
 
-		m_ScriptInterface.RegisterFunction<void, CScriptValRooted, CAIWorker::PostCommand>("PostCommand");
-		m_ScriptInterface.RegisterFunction<void, CAIWorker::DumpHeap>("DumpHeap");
-		m_ScriptInterface.RegisterFunction<void, CAIWorker::ForceGC>("ForceGC");
+		m_ScriptInterface->RegisterFunction<void, int, CScriptValRooted, CAIWorker::PostCommand>("PostCommand");
+		m_ScriptInterface->RegisterFunction<void, std::wstring, CAIWorker::IncludeModule>("IncludeModule");
+		m_ScriptInterface->RegisterFunction<void, CAIWorker::DumpHeap>("DumpHeap");
+		m_ScriptInterface->RegisterFunction<void, CAIWorker::ForceGC>("ForceGC");
 		
-		m_ScriptInterface.RegisterFunction<void, std::wstring, std::vector<u32>, u32, u32, u32, CAIWorker::DumpImage>("DumpImage");
+		m_ScriptInterface->RegisterFunction<void, std::wstring, std::vector<u32>, u32, u32, u32, CAIWorker::DumpImage>("DumpImage");
 	}
 
 	~CAIWorker()
@@ -343,18 +244,57 @@
 		m_PassabilityMapVal = CScriptValRooted();
 		m_TerritoryMapVal = CScriptValRooted();
 	}
+	
+	bool LoadScripts(const std::wstring& moduleName)
+	{
+		// Ignore modules that are already loaded
+		if (m_LoadedModules.find(moduleName) != m_LoadedModules.end())
+			return true;
 
-	// This is called by AIs if they use the v3 API.
-	// If the AIs originate the call, cbdata is not NULL.
-	// If the shared component does, it is, so it must not be taken into account.
-	static void PostCommand(void* cbdata, CScriptValRooted cmd)
+		// Mark this as loaded, to prevent it recursively loading itself
+		m_LoadedModules.insert(moduleName);
+
+		// Load and execute *.js
+		VfsPaths pathnames;
+		vfs::GetPathnames(g_VFS, L"simulation/ai/" + moduleName + L"/", L"*.js", pathnames);
+		for (VfsPaths::iterator it = pathnames.begin(); it != pathnames.end(); ++it)
+		{
+			if (!m_ScriptInterface->LoadGlobalScriptFile(*it))
+			{
+				LOGERROR(L"Failed to load script %ls", it->string().c_str());
+				return false;
+			}
+		}
+
+		return true;
+	}
+	
+	static void IncludeModule(void* cbdata, std::wstring name)
 	{
-		if (cbdata == NULL) {
-			debug_warn(L"Warning: the shared component has tried to push an engine command. Ignoring.");
-			return;
+		CAIWorker* self = static_cast<CAIWorker*> (cbdata);
+		self->LoadScripts(name);
+	}
+
+	static void PostCommand(void* cbdata, int playerid, CScriptValRooted cmd)
+	{
+		CAIWorker* self = static_cast<CAIWorker*> (cbdata);
+		self->PostCommand(playerid, cmd);
+	}
+	
+	void PostCommand(int playerid, CScriptValRooted cmd)
+	{
+		bool playerFound = false;
+		for (int i=0; i<m_Players.size(); i++)
+		{
+			if (m_Players[i]->m_Player == playerid)	
+			{
+				m_Players[i]->m_Commands.push_back(m_ScriptInterface->WriteStructuredClone(cmd.get()));
+				playerFound = true;
+			}
 		}
-		CAIPlayer* self = static_cast<CAIPlayer*> (cbdata);
-		self->m_Commands.push_back(self->m_ScriptInterface.WriteStructuredClone(cmd.get()));
+		
+		if (!playerFound)
+			LOGERROR(L"Invalid playerid in PostCommand!");	
 	}
 	// The next two ought to be implmeneted someday but for now as it returns "null" it can't
 	static void DumpHeap(void* cbdata)
@@ -364,7 +304,7 @@
 			return;
 		}
 		CAIWorker* self = static_cast<CAIWorker*> (cbdata);
-		self->m_ScriptInterface.DumpHeap();
+		self->m_ScriptInterface->DumpHeap();
 	}
 	static void ForceGC(void* cbdata)
 	{
@@ -374,7 +314,7 @@
 		}
 		CAIWorker* self = static_cast<CAIWorker*> (cbdata);
 		PROFILE3("AI compute GC");
-		JS_GC(self->m_ScriptInterface.GetContext());
+		JS_GC(self->m_ScriptInterface->GetContext());
 	}
 	
 	/**
@@ -424,13 +364,18 @@
 		
 		// reset the value so it can be used to determine if we actually initialized it.
 		m_HasSharedComponent = false;
-				
+		
+		if (LoadScripts(L"common-api-v3"))
+			m_HasSharedComponent = true;
+		else
+			return false;
+		/*		
 		VfsPaths sharedPathnames;
 		// Check for "shared" module.
 		vfs::GetPathnames(g_VFS, L"simulation/ai/common-api-v3/", L"*.js", sharedPathnames);
 		for (VfsPaths::iterator it = sharedPathnames.begin(); it != sharedPathnames.end(); ++it)
 		{
-			if (!m_ScriptInterface.LoadGlobalScriptFile(*it))
+			if (!m_ScriptInterface->LoadGlobalScriptFile(*it))
 			{
 				LOGERROR(L"Failed to load shared script %ls", it->string().c_str());
 				return false;
@@ -439,13 +384,21 @@
 		}
 		if (!m_HasSharedComponent)
 			return false;
-		
+		*/
 		// mainly here for the error messages
 		OsPath path = L"simulation/ai/common-api-v2/";
 		
-		// Constructor name is SharedScript
+		// Constructor name is SharedScript, it's in the module API3
+		// TODO: Hardcoding this bad, we need a smarter way. 
+		CScriptVal AIModule;
 		CScriptVal ctor;
-		if (!m_ScriptInterface.GetProperty(m_ScriptInterface.GetGlobalObject(), "SharedScript", ctor)
+		if (!m_ScriptInterface->GetProperty(m_ScriptInterface->GetGlobalObject(), "API3", AIModule) || AIModule.undefined())
+		{
+			LOGERROR(L"Failed to create shared AI component: %ls: can't find module '%hs'", path.string().c_str(), "API3");
+			return false;
+		}
+		
+		if (!m_ScriptInterface->GetProperty(AIModule.get(), "SharedScript", ctor)
 			|| ctor.undefined())
 		{
 			LOGERROR(L"Failed to create shared AI component: %ls: can't find constructor '%hs'", path.string().c_str(), "SharedScript");
@@ -454,32 +407,32 @@
 		
 		// Set up the data to pass as the constructor argument
 		CScriptVal settings;
-		m_ScriptInterface.Eval(L"({})", settings);
+		m_ScriptInterface->Eval(L"({})", settings);
 		CScriptVal playersID;
-		m_ScriptInterface.Eval(L"({})", playersID);
+		m_ScriptInterface->Eval(L"({})", playersID);
 		
 		for (size_t i = 0; i < m_Players.size(); ++i)
 		{
-			jsval val = m_ScriptInterface.ToJSVal(m_ScriptInterface.GetContext(), m_Players[i]->m_Player);
-			m_ScriptInterface.SetPropertyInt(playersID.get(), i, CScriptVal(val), true);
+			jsval val = m_ScriptInterface->ToJSVal(m_ScriptInterface->GetContext(), m_Players[i]->m_Player);
+			m_ScriptInterface->SetPropertyInt(playersID.get(), i, CScriptVal(val), true);
 		}
 		
-		m_ScriptInterface.SetProperty(settings.get(), "players", playersID);
+		m_ScriptInterface->SetProperty(settings.get(), "players", playersID);
 		ENSURE(m_HasLoadedEntityTemplates);
-		m_ScriptInterface.SetProperty(settings.get(), "templates", m_EntityTemplates, false);
+		m_ScriptInterface->SetProperty(settings.get(), "templates", m_EntityTemplates, false);
 		
 		if (hasTechs)
 		{
-			m_ScriptInterface.SetProperty(settings.get(), "techTemplates", m_TechTemplates, false);
+			m_ScriptInterface->SetProperty(settings.get(), "techTemplates", m_TechTemplates, false);
 		}
 		else
 		{
 			// won't get the tech templates directly.
 			CScriptVal fakeTech;
-			m_ScriptInterface.Eval("({})", fakeTech);
-			m_ScriptInterface.SetProperty(settings.get(), "techTemplates", fakeTech, false);
+			m_ScriptInterface->Eval("({})", fakeTech);
+			m_ScriptInterface->SetProperty(settings.get(), "techTemplates", fakeTech, false);
 		}
-		m_SharedAIObj = CScriptValRooted(m_ScriptInterface.GetContext(),m_ScriptInterface.CallConstructor(ctor.get(), settings.get()));
+		m_SharedAIObj = CScriptValRooted(m_ScriptInterface->GetContext(),m_ScriptInterface->CallConstructor(ctor.get(), settings.get()));
 	
 		
 		if (m_SharedAIObj.undefined())
@@ -493,7 +446,7 @@
 
 	bool AddPlayer(const std::wstring& aiName, player_id_t player, uint8_t difficulty, bool callConstructor)
 	{
-		shared_ptr<CAIPlayer> ai(new CAIPlayer(*this, aiName, player, difficulty, m_ScriptRuntime, m_RNG));
+		shared_ptr<CAIPlayer> ai(new CAIPlayer(*this, aiName, player, difficulty, m_ScriptInterface));
 		if (!ai->Initialise(callConstructor))
 			return false;
 		
@@ -501,7 +454,7 @@
 		if (!m_HasSharedComponent)
 			m_HasSharedComponent = ai->m_UseSharedComponent;
 
-		m_ScriptInterface.MaybeGC();
+		m_ScriptInterface->MaybeGC();
 
 		m_Players.push_back(ai);
 
@@ -513,18 +466,18 @@
 		// this will be run last by InitGame.Js, passing the full game representation.
 		// For now it will run for the shared Component.
 		// This is NOT run during deserialization.
-		CScriptVal state = m_ScriptInterface.ReadStructuredClone(gameState);
-		JSContext* cx = m_ScriptInterface.GetContext();
+		CScriptVal state = m_ScriptInterface->ReadStructuredClone(gameState);
+		JSContext* cx = m_ScriptInterface->GetContext();
 
 		m_PassabilityMapVal = CScriptValRooted(cx, ScriptInterface::ToJSVal(cx, passabilityMap));
 		m_TerritoryMapVal = CScriptValRooted(cx, ScriptInterface::ToJSVal(cx, territoryMap));
 		if (m_HasSharedComponent)
 		{
-			m_ScriptInterface.SetProperty(state.get(), "passabilityMap", m_PassabilityMapVal, true);
-			m_ScriptInterface.SetProperty(state.get(), "territoryMap", m_TerritoryMapVal, true);
+			m_ScriptInterface->SetProperty(state.get(), "passabilityMap", m_PassabilityMapVal, true);
+			m_ScriptInterface->SetProperty(state.get(), "territoryMap", m_TerritoryMapVal, true);
 
-			m_ScriptInterface.CallFunctionVoid(m_SharedAIObj.get(), "init", state);
-			m_ScriptInterface.MaybeGC();
+			m_ScriptInterface->CallFunctionVoid(m_SharedAIObj.get(), "init", state);
+			m_ScriptInterface->MaybeGC();
 			
 			for (size_t i = 0; i < m_Players.size(); ++i)
 			{
@@ -545,7 +498,7 @@
 		{
 			m_PassabilityMap = passabilityMap;
 
-			JSContext* cx = m_ScriptInterface.GetContext();
+			JSContext* cx = m_ScriptInterface->GetContext();
 			m_PassabilityMapVal = CScriptValRooted(cx, ScriptInterface::ToJSVal(cx, m_PassabilityMap));
 		}
 
@@ -553,7 +506,7 @@
 		{
 			m_TerritoryMap = territoryMap;
 
-			JSContext* cx = m_ScriptInterface.GetContext();
+			JSContext* cx = m_ScriptInterface->GetContext();
 			m_TerritoryMapVal = CScriptValRooted(cx, ScriptInterface::ToJSVal(cx, m_TerritoryMap));
 		}
 
@@ -583,25 +536,25 @@
 	}
 
 	void RegisterTechTemplates(const shared_ptr<ScriptInterface::StructuredClone>& techTemplates) {
-		JSContext* cx = m_ScriptInterface.GetContext();
-		m_TechTemplates = CScriptValRooted(cx, m_ScriptInterface.ReadStructuredClone(techTemplates));
+		JSContext* cx = m_ScriptInterface->GetContext();
+		m_TechTemplates = CScriptValRooted(cx, m_ScriptInterface->ReadStructuredClone(techTemplates));
 	}
 	
 	void LoadEntityTemplates(const std::vector<std::pair<std::string, const CParamNode*> >& templates)
 	{
 		m_HasLoadedEntityTemplates = true;
 
-		m_ScriptInterface.Eval("({})", m_EntityTemplates);
+		m_ScriptInterface->Eval("({})", m_EntityTemplates);
 
 		for (size_t i = 0; i < templates.size(); ++i)
 		{
-			jsval val = templates[i].second->ToJSVal(m_ScriptInterface.GetContext(), false);
-			m_ScriptInterface.SetProperty(m_EntityTemplates.get(), templates[i].first.c_str(), CScriptVal(val), true);
+			jsval val = templates[i].second->ToJSVal(m_ScriptInterface->GetContext(), false);
+			m_ScriptInterface->SetProperty(m_EntityTemplates.get(), templates[i].first.c_str(), CScriptVal(val), true);
 		}
 
 		// Since the template data is shared between AI players, freeze it
 		// to stop any of them changing it and confusing the other players
-		m_ScriptInterface.FreezeObject(m_EntityTemplates.get(), true);
+		m_ScriptInterface->FreezeObject(m_EntityTemplates.get(), true);
 	}
 
 	void Serialize(std::ostream& stream, bool isDebug)
@@ -610,13 +563,13 @@
 
 		if (isDebug)
 		{
-			CDebugSerializer serializer(m_ScriptInterface, stream);
+			CDebugSerializer serializer(*m_ScriptInterface, stream);
 			serializer.Indent(4);
 			SerializeState(serializer);
 		}
 		else
 		{
-			CStdSerializer serializer(m_ScriptInterface, stream);
+			CStdSerializer serializer(*m_ScriptInterface, stream);
 			// TODO: see comment in Deserialize()
 			serializer.SetSerializablePrototypes(m_SerializablePrototypes);
 			SerializeState(serializer);
@@ -637,7 +590,7 @@
 		if (m_HasSharedComponent)
 		{
 			CScriptVal sharedData;
-			if (!m_ScriptInterface.CallFunction(m_SharedAIObj.get(), "Serialize", sharedData))
+			if (!m_ScriptInterface->CallFunction(m_SharedAIObj.get(), "Serialize", sharedData))
 				LOGERROR(L"AI shared script Serialize call failed");
 			serializer.ScriptVal("sharedData", sharedData);
 		}
@@ -650,15 +603,15 @@
 			serializer.NumberU32_Unbounded("num commands", (u32)m_Players[i]->m_Commands.size());
 			for (size_t j = 0; j < m_Players[i]->m_Commands.size(); ++j)
 			{
-				CScriptVal val = m_ScriptInterface.ReadStructuredClone(m_Players[i]->m_Commands[j]);
+				CScriptVal val = m_ScriptInterface->ReadStructuredClone(m_Players[i]->m_Commands[j]);
 				serializer.ScriptVal("command", val);
 			}
 
-			bool hasCustomSerialize = m_ScriptInterface.HasProperty(m_Players[i]->m_Obj.get(), "Serialize");
+			bool hasCustomSerialize = m_ScriptInterface->HasProperty(m_Players[i]->m_Obj.get(), "Serialize");
 			if (hasCustomSerialize)
 			{
 				CScriptVal scriptData;
-				if (!m_ScriptInterface.CallFunction(m_Players[i]->m_Obj.get(), "Serialize", scriptData))
+				if (!m_ScriptInterface->CallFunction(m_Players[i]->m_Obj.get(), "Serialize", scriptData))
 					LOGERROR(L"AI script Serialize call failed");
 				serializer.ScriptVal("data", scriptData);
 			}
@@ -673,7 +626,7 @@
 	{
 		ENSURE(m_CommandsComputed); // deserializing while we're still actively computing would be bad
 
-		CStdDeserializer deserializer(m_ScriptInterface, stream);
+		CStdDeserializer deserializer(*m_ScriptInterface, stream);
 
 		m_PlayerMetadata.clear();
 		m_Players.clear();
@@ -695,7 +648,7 @@
 		{
 			CScriptVal sharedData;
 			deserializer.ScriptVal("sharedData", sharedData);
-			if (!m_ScriptInterface.CallFunctionVoid(m_SharedAIObj.get(), "Deserialize", sharedData))
+			if (!m_ScriptInterface->CallFunctionVoid(m_SharedAIObj.get(), "Deserialize", sharedData))
 				LOGERROR(L"AI shared script Deserialize call failed");
 		}
 
@@ -717,7 +670,7 @@
 			{
 				CScriptVal val;
 				deserializer.ScriptVal("command", val);
-				m_Players.back()->m_Commands.push_back(m_ScriptInterface.WriteStructuredClone(val.get()));
+				m_Players.back()->m_Commands.push_back(m_ScriptInterface->WriteStructuredClone(val.get()));
 			}
 			
 			// TODO: this is yucky but necessary while the AIs are sharing data between contexts;
@@ -726,17 +679,17 @@
 			//	prototypes could be stored in their ScriptInterface
 			deserializer.SetSerializablePrototypes(m_DeserializablePrototypes);
 
-			bool hasCustomDeserialize = m_ScriptInterface.HasProperty(m_Players.back()->m_Obj.get(), "Deserialize");
+			bool hasCustomDeserialize = m_ScriptInterface->HasProperty(m_Players.back()->m_Obj.get(), "Deserialize");
 			if (hasCustomDeserialize)
 			{
 				CScriptVal scriptData;
 				deserializer.ScriptVal("data", scriptData);
 				if (m_Players[i]->m_UseSharedComponent)
 				{
-					if (!m_ScriptInterface.CallFunctionVoid(m_Players.back()->m_Obj.get(), "Deserialize", scriptData, m_SharedAIObj))
+					if (!m_ScriptInterface->CallFunctionVoid(m_Players.back()->m_Obj.get(), "Deserialize", scriptData, m_SharedAIObj))
 						LOGERROR(L"AI script Deserialize call failed");
 				}
-				else if (!m_ScriptInterface.CallFunctionVoid(m_Players.back()->m_Obj.get(), "Deserialize", scriptData))
+				else if (!m_ScriptInterface->CallFunctionVoid(m_Players.back()->m_Obj.get(), "Deserialize", scriptData))
 				{
 					LOGERROR(L"AI script deserialize() call failed");
 				}
@@ -770,7 +723,7 @@
 		if (m_PlayerMetadata.find(path) == m_PlayerMetadata.end())
 		{
 			// Load and cache the AI player metadata
-			m_PlayerMetadata[path] = m_ScriptInterface.ReadJSONFile(path);
+			m_PlayerMetadata[path] = m_ScriptInterface->ReadJSONFile(path);
 		}
 
 		return m_PlayerMetadata[path];
@@ -786,7 +739,7 @@
 			if (m_TurnNum++ % 50 == 0)
 			{
 				PROFILE3("AI compute GC");
-				m_ScriptInterface.MaybeGC();
+				m_ScriptInterface->MaybeGC();
 			}
 			return;
 		}
@@ -795,13 +748,13 @@
 		CScriptVal state;
 		{
 			PROFILE3("AI compute read state");
-			state = m_ScriptInterface.ReadStructuredClone(m_GameState);
-			m_ScriptInterface.SetProperty(state.get(), "passabilityMap", m_PassabilityMapVal, true);
-			m_ScriptInterface.SetProperty(state.get(), "territoryMap", m_TerritoryMapVal, true);
+			state = m_ScriptInterface->ReadStructuredClone(m_GameState);
+			m_ScriptInterface->SetProperty(state.get(), "passabilityMap", m_PassabilityMapVal, true);
+			m_ScriptInterface->SetProperty(state.get(), "territoryMap", m_TerritoryMapVal, true);
 		}
 
 		// It would be nice to do
-		//   m_ScriptInterface.FreezeObject(state.get(), true);
+		//   m_ScriptInterface->FreezeObject(state.get(), true);
 		// to prevent AI scripts accidentally modifying the state and
 		// affecting other AI scripts they share it with. But the performance
 		// cost is far too high, so we won't do that.
@@ -810,7 +763,7 @@
 		if (m_HasSharedComponent)
 		{
 			PROFILE3("AI run shared component");
-			m_ScriptInterface.CallFunctionVoid(m_SharedAIObj.get(), "onUpdate", state);
+			m_ScriptInterface->CallFunctionVoid(m_SharedAIObj.get(), "onUpdate", state);
 		}
 		
 		for (size_t i = 0; i < m_Players.size(); ++i)
@@ -818,18 +771,19 @@
 			PROFILE3("AI script");
 			PROFILE2_ATTR("player: %d", m_Players[i]->m_Player);
 			PROFILE2_ATTR("script: %ls", m_Players[i]->m_AIName.c_str());
+
 			if (m_HasSharedComponent && m_Players[i]->m_UseSharedComponent)
-				m_Players[i]->Run(state,m_SharedAIObj);
+				m_Players[i]->Run(state, m_Players[i]->m_Player, m_SharedAIObj);
 			else
-				m_Players[i]->Run(state);
+				m_Players[i]->Run(state, m_Players[i]->m_Player);
 		}
 
 		// Run GC if we are about to overflow
-		if (JS_GetGCParameter(m_ScriptInterface.GetRuntime(), JSGC_BYTES) > 33000000)
+		if (JS_GetGCParameter(m_ScriptInterface->GetRuntime(), JSGC_BYTES) > 33000000)
 		{
 			PROFILE3("AI compute GC");
 
-			JS_GC(m_ScriptInterface.GetContext());
+			JS_GC(m_ScriptInterface->GetContext());
 		}
 		
 		// Run the GC every so often.
@@ -838,12 +792,12 @@
 		/*if (m_TurnNum++ % 20 == 0)
 		{
 			PROFILE3("AI compute GC");
-			m_ScriptInterface.MaybeGC();
+			m_ScriptInterface->MaybeGC();
 		}*/
 	}
 
 	shared_ptr<ScriptRuntime> m_ScriptRuntime;
-	ScriptInterface m_ScriptInterface;
+	shared_ptr<ScriptInterface> m_ScriptInterface;
 	boost::rand48 m_RNG;
 	u32 m_TurnNum;
 
@@ -858,6 +812,8 @@
 	CScriptValRooted m_SharedAIObj;
 	std::vector<SCommandSets> m_Commands;
 	
+	std::set<std::wstring> m_LoadedModules;
+	
 	shared_ptr<ScriptInterface::StructuredClone> m_GameState;
 	Grid<u16> m_PassabilityMap;
 	CScriptValRooted m_PassabilityMapVal;
