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";
@@ -221,7 +106,7 @@
 
 			// Get the constructor name from the metadata
 			std::string constructor;
-			if (!m_ScriptInterface.GetProperty(metadata.get(), "constructor", constructor))
+			if (!m_ScriptInterface->GetProperty(metadata.get(), "constructor", constructor))
 			{
 				LOGERROR(L"Failed to create AI player: %ls: missing 'constructor'", path.string().c_str());
 				return false;
@@ -229,14 +114,14 @@
 
 			// 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(m_ScriptInterface->GetGlobalObject(), 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 +129,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 +151,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 +179,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 +197,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 +205,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 +228,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 +288,7 @@
 			return;
 		}
 		CAIWorker* self = static_cast<CAIWorker*> (cbdata);
-		self->m_ScriptInterface.DumpHeap();
+		self->m_ScriptInterface->DumpHeap();
 	}
 	static void ForceGC(void* cbdata)
 	{
@@ -374,7 +298,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 +348,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 +368,13 @@
 		}
 		if (!m_HasSharedComponent)
 			return false;
-		
+		*/
 		// mainly here for the error messages
 		OsPath path = L"simulation/ai/common-api-v2/";
 		
 		// Constructor name is SharedScript
 		CScriptVal ctor;
-		if (!m_ScriptInterface.GetProperty(m_ScriptInterface.GetGlobalObject(), "SharedScript", ctor)
+		if (!m_ScriptInterface->GetProperty(m_ScriptInterface->GetGlobalObject(), "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 +383,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 +422,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 +430,7 @@
 		if (!m_HasSharedComponent)
 			m_HasSharedComponent = ai->m_UseSharedComponent;
 
-		m_ScriptInterface.MaybeGC();
+		m_ScriptInterface->MaybeGC();
 
 		m_Players.push_back(ai);
 
@@ -513,18 +442,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 +474,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 +482,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 +512,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 +539,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 +566,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 +579,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 +602,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 +624,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 +646,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 +655,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 +699,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 +715,7 @@
 			if (m_TurnNum++ % 50 == 0)
 			{
 				PROFILE3("AI compute GC");
-				m_ScriptInterface.MaybeGC();
+				m_ScriptInterface->MaybeGC();
 			}
 			return;
 		}
@@ -795,13 +724,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 +739,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 +747,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 +768,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 +788,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;
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-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-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)
@@ -2,8 +2,6 @@
  * Copied with changes from QuantumState's original for qBot, it's a component for storing 8 bit values.
  */
 
-const TERRITORY_PLAYER_MASK = 0x3F;
-
 function Map(sharedScript, originalMap, actualCopy){
 	// get the map to find out the correct dimensions
 	var gameMap = sharedScript.passabilityMap;
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)
@@ -584,32 +584,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 +617,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;
 	},
 	
@@ -639,36 +639,36 @@
 			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 +686,7 @@
 			return this;
 		}
 
-		Engine.PostCommand({
+		Engine.PostCommand(PlayerID,{
 			"type": "train",
 			"entities": [this.id()],
 			"template": type,
@@ -699,8 +699,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 +715,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,7 +731,7 @@
 		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;
 	}
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)
@@ -188,13 +188,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.attackMove = function(x, z, queued)
 {
 	queued = queued || false;
-	Engine.PostCommand({"type": "attack-walk", "entities": this.toIdArray(), "x": x, "z": z, "queued": queued});
+	Engine.PostCommand(PlayerID,{"type": "attack-walk", "entities": this.toIdArray(), "x": x, "z": z, "queued": queued});
 	return this;
 };
 EntityCollection.prototype.moveIndiv = function(x, z, queued)
@@ -206,13 +206,13 @@
 		// 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()
 {
-	Engine.PostCommand({"type": "delete-entities", "entities": this.toIdArray()});
+	Engine.PostCommand(PlayerID,{"type": "delete-entities", "entities": this.toIdArray()});
 	return this;
 };
 EntityCollection.prototype.attack = function(unit)
@@ -226,13 +226,13 @@
 	{
 		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)
 {
-	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;
 };
 
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)
@@ -6,7 +6,6 @@
 		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;
@@ -29,8 +28,9 @@
 	this.isDeserialized = true;
 };
 
-BaseAI.prototype.Init = function(state, sharedAI)
+BaseAI.prototype.Init = function(state, playerID, sharedAI)
 {
+	PlayerID = playerID;
 	// define some references
 	this.entities = sharedAI.entities;
 	this.templates = sharedAI.templates;
@@ -43,7 +43,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;
 	
@@ -56,9 +56,10 @@
 {	// AIs override this function
 };
 
-BaseAI.prototype.HandleMessage = function(state, sharedAI)
+BaseAI.prototype.HandleMessage = function(state, playerID, sharedAI)
 {
 	this.events = sharedAI.events;
+	PlayerID = playerID;
 	
 	if (this.isDeserialized && this.turn !== 0)
 	{
@@ -76,14 +77,14 @@
 
 BaseAI.prototype.chat = function(message)
 {
-	Engine.PostCommand({"type": "chat", "message": message});
+	Engine.PostCommand(PlayerID,{"type": "chat", "message": message});
 };
 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)
 {
-	Engine.PostCommand({"type": "chat", "message": "/enemy " +message});
+	Engine.PostCommand(PlayerID,{"type": "chat", "message": "/enemy " +message});
 };
 
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)
@@ -12,12 +12,14 @@
 	-picking new CC locations.
  */
 
-var HQ = function() {
-	this.targetNumBuilders = Config.Economy.targetNumBuilders; // number of workers we want building stuff
+var 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,13 +29,13 @@
 	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 Defence(this.Config);
 	
 	this.navalManager = new NavalManager();
 	
@@ -48,10 +50,10 @@
 	this.basesMap = new 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.
@@ -79,13 +81,13 @@
 				if (ent.resourceSupplyType().generic === "treasure" && SquareVectorDistance(ent.position(), CC.position()) < 5000)
 					treasureAmount[i] += ent.resourceSupplyMax();
 			});
-		this.baseManagers[1] = new BaseManager();
+		this.baseManagers[1] = new 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;
 
@@ -112,7 +114,7 @@
 	}
 	
 	var map = new Map(gameState.sharedScript, gameState.sharedScript.CCResourceMaps["wood"].map);
-	if (Config.debug)
+	if (this.Config.debug)
 		map.dumpIm("map_CC_Wood.png");
 	
 	//this.reassignIdleWorkers(gameState);
@@ -125,22 +127,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){
@@ -193,8 +195,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 = playerGlobals[PlayerID].uniqueIDBases;
+					this.baseManagers[bID] = new BaseManager(this.Config);
 					this.baseManagers[bID].init(gameState, events, true);
 					this.baseManagers[bID].setAnchor(ent);
 					this.baseManagers[bID].initTerritory(this, gameState);
@@ -411,6 +413,7 @@
 // TODO: improve choice alogrithm
 HQ.prototype.switchWorkerBase = function(gameState, worker, type) {
 	var bestBase = 0;
+
 	for (var i in this.baseManagers)
 	{
 		if (this.baseManagers[i].willGather[type] >= 1)
@@ -645,7 +648,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);
@@ -674,7 +677,7 @@
 };
 
 HQ.prototype.buildMarket = function(gameState, queues){
-	if (gameState.getPopulation() > Config.Economy.popForMarket && gameState.currentPhase() >= 2 ) {
+	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
@@ -685,7 +688,7 @@
 
 // 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) {
+	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){
@@ -752,6 +755,8 @@
 		if (numPlanned < 3 || (numPlanned < 5 && gameState.getPopulation() > 80))
 		{
 			var plan = new 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 +766,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);
@@ -781,12 +786,13 @@
 	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)
@@ -878,7 +884,7 @@
 };
 
 HQ.prototype.buildBlacksmith = function(gameState, queues){
-	if (gameState.getTimeElapsed() > Config.Military.timeForBlacksmith*1000) {
+	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"));
@@ -896,14 +902,14 @@
 	Engine.ProfileStart("Build buildings");
 	var workersNumber = gameState.getOwnEntitiesByRole("worker").filter(Filters.not(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 }));
 		}
 	}
 	
-	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 }));
 	
@@ -917,7 +923,7 @@
 			}
 		}
 	//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)
@@ -1047,7 +1053,7 @@
 
 // Some functions are run every turn
 // Others once in a while
-HQ.prototype.update = function(gameState, queues, events) {
+HQ.prototype.update = function(gameState, queues, events) {	
 	Engine.ProfileStart("Headquarters update");
 	
 	this.checkEvents(gameState,events,queues);
@@ -1057,7 +1063,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 +1071,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 +1093,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) % (playerGlobals[PlayerID].uniqueIDBases - 1)) === 0)
 			this.baseManagers[i].update(gameState, queues, events);
 	}
 
@@ -1174,11 +1180,11 @@
 	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 CityAttack(gameState, this, this.Config, this.TotalAttackNumber, -1, "rush")
 		this.TotalAttackNumber++;
 		this.upcomingAttacks["CityAttack"].push(Lalala);
 		debug ("Starting a little something");
@@ -1193,7 +1199,7 @@
 			} 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 CityAttack(gameState, this, this.Config, this.TotalAttackNumber, -1);
 					if (Lalala.failed)
 					{
 						this.attackPlansEncounteredWater = true; // hack
@@ -1202,8 +1208,8 @@
 						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 CityAttack(gameState, this, this.Config, this.TotalAttackNumber, -1, "superSized");
 					if (Lalala.failed)
 					{
 						this.attackPlansEncounteredWater = true; // hack
@@ -1243,7 +1249,7 @@
 	this.buildDropsites(gameState, queues);
 	Engine.ProfileStop();
 
-	if (Config.difficulty !== 0)
+	if (this.Config.difficulty !== 0)
 		this.tryBartering(gameState);
 		
 	this.buildFarmstead(gameState, queues);
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)
@@ -199,6 +199,7 @@
 };
 
 Worker.prototype.startGathering = function(baseManager, gameState) {
+
 	var resource = this.ent.getMetadata(PlayerID, "gather-type");
 	var ent = this.ent;
 	var self = this;
@@ -254,6 +255,7 @@
 			}
 		});
 	}
+	
 	// we've found no fitting dropsites close enough from us.
 	// So'll try with far away.
 	if (!nearestResources || nearestResources.length === 0) {
@@ -271,7 +273,7 @@
 			}
 		});
 	}
-
+	
 	if (!nearestResources || nearestResources.length === 0){
 		if (resource === "food")
 			if (this.buildAnyField(gameState))
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)
@@ -10,9 +10,10 @@
 	-updating whatever needs updating, keeping track of stuffs (rebuilding needs…)
  */
 
-var BaseManager = function() {
+var BaseManager = function(Config) {
+	this.Config = Config;
 	this.farmingFields = false;
-	this.ID = uniqueIDBases++;
+	this.ID = playerGlobals[PlayerID].uniqueIDBases++;
 	
 	// anchor building: seen as the main building of the base. Needs to have territorial influence
 	this.anchor = undefined;
@@ -318,51 +319,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]});
 			});
 		}
 	}
@@ -452,7 +453,7 @@
 		}
 	}
 	
-	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.
@@ -589,7 +590,7 @@
 			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 });
 					plan.isGo = function() { return false; };	// don't start right away.
@@ -771,6 +772,7 @@
 }
 
 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
 	
@@ -832,7 +834,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)
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)
@@ -18,7 +18,7 @@
 var TransportPlan = function(gameState, units, destination, allAtOnce, escortSize, onlyIfOK) {
 	var self = this;
 
-	this.ID = uniqueIDTPlans++;
+	this.ID = playerGlobals[PlayerID].uniqueIDTPlans++;
 	
 	var unitsID = [];
 	if (units.length !== undefined)
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)
@@ -4,7 +4,7 @@
 
 	this.metadata = metadata;
 
-	this.ID = uniqueIDBOPlans++;
+	this.ID = playerGlobals[PlayerID].uniqueIDBOPlans++;
 
 	this.template = gameState.getTemplate(this.type);
 	if (!this.template) {
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,8 @@
-// Baseconfig is the highest difficulty.
-var baseConfig = {
-	"Military" : {
+var 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 +10,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 +21,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 +55,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 +72,43 @@
 		"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();
+
+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;
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)
@@ -2,7 +2,7 @@
 	this.type = gameState.applyCiv(type);
 	this.metadata = metadata;
 
-	this.ID = uniqueIDBOPlans++;
+	this.ID = playerGlobals[PlayerID].uniqueIDBOPlans++;
 	
 	this.template = gameState.getTemplate(this.type);
 	if (!this.template)
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,29 @@
 // "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.
+var playerGlobals = [];
+var g_debugEnabled = false;
 
 function AegisBot(settings) {
 	BaseAI.call(this, settings);
 
-	Config.updateDifficulty(settings.difficulty);
+	this.Config = new 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.queueManager = new QueueManager(this.queues, this.priorities);
+	this.queueManager = new QueueManager(this.Config, this.queues, this.priorities);
 
-	this.HQ = new HQ();
+	this.HQ = new HQ(this.Config);
 
 	this.firstTime = true;
 
@@ -35,24 +36,29 @@
 AegisBot.prototype = new BaseAI();
 
 AegisBot.prototype.CustomInit = function(gameState, sharedScript) {
-	
+
+	playerGlobals[PlayerID] = {};
+	playerGlobals[PlayerID].uniqueIDBOPlans = 0;	// training/building/research plans
+	playerGlobals[PlayerID].uniqueIDBases = 1;	// base manager ID. Starts at one because "0" means "no base" on the map
+	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);
+	debug ("Initialized with the difficulty " + this.Config.difficulty);
 
-	var ents = gameState.getEntities().filter(Filters.byOwner(PlayerID));
+	var ents = gameState.getEntities().filter(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(Filters.byOwner(this.player));
 	}
 	
 	var filter = Filters.byClass("CivCentre");
-	var enemyKeyEntities = gameState.getEntities().filter(Filters.not(Filters.byOwner(PlayerID))).filter(filter);
+	var enemyKeyEntities = gameState.getEntities().filter(Filters.not(Filters.byOwner(this.player))).filter(filter);
 	
 	if (enemyKeyEntities.length == 0){
-		enemyKeyEntities = gameState.getEntities().filter(Filters.not(Filters.byOwner(PlayerID)));
+		enemyKeyEntities = gameState.getEntities().filter(Filters.not(Filters.byOwner(this.player)));
 	}
 
 	this.myIndex = this.accessibility.getAccessValue(myKeyEntities.toEntityArray()[0].position());
@@ -65,7 +71,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.
@@ -81,6 +87,7 @@
 }
 
 AegisBot.prototype.OnUpdate = function(sharedScript) {
+
 	if (this.gameFinished){
 		return;
 	}
@@ -132,7 +139,7 @@
 		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)
 		{
@@ -142,7 +149,7 @@
 			this.queues.majorTech.addItem(new ResearchPlan(this.gameState, townPhase,0,-1,true));	// we rush the town phase.
 			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");
@@ -215,15 +222,15 @@
 	// 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.
 	}
 };
 
@@ -238,7 +245,7 @@
 };*/
 
 function debug(output){
-	if (Config.debug){
+	if (g_debugEnabled){
 		if (typeof output === "string"){
 			warn(output);
 		}else{
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,6 @@
 // directly imported from Marilyn, with slight modifications to work with qBot.
 
-function Defence(){
+function Defence(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.
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,7 +1,7 @@
 var ResearchPlan = function(gameState, type, startTime, expectedTime, rush) {
 	this.type = type;
 
-	this.ID = uniqueIDBOPlans++;
+	this.ID = playerGlobals[PlayerID].uniqueIDBOPlans++;
 
 	this.template = gameState.getTemplate(this.type);
 	if (!this.template || this.template.researchTime === undefined) {
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)
@@ -31,7 +31,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 +88,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) ||
@@ -133,10 +133,10 @@
 	var ret = new 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;
 };
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)
@@ -17,7 +17,8 @@
 //
 // This system should be improved. It's probably not flexible enough.
 
-var QueueManager = function(queues, priorities) {
+var QueueManager = function(Config, queues, priorities) {
+	this.Config = Config;
 	this.queues = queues;
 	this.priorities = priorities;
 	this.account = {};
@@ -143,7 +144,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.
@@ -282,7 +285,7 @@
 
 // nice readable HTML version.
 QueueManager.prototype.HTMLprintQueues = function(gameState){
-	if (!Config.debug)
+	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){
@@ -522,7 +525,9 @@
 		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]]) });
 	}
 }
@@ -539,7 +544,9 @@
 		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]]) });
 	}
 }
@@ -548,7 +555,8 @@
 	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]]) });
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)
@@ -6,8 +6,9 @@
  * There is a basic support for naval expeditions here. 
  */
 
-function CityAttack(gameState, HQ, uniqueID, targetEnemy, type , targetFinder) {
+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=[];
 	
@@ -50,7 +51,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;
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
+};
