Index: binaries/data/mods/public/gui/pregame/mainmenu.js
===================================================================
--- binaries/data/mods/public/gui/pregame/mainmenu.js	(Revision 14461)
+++ binaries/data/mods/public/gui/pregame/mainmenu.js	(Arbeitskopie)
@@ -11,7 +11,7 @@
 	// Play main menu music
 	global.music.setState(global.music.states.MENU);
 
-	userReportEnabledText = getGUIObjectByName("userReportEnabledText").caption;
+	userReportEnabledText = Engine.GetGUIObjectByName("userReportEnabledText").caption;
 
 	// initialize currentSubmenuType with placeholder to avoid null when switching
 	currentSubmenuType = "submenuSinglePlayer";
@@ -32,9 +32,9 @@
 {
 	if (background == "hellenes1")
 	{
-		var layer1 = getGUIObjectByName("backgroundHele1-1");
-		var layer2 = getGUIObjectByName("backgroundHele1-2");
-		var layer3 = getGUIObjectByName("backgroundHele1-3");
+		var layer1 = Engine.GetGUIObjectByName("backgroundHele1-1");
+		var layer2 = Engine.GetGUIObjectByName("backgroundHele1-2");
+		var layer3 = Engine.GetGUIObjectByName("backgroundHele1-3");
 		
 		layer1.hidden = false;
 		layer2.hidden = false;
@@ -59,10 +59,10 @@
 	
 	if (background == "persians1")
 	{
-		var layer1 = getGUIObjectByName("backgroundPers1-1");
-		var layer2 = getGUIObjectByName("backgroundPers1-2");
-		var layer3 = getGUIObjectByName("backgroundPers1-3");
-		var layer4 = getGUIObjectByName("backgroundPers1-4");
+		var layer1 = Engine.GetGUIObjectByName("backgroundPers1-1");
+		var layer2 = Engine.GetGUIObjectByName("backgroundPers1-2");
+		var layer3 = Engine.GetGUIObjectByName("backgroundPers1-3");
+		var layer4 = Engine.GetGUIObjectByName("backgroundPers1-4");
 		
 		layer1.hidden = false;
 		layer2.hidden = false;
@@ -91,7 +91,7 @@
 
 function submitUserReportMessage()
 {
-	var input = getGUIObjectByName("userReportMessageInput");
+	var input = Engine.GetGUIObjectByName("userReportMessageInput");
 	var msg = input.caption;
 	if (msg.length)
 		Engine.SubmitUserReport("message", 1, msg);
@@ -148,7 +148,7 @@
 
 	if (Engine.IsUserReportEnabled())
 	{
-		getGUIObjectByName("userReportEnabledText").caption = 
+		Engine.GetGUIObjectByName("userReportEnabledText").caption = 
 			userReportEnabledText.replace(/\$status/,
 				formatUserReportStatus(Engine.GetUserReportStatus()));
 	}
@@ -159,26 +159,37 @@
 		g_ShowSplashScreens = false;
 
 		if (Engine.ConfigDB_GetValue("user", "splashscreenenable") !== "false")
-			Engine.PushGuiPage("page_splashscreen.xml", { "page": "splashscreen" } );
-
-		// Warn about removing fixed render path
-		if (Engine.Renderer_GetRenderPath() == "fixed")
-			messageBox(
-				600,
-				300,
-				"[font=\"serif-bold-16\"][color=\"200 20 20\"]Warning:[/color] You appear to be using non-shader (fixed function) graphics. This option will be removed in a future 0 A.D. release, to allow for more advanced graphics features. We advise upgrading your graphics card to a more recent, shader-compatible model.\n\nPlease press \"Read More\" for more information or \"Ok\" to continue.",
-				"WARNING!",
-				0,
-				["Ok", "Read More"],
-				[null, function() { Engine.OpenURL("http://www.wildfiregames.com/forum/index.php?showtopic=16734"); }]
-			);
+			Engine.PushGuiPage("page_splashscreen.xml", { "page": "splashscreen", callback : "SplashScreenClosedCallback" } );
+		else
+			ShowRenderPathMessage();
+		
 	}
 }
 
+function ShowRenderPathMessage()
+{
+	// Warn about removing fixed render path
+	if (Engine.Renderer_GetRenderPath() == "fixed")
+		messageBox(
+			600,
+			300,
+			"[font=\"serif-bold-16\"][color=\"200 20 20\"]Warning:[/color] You appear to be using non-shader (fixed function) graphics. This option will be removed in a future 0 A.D. release, to allow for more advanced graphics features. We advise upgrading your graphics card to a more recent, shader-compatible model.\n\nPlease press \"Read More\" for more information or \"Ok\" to continue.",
+			"WARNING!",
+			0,
+			["Ok", "Read More"],
+			[ null, function() { Engine.OpenURL("http://www.wildfiregames.com/forum/index.php?showtopic=16734"); } ]
+		);
+}
+
+function SplashScreenClosedCallback()
+{
+	ShowRenderPathMessage();
+}
+
 function EnableUserReport(Enabled)
 {
-	getGUIObjectByName("userReportDisabled").hidden = Enabled;
- 	getGUIObjectByName("userReportEnabled").hidden = !Enabled;
+	Engine.GetGUIObjectByName("userReportDisabled").hidden = Enabled;
+ 	Engine.GetGUIObjectByName("userReportEnabled").hidden = !Enabled;
  	Engine.SetUserReportEnabled(Enabled);
 }
 
@@ -198,14 +209,14 @@
 // Slide menu
 function updateMenuPosition(dt)
 {
-	var submenu = getGUIObjectByName("submenu");
+	var submenu = Engine.GetGUIObjectByName("submenu");
 
 	if (submenu.hidden == false)
 	{
 		// Number of pixels per millisecond to move
 		const SPEED = 1.2;
 
-		var maxOffset = getGUIObjectByName("mainMenu").size.right - submenu.size.left;
+		var maxOffset = Engine.GetGUIObjectByName("mainMenu").size.right - submenu.size.left;
 		if (maxOffset > 0)
 		{
 			var offset = Math.min(SPEED * dt, maxOffset);
@@ -222,10 +233,10 @@
 {
 	// switch to new submenu type
 	currentSubmenuType = newSubmenu;
-	getGUIObjectByName(currentSubmenuType).hidden = false;
+	Engine.GetGUIObjectByName(currentSubmenuType).hidden = false;
 
 	// set position of new submenu
-	var submenu = getGUIObjectByName("submenu");
+	var submenu = Engine.GetGUIObjectByName("submenu");
 	var top = position - MARGIN;
 	var bottom = position + ((buttonHeight + MARGIN) * numButtons);
 	submenu.size = submenu.size.left + " " + top + " " + submenu.size.right + " " + bottom;
@@ -234,7 +245,7 @@
 	blendSubmenuIntoMain(top, bottom);
 
 	// Reveal submenu
-	getGUIObjectByName("submenu").hidden = false;
+	Engine.GetGUIObjectByName("submenu").hidden = false;
 }
 
 // Closes the menu and resets position
@@ -243,24 +254,24 @@
 //	playButtonSound();
 
 	// remove old submenu type
-	getGUIObjectByName(currentSubmenuType).hidden = true;
+	Engine.GetGUIObjectByName(currentSubmenuType).hidden = true;
 
 	// hide submenu and reset position
-	var submenu = getGUIObjectByName("submenu");
+	var submenu = Engine.GetGUIObjectByName("submenu");
 	submenu.hidden = true;
-	submenu.size = getGUIObjectByName("mainMenu").size;
+	submenu.size = Engine.GetGUIObjectByName("mainMenu").size;
 
 	// reset main menu panel right border
-	getGUIObjectByName("MainMenuPanelRightBorderTop").size = "100%-2 0 100% 100%";
+	Engine.GetGUIObjectByName("MainMenuPanelRightBorderTop").size = "100%-2 0 100% 100%";
 }
 
 // Sizes right border on main menu panel to match the submenu
 function blendSubmenuIntoMain(topPosition, bottomPosition)
 {
-	var topSprite = getGUIObjectByName("MainMenuPanelRightBorderTop");
+	var topSprite = Engine.GetGUIObjectByName("MainMenuPanelRightBorderTop");
 	topSprite.size = "100%-2 0 100% " + (topPosition + MARGIN);
 
-	var bottomSprite = getGUIObjectByName("MainMenuPanelRightBorderBottom");
+	var bottomSprite = Engine.GetGUIObjectByName("MainMenuPanelRightBorderBottom");
 	bottomSprite.size = "100%-2 " + (bottomPosition) + " 100% 100%";
 }
 
@@ -291,14 +302,14 @@
 //
 //		if (tmpName != tabName)
 //		{
-//			getGUIObjectByName (tmpName + "Window").hidden = true;
-//			getGUIObjectByName (tmpName + "Button").enabled = true;
+//			Engine.GetGUIObjectByName (tmpName + "Window").hidden = true;
+//			Engine.GetGUIObjectByName (tmpName + "Button").enabled = true;
 //		}
 //	}
 //
 //	// Make given tab visible.
-//	getGUIObjectByName (tabName + "Window").hidden = false;
-//	getGUIObjectByName (tabName + "Button").enabled = false;
+//	Engine.GetGUIObjectByName (tabName + "Window").hidden = false;
+//	Engine.GetGUIObjectByName (tabName + "Button").enabled = false;
 //}
 //
 //// Move the credits up the screen.
Index: binaries/data/mods/public/gui/pregame/mainmenu.xml
===================================================================
--- binaries/data/mods/public/gui/pregame/mainmenu.xml	(Revision 14461)
+++ binaries/data/mods/public/gui/pregame/mainmenu.xml	(Arbeitskopie)
@@ -446,7 +446,7 @@
 						closeMenu();
 						<![CDATA[
 							var btCaptions = ["Yes", "No"];
-							var btCode = [exit, null];
+							var btCode = [Engine.Exit, null]
 							messageBox(400, 200, "Are you sure you want to quit 0 A.D.?", "Confirmation", 0, btCaptions, btCode);
 						]]>
 					</action>
@@ -549,7 +549,7 @@
 				size="50%-128 100%-36 50%+128 100%"
 			>
 				<action on="Load"><![CDATA[
-					this.caption = "Build: " + buildTime(0) + " - " + buildTime(2);
+					this.caption = "Build: " + Engine.BuildTime(0) + " - " + Engine.BuildTime(2);
 				]]></action>
 			</object>
 		</object>
Index: binaries/data/mods/public/gui/session/input.js
===================================================================
--- binaries/data/mods/public/gui/session/input.js	(Revision 14461)
+++ binaries/data/mods/public/gui/session/input.js	(Arbeitskopie)
@@ -56,7 +56,7 @@
 {
 	var cursorSet = false;
 	var tooltipSet = false;
-	var informationTooltip = getGUIObjectByName("informationTooltip");
+	var informationTooltip = Engine.GetGUIObjectByName("informationTooltip");
 	if (!mouseIsOverObject)
 	{
 		var action = determineAction(mouseX, mouseY);
@@ -84,7 +84,7 @@
 	if (!tooltipSet)
 		informationTooltip.hidden = true;
 	
-	var placementTooltip = getGUIObjectByName("placementTooltip");
+	var placementTooltip = Engine.GetGUIObjectByName("placementTooltip");
 	if (placementSupport.tooltipMessage)
 	{
 		if (placementSupport.tooltipError)
@@ -746,7 +746,7 @@
 			if (x0 > x1) { var t = x0; x0 = x1; x1 = t; }
 			if (y0 > y1) { var t = y0; y0 = y1; y1 = t; }
 
-			var bandbox = getGUIObjectByName("bandbox");
+			var bandbox = Engine.GetGUIObjectByName("bandbox");
 			bandbox.size = [x0, y0, x1, y1].join(" ");
 			bandbox.hidden = false;
 
@@ -766,7 +766,7 @@
 				if (x0 > x1) { var t = x0; x0 = x1; x1 = t; }
 				if (y0 > y1) { var t = y0; y0 = y1; y1 = t; }
 
-				var bandbox = getGUIObjectByName("bandbox");
+				var bandbox = Engine.GetGUIObjectByName("bandbox");
 				bandbox.hidden = true;
 
 				// Get list of entities limited to preferred entities
@@ -810,7 +810,7 @@
 			else if (ev.button == SDL_BUTTON_RIGHT)
 			{
 				// Cancel selection
-				var bandbox = getGUIObjectByName("bandbox");
+				var bandbox = Engine.GetGUIObjectByName("bandbox");
 				bandbox.hidden = true;
 
 				g_Selection.setHighlightList([]);
@@ -1060,7 +1060,7 @@
 function handleInputAfterGui(ev)
 {
 	// Handle the time-warp testing features, restricted to single-player
-	if (!g_IsNetworked && getGUIObjectByName("devTimeWarp").checked)
+	if (!g_IsNetworked && Engine.GetGUIObjectByName("devTimeWarp").checked)
 	{
 		if (ev.type == "hotkeydown" && ev.hotkey == "timewarp.fastforward")
 			Engine.SetSimRate(20.0);
Index: binaries/data/mods/public/gui/session/unit_commands.js
===================================================================
--- binaries/data/mods/public/gui/session/unit_commands.js	(Revision 14461)
+++ binaries/data/mods/public/gui/session/unit_commands.js	(Arbeitskopie)
@@ -41,7 +41,7 @@
 // Lay out a row of centered buttons (does not work inside a loop like the other function)
 function layoutButtonRowCentered(rowNumber, guiName, startIndex, endIndex, width)
 {
-	var buttonSideLength = getGUIObjectByName("unit"+guiName+"Button[0]").size.bottom;
+	var buttonSideLength = Engine.GetGUIObjectByName("unit"+guiName+"Button[0]").size.bottom;
 	var buttonSpacer = buttonSideLength+1;
 	var colNumber = 0;
 
@@ -51,8 +51,8 @@
 
 	for (var i = startIndex; i < endIndex; i++)
 	{
-		var button = getGUIObjectByName("unit"+guiName+"Button["+i+"]");
-		var icon = getGUIObjectByName("unit"+guiName+"Icon["+i+"]");
+		var button = Engine.GetGUIObjectByName("unit"+guiName+"Button["+i+"]");
+		var icon = Engine.GetGUIObjectByName("unit"+guiName+"Icon["+i+"]");
 
 		if (button)
 		{
@@ -116,7 +116,7 @@
 
 	for (var i = startIndex; i < endIndex; i++)
 	{
-		var button = getGUIObjectByName("unit"+guiName+objectName+"["+i+"]");
+		var button = Engine.GetGUIObjectByName("unit"+guiName+objectName+"["+i+"]");
 
 		if (button)
 		{
@@ -316,10 +316,10 @@
 		// If a tech has been researched it leaves an empty slot
 		if (guiName == RESEARCH && !item)
 		{
-			getGUIObjectByName("unit"+guiName+"Button["+i+"]").hidden = true;
+			Engine.GetGUIObjectByName("unit"+guiName+"Button["+i+"]").hidden = true;
 			// We also remove the paired tech and the pair symbol
-			getGUIObjectByName("unit"+guiName+"Button["+(i+rowLength)+"]").hidden = true;
-			getGUIObjectByName("unit"+guiName+"Pair["+i+"]").hidden = true;
+			Engine.GetGUIObjectByName("unit"+guiName+"Button["+(i+rowLength)+"]").hidden = true;
+			Engine.GetGUIObjectByName("unit"+guiName+"Pair["+i+"]").hidden = true;
 			continue;
 		}
 
@@ -387,7 +387,7 @@
 				var name = getEntityNames(template);
 				var tooltip = name;
 				var count = g_Selection.groups.getCount(item);
-				getGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (count > 1 ? count : "");
+				Engine.GetGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (count > 1 ? count : "");
 				break;
 
 			case QUEUE:
@@ -396,16 +396,16 @@
 					tooltip += "\n[color=\"red\"]Insufficient population capacity:\n[/color]"+getCostComponentDisplayName("population")+" "+item.neededSlots;
 
 				var progress = Math.round(item.progress*100) + "%";
-				getGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (item.count > 1 ? item.count : "");
+				Engine.GetGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (item.count > 1 ? item.count : "");
 
 				if (i == 0)
 				{
-					getGUIObjectByName("queueProgress").caption = (item.progress ? progress : "");
-					var size = getGUIObjectByName("unit"+guiName+"ProgressSlider["+i+"]").size;
+					Engine.GetGUIObjectByName("queueProgress").caption = (item.progress ? progress : "");
+					var size = Engine.GetGUIObjectByName("unit"+guiName+"ProgressSlider["+i+"]").size;
 
 					// Buttons are assumed to be square, so left/right offsets can be used for top/bottom.
 					size.top = size.left + Math.round(item.progress * (size.right - size.left));
-					getGUIObjectByName("unit"+guiName+"ProgressSlider["+i+"]").size = size;
+					Engine.GetGUIObjectByName("unit"+guiName+"ProgressSlider["+i+"]").size = size;
 				}
 				break;
 
@@ -413,7 +413,7 @@
 				var name = getEntityNames(template);
 				var tooltip = "Unload " + name + "\nSingle-click to unload 1. Shift-click to unload all of this type.";
 				var count = garrisonGroups.getCount(item);
-				getGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (count > 1 ? count : "");
+				Engine.GetGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (count > 1 ? count : "");
 				break;
 
 			case GATE:
@@ -430,7 +430,7 @@
 
 					tooltip += "\n" + getEntityCostTooltip(template, wallCount);
 
-					var affordableMask = getGUIObjectByName("unitGateUnaffordable["+i+"]");
+					var affordableMask = Engine.GetGUIObjectByName("unitGateUnaffordable["+i+"]");
 					affordableMask.hidden = true;
 
 					var neededResources = Engine.GuiInterfaceCall("GetNeededResources", multiplyEntityCosts(template, wallCount));
@@ -510,11 +510,11 @@
 				if (item.name == "unload-all")
 				{
 					var count = garrisonGroups.getTotalCount();
-					getGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (count > 0 ? count : "");
+					Engine.GetGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (count > 0 ? count : "");
 				}
 				else
 				{
-					getGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = "";
+					Engine.GetGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = "";
 				}
 
 				tooltip = (item.tooltip ? item.tooltip : toTitleCase(item.name));
@@ -525,13 +525,13 @@
 		}
 
 		// Button
-		var button = getGUIObjectByName("unit"+guiName+"Button["+i+"]");
-		var button1 = getGUIObjectByName("unit"+guiName+"Button["+(i+rowLength)+"]");
-		var affordableMask = getGUIObjectByName("unit"+guiName+"Unaffordable["+i+"]");
-		var affordableMask1 = getGUIObjectByName("unit"+guiName+"Unaffordable["+(i+rowLength)+"]");
-		var icon = getGUIObjectByName("unit"+guiName+"Icon["+i+"]");
-		var guiSelection = getGUIObjectByName("unit"+guiName+"Selection["+i+"]");
-		var pair = getGUIObjectByName("unit"+guiName+"Pair["+i+"]");
+		var button = Engine.GetGUIObjectByName("unit"+guiName+"Button["+i+"]");
+		var button1 = Engine.GetGUIObjectByName("unit"+guiName+"Button["+(i+rowLength)+"]");
+		var affordableMask = Engine.GetGUIObjectByName("unit"+guiName+"Unaffordable["+i+"]");
+		var affordableMask1 = Engine.GetGUIObjectByName("unit"+guiName+"Unaffordable["+(i+rowLength)+"]");
+		var icon = Engine.GetGUIObjectByName("unit"+guiName+"Icon["+i+"]");
+		var guiSelection = Engine.GetGUIObjectByName("unit"+guiName+"Selection["+i+"]");
+		var pair = Engine.GetGUIObjectByName("unit"+guiName+"Pair["+i+"]");
 		button.hidden = false;
 		button.tooltip = tooltip;
 
@@ -551,14 +551,14 @@
 			{
 				button.onpress = (function(e){ return function() { callback(e) } })(item.bottom);
 
-				var icon1 = getGUIObjectByName("unit"+guiName+"Icon["+(i+rowLength)+"]");
+				var icon1 = Engine.GetGUIObjectByName("unit"+guiName+"Icon["+(i+rowLength)+"]");
 				button1.hidden = false;
 				button1.tooltip = tooltip1;
 				button1.onpress = (function(e){ return function() { callback(e) } })(item.top);
 
 				// when we hover over a pair, the other one gets a red cross over it to show it won't be available any more.
-				var unchosenIcon = getGUIObjectByName("unit"+guiName+"UnchosenIcon["+i+"]");
-				var unchosenIcon1 = getGUIObjectByName("unit"+guiName+"UnchosenIcon["+(i+rowLength)+"]");
+				var unchosenIcon = Engine.GetGUIObjectByName("unit"+guiName+"UnchosenIcon["+i+"]");
+				var unchosenIcon1 = Engine.GetGUIObjectByName("unit"+guiName+"UnchosenIcon["+(i+rowLength)+"]");
 
 				button1.onmouseenter = (function(e){ return function() { setOverlay(e, true) } })(unchosenIcon);
 				button1.onmouseleave = (function(e){ return function() { setOverlay(e, false) } })(unchosenIcon);
@@ -571,7 +571,7 @@
 			else
 			{
 				// Hide the overlay.
-				var unchosenIcon = getGUIObjectByName("unit"+guiName+"UnchosenIcon["+i+"]");
+				var unchosenIcon = Engine.GetGUIObjectByName("unit"+guiName+"UnchosenIcon["+i+"]");
 				unchosenIcon.hidden = true;
 			}
 		}
@@ -792,7 +792,7 @@
 						trainNum = buildingsCountToTrainFullBatch * fullBatchSize + remainderBatch;
 						button_disableable = !Engine.HotkeyIsPressed("selection.remove");
 					}
-					getGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (batchTrainingCount > 0) ? batchTrainingCount : "";
+					Engine.GetGUIObjectByName("unit"+guiName+"Count["+i+"]").caption = (batchTrainingCount > 0) ? batchTrainingCount : "";
 				}
 
 				// Walls have no cost defined.
@@ -834,11 +834,11 @@
 
 	var numRows = Math.ceil(numButtons / rowLength);
 
-	var buttonSideLength = getGUIObjectByName("unit"+guiName+"Button[0]").size.bottom;
+	var buttonSideLength = Engine.GetGUIObjectByName("unit"+guiName+"Button[0]").size.bottom;
 
 	// We sort pairs upside down, so get the size from the topmost button.
 	if (guiName == RESEARCH)
-		buttonSideLength = getGUIObjectByName("unit"+guiName+"Button["+(rowLength*numRows)+"]").size.bottom;
+		buttonSideLength = Engine.GetGUIObjectByName("unit"+guiName+"Button["+(rowLength*numRows)+"]").size.bottom;
 
 	var buttonSpacer = buttonSideLength+1;
 
@@ -866,7 +866,7 @@
 	// Layout pair icons
 	if (guiName == RESEARCH)
 	{
-		var pairSize = getGUIObjectByName("unit"+guiName+"Pair[0]").size;
+		var pairSize = Engine.GetGUIObjectByName("unit"+guiName+"Pair[0]").size;
 		var pairSideWidth = pairSize.right;
 		var pairSideHeight = pairSize.bottom;
 		var pairSpacerHeight = pairSideHeight + 1;
@@ -878,7 +878,7 @@
 	// Resize Queue panel if needed
 	if (guiName == QUEUE) // or garrison
 	{
-		var panel = getGUIObjectByName("unitQueuePanel");
+		var panel = Engine.GetGUIObjectByName("unitQueuePanel");
 		var size = panel.size;
 		size.top = (UNIT_PANEL_BASE - ((numRows-1)*UNIT_PANEL_HEIGHT));
 		panel.size = size;
@@ -886,15 +886,15 @@
 
 	// Hide any buttons we're no longer using
 	for (var i = numButtons; i < g_unitPanelButtons[guiName]; ++i)
-		getGUIObjectByName("unit"+guiName+"Button["+i+"]").hidden = true;
+		Engine.GetGUIObjectByName("unit"+guiName+"Button["+i+"]").hidden = true;
 
 	// Hide unused pair buttons and symbols
 	if (guiName == RESEARCH)
 	{
 		for (var i = numButtons; i < g_unitPanelButtons[guiName]; ++i)
 		{
-			getGUIObjectByName("unit"+guiName+"Button["+(i+rowLength)+"]").hidden = true;
-			getGUIObjectByName("unit"+guiName+"Pair["+i+"]").hidden = true;
+			Engine.GetGUIObjectByName("unit"+guiName+"Button["+(i+rowLength)+"]").hidden = true;
+			Engine.GetGUIObjectByName("unit"+guiName+"Pair["+i+"]").hidden = true;
 		}
 	}
 
@@ -910,7 +910,7 @@
 	for (var i = 0; i < TRADING_RESOURCES.length; i++)
 	{
 		var resource = TRADING_RESOURCES[i];
-		var button = getGUIObjectByName("unitTradingButton["+i+"]");
+		var button = Engine.GetGUIObjectByName("unitTradingButton["+i+"]");
 		button.size = (i * 46) + " 0 " + ((i + 1) * 46) + " 46";
 		if (resource == requiredGoods)
 			var selectRequiredGoodsData = { "entities": selection, "requiredGoods": undefined };
@@ -919,8 +919,8 @@
 		button.onpress = (function(e){ return function() { selectRequiredGoods(e); } })(selectRequiredGoodsData);
 		button.enabled = true;
 		button.tooltip = "Set/unset " + resource + " as forced trading goods.";
-		var icon = getGUIObjectByName("unitTradingIcon["+i+"]");
-		var selected = getGUIObjectByName("unitTradingSelection["+i+"]");
+		var icon = Engine.GetGUIObjectByName("unitTradingIcon["+i+"]");
+		var selected = Engine.GetGUIObjectByName("unitTradingSelection["+i+"]");
 		selected.hidden = !(resource == requiredGoods);
 		var grayscale = (resource != requiredGoods) ? "grayscale:" : "";
 		icon.sprite = "stretched:"+grayscale+"session/icons/resources/" + resource + ".png";
@@ -946,15 +946,15 @@
 			if (j == 0)
 			{
 				// Display the selection overlay
-				var selection = getGUIObjectByName("unitBarter" + action + "Selection["+i+"]");
+				var selection = Engine.GetGUIObjectByName("unitBarter" + action + "Selection["+i+"]");
 				selection.hidden = !(i == g_barterSell);
 			}
 
 			// We gray out the not selected icons in 'sell' row
 			var grayscale = (j == 0 && i != g_barterSell) ? "grayscale:" : "";
-			var icon = getGUIObjectByName("unitBarter" + action + "Icon["+i+"]");
+			var icon = Engine.GetGUIObjectByName("unitBarter" + action + "Icon["+i+"]");
 
-			var button = getGUIObjectByName("unitBarter" + action + "Button["+i+"]");
+			var button = Engine.GetGUIObjectByName("unitBarter" + action + "Button["+i+"]");
 			button.size = (i * 46) + " 0 " + ((i + 1) * 46) + " 46";
 			var amountToBuy;
 			// We don't display a button in 'buy' row if the same resource is selected in 'sell' row
@@ -986,7 +986,7 @@
 					var hidden = neededResources ? false : true;
 					for (var ii = 0; ii < BARTER_RESOURCES.length; ii++)
 					{
-						var affordableMask = getGUIObjectByName("unitBarterBuyUnaffordable["+ii+"]");
+						var affordableMask = Engine.GetGUIObjectByName("unitBarterBuyUnaffordable["+ii+"]");
 						affordableMask.hidden = hidden;
 					}
 				}
@@ -999,7 +999,7 @@
 				button.onpress = (function(exchangeResourcesParameters){ return function() { exchangeResources(exchangeResourcesParameters); } })(exchangeResourcesParameters);
 				amount = amountToBuy;
 			}
-			getGUIObjectByName("unitBarter" + action + "Amount["+i+"]").caption = amount;
+			Engine.GetGUIObjectByName("unitBarter" + action + "Amount["+i+"]").caption = amount;
 		}
 	}
 }
@@ -1068,7 +1068,7 @@
 				function (item) { performStance(entState.id, item); } );
 		}
 
-		getGUIObjectByName("unitBarterPanel").hidden = !entState.barterMarket;
+		Engine.GetGUIObjectByName("unitBarterPanel").hidden = !entState.barterMarket;
 		if (entState.barterMarket)
 		{
 			usedPanels["Barter"] = 1;
@@ -1246,7 +1246,7 @@
 	var offset = 0;
 	for each (var panelName in g_unitPanels)
 	{
-		var panel = getGUIObjectByName("unit" + panelName + "Panel");
+		var panel = Engine.GetGUIObjectByName("unit" + panelName + "Panel");
 		if (usedPanels[panelName])
 			panel.hidden = false;
 		else
@@ -1258,7 +1258,7 @@
 function hideUnitCommands()
 {
 	for each (var panelName in g_unitPanels)
-		getGUIObjectByName("unit" + panelName + "Panel").hidden = true;
+		Engine.GetGUIObjectByName("unit" + panelName + "Panel").hidden = true;
 }
 
 // Get all of the available entities which can be trained by the selected entities
Index: binaries/data/mods/public/gui/session/menu.js
===================================================================
--- binaries/data/mods/public/gui/session/menu.js	(Revision 14461)
+++ binaries/data/mods/public/gui/session/menu.js	(Arbeitskopie)
@@ -45,7 +45,7 @@
 // Ignore size defined in XML and set the actual menu size here
 function initMenuPosition()
 {
-	menu = getGUIObjectByName("menu");
+	menu = Engine.GetGUIObjectByName("menu");
 	menu.size = INITIAL_MENU_POSITION;
 }
 
@@ -153,20 +153,21 @@
 	messageBox(400, 200, "Are you sure you want to quit?", "Confirmation", 0, btCaptions, btCode);
 }
 
+
 function openDeleteDialog(selection)
 {
 	closeMenu();
 	closeOpenDialogs();
 
-	var deleteSelectedEntities = function ()
+	var deleteSelectedEntities = function (selectionArg)
 	{
-		Engine.PostNetworkCommand({"type": "delete-entities", "entities": selection});
+		Engine.PostNetworkCommand({"type": "delete-entities", "entities": selectionArg});
 	};
 
 	var btCaptions = ["Yes", "No"];
 	var btCode = [deleteSelectedEntities, resumeGame];
 
-	messageBox(400, 200, "Destroy everything currently selected?", "Delete", 0, btCaptions, btCode);
+	messageBox(400, 200, "Destroy everything currently selected?", "Delete", 0, btCaptions, btCode, [selection, null]);
 }
 
 // Menu functions
@@ -182,38 +183,38 @@
 
 function openSettings(pause)
 {
-	getGUIObjectByName("settingsDialogPanel").hidden = false;
+	Engine.GetGUIObjectByName("settingsDialogPanel").hidden = false;
 	if (pause)
 		pauseGame();
 }
 
 function closeSettings(resume)
 {
-	getGUIObjectByName("settingsDialogPanel").hidden = true;
+	Engine.GetGUIObjectByName("settingsDialogPanel").hidden = true;
 	if (resume)
 		resumeGame();
 }
 
 function openChat()
 {
-	getGUIObjectByName("chatInput").focus(); // Grant focus to the input area
-	getGUIObjectByName("chatDialogPanel").hidden = false;
+	Engine.GetGUIObjectByName("chatInput").focus(); // Grant focus to the input area
+	Engine.GetGUIObjectByName("chatDialogPanel").hidden = false;
 
 }
 
 function closeChat()
 {
-	getGUIObjectByName("chatInput").caption = ""; // Clear chat input
-	getGUIObjectByName("chatInput").blur(); // Remove focus
-	getGUIObjectByName("chatDialogPanel").hidden = true;
+	Engine.GetGUIObjectByName("chatInput").caption = ""; // Clear chat input
+	Engine.GetGUIObjectByName("chatInput").blur(); // Remove focus
+	Engine.GetGUIObjectByName("chatDialogPanel").hidden = true;
 }
 
 function toggleChatWindow(teamChat)
 {
 	closeSettings();
 
-	var chatWindow = getGUIObjectByName("chatDialogPanel");
-	var chatInput = getGUIObjectByName("chatInput");
+	var chatWindow = Engine.GetGUIObjectByName("chatDialogPanel");
+	var chatInput = Engine.GetGUIObjectByName("chatInput");
 
 	if (chatWindow.hidden)
 		chatInput.focus(); // Grant focus to the input area
@@ -227,7 +228,7 @@
 		chatInput.caption = ""; // Clear chat input
 	}
 
-	getGUIObjectByName("toggleTeamChat").checked = teamChat;
+	Engine.GetGUIObjectByName("toggleTeamChat").checked = teamChat;
 	chatWindow.hidden = !chatWindow.hidden;
 }
 
@@ -251,14 +252,14 @@
 	var players = getPlayerData(g_PlayerAssignments);
 
 	// Get offset for one line
-	var onesize = getGUIObjectByName("diplomacyPlayer[0]").size;
+	var onesize = Engine.GetGUIObjectByName("diplomacyPlayer[0]").size;
 	var rowsize = onesize.bottom - onesize.top;
 
 	// We don't include gaia
 	for (var i = 1; i < players.length; i++)
 	{
 		// Apply offset
-		var row = getGUIObjectByName("diplomacyPlayer["+(i-1)+"]");
+		var row = Engine.GetGUIObjectByName("diplomacyPlayer["+(i-1)+"]");
 		var size = row.size;
 		size.top = rowsize*(i-1);
 		size.bottom = rowsize*i;
@@ -268,27 +269,27 @@
 		var playerColor = players[i].color.r+" "+players[i].color.g+" "+players[i].color.b;
 		row.sprite = "colour: "+playerColor + " 32";
 
-		getGUIObjectByName("diplomacyPlayerName["+(i-1)+"]").caption = "[color=\"" + playerColor + "\"]" + players[i].name + "[/color]";
-		getGUIObjectByName("diplomacyPlayerCiv["+(i-1)+"]").caption = g_CivData[players[i].civ].Name;
+		Engine.GetGUIObjectByName("diplomacyPlayerName["+(i-1)+"]").caption = "[color=\"" + playerColor + "\"]" + players[i].name + "[/color]";
+		Engine.GetGUIObjectByName("diplomacyPlayerCiv["+(i-1)+"]").caption = g_CivData[players[i].civ].Name;
 
-		getGUIObjectByName("diplomacyPlayerTeam["+(i-1)+"]").caption = (players[i].team < 0) ? "None" : players[i].team+1;
+		Engine.GetGUIObjectByName("diplomacyPlayerTeam["+(i-1)+"]").caption = (players[i].team < 0) ? "None" : players[i].team+1;
 
 		if (i != we)
-			getGUIObjectByName("diplomacyPlayerTheirs["+(i-1)+"]").caption = (players[i].isAlly[we] ? "Ally" : (players[i].isNeutral[we] ? "Neutral" : "Enemy"));
+			Engine.GetGUIObjectByName("diplomacyPlayerTheirs["+(i-1)+"]").caption = (players[i].isAlly[we] ? "Ally" : (players[i].isNeutral[we] ? "Neutral" : "Enemy"));
 
 		// Don't display the options for ourself, or if we or the other player aren't active anymore
 		if (i == we || players[we].state != "active" || players[i].state != "active")
 		{
 			// Hide the unused/unselectable options
 			for each (var a in ["TributeFood", "TributeWood", "TributeStone", "TributeMetal", "Ally", "Neutral", "Enemy"])
-				getGUIObjectByName("diplomacyPlayer"+a+"["+(i-1)+"]").hidden = true;
+				Engine.GetGUIObjectByName("diplomacyPlayer"+a+"["+(i-1)+"]").hidden = true;
 			continue;
 		}
 
 		// Tribute
 		for each (var resource in ["food", "wood", "stone", "metal"])
 		{
-			var button = getGUIObjectByName("diplomacyPlayerTribute"+toTitleCase(resource)+"["+(i-1)+"]");
+			var button = Engine.GetGUIObjectByName("diplomacyPlayerTribute"+toTitleCase(resource)+"["+(i-1)+"]");
 			button.onpress = (function(player, resource, button){
 				// Implement something like how unit batch training works. Shift+click to send 500, shift+click+click to send 1000, etc.
 				// Also see input.js (searching for "INPUT_MASSTRIBUTING" should get all the relevant parts).
@@ -330,7 +331,7 @@
 		// Set up the buttons
 		for each (var setting in ["ally", "neutral", "enemy"])
 		{
-			var button = getGUIObjectByName("diplomacyPlayer"+toTitleCase(setting)+"["+(i-1)+"]");
+			var button = Engine.GetGUIObjectByName("diplomacyPlayer"+toTitleCase(setting)+"["+(i-1)+"]");
 
 			if (setting == "ally")
 			{
@@ -359,13 +360,13 @@
 		}
 	}
 
-	getGUIObjectByName("diplomacyDialogPanel").hidden = false;
+	Engine.GetGUIObjectByName("diplomacyDialogPanel").hidden = false;
 }
 
 function closeDiplomacy()
 {
 	isDiplomacyOpen = false;
-	getGUIObjectByName("diplomacyDialogPanel").hidden = true;
+	Engine.GetGUIObjectByName("diplomacyDialogPanel").hidden = true;
 }
 
 function toggleDiplomacy()
@@ -409,24 +410,24 @@
 	var selec = RESOURCES[0];
 	for (var i = 0; i < RESOURCES.length; ++i)
 	{
-		var buttonResource = getGUIObjectByName("tradeResource["+i+"]");
+		var buttonResource = Engine.GetGUIObjectByName("tradeResource["+i+"]");
 		if (i > 0)
 		{
-			var size = getGUIObjectByName("tradeResource["+(i-1)+"]").size;
+			var size = Engine.GetGUIObjectByName("tradeResource["+(i-1)+"]").size;
 			var width = size.right - size.left;
 			size.left += width;
 			size.right += width;
-			getGUIObjectByName("tradeResource["+i+"]").size = size;
+			Engine.GetGUIObjectByName("tradeResource["+i+"]").size = size;
 		}
 		var resource = RESOURCES[i];
 		proba[resource] = (proba[resource] ? proba[resource] : 0);
-		var buttonResource = getGUIObjectByName("tradeResourceButton["+i+"]");
-		var icon = getGUIObjectByName("tradeResourceIcon["+i+"]");
+		var buttonResource = Engine.GetGUIObjectByName("tradeResourceButton["+i+"]");
+		var icon = Engine.GetGUIObjectByName("tradeResourceIcon["+i+"]");
 		icon.sprite = "stretched:session/icons/resources/" + resource + ".png";
-		var label = getGUIObjectByName("tradeResourceText["+i+"]");
-		var buttonUp = getGUIObjectByName("tradeArrowUp["+i+"]");
-		var buttonDn = getGUIObjectByName("tradeArrowDn["+i+"]");
-		var iconSel = getGUIObjectByName("tradeResourceSelection["+i+"]");
+		var label = Engine.GetGUIObjectByName("tradeResourceText["+i+"]");
+		var buttonUp = Engine.GetGUIObjectByName("tradeArrowUp["+i+"]");
+		var buttonDn = Engine.GetGUIObjectByName("tradeArrowDn["+i+"]");
+		var iconSel = Engine.GetGUIObjectByName("tradeResourceSelection["+i+"]");
 		button[resource] = { "res": buttonResource, "up": buttonUp, "dn": buttonDn, "label": label, "sel": iconSel };
 
 		buttonResource.onpress = (function(resource){
@@ -479,7 +480,7 @@
 		if (inactive > 0)
 			caption += comma + "[color=\"orange\"]" + inactive + " inactive[/color]";
 	}
-	getGUIObjectByName("landTraders").caption = caption;
+	Engine.GetGUIObjectByName("landTraders").caption = caption;
 
 	caption = "";
 	comma = "";
@@ -496,15 +497,15 @@
 		if (inactive > 0)
 			caption += comma + "[color=\"orange\"]" + inactive + " inactive[/color]";
 	}
-	getGUIObjectByName("shipTraders").caption = caption;
+	Engine.GetGUIObjectByName("shipTraders").caption = caption;
 
-	getGUIObjectByName("tradeDialogPanel").hidden = false;
+	Engine.GetGUIObjectByName("tradeDialogPanel").hidden = false;
 }
 
 function closeTrade()
 {
 	isTradeOpen = false;
-	getGUIObjectByName("tradeDialogPanel").hidden = true;
+	Engine.GetGUIObjectByName("tradeDialogPanel").hidden = true;
 }
 
 function toggleTrade()
@@ -517,22 +518,22 @@
 
 function toggleGameSpeed()
 {
-	var gameSpeed = getGUIObjectByName("gameSpeed");
+	var gameSpeed = Engine.GetGUIObjectByName("gameSpeed");
 	gameSpeed.hidden = !gameSpeed.hidden;
 }
 
 function pauseGame()
 {
-	getGUIObjectByName("pauseButtonText").caption = RESUME;
-	getGUIObjectByName("pauseOverlay").hidden = false;
-	setPaused(true);
+	Engine.GetGUIObjectByName("pauseButtonText").caption = RESUME;
+	Engine.GetGUIObjectByName("pauseOverlay").hidden = false;
+	Engine.SetPaused(true);
 }
 
 function resumeGame()
 {
-	getGUIObjectByName("pauseButtonText").caption = PAUSE;
-	getGUIObjectByName("pauseOverlay").hidden = true;
-	setPaused(false);
+	Engine.GetGUIObjectByName("pauseButtonText").caption = PAUSE;
+	Engine.GetGUIObjectByName("pauseOverlay").hidden = true;
+	Engine.SetPaused(false);
 }
 
 function togglePause()
@@ -540,17 +541,17 @@
 	closeMenu();
 	closeOpenDialogs();
 
-	var pauseOverlay = getGUIObjectByName("pauseOverlay");
+	var pauseOverlay = Engine.GetGUIObjectByName("pauseOverlay");
 
 	if (pauseOverlay.hidden)
 	{
-		getGUIObjectByName("pauseButtonText").caption = RESUME;
-		setPaused(true);
+		Engine.GetGUIObjectByName("pauseButtonText").caption = RESUME;
+		Engine.SetPaused(true);
 	}
 	else
 	{
-		setPaused(false);
-		getGUIObjectByName("pauseButtonText").caption = PAUSE;
+		Engine.SetPaused(false);
+		Engine.GetGUIObjectByName("pauseButtonText").caption = PAUSE;
 	}
 
 	pauseOverlay.hidden = !pauseOverlay.hidden;
@@ -569,11 +570,11 @@
 	if (Engine.HasXmppClient() && Engine.IsRankedGame())
 		return;
 
-	var devCommands = getGUIObjectByName("devCommands");
+	var devCommands = Engine.GetGUIObjectByName("devCommands");
 	var text = devCommands.hidden ? "opened." : "closed.";
 	submitChatDirectly("The Developer Overlay was " + text);
 	// Update the options dialog
-	getGUIObjectByName("developerOverlayCheckbox").checked = devCommands.hidden;
+	Engine.GetGUIObjectByName("developerOverlayCheckbox").checked = devCommands.hidden;
 	devCommands.hidden = !devCommands.hidden;
 }
 
Index: binaries/data/mods/public/gui/session/session.xml
===================================================================
--- binaries/data/mods/public/gui/session/session.xml	(Revision 14461)
+++ binaries/data/mods/public/gui/session/session.xml	(Arbeitskopie)
@@ -66,7 +66,7 @@
 	    <action on="Press">
 		var newSetting = !Engine.Renderer_GetSilhouettesEnabled();
 		Engine.Renderer_SetSilhouettesEnabled(newSetting);
-		getGUIObjectByName("silhouettesCheckbox").checked = newSetting;
+		Engine.GetGUIObjectByName("silhouettesCheckbox").checked = newSetting;
 	    </action>
 	</object>
 
@@ -259,7 +259,7 @@
 
 	    <object size="0 16 100%-18 32" type="text" style="devCommandsText">Change perspective</object>
 	    <object size="100%-16 16 100% 32" type="checkbox" style="StoneCrossBox">
-		<action on="Press">getGUIObjectByName("viewPlayer").hidden = !this.checked;</action>
+		<action on="Press">Engine.GetGUIObjectByName("viewPlayer").hidden = !this.checked;</action>
 	    </object>
 
 	    <object size="0 32 100%-18 48" type="text" style="devCommandsText">Display selection state</object>
@@ -679,8 +679,8 @@
 		ALPHA XV : Osiris<!-- IMPORTANT: remember to update pregame/mainmenu.xml in sync with this -->
 
 		<!-- Displays build date and revision number-->
-		<object size="50%-128 0 50%+128 100%-2" name="buildTimeLabel" type="text" style="BuildNameText" ghost="true">
-		    <action on="Load">this.caption = buildTime(0) + " (" + buildTime(2) + ")"</action>
+		<object size="50%-128 0 50%+128 100%-2" name="Engine.BuildTimeLabel" type="text" style="BuildNameText" ghost="true">
+		    <action on="Load">this.caption = Engine.BuildTime(0) + " (" + Engine.BuildTime(2) + ")"</action>
 		</object>
 	    </object>
 
Index: binaries/data/mods/public/gui/session/messages.js
===================================================================
--- binaries/data/mods/public/gui/session/messages.js	(Revision 14461)
+++ binaries/data/mods/public/gui/session/messages.js	(Arbeitskopie)
@@ -136,12 +136,12 @@
 	var messages = [];
 	for each (var n in notifications)
 		messages.push(n.message);
-	getGUIObjectByName("notificationText").caption = messages.join("\n");
+	Engine.GetGUIObjectByName("notificationText").caption = messages.join("\n");
 }
 
 function updateTimeNotifications()
 {
-	getGUIObjectByName("timeNotificationText").caption = Engine.GuiInterfaceCall("GetTimeNotificationText");
+	Engine.GetGUIObjectByName("timeNotificationText").caption = Engine.GuiInterfaceCall("GetTimeNotificationText");
 }
 
 // Returns [username, playercolor] for the given player
@@ -167,7 +167,7 @@
 		if (g_Disconnected)
 			return;
 
-		var obj = getGUIObjectByName("netStatus");
+		var obj = Engine.GetGUIObjectByName("netStatus");
 		switch (message.status)
 		{
 		case "waiting_for_players":
@@ -265,7 +265,7 @@
 
 function submitChatInput()
 {
-	var input = getGUIObjectByName("chatInput");
+	var input = Engine.GetGUIObjectByName("chatInput");
 	var text = input.caption;
 	var isCheat = false;
 	if (text.length)
@@ -305,7 +305,7 @@
 
 		if (!isCheat)
 		{
-			if (getGUIObjectByName("toggleTeamChat").checked)
+			if (Engine.GetGUIObjectByName("toggleTeamChat").checked)
 				text = "/team " + text;
 
 			if (g_IsNetworked)
@@ -443,7 +443,7 @@
 	if (chatMessages.length > MAX_NUM_CHAT_LINES)
 		removeOldChatMessages();
 	else
-		getGUIObjectByName("chatText").caption = chatMessages.join("\n");
+		Engine.GetGUIObjectByName("chatText").caption = chatMessages.join("\n");
 }
 
 function removeOldChatMessages()
@@ -451,7 +451,7 @@
 	clearTimeout(chatTimers[0]); // The timer only needs to be cleared when new messages bump old messages off
 	chatTimers.shift();
 	chatMessages.shift();
-	getGUIObjectByName("chatText").caption = chatMessages.join("\n");
+	Engine.GetGUIObjectByName("chatText").caption = chatMessages.join("\n");
 }
 
 // Parses chat messages for commands.
Index: binaries/data/mods/public/gui/session/session.js
===================================================================
--- binaries/data/mods/public/gui/session/session.js	(Revision 14461)
+++ binaries/data/mods/public/gui/session/session.js	(Arbeitskopie)
@@ -137,7 +137,7 @@
 		if (initData.savedGUIData)
 			restoreSavedGameData(initData.savedGUIData);
 
-		getGUIObjectByName("gameSpeedButton").hidden = g_IsNetworked;
+		Engine.GetGUIObjectByName("gameSpeedButton").hidden = g_IsNetworked;
 	}
 	else // Needed for autostart loading option
 	{
@@ -150,15 +150,15 @@
 
 	g_GameSpeeds = initGameSpeeds();
 	g_CurrentSpeed = Engine.GetSimRate();
-	var gameSpeed = getGUIObjectByName("gameSpeed");
+	var gameSpeed = Engine.GetGUIObjectByName("gameSpeed");
 	gameSpeed.list = g_GameSpeeds.names;
 	gameSpeed.list_data = g_GameSpeeds.speeds;
 	var idx = g_GameSpeeds.speeds.indexOf(g_CurrentSpeed);
 	gameSpeed.selected = idx != -1 ? idx : g_GameSpeeds["default"];
 	gameSpeed.onSelectionChange = function() { changeGameSpeed(+this.list_data[this.selected]); }
 
-	getGUIObjectByName("civIcon").sprite = "stretched:" + g_CivData[g_Players[Engine.GetPlayerID()].civ].Emblem;
-	getGUIObjectByName("civIcon").tooltip = g_CivData[g_Players[Engine.GetPlayerID()].civ].Name;
+	Engine.GetGUIObjectByName("civIcon").sprite = "stretched:" + g_CivData[g_Players[Engine.GetPlayerID()].civ].Emblem;
+	Engine.GetGUIObjectByName("civIcon").tooltip = g_CivData[g_Players[Engine.GetPlayerID()].civ].Name;
 	initMenuPosition(); // set initial position
 
 	// Populate player selection dropdown
@@ -170,14 +170,14 @@
 		playerIDs.push(player);
 	}
 
-	var viewPlayerDropdown = getGUIObjectByName("viewPlayer");
+	var viewPlayerDropdown = Engine.GetGUIObjectByName("viewPlayer");
 	viewPlayerDropdown.list = playerNames;
 	viewPlayerDropdown.list_data = playerIDs;
 	viewPlayerDropdown.selected = Engine.GetPlayerID();
 
 	// If in Atlas editor, disable the exit button
 	if (Engine.IsAtlasRunning())
-		getGUIObjectByName("menuExitButton").enabled = false;
+		Engine.GetGUIObjectByName("menuExitButton").enabled = false;
 
 	if (hotloadData)
 	{
@@ -194,7 +194,7 @@
 	}
 
 	if (Engine.ConfigDB_GetValue("user", "gui.session.timeelapsedcounter") === "true")
-		getGUIObjectByName("timeElapsedCounter").hidden = false;
+		Engine.GetGUIObjectByName("timeElapsedCounter").hidden = false;
 
 	onSimulationUpdate();
 
@@ -210,8 +210,8 @@
 {
 	Engine.SetPlayerID(playerID);
 	if (playerID != 0) {
-		getGUIObjectByName("civIcon").sprite = "stretched:" + g_CivData[g_Players[playerID].civ].Emblem;
-		getGUIObjectByName("civIcon").tooltip = g_CivData[g_Players[playerID].civ].Name;
+		Engine.GetGUIObjectByName("civIcon").sprite = "stretched:" + g_CivData[g_Players[playerID].civ].Emblem;
+		Engine.GetGUIObjectByName("civIcon").tooltip = g_CivData[g_Players[playerID].civ].Name;
 	}
 }
 
@@ -280,7 +280,7 @@
 	}
 
 	stopAmbient();
-	endGame();
+	Engine.EndGame();
 
 	if (g_IsController && Engine.HasXmppClient())
 		Engine.SendUnregisterGame();
@@ -367,9 +367,9 @@
 
 	// When training is blocked, flash population (alternates colour every 500msec)
 	if (g_IsTrainingBlocked && (Date.now() % 1000) < 500)
-		getGUIObjectByName("resourcePop").textcolor = POPULATION_ALERT_COLOR;
+		Engine.GetGUIObjectByName("resourcePop").textcolor = POPULATION_ALERT_COLOR;
 	else
-		getGUIObjectByName("resourcePop").textcolor = DEFAULT_POPULATION_COLOR;
+		Engine.GetGUIObjectByName("resourcePop").textcolor = DEFAULT_POPULATION_COLOR;
 
 	// Clear renamed entities list
 	Engine.GuiInterfaceCall("ClearRenamedEntities");
@@ -398,7 +398,7 @@
 		return;
 
 	// We can't resign once the game is over.
-	getGUIObjectByName("menuResignButton").enabled = false;
+	Engine.GetGUIObjectByName("menuResignButton").enabled = false;
 
 	// Make sure nothing is open to avoid stacking.
 	closeMenu();
@@ -430,8 +430,8 @@
 	{
 		global.music.setState(global.music.states.VICTORY);
 		// TODO: Reveal map directly instead of this silly proxy.
-		if (!getGUIObjectByName("devCommandsRevealMap").checked)
-			getGUIObjectByName("devCommandsRevealMap").checked = true;
+		if (!Engine.GetGUIObjectByName("devCommandsRevealMap").checked)
+			Engine.GetGUIObjectByName("devCommandsRevealMap").checked = true;
 		messageBox(400, 200, message, "VICTORIOUS!", 0, btCaptions, btCode);
 	}
 
@@ -491,7 +491,7 @@
 {
 	var simState = GetSimState();
 	var playerState = simState.players[Engine.GetPlayerID()];
-	var heroButton = getGUIObjectByName("unitHeroButton");
+	var heroButton = Engine.GetGUIObjectByName("unitHeroButton");
 
 	if (!playerState || playerState.heroes.length <= 0)
 	{
@@ -499,7 +499,7 @@
 		return;
 	}
 
-	var heroImage = getGUIObjectByName("unitHeroImage");
+	var heroImage = Engine.GetGUIObjectByName("unitHeroImage");
 	var heroState = GetExtendedEntityState(playerState.heroes[0]);
 	var template = GetTemplateData(heroState.template);
 	heroImage.sprite = "stretched:session/portraits/" + template.icon;
@@ -535,8 +535,8 @@
 	g_Groups.update();
 	for (var i = 0; i < 10; i++)
 	{
-		var button = getGUIObjectByName("unit"+guiName+"Button["+i+"]");
-		var label = getGUIObjectByName("unit"+guiName+"Label["+i+"]").caption = i;
+		var button = Engine.GetGUIObjectByName("unit"+guiName+"Button["+i+"]");
+		var label = Engine.GetGUIObjectByName("unit"+guiName+"Label["+i+"]").caption = i;
 		if (g_Groups.groups[i].getTotalCount() == 0)
 			button.hidden = true;
 		else
@@ -547,7 +547,7 @@
 	var numButtons = i;
 	var rowLength = 1;
 	var numRows = Math.ceil(numButtons / rowLength);
-	var buttonSideLength = getGUIObjectByName("unit"+guiName+"Button[0]").size.bottom;
+	var buttonSideLength = Engine.GetGUIObjectByName("unit"+guiName+"Button[0]").size.bottom;
 	var buttonSpacer = buttonSideLength+1;
 	for (var i = 0; i < numRows; i++)
 		layoutButtonRow(i, guiName, buttonSideLength, buttonSpacer, rowLength*i, rowLength*(i+1) );
@@ -556,9 +556,9 @@
 function updateDebug()
 {
 	var simState = GetSimState();
-	var debug = getGUIObjectByName("debug");
+	var debug = Engine.GetGUIObjectByName("debug");
 
-	if (getGUIObjectByName("devDisplayState").checked)
+	if (Engine.GetGUIObjectByName("devDisplayState").checked)
 	{
 		debug.hidden = false;
 	}
@@ -596,11 +596,11 @@
 	if (!playerState)
 		return;
 
-	getGUIObjectByName("resourceFood").caption = playerState.resourceCounts.food;
-	getGUIObjectByName("resourceWood").caption = playerState.resourceCounts.wood;
-	getGUIObjectByName("resourceStone").caption = playerState.resourceCounts.stone;
-	getGUIObjectByName("resourceMetal").caption = playerState.resourceCounts.metal;
-	getGUIObjectByName("resourcePop").caption = playerState.popCount + "/" + playerState.popLimit;
+	Engine.GetGUIObjectByName("resourceFood").caption = playerState.resourceCounts.food;
+	Engine.GetGUIObjectByName("resourceWood").caption = playerState.resourceCounts.wood;
+	Engine.GetGUIObjectByName("resourceStone").caption = playerState.resourceCounts.stone;
+	Engine.GetGUIObjectByName("resourceMetal").caption = playerState.resourceCounts.metal;
+	Engine.GetGUIObjectByName("resourcePop").caption = playerState.popCount + "/" + playerState.popLimit;
 
 	g_IsTrainingBlocked = playerState.trainingBlocked;
 }
@@ -625,10 +625,10 @@
 		return;
 
 	// Set up initial positioning.
-	var buttonSideLength = getGUIObjectByName("researchStartedButton[0]").size.right;
+	var buttonSideLength = Engine.GetGUIObjectByName("researchStartedButton[0]").size.right;
 	for (var i = 0; i < 10; ++i)
 	{
-		var button = getGUIObjectByName("researchStartedButton[" + i + "]");
+		var button = Engine.GetGUIObjectByName("researchStartedButton[" + i + "]");
 		var size = button.size;
 		size.top = (4 + buttonSideLength) * i;
 		size.bottom = size.top + buttonSideLength;
@@ -643,34 +643,34 @@
 			break;
 
 		var template = GetTechnologyData(tech);
-		var button = getGUIObjectByName("researchStartedButton[" + numButtons + "]");
+		var button = Engine.GetGUIObjectByName("researchStartedButton[" + numButtons + "]");
 		button.hidden = false;
 		button.tooltip = getEntityNames(template);
 		button.onpress = (function(e) { return function() { selectAndMoveTo(e) } })(researchStarted[tech].researcher);
 
 		var icon = "stretched:session/portraits/" + template.icon;
-		getGUIObjectByName("researchStartedIcon[" + numButtons + "]").sprite = icon;
+		Engine.GetGUIObjectByName("researchStartedIcon[" + numButtons + "]").sprite = icon;
 
 		// Scale the progress indicator.
-		var size = getGUIObjectByName("researchStartedProgressSlider[" + numButtons + "]").size;
+		var size = Engine.GetGUIObjectByName("researchStartedProgressSlider[" + numButtons + "]").size;
 
 		// Buttons are assumed to be square, so left/right offsets can be used for top/bottom.
 		size.top = size.left + Math.round(researchStarted[tech].progress * (size.right - size.left));
-		getGUIObjectByName("researchStartedProgressSlider[" + numButtons + "]").size = size;
+		Engine.GetGUIObjectByName("researchStartedProgressSlider[" + numButtons + "]").size = size;
 
 		++numButtons;
 	}
 
 	// Hide unused buttons.
 	for (var i = numButtons; i < 10; ++i)
-		getGUIObjectByName("researchStartedButton[" + i + "]").hidden = true;
+		Engine.GetGUIObjectByName("researchStartedButton[" + i + "]").hidden = true;
 }
 
 function updateTimeElapsedCounter()
 {
 	var simState = GetSimState();
 	var speed = g_CurrentSpeed != 1.0 ? " (" + g_CurrentSpeed + "x)" : "";
-	var timeElapsedCounter = getGUIObjectByName("timeElapsedCounter");
+	var timeElapsedCounter = Engine.GetGUIObjectByName("timeElapsedCounter");
 	timeElapsedCounter.caption = timeToString(simState.timeElapsed) + speed;
 }
 
Index: binaries/data/mods/public/gui/session/selection_details.js
===================================================================
--- binaries/data/mods/public/gui/session/selection_details.js	(Revision 14461)
+++ binaries/data/mods/public/gui/session/selection_details.js	(Arbeitskopie)
@@ -1,13 +1,13 @@
 function layoutSelectionSingle()
 {
-	getGUIObjectByName("detailsAreaSingle").hidden = false;
-	getGUIObjectByName("detailsAreaMultiple").hidden = true;
+	Engine.GetGUIObjectByName("detailsAreaSingle").hidden = false;
+	Engine.GetGUIObjectByName("detailsAreaMultiple").hidden = true;
 }
 
 function layoutSelectionMultiple()
 {
-	getGUIObjectByName("detailsAreaMultiple").hidden = false;
-	getGUIObjectByName("detailsAreaSingle").hidden = true;
+	Engine.GetGUIObjectByName("detailsAreaMultiple").hidden = false;
+	Engine.GetGUIObjectByName("detailsAreaSingle").hidden = true;
 }
 
 // Fills out information that most entities have
@@ -36,48 +36,48 @@
 	// Rank
 	if (entState.identity && entState.identity.rank && entState.identity.classes)
 	{
-		getGUIObjectByName("rankIcon").tooltip = entState.identity.rank + " Rank";
-		getGUIObjectByName("rankIcon").sprite = getRankIconSprite(entState);					
-		getGUIObjectByName("rankIcon").hidden = false;
+		Engine.GetGUIObjectByName("rankIcon").tooltip = entState.identity.rank + " Rank";
+		Engine.GetGUIObjectByName("rankIcon").sprite = getRankIconSprite(entState);					
+		Engine.GetGUIObjectByName("rankIcon").hidden = false;
 	}
 	else
 	{
-		getGUIObjectByName("rankIcon").hidden = true;
-		getGUIObjectByName("rankIcon").tooltip = "";
+		Engine.GetGUIObjectByName("rankIcon").hidden = true;
+		Engine.GetGUIObjectByName("rankIcon").tooltip = "";
 	}
 								
 	// Hitpoints
 	if (entState.hitpoints)
 	{
-		var unitHealthBar = getGUIObjectByName("healthBar");
+		var unitHealthBar = Engine.GetGUIObjectByName("healthBar");
 		var healthSize = unitHealthBar.size;
 		healthSize.rright = 100*Math.max(0, Math.min(1, entState.hitpoints / entState.maxHitpoints));
 		unitHealthBar.size = healthSize;
 
 		var hitpoints = Math.ceil(entState.hitpoints) + " / " + entState.maxHitpoints;
-		getGUIObjectByName("healthStats").caption = hitpoints;
-		getGUIObjectByName("healthSection").hidden = false;
+		Engine.GetGUIObjectByName("healthStats").caption = hitpoints;
+		Engine.GetGUIObjectByName("healthSection").hidden = false;
 	}
 	else
 	{
-		getGUIObjectByName("healthSection").hidden = true;
+		Engine.GetGUIObjectByName("healthSection").hidden = true;
 	}
 	
 	// TODO: Stamina
 	var player = Engine.GetPlayerID();
 	if (entState.stamina && (entState.player == player || g_DevSettings.controlAll))
 	{
-		getGUIObjectByName("staminaSection").hidden = false;
+		Engine.GetGUIObjectByName("staminaSection").hidden = false;
 	}
 	else
 	{
-		getGUIObjectByName("staminaSection").hidden = true;
+		Engine.GetGUIObjectByName("staminaSection").hidden = true;
 	}
 
 	// Experience
 	if (entState.promotion)
 	{
-		var experienceBar = getGUIObjectByName("experienceBar");
+		var experienceBar = Engine.GetGUIObjectByName("experienceBar");
 		var experienceSize = experienceBar.size;
 		experienceSize.rtop = 100 - (100 * Math.max(0, Math.min(1, 1.0 * +entState.promotion.curr / +entState.promotion.req)));
 		experienceBar.size = experienceSize;
@@ -85,12 +85,12 @@
 		var experience = "[font=\"serif-bold-13\"]Experience: [/font]" + Math.floor(entState.promotion.curr);
 		if (entState.promotion.curr < entState.promotion.req)
 			experience += " / " + entState.promotion.req;
-		getGUIObjectByName("experience").tooltip = experience;
-		getGUIObjectByName("experience").hidden = false;
+		Engine.GetGUIObjectByName("experience").tooltip = experience;
+		Engine.GetGUIObjectByName("experience").hidden = false;
 	}
 	else
 	{
-		getGUIObjectByName("experience").hidden = true;
+		Engine.GetGUIObjectByName("experience").hidden = true;
 	}
 
 	// Resource stats
@@ -102,25 +102,25 @@
 		if (resourceType == "treasure")
 			resourceType = entState.resourceSupply.type["specific"];
 
-		var unitResourceBar = getGUIObjectByName("resourceBar");
+		var unitResourceBar = Engine.GetGUIObjectByName("resourceBar");
 		var resourceSize = unitResourceBar.size;
 
 		resourceSize.rright = entState.resourceSupply.isInfinite ? 100 :
 						100 * Math.max(0, Math.min(1, +entState.resourceSupply.amount / +entState.resourceSupply.max));
 		unitResourceBar.size = resourceSize;
-		getGUIObjectByName("resourceLabel").caption = toTitleCase(resourceType) + ":";
-		getGUIObjectByName("resourceStats").caption = resources;
+		Engine.GetGUIObjectByName("resourceLabel").caption = toTitleCase(resourceType) + ":";
+		Engine.GetGUIObjectByName("resourceStats").caption = resources;
 
 		if (entState.hitpoints)
-			getGUIObjectByName("resourceSection").size = getGUIObjectByName("staminaSection").size;
+			Engine.GetGUIObjectByName("resourceSection").size = Engine.GetGUIObjectByName("staminaSection").size;
 		else
-			getGUIObjectByName("resourceSection").size = getGUIObjectByName("healthSection").size;
+			Engine.GetGUIObjectByName("resourceSection").size = Engine.GetGUIObjectByName("healthSection").size;
 
-		getGUIObjectByName("resourceSection").hidden = false;
+		Engine.GetGUIObjectByName("resourceSection").hidden = false;
 	}
 	else
 	{
-		getGUIObjectByName("resourceSection").hidden = true;
+		Engine.GetGUIObjectByName("resourceSection").hidden = true;
 	}
 
 	// Resource carrying
@@ -129,84 +129,84 @@
 		// We should only be carrying one resource type at once, so just display the first
 		var carried = entState.resourceCarrying[0];
 
-		getGUIObjectByName("resourceCarryingIcon").hidden = false;
-		getGUIObjectByName("resourceCarryingText").hidden = false;
-		getGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/resources/"+carried.type+".png";
-		getGUIObjectByName("resourceCarryingText").caption = carried.amount + " / " + carried.max;
-		getGUIObjectByName("resourceCarryingIcon").tooltip = "";
+		Engine.GetGUIObjectByName("resourceCarryingIcon").hidden = false;
+		Engine.GetGUIObjectByName("resourceCarryingText").hidden = false;
+		Engine.GetGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/resources/"+carried.type+".png";
+		Engine.GetGUIObjectByName("resourceCarryingText").caption = carried.amount + " / " + carried.max;
+		Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = "";
 	}
 	// Use the same indicators for traders
 	else if (entState.trader && entState.trader.goods.amount)
 	{
-		getGUIObjectByName("resourceCarryingIcon").hidden = false;
-		getGUIObjectByName("resourceCarryingText").hidden = false;
-		getGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/resources/"+entState.trader.goods.type+".png";
+		Engine.GetGUIObjectByName("resourceCarryingIcon").hidden = false;
+		Engine.GetGUIObjectByName("resourceCarryingText").hidden = false;
+		Engine.GetGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/resources/"+entState.trader.goods.type+".png";
 		var totalGain = entState.trader.goods.amount.traderGain;
 		if (entState.trader.goods.amount.market1Gain)
 			totalGain += entState.trader.goods.amount.market1Gain;
 		if (entState.trader.goods.amount.market2Gain)
 			totalGain += entState.trader.goods.amount.market2Gain;
-		getGUIObjectByName("resourceCarryingText").caption = totalGain;
-		getGUIObjectByName("resourceCarryingIcon").tooltip = "Gain: " + getTradingTooltip(entState.trader.goods.amount);
+		Engine.GetGUIObjectByName("resourceCarryingText").caption = totalGain;
+		Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = "Gain: " + getTradingTooltip(entState.trader.goods.amount);
 	}
 	// And for number of workers
 	else if (entState.foundation)
 	{
-		getGUIObjectByName("resourceCarryingIcon").hidden = false;
-		getGUIObjectByName("resourceCarryingText").hidden = false;
-		getGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/repair.png";
-		getGUIObjectByName("resourceCarryingText").caption = entState.foundation.numBuilders + "    ";
-		getGUIObjectByName("resourceCarryingIcon").tooltip = "Number of builders";
+		Engine.GetGUIObjectByName("resourceCarryingIcon").hidden = false;
+		Engine.GetGUIObjectByName("resourceCarryingText").hidden = false;
+		Engine.GetGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/repair.png";
+		Engine.GetGUIObjectByName("resourceCarryingText").caption = entState.foundation.numBuilders + "    ";
+		Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = "Number of builders";
 	}
 	else if (entState.resourceSupply && (!entState.resourceSupply.killBeforeGather || !entState.hitpoints))
 	{
-		getGUIObjectByName("resourceCarryingIcon").hidden = false;
-		getGUIObjectByName("resourceCarryingText").hidden = false;
-		getGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/repair.png";
-		getGUIObjectByName("resourceCarryingText").caption = entState.resourceSupply.gatherers.length + " / " + entState.resourceSupply.maxGatherers + "    ";
-		getGUIObjectByName("resourceCarryingIcon").tooltip = "Current/max gatherers";
+		Engine.GetGUIObjectByName("resourceCarryingIcon").hidden = false;
+		Engine.GetGUIObjectByName("resourceCarryingText").hidden = false;
+		Engine.GetGUIObjectByName("resourceCarryingIcon").sprite = "stretched:session/icons/repair.png";
+		Engine.GetGUIObjectByName("resourceCarryingText").caption = entState.resourceSupply.gatherers.length + " / " + entState.resourceSupply.maxGatherers + "    ";
+		Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = "Current/max gatherers";
 	}
 	else
 	{
-		getGUIObjectByName("resourceCarryingIcon").hidden = true;
-		getGUIObjectByName("resourceCarryingText").hidden = true;
+		Engine.GetGUIObjectByName("resourceCarryingIcon").hidden = true;
+		Engine.GetGUIObjectByName("resourceCarryingText").hidden = true;
 	}
 
 	// Set Player details
-	getGUIObjectByName("specific").caption = specificName;
-	getGUIObjectByName("player").caption = playerName;
-	getGUIObjectByName("playerColorBackground").sprite = "colour: " + playerColor;
+	Engine.GetGUIObjectByName("specific").caption = specificName;
+	Engine.GetGUIObjectByName("player").caption = playerName;
+	Engine.GetGUIObjectByName("playerColorBackground").sprite = "colour: " + playerColor;
 	
 	if (genericName)
 	{
-		getGUIObjectByName("generic").caption = "(" + genericName + ")";
+		Engine.GetGUIObjectByName("generic").caption = "(" + genericName + ")";
 	}
 	else
 	{
-		getGUIObjectByName("generic").caption = "";
+		Engine.GetGUIObjectByName("generic").caption = "";
 
 	}
 
 	if ("Gaia" != civName)
 	{
-		getGUIObjectByName("playerCivIcon").sprite = "stretched:grayscale:" + civEmblem;
-		getGUIObjectByName("player").tooltip = civName;
+		Engine.GetGUIObjectByName("playerCivIcon").sprite = "stretched:grayscale:" + civEmblem;
+		Engine.GetGUIObjectByName("player").tooltip = civName;
 	}
 	else
 	{
-		getGUIObjectByName("playerCivIcon").sprite = "";
-		getGUIObjectByName("player").tooltip = "";
+		Engine.GetGUIObjectByName("playerCivIcon").sprite = "";
+		Engine.GetGUIObjectByName("player").tooltip = "";
 	}
 
 	// Icon image
 	if (template.icon)
 	{
-		getGUIObjectByName("icon").sprite = "stretched:session/portraits/" + template.icon;
+		Engine.GetGUIObjectByName("icon").sprite = "stretched:session/portraits/" + template.icon;
 	}
 	else
 	{
 		// TODO: we should require all entities to have icons, so this case never occurs
-		getGUIObjectByName("icon").sprite = "bkFillBlack";
+		Engine.GetGUIObjectByName("icon").sprite = "bkFillBlack";
 	}
 
 	// Attack and Armor
@@ -236,7 +236,7 @@
 		}
 	}
 	
-	getGUIObjectByName("attackAndArmorStats").tooltip = attack + "\n[font=\"serif-bold-13\"]Armor:[/font] " + armorTypeDetails(entState.armour);
+	Engine.GetGUIObjectByName("attackAndArmorStats").tooltip = attack + "\n[font=\"serif-bold-13\"]Armor:[/font] " + armorTypeDetails(entState.armour);
 
 	// Icon Tooltip
 	var iconTooltip = "";
@@ -247,11 +247,11 @@
 	if (template.tooltip)
 		iconTooltip += "\n[font=\"serif-13\"]" + template.tooltip + "[/font]";
 
-	getGUIObjectByName("iconBorder").tooltip = iconTooltip;
+	Engine.GetGUIObjectByName("iconBorder").tooltip = iconTooltip;
 
 	// Unhide Details Area
-	getGUIObjectByName("detailsAreaSingle").hidden = false;
-	getGUIObjectByName("detailsAreaMultiple").hidden = true;
+	Engine.GetGUIObjectByName("detailsAreaSingle").hidden = false;
+	Engine.GetGUIObjectByName("detailsAreaMultiple").hidden = true;
 }
 
 // Fills out information for multiple entities
@@ -275,45 +275,45 @@
 
 	if (averageHealth > 0)
 	{
-		var unitHealthBar = getGUIObjectByName("healthBarMultiple");
+		var unitHealthBar = Engine.GetGUIObjectByName("healthBarMultiple");
 		var healthSize = unitHealthBar.size;	
 		healthSize.rtop = 100-100*Math.max(0, Math.min(1, averageHealth / maxHealth));
 		unitHealthBar.size = healthSize;
 
 		var hitpoints = "[font=\"serif-bold-13\"]Hitpoints [/font]" + averageHealth + " / " + maxHealth;
-		var healthMultiple = getGUIObjectByName("healthMultiple");
+		var healthMultiple = Engine.GetGUIObjectByName("healthMultiple");
 		healthMultiple.tooltip = hitpoints;
 		healthMultiple.hidden = false;
 	}
 	else
 	{
-		getGUIObjectByName("healthMultiple").hidden = true;
+		Engine.GetGUIObjectByName("healthMultiple").hidden = true;
 	}
 	
 	// TODO: Stamina
-	// getGUIObjectByName("staminaBarMultiple");
+	// Engine.GetGUIObjectByName("staminaBarMultiple");
 
-	getGUIObjectByName("numberOfUnits").caption = selection.length;
+	Engine.GetGUIObjectByName("numberOfUnits").caption = selection.length;
 
 	// Unhide Details Area
-	getGUIObjectByName("detailsAreaMultiple").hidden = false;
-	getGUIObjectByName("detailsAreaSingle").hidden = true;
+	Engine.GetGUIObjectByName("detailsAreaMultiple").hidden = false;
+	Engine.GetGUIObjectByName("detailsAreaSingle").hidden = true;
 }
 
 // Updates middle entity Selection Details Panel
 function updateSelectionDetails()
 {
-	var supplementalDetailsPanel = getGUIObjectByName("supplementalSelectionDetails");
-	var detailsPanel = getGUIObjectByName("selectionDetails");
-	var commandsPanel = getGUIObjectByName("unitCommands");
+	var supplementalDetailsPanel = Engine.GetGUIObjectByName("supplementalSelectionDetails");
+	var detailsPanel = Engine.GetGUIObjectByName("selectionDetails");
+	var commandsPanel = Engine.GetGUIObjectByName("unitCommands");
 
 	g_Selection.update();
 	var selection = g_Selection.toList();
 	
 	if (selection.length == 0)
 	{
-		getGUIObjectByName("detailsAreaMultiple").hidden = true;
-		getGUIObjectByName("detailsAreaSingle").hidden = true;
+		Engine.GetGUIObjectByName("detailsAreaMultiple").hidden = true;
+		Engine.GetGUIObjectByName("detailsAreaSingle").hidden = true;
 		hideUnitCommands();
 	
 		supplementalDetailsPanel.hidden = true;
Index: binaries/data/mods/public/gui/splashscreen/splashscreen.js
===================================================================
--- binaries/data/mods/public/gui/splashscreen/splashscreen.js	(Revision 14461)
+++ binaries/data/mods/public/gui/splashscreen/splashscreen.js	(Arbeitskopie)
@@ -1,4 +1,6 @@
 function init(data)
 {
-	getGUIObjectByName("mainText").caption = readFile("gui/splashscreen/" + data.page + ".txt");
+	Engine.GetGUIObjectByName("mainText").caption = Engine.ReadFile("gui/splashscreen/" + data.page + ".txt");
+
 }
+
Index: binaries/data/mods/public/gui/splashscreen/splashscreen.xml
===================================================================
--- binaries/data/mods/public/gui/splashscreen/splashscreen.xml	(Revision 14461)
+++ binaries/data/mods/public/gui/splashscreen/splashscreen.xml	(Arbeitskopie)
@@ -22,9 +22,9 @@
 		<object name="btnOK" type="button" style="StoneButton" tooltip_style="snToolTip" size="24 100%-52 188 100%-24">
 			OK
 			<action on="Press"><![CDATA[
-			Engine.ConfigDB_CreateValue("user", "splashscreenenable", getGUIObjectByName("displaySplashScreen").checked ? "true" : "false");
+			Engine.ConfigDB_CreateValue("user", "splashscreenenable", Engine.GetGUIObjectByName("displaySplashScreen").checked ? "true" : "false");
 			Engine.ConfigDB_WriteFile("user", "config/user.cfg");
-			Engine.PopGuiPage();
+			Engine.PopGuiPage(0);
 			]]></action>
 		</object>
 		<object type="button" style="StoneButton" size="192 100%-52 356 100%-24">
Index: binaries/data/mods/public/gui/options/options.xml
===================================================================
--- binaries/data/mods/public/gui/options/options.xml	(Revision 14461)
+++ binaries/data/mods/public/gui/options/options.xml	(Arbeitskopie)
@@ -49,14 +49,14 @@
                 <action on="Load">this.caption = Engine.ConfigDB_GetValue("user", "sound.mastergain");</action>
             </object>
             <object size="70%+35 25 70%+75 50" type="button" style="StoneButton">Save
-                <action on="Press">Engine.ConfigDB_CreateValue("user", "sound.mastergain", String(getGUIObjectByName("SMasterCFG").caption));</action>
+                <action on="Press">Engine.ConfigDB_CreateValue("user", "sound.mastergain", String(Engine.GetGUIObjectByName("SMasterCFG").caption));</action>
             </object>
             <object size="0 50 65% 75" type="text" style="RightLabelText" ghost="true">Music Gain</object>
             <object name="SMusicCFG" size="70% 50 70%+35 75" type="input" style="StoneInput">
                 <action on="Load">this.caption = Engine.ConfigDB_GetValue("user", "sound.musicgain");</action>
             </object>
             <object size="70%+35 50 70%+75 75" type="button" style="StoneButton">Save
-                <action on="Press">Engine.ConfigDB_CreateValue("user", "sound.musicgain", String(getGUIObjectByName("SMusicCFG").caption));</action>
+                <action on="Press">Engine.ConfigDB_CreateValue("user", "sound.musicgain", String(Engine.GetGUIObjectByName("SMusicCFG").caption));</action>
             </object>
         </object>
 <!--
Index: binaries/data/mods/public/gui/lobby/lobby.js
===================================================================
--- binaries/data/mods/public/gui/lobby/lobby.js	(Revision 14461)
+++ binaries/data/mods/public/gui/lobby/lobby.js	(Arbeitskopie)
@@ -21,15 +21,15 @@
 	g_mapSizes.shortNames.splice(0, 0, "Any");
 	g_mapSizes.tiles.splice(0, 0, "");
 
-	var mapSizeFilter = getGUIObjectByName("mapSizeFilter");
+	var mapSizeFilter = Engine.GetGUIObjectByName("mapSizeFilter");
 	mapSizeFilter.list = g_mapSizes.shortNames;
 	mapSizeFilter.list_data = g_mapSizes.tiles;
 
-	var playersNumberFilter = getGUIObjectByName("playersNumberFilter");
+	var playersNumberFilter = Engine.GetGUIObjectByName("playersNumberFilter");
 	playersNumberFilter.list = ["Any",2,3,4,5,6,7,8];
 	playersNumberFilter.list_data = ["",2,3,4,5,6,7,8];
 
-	var mapTypeFilter = getGUIObjectByName("mapTypeFilter");
+	var mapTypeFilter = Engine.GetGUIObjectByName("mapTypeFilter");
 	mapTypeFilter.list = ["Any", "Skirmish", "Random", "Scenario"];
 	mapTypeFilter.list_data = ["", "skirmish", "random", "scenario"];
 
@@ -70,16 +70,16 @@
 function resetFilters()
 {
 	// Reset states of gui objects
-	getGUIObjectByName("mapSizeFilter").selected = 0
-	getGUIObjectByName("playersNumberFilter").selected = 0;
-	getGUIObjectByName("mapTypeFilter").selected = 0;
-	getGUIObjectByName("showFullFilter").checked = true;
+	Engine.GetGUIObjectByName("mapSizeFilter").selected = 0
+	Engine.GetGUIObjectByName("playersNumberFilter").selected = 0;
+	Engine.GetGUIObjectByName("mapTypeFilter").selected = 0;
+	Engine.GetGUIObjectByName("showFullFilter").checked = true;
 
 	// Update the list of games
 	updateGameList();
 
 	// Update info box about the game currently selected
-	selectGame(getGUIObjectByName("gamesBox").selected);
+	selectGame(Engine.GetGUIObjectByName("gamesBox").selected);
 }
 
 function applyFilters()
@@ -88,7 +88,7 @@
 	updateGameList();
 
 	// Update info box about the game currently selected
-	selectGame(getGUIObjectByName("gamesBox").selected);
+	selectGame(Engine.GetGUIObjectByName("gamesBox").selected);
 }
 
 function displayGame(g, mapSizeFilter, playersNumberFilter, mapTypeFilter, showFullFilter)
@@ -108,7 +108,7 @@
 // Do a full update of the player listing **Only call on init**
 function updatePlayerList()
 {
-	var playersBox = getGUIObjectByName("playersBox");
+	var playersBox = Engine.GetGUIObjectByName("playersBox");
 	[playerList, presenceList, nickList] = [[],[],[]];
 	for each (var p in Engine.GetPlayerList())
 	{
@@ -131,7 +131,7 @@
 	// Get list from C++
 	var boardList = Engine.GetBoardList();
 	// Get GUI leaderboard object
-	var leaderboard = getGUIObjectByName("leaderboardBox");
+	var leaderboard = Engine.GetGUIObjectByName("leaderboardBox");
 	// Sort list in acending order by rating
 	boardList.sort(function(a, b) b.rating - a.rating);
 
@@ -161,7 +161,7 @@
 // Update game listing
 function updateGameList()
 {
-	var gamesBox = getGUIObjectByName("gamesBox");
+	var gamesBox = Engine.GetGUIObjectByName("gamesBox");
 	var gameList = Engine.GetGameList();
 	// Store the game whole game list data so that we can access it later
 	// to update the game info panel.
@@ -181,10 +181,10 @@
 	var list = [];
 	var list_data = [];
 
-	var mapSizeFilterDD = getGUIObjectByName("mapSizeFilter");
-	var playersNumberFilterDD = getGUIObjectByName("playersNumberFilter");
-	var mapTypeFilterDD = getGUIObjectByName("mapTypeFilter");
-	var showFullFilterCB = getGUIObjectByName("showFullFilter");
+	var mapSizeFilterDD = Engine.GetGUIObjectByName("mapSizeFilter");
+	var playersNumberFilterDD = Engine.GetGUIObjectByName("playersNumberFilter");
+	var mapTypeFilterDD = Engine.GetGUIObjectByName("mapTypeFilter");
+	var showFullFilterCB = Engine.GetGUIObjectByName("showFullFilter");
 
 	// Get filter values
 	var mapSizeFilter = mapSizeFilterDD.selected >= 0 ? mapSizeFilterDD.list_data[mapSizeFilterDD.selected] : "";
@@ -224,8 +224,8 @@
 		gamesBox.selected = -1;
 
 	// If game selected, update info box about the game.
-	if(getGUIObjectByName("gamesBox").selected != -1)
-		selectGame(getGUIObjectByName("gamesBox").selected)
+	if(Engine.GetGUIObjectByName("gamesBox").selected != -1)
+		selectGame(Engine.GetGUIObjectByName("gamesBox").selected)
 }
 
 // The following function colorizes and formats the entries in the player list.
@@ -267,37 +267,37 @@
 	if (selected == -1)
 	{
 		// Hide the game info panel if a game is not selected
-		getGUIObjectByName("gameInfo").hidden = true;
-		getGUIObjectByName("gameInfoEmpty").hidden = false;
-		getGUIObjectByName("joinGameButton").hidden = true;
+		Engine.GetGUIObjectByName("gameInfo").hidden = true;
+		Engine.GetGUIObjectByName("gameInfoEmpty").hidden = false;
+		Engine.GetGUIObjectByName("joinGameButton").hidden = true;
 		return;
 	}
 
 	var mapData;
-	var g = getGUIObjectByName("gamesBox").list_data[selected];
+	var g = Engine.GetGUIObjectByName("gamesBox").list_data[selected];
 
 	// Load map data
 	if (g_GameList[g].mapType == "random" && g_GameList[g].mapName == "random")
 		mapData = {"settings": {"Description": "A randomly selected map."}};
-	else if (g_GameList[g].mapType == "random" && fileExists(g_GameList[g].mapName + ".json"))
+	else if (g_GameList[g].mapType == "random" && Engine.FileExists(g_GameList[g].mapName + ".json"))
 		mapData = parseJSONData(g_GameList[g].mapName + ".json");
-	else if (fileExists(g_GameList[g].mapName + ".xml"))
+	else if (Engine.FileExists(g_GameList[g].mapName + ".xml"))
 		mapData = Engine.LoadMapSettings(g_GameList[g].mapName + ".xml");
 	else
 		// Warn the player if we can't find the map. 
 		warn("Map '"+ g_GameList[g].mapName +"'  not found");
 
 	// Show the game info paneland join button.
-	getGUIObjectByName("gameInfo").hidden = false;
-	getGUIObjectByName("gameInfoEmpty").hidden = true;
-	getGUIObjectByName("joinGameButton").hidden = false;
+	Engine.GetGUIObjectByName("gameInfo").hidden = false;
+	Engine.GetGUIObjectByName("gameInfoEmpty").hidden = true;
+	Engine.GetGUIObjectByName("joinGameButton").hidden = false;
 
 	// Display the map name, number of players, the names of the players, the map size and the map type.
-	getGUIObjectByName("sgMapName").caption = g_GameList[g].niceMapName;
-	getGUIObjectByName("sgNbPlayers").caption = g_GameList[g].nbp + "/" + g_GameList[g].tnbp;
-	getGUIObjectByName("sgPlayersNames").caption = g_GameList[g].players;
-	getGUIObjectByName("sgMapSize").caption = g_GameList[g].mapSize.split("(")[0];
-	getGUIObjectByName("sgMapType").caption = toTitleCase(g_GameList[g].mapType);
+	Engine.GetGUIObjectByName("sgMapName").caption = g_GameList[g].niceMapName;
+	Engine.GetGUIObjectByName("sgNbPlayers").caption = g_GameList[g].nbp + "/" + g_GameList[g].tnbp;
+	Engine.GetGUIObjectByName("sgPlayersNames").caption = g_GameList[g].players;
+	Engine.GetGUIObjectByName("sgMapSize").caption = g_GameList[g].mapSize.split("(")[0];
+	Engine.GetGUIObjectByName("sgMapType").caption = toTitleCase(g_GameList[g].mapType);
 
 	// Display map description if it exists, otherwise display a placeholder.
 	if (mapData && mapData.settings.Description)
@@ -311,13 +311,13 @@
 	else
 		var mapPreview = "nopreview.png";
 	
-	getGUIObjectByName("sgMapDescription").caption = mapDescription;
-	getGUIObjectByName("sgMapPreview").sprite = "cropped:(0.7812,0.5859)session/icons/mappreview/" + mapPreview;
+	Engine.GetGUIObjectByName("sgMapDescription").caption = mapDescription;
+	Engine.GetGUIObjectByName("sgMapPreview").sprite = "cropped:(0.7812,0.5859)session/icons/mappreview/" + mapPreview;
 }
 
 function joinSelectedGame()
 {
-	var gamesBox = getGUIObjectByName("gamesBox");
+	var gamesBox = Engine.GetGUIObjectByName("gamesBox");
 	if (gamesBox.selected >= 0)
 	{
 		var g = gamesBox.list_data[gamesBox.selected];
@@ -377,7 +377,7 @@
 		case "muc":
 			var nick = message.text;
 			var presence = Engine.LobbyGetPlayerPresence(nick);
-			var playersBox = getGUIObjectByName("playersBox");
+			var playersBox = Engine.GetGUIObjectByName("playersBox");
 			var playerList = playersBox.list_name;
 			var presenceList = playersBox.list_status;
 			var nickList = playersBox.list;
@@ -449,11 +449,11 @@
 					updateBoardList();
 					updatePlayerList();
 					// Disable the 'host' button
-					getGUIObjectByName("hostButton").enabled = false;
+					Engine.GetGUIObjectByName("hostButton").enabled = false;
 				}
 				else if (message.text == "connected")
 				{
-					getGUIObjectByName("hostButton").enabled = true;
+					Engine.GetGUIObjectByName("hostButton").enabled = true;
 				}
 				break;
 			case "error":
@@ -481,7 +481,7 @@
 /* Messages */
 function submitChatInput()
 {
-	var input = getGUIObjectByName("chatInput");
+	var input = Engine.GetGUIObjectByName("chatInput");
 	var text = escapeText(input.caption);
 	if (text.length)
 	{
@@ -493,7 +493,7 @@
 
 function completeNick()
 {
-	var input = getGUIObjectByName("chatInput");
+	var input = Engine.GetGUIObjectByName("chatInput");
 	var text = escapeText(input.caption);
 	if (text.length)
 	{
@@ -584,7 +584,7 @@
 	if (formatted)
 	{
 		g_ChatMessages.push(formatted);
-		getGUIObjectByName("chatText").caption = g_ChatMessages.join("\n");
+		Engine.GetGUIObjectByName("chatText").caption = g_ChatMessages.join("\n");
 	}
 }
 
Index: binaries/data/mods/public/gui/lobby/lobby.xml
===================================================================
--- binaries/data/mods/public/gui/lobby/lobby.xml	(Revision 14461)
+++ binaries/data/mods/public/gui/lobby/lobby.xml	(Arbeitskopie)
@@ -35,7 +35,7 @@
 		<object name="leftButtonPanel" size="20 100%-45 15% 100%-20">
 			<object type="button" style="StoneButton" size="0 0 100% 100%">
 				Leaderboard
-				<action on="Press">getGUIObjectByName("leaderboard").hidden = false;getGUIObjectByName("leaderboardFade").hidden = false;</action>
+				<action on="Press">Engine.GetGUIObjectByName("leaderboard").hidden = false;Engine.GetGUIObjectByName("leaderboardFade").hidden = false;</action>
 			</object>
 		</object>
 
@@ -178,7 +178,7 @@
 			</object>
 			<object type="button" style="StoneButton" size="50%+5 100%-45 50%+133 100%-17">
 				Back
-				<action on="Press">getGUIObjectByName("leaderboard").hidden = true;getGUIObjectByName("leaderboardFade").hidden = true;</action>
+				<action on="Press">Engine.GetGUIObjectByName("leaderboard").hidden = true;Engine.GetGUIObjectByName("leaderboardFade").hidden = true;</action>
 			</object>
 			<object type="button" style="StoneButton" size="50%-133 100%-45 50%-5 100%-17">
 				Update
Index: binaries/data/mods/public/gui/lobby/prelobby.js
===================================================================
--- binaries/data/mods/public/gui/lobby/prelobby.js	(Revision 14461)
+++ binaries/data/mods/public/gui/lobby/prelobby.js	(Arbeitskopie)
@@ -9,7 +9,7 @@
 
 function lobbyStop()
 {
-	getGUIObjectByName("feedback").caption = "";
+	Engine.GetGUIObjectByName("feedback").caption = "";
 
 	if (g_LobbyIsConnecting == false)
 		return;
@@ -26,9 +26,9 @@
 	if (Engine.HasXmppClient())
 		Engine.StopXmppClient();
 
-	var username = getGUIObjectByName("connectUsername").caption;
-	var password = getGUIObjectByName("connectPassword").caption;
-	var feedback = getGUIObjectByName("feedback");
+	var username = Engine.GetGUIObjectByName("connectUsername").caption;
+	var password = Engine.GetGUIObjectByName("connectPassword").caption;
+	var feedback = Engine.GetGUIObjectByName("feedback");
 	var room = Engine.ConfigDB_GetValue("user", "lobby.room");
 
 	feedback.caption = "Connecting....";
@@ -49,17 +49,17 @@
 	if (Engine.HasXmppClient())
 		Engine.StopXmppClient();
 
-	var account = getGUIObjectByName("connectUsername").caption;
-	var password = getGUIObjectByName("connectPassword").caption;
-	var passwordAgain = getGUIObjectByName("registerPasswordAgain").caption;
-	var feedback = getGUIObjectByName("feedback");
+	var account = Engine.GetGUIObjectByName("connectUsername").caption;
+	var password = Engine.GetGUIObjectByName("connectPassword").caption;
+	var passwordAgain = Engine.GetGUIObjectByName("registerPasswordAgain").caption;
+	var feedback = Engine.GetGUIObjectByName("feedback");
 
 	// Check the passwords match.
 	if (password != passwordAgain)
 	{
 		feedback.caption = "Passwords do not match";
-		getGUIObjectByName("connectPassword").caption = "";
-		getGUIObjectByName("registerPasswordAgain").caption = "";
+		Engine.GetGUIObjectByName("connectPassword").caption = "";
+		Engine.GetGUIObjectByName("registerPasswordAgain").caption = "";
 		switchRegister();
 		return;
 	}
@@ -74,31 +74,31 @@
 
 function switchRegister()
 {
-	if (getGUIObjectByName("pageRegister").hidden)
+	if (Engine.GetGUIObjectByName("pageRegister").hidden)
 	{
 		lobbyStop();
-		getGUIObjectByName("pageRegister").hidden = false;
-		getGUIObjectByName("pageConnect").hidden = true;
-		getGUIObjectByName("connect").enabled = false;
+		Engine.GetGUIObjectByName("pageRegister").hidden = false;
+		Engine.GetGUIObjectByName("pageConnect").hidden = true;
+		Engine.GetGUIObjectByName("connect").enabled = false;
 	}
 	else
 	{
-		getGUIObjectByName("pageRegister").hidden = true;
-		getGUIObjectByName("pageConnect").hidden = false;
-		getGUIObjectByName("connect").enabled = true;
+		Engine.GetGUIObjectByName("pageRegister").hidden = true;
+		Engine.GetGUIObjectByName("pageConnect").hidden = false;
+		Engine.GetGUIObjectByName("connect").enabled = true;
 	}
 }
 
 function onTick()
 {
 	//
-	var username = getGUIObjectByName("connectUsername").caption;
-	var password = getGUIObjectByName("connectPassword").caption;
-	var passwordAgain = getGUIObjectByName("registerPasswordAgain").caption;
-	var feedback = getGUIObjectByName("feedback");
-	var pageRegisterHidden = getGUIObjectByName("pageRegister").hidden;
-	var connectButton = getGUIObjectByName("connect");
-	var registerButton = getGUIObjectByName("register"); 
+	var username = Engine.GetGUIObjectByName("connectUsername").caption;
+	var password = Engine.GetGUIObjectByName("connectPassword").caption;
+	var passwordAgain = Engine.GetGUIObjectByName("registerPasswordAgain").caption;
+	var feedback = Engine.GetGUIObjectByName("feedback");
+	var pageRegisterHidden = Engine.GetGUIObjectByName("pageRegister").hidden;
+	var connectButton = Engine.GetGUIObjectByName("connect");
+	var registerButton = Engine.GetGUIObjectByName("register"); 
 	var sanitizedName = sanitizePlayerName(username, true, true)
 	// If there aren't a username and password entered, we can't start registration or connection.
 	if (!username || !password)
Index: binaries/data/mods/public/gui/lobby/prelobby.xml
===================================================================
--- binaries/data/mods/public/gui/lobby/prelobby.xml	(Revision 14461)
+++ binaries/data/mods/public/gui/lobby/prelobby.xml	(Arbeitskopie)
@@ -66,7 +66,7 @@
 		<object type="button" size="18 100%-45 126 100%-17" style="StoneButton">
 			Cancel
 			<action on="Press">
-				if (getGUIObjectByName("pageRegister").hidden)
+				if (Engine.GetGUIObjectByName("pageRegister").hidden)
 				{
 					lobbyStop();
 					Engine.PopGuiPage();
@@ -78,7 +78,7 @@
 		<object name="register" type="button" size="136 100%-45 244 100%-17" style="StoneButton">
 			Register
 			<action on="Press">
-				if (getGUIObjectByName("pageRegister").hidden)
+				if (Engine.GetGUIObjectByName("pageRegister").hidden)
 				{
 					switchRegister();
 				}
Index: binaries/data/mods/public/gui/loading/loading.js
===================================================================
--- binaries/data/mods/public/gui/loading/loading.js	(Revision 14461)
+++ binaries/data/mods/public/gui/loading/loading.js	(Arbeitskopie)
@@ -6,31 +6,31 @@
 	g_Data = data;
 
 	// Set to "hourglass" cursor.
-	setCursor("cursor-wait");
+	Engine.SetCursor("cursor-wait");
 
 	// Get tip image and corresponding tip text
-	var tipTextLoadingArray = buildDirEntList("gui/text/tips/", "*.txt", false);
+	var tipTextLoadingArray = Engine.BuildDirEntList("gui/text/tips/", "*.txt", false);
 
 	if (tipTextLoadingArray.length > 0)
 	{
 		// Set tip text
 		var tipTextFilePath = tipTextLoadingArray[getRandom (0, tipTextLoadingArray.length-1)];
-		var tipText = readFile(tipTextFilePath);
+		var tipText = Engine.ReadFile(tipTextFilePath);
 
 		if (tipText)
 		{
 			var index = tipText.indexOf("\n");
 			var tipTextTitle = tipText.substring(0, index);
 			var tipTextMessage = tipText.substring(index);
-			getGUIObjectByName("tipTitle").caption = tipTextTitle? tipTextTitle : "";
-			getGUIObjectByName("tipText").caption = tipTextMessage? tipTextMessage : "";
+			Engine.GetGUIObjectByName("tipTitle").caption = tipTextTitle? tipTextTitle : "";
+			Engine.GetGUIObjectByName("tipText").caption = tipTextMessage? tipTextMessage : "";
 		}
 
 		// Set tip image
 		var fileName = tipTextFilePath.substring(tipTextFilePath.lastIndexOf("/")+1).replace(".txt", ".png");
 		var tipImageFilePath = "loading/tips/" + fileName;
 		var sprite = "stretched:" + tipImageFilePath;
-		getGUIObjectByName("tipImage").sprite = sprite? sprite : "";
+		Engine.GetGUIObjectByName("tipImage").sprite = sprite? sprite : "";
 	}
 	else
 	{
@@ -39,7 +39,7 @@
 
 	// janwas: main loop now sets progress / description, but that won't
 	// happen until the first timeslice completes, so set initial values.
-	var loadingMapName = getGUIObjectByName ("loadingMapName");
+	var loadingMapName = Engine.GetGUIObjectByName ("loadingMapName");
 
 	if (data)
 	{
@@ -60,12 +60,12 @@
 		}
 	}
 
-	getGUIObjectByName("progressText").caption = "";
-	getGUIObjectByName("progressbar").caption = 0;
+	Engine.GetGUIObjectByName("progressText").caption = "";
+	Engine.GetGUIObjectByName("progressbar").caption = 0;
 
 	// Pick a random quote of the day (each line is a separate tip).
-	var quoteArray = readFileLines("gui/text/quotes.txt");
-	getGUIObjectByName("quoteText").caption = quoteArray[getRandom(0, quoteArray.length-1)];
+	var quoteArray = Engine.ReadFileLines("gui/text/quotes.txt");
+	Engine.GetGUIObjectByName("quoteText").caption = quoteArray[getRandom(0, quoteArray.length-1)];
 }
 
 // ====================================================================
@@ -77,15 +77,15 @@
 		// Show 100 when it is really 99
 		var progress = g_Progress + 1;
 
-		getGUIObjectByName("progressbar").caption = progress; // display current progress
-		getGUIObjectByName("progressText").caption = progress + "%";
+		Engine.GetGUIObjectByName("progressbar").caption = progress; // display current progress
+		Engine.GetGUIObjectByName("progressText").caption = progress + "%";
 
 		// Displays detailed loading info rather than a percent
-		// getGUIObjectByName("progressText").caption = g_LoadDescription; // display current progess details
+		// Engine.GetGUIObjectByName("progressText").caption = g_LoadDescription; // display current progess details
 
 		// Keep curved right edge of progress bar in sync with the rest of the progress bar
-		var middle = getGUIObjectByName("progressbar");
-		var rightSide = getGUIObjectByName("progressbar_right");
+		var middle = Engine.GetGUIObjectByName("progressbar");
+		var rightSide = Engine.GetGUIObjectByName("progressbar_right");
 
 		var middleLength = (middle.size.right - middle.size.left) - (END_PIECE_WIDTH / 2);
 		var increment = Math.round(progress * middleLength / 100);
@@ -112,5 +112,5 @@
 	Engine.SwitchGuiPage("page_session.xml", g_Data);
 
 	// Restore default cursor.
-	setCursor("arrow-default");
+	Engine.SetCursor("arrow-default");
 }
Index: binaries/data/mods/public/gui/gamesetup/gamesetup_mp.xml
===================================================================
--- binaries/data/mods/public/gui/gamesetup/gamesetup_mp.xml	(Revision 14461)
+++ binaries/data/mods/public/gui/gamesetup/gamesetup_mp.xml	(Arbeitskopie)
@@ -48,8 +48,8 @@
 			<object hotkey="confirm" type="button" size="50%-144 100%-60 50%-16 100%-32" style="StoneButton">
 				Continue
 				<action on="Press">
-					var joinPlayerName = getGUIObjectByName("joinPlayerName").caption;
-					var joinServer = getGUIObjectByName("joinServer").caption;
+					var joinPlayerName = Engine.GetGUIObjectByName("joinPlayerName").caption;
+					var joinServer = Engine.GetGUIObjectByName("joinServer").caption;
 					Engine.ConfigDB_CreateValue("user", "playername", joinPlayerName);
 					Engine.ConfigDB_CreateValue("user", "multiplayerserver", joinServer);
 					Engine.ConfigDB_WriteFile("user", "config/user.cfg");
@@ -94,10 +94,10 @@
 			<object type="button" size="50%-144 100%-60 50%-16 100%-32" style="StoneButton">
 				Continue
 				<action on="Press">
-					var hostPlayerName = getGUIObjectByName("hostPlayerName").caption;
+					var hostPlayerName = Engine.GetGUIObjectByName("hostPlayerName").caption;
 					Engine.ConfigDB_CreateValue("user", "playername", hostPlayerName);
 					Engine.ConfigDB_WriteFile("user", "config/user.cfg");
-					if (startHost(hostPlayerName, getGUIObjectByName("hostServerName").caption))
+					if (startHost(hostPlayerName, Engine.GetGUIObjectByName("hostServerName").caption))
 						switchSetupPage("pageHost", "pageConnecting");
 				</action>
 			</object>
Index: binaries/data/mods/public/gui/gamesetup/gamesetup_mp.js
===================================================================
--- binaries/data/mods/public/gui/gamesetup/gamesetup_mp.js	(Revision 14461)
+++ binaries/data/mods/public/gui/gamesetup/gamesetup_mp.js	(Arbeitskopie)
@@ -18,21 +18,21 @@
 		}
 		else
 		{
-			getGUIObjectByName("pageJoin").hidden = false;
-			getGUIObjectByName("pageHost").hidden = true;
+			Engine.GetGUIObjectByName("pageJoin").hidden = false;
+			Engine.GetGUIObjectByName("pageHost").hidden = true;
 		}
 		break;
 	case "host":
-		getGUIObjectByName("pageJoin").hidden = true;
-		getGUIObjectByName("pageHost").hidden = false;
+		Engine.GetGUIObjectByName("pageJoin").hidden = true;
+		Engine.GetGUIObjectByName("pageHost").hidden = false;
 		if(Engine.HasXmppClient())
 		{
-			getGUIObjectByName("hostServerNameWrapper").hidden = false;
-			getGUIObjectByName("hostPlayerName").caption = attribs.name;
-			getGUIObjectByName("hostServerName").caption = attribs.name + "'s game";
+			Engine.GetGUIObjectByName("hostServerNameWrapper").hidden = false;
+			Engine.GetGUIObjectByName("hostPlayerName").caption = attribs.name;
+			Engine.GetGUIObjectByName("hostServerName").caption = attribs.name + "'s game";
 		}
 		else
-			getGUIObjectByName("hostPlayerNameWrapper").hidden = false;
+			Engine.GetGUIObjectByName("hostPlayerNameWrapper").hidden = false;
 		break;
 	default:
 		error("Unrecognised multiplayer game type : " + attribs.multiplayerGameType);
@@ -55,7 +55,7 @@
 	g_GameType = type;
 	g_IsConnecting = true;
 	g_IsRejoining = false;
-	getGUIObjectByName("connectionStatus").caption = "Connecting to server...";
+	Engine.GetGUIObjectByName("connectionStatus").caption = "Connecting to server...";
 }
 
 function onTick()
@@ -131,13 +131,13 @@
 				switch (message.status)
 				{
 				case "connected":
-					getGUIObjectByName("connectionStatus").caption = "Registering with server...";
+					Engine.GetGUIObjectByName("connectionStatus").caption = "Registering with server...";
 					break;
 
 				case "authenticated":
 					if (message.rejoining)
 					{
-						getGUIObjectByName("connectionStatus").caption = "Game has already started - rejoining...";
+						Engine.GetGUIObjectByName("connectionStatus").caption = "Game has already started - rejoining...";
 						g_IsRejoining = true;
 						return; // we'll process the game setup messages in the next tick
 					}
@@ -167,8 +167,8 @@
 
 function switchSetupPage(oldpage, newpage)
 {
-	getGUIObjectByName(oldpage).hidden = true;
-	getGUIObjectByName(newpage).hidden = false;
+	Engine.GetGUIObjectByName(oldpage).hidden = true;
+	Engine.GetGUIObjectByName(newpage).hidden = false;
 }
 
 function startHost(playername, servername)
@@ -180,7 +180,7 @@
 		{
 			if (g.name === servername)
 			{
-				getGUIObjectByName("hostFeedback").caption = "Game name already in use.";
+				Engine.GetGUIObjectByName("hostFeedback").caption = "Game name already in use.";
 				return false;
 			}
 		}
Index: binaries/data/mods/public/gui/gamesetup/gamesetup.js
===================================================================
--- binaries/data/mods/public/gui/gamesetup/gamesetup.js	(Revision 14461)
+++ binaries/data/mods/public/gui/gamesetup/gamesetup.js	(Arbeitskopie)
@@ -88,7 +88,7 @@
 		g_ServerName = attribs.serverName;
 
 	// Init the Cancel Button caption and tooltip
-	var cancelButton = getGUIObjectByName("cancelGame");
+	var cancelButton = Engine.GetGUIObjectByName("cancelGame");
 	if(!Engine.HasXmppClient())
 	{
 		cancelButton.tooltip = "Return to the main menu."
@@ -124,7 +124,7 @@
 	initCivNameList();
 
 	// Init map types
-	var mapTypes = getGUIObjectByName("mapTypeSelection");
+	var mapTypes = Engine.GetGUIObjectByName("mapTypeSelection");
 	mapTypes.list = ["Skirmish","Random","Scenario"];
 	mapTypes.list_data = ["skirmish","random","scenario"];
 
@@ -135,7 +135,7 @@
 	addFilter("All Maps", function(settings) { return true; });
 
 	// Populate map filters dropdown
-	var mapFilters = getGUIObjectByName("mapFilterSelection");
+	var mapFilters = Engine.GetGUIObjectByName("mapFilterSelection");
 	mapFilters.list = getFilters();
 	g_GameAttributes.mapFilter = "Default";
 
@@ -151,7 +151,7 @@
 
 		initMapNameList();
 
-		var numPlayersSelection = getGUIObjectByName("numPlayersSelection");
+		var numPlayersSelection = Engine.GetGUIObjectByName("numPlayersSelection");
 		var players = [];
 		for (var i = 1; i <= MAX_PLAYERS; ++i)
 			players.push(i);
@@ -159,9 +159,9 @@
 		numPlayersSelection.list_data = players;
 		numPlayersSelection.selected = MAX_PLAYERS - 1;
 
-		var gameSpeed = getGUIObjectByName("gameSpeed");
+		var gameSpeed = Engine.GetGUIObjectByName("gameSpeed");
 		gameSpeed.hidden = false;
-		getGUIObjectByName("gameSpeedText").hidden = true;
+		Engine.GetGUIObjectByName("gameSpeedText").hidden = true;
 		gameSpeed.list = g_GameSpeeds.names;
 		gameSpeed.list_data = g_GameSpeeds.speeds;
 		gameSpeed.onSelectionChange = function()
@@ -175,7 +175,7 @@
 		}
 		gameSpeed.selected = g_GameSpeeds["default"];
 
-		var populationCaps = getGUIObjectByName("populationCap");
+		var populationCaps = Engine.GetGUIObjectByName("populationCap");
 		populationCaps.list = POPULATION_CAP;
 		populationCaps.list_data = POPULATION_CAP_DATA;
 		populationCaps.selected = POPULATION_CAP_DEFAULTIDX;
@@ -188,7 +188,7 @@
 				updateGameAttributes();
 		}
 
-		var startingResourcesL = getGUIObjectByName("startingResources");
+		var startingResourcesL = Engine.GetGUIObjectByName("startingResources");
 		startingResourcesL.list = STARTING_RESOURCES;
 		startingResourcesL.list_data = STARTING_RESOURCES_DATA;
 		startingResourcesL.selected = STARTING_RESOURCES_DEFAULTIDX;
@@ -201,7 +201,7 @@
 				updateGameAttributes();
 		}
 
-		var victoryConditions = getGUIObjectByName("victoryCondition");
+		var victoryConditions = Engine.GetGUIObjectByName("victoryCondition");
 		victoryConditions.list = VICTORY_TEXT;
 		victoryConditions.list_data = VICTORY_DATA;
 		victoryConditions.onSelectionChange = function()
@@ -214,7 +214,7 @@
 		};
 		victoryConditions.selected = VICTORY_DEFAULTIDX;
 
-		var mapSize = getGUIObjectByName("mapSize");
+		var mapSize = Engine.GetGUIObjectByName("mapSize");
 		mapSize.list = g_MapSizes.names;
 		mapSize.list_data = g_MapSizes.tiles;
 		mapSize.onSelectionChange = function()
@@ -227,7 +227,7 @@
 		};
 		mapSize.selected = 0;
 
-		getGUIObjectByName("revealMap").onPress = function()
+		Engine.GetGUIObjectByName("revealMap").onPress = function()
 		{	// Update attributes so other players can see change
 			g_GameAttributes.settings.RevealMap = this.checked;
 
@@ -235,7 +235,7 @@
 				updateGameAttributes();
 		};
 
-		getGUIObjectByName("lockTeams").onPress = function()
+		Engine.GetGUIObjectByName("lockTeams").onPress = function()
 		{	// Update attributes so other players can see change
 			g_GameAttributes.settings.LockTeams = this.checked;
 
@@ -243,7 +243,7 @@
 				updateGameAttributes();
 		};
 
-		getGUIObjectByName("enableCheats").onPress = function()
+		Engine.GetGUIObjectByName("enableCheats").onPress = function()
 		{	// Update attributes so other players can see change
 			g_GameAttributes.settings.CheatsEnabled = this.checked;
 
@@ -255,45 +255,45 @@
 	{
 		// If we're a network client, disable all the map controls
 		// TODO: make them look visually disabled so it's obvious why they don't work
-		getGUIObjectByName("mapTypeSelection").hidden = true;
-		getGUIObjectByName("mapTypeText").hidden = false;
-		getGUIObjectByName("mapFilterSelection").hidden = true;
-		getGUIObjectByName("mapFilterText").hidden = false;
-		getGUIObjectByName("mapSelectionText").hidden = false;
-		getGUIObjectByName("mapSelection").hidden = true;
-		getGUIObjectByName("victoryConditionText").hidden = false;
-		getGUIObjectByName("victoryCondition").hidden = true;
-		getGUIObjectByName("gameSpeedText").hidden = false;
-		getGUIObjectByName("gameSpeed").hidden = true;
+		Engine.GetGUIObjectByName("mapTypeSelection").hidden = true;
+		Engine.GetGUIObjectByName("mapTypeText").hidden = false;
+		Engine.GetGUIObjectByName("mapFilterSelection").hidden = true;
+		Engine.GetGUIObjectByName("mapFilterText").hidden = false;
+		Engine.GetGUIObjectByName("mapSelectionText").hidden = false;
+		Engine.GetGUIObjectByName("mapSelection").hidden = true;
+		Engine.GetGUIObjectByName("victoryConditionText").hidden = false;
+		Engine.GetGUIObjectByName("victoryCondition").hidden = true;
+		Engine.GetGUIObjectByName("gameSpeedText").hidden = false;
+		Engine.GetGUIObjectByName("gameSpeed").hidden = true;
 
 		// Disable player and game options controls
 		// TODO: Shouldn't players be able to choose their own assignment?
 		for (var i = 0; i < MAX_PLAYERS; ++i)
 		{
-			getGUIObjectByName("playerAssignment["+i+"]").enabled = false;
-			getGUIObjectByName("playerCiv["+i+"]").hidden = true;
-			getGUIObjectByName("playerTeam["+i+"]").hidden = true;
+			Engine.GetGUIObjectByName("playerAssignment["+i+"]").enabled = false;
+			Engine.GetGUIObjectByName("playerCiv["+i+"]").hidden = true;
+			Engine.GetGUIObjectByName("playerTeam["+i+"]").hidden = true;
 		}
 
-		getGUIObjectByName("numPlayersSelection").hidden = true;
+		Engine.GetGUIObjectByName("numPlayersSelection").hidden = true;
 	}
 
 	// Set up multiplayer/singleplayer bits:
 	if (!g_IsNetworked)
 	{
-		getGUIObjectByName("chatPanel").hidden = true;
-		getGUIObjectByName("enableCheats").checked = true;
+		Engine.GetGUIObjectByName("chatPanel").hidden = true;
+		Engine.GetGUIObjectByName("enableCheats").checked = true;
 		g_GameAttributes.settings.CheatsEnabled = true;
 	}
 	else
 	{
-		getGUIObjectByName("enableCheatsDesc").hidden = false;
-		getGUIObjectByName("enableCheats").checked = false;
+		Engine.GetGUIObjectByName("enableCheatsDesc").hidden = false;
+		Engine.GetGUIObjectByName("enableCheats").checked = false;
 		g_GameAttributes.settings.CheatsEnabled = false;
 		if (g_IsController)
-			getGUIObjectByName("enableCheats").hidden = false;
+			Engine.GetGUIObjectByName("enableCheats").hidden = false;
 		else
-			getGUIObjectByName("enableCheatsText").hidden = false;
+			Engine.GetGUIObjectByName("enableCheatsText").hidden = false;
 	}
 
 	// Settings for all possible player slots
@@ -301,7 +301,7 @@
 	for (var i = 0; i < MAX_PLAYERS; ++i)
 	{
 		// Space player boxes
-		var box = getGUIObjectByName("playerBox["+i+"]");
+		var box = Engine.GetGUIObjectByName("playerBox["+i+"]");
 		var boxSize = box.size;
 		var h = boxSize.bottom - boxSize.top;
 		boxSize.top = i * boxSpacing;
@@ -309,7 +309,7 @@
 		box.size = boxSize;
 
 		// Populate team dropdowns
-		var team = getGUIObjectByName("playerTeam["+i+"]");
+		var team = Engine.GetGUIObjectByName("playerTeam["+i+"]");
 		team.list = ["None", "1", "2", "3", "4"];
 		team.list_data = [-1, 0, 1, 2, 3];
 		team.selected = 0;
@@ -325,7 +325,7 @@
 		};
 
 		// Set events
-		var civ = getGUIObjectByName("playerCiv["+i+"]");
+		var civ = Engine.GetGUIObjectByName("playerCiv["+i+"]");
 		civ.onSelectionChange = function()
 		{	// Update civ
 			if ((this.selected != -1)&&(g_GameAttributes.mapType !== "scenario"))
@@ -339,13 +339,13 @@
 	if (g_IsNetworked)
 	{
 		// For multiplayer, focus the chat input box by default
-		getGUIObjectByName("chatInput").focus();
+		Engine.GetGUIObjectByName("chatInput").focus();
 	}
 	else
 	{
 		// For single-player, focus the map list by default,
 		// to allow easy keyboard selection of maps
-		getGUIObjectByName("mapSelection").focus();
+		Engine.GetGUIObjectByName("mapSelection").focus();
 	}
 }
 
@@ -488,7 +488,7 @@
 	// Update the dropdowns
 	for (var i = 0; i < MAX_PLAYERS; ++i)
 	{
-		var civ = getGUIObjectByName("playerCiv["+i+"]");
+		var civ = Engine.GetGUIObjectByName("playerCiv["+i+"]");
 		civ.list = civListNames;
 		civ.list_data = civListCodes;
 		civ.selected = 0;
@@ -500,7 +500,7 @@
 {
 	// Get a list of map filenames
 	// TODO: Should verify these are valid maps before adding to list
-	var mapSelectionBox = getGUIObjectByName("mapSelection")
+	var mapSelectionBox = Engine.GetGUIObjectByName("mapSelection")
 	var mapFiles;
 
 	switch (g_GameAttributes.mapType)
@@ -609,8 +609,8 @@
 	}
 	else if (g_LoadingState == 1)
 	{
-		getGUIObjectByName("loadingWindow").hidden = true;
-		getGUIObjectByName("setupWindow").hidden = false;
+		Engine.GetGUIObjectByName("loadingWindow").hidden = true;
+		Engine.GetGUIObjectByName("setupWindow").hidden = false;
 		initMain();
 		g_LoadingState++;
 	}
@@ -813,8 +813,8 @@
 		return;
 
 	if (g_GameAttributes.map == "random")
-		selectMap(getGUIObjectByName("mapSelection").list_data[Math.floor(Math.random() *
-			(getGUIObjectByName("mapSelection").list.length - 1)) + 1]);
+		selectMap(Engine.GetGUIObjectByName("mapSelection").list_data[Math.floor(Math.random() *
+			(Engine.GetGUIObjectByName("mapSelection").list.length - 1)) + 1]);
 
 	g_GameAttributes.settings.mapType = g_GameAttributes.mapType;
 	var numPlayers = g_GameAttributes.settings.PlayerData.length;
@@ -876,7 +876,7 @@
 		var playerID = -1;
 		for (var i = 0; i < numPlayers; ++i)
 		{
-			var assignBox = getGUIObjectByName("playerAssignment["+i+"]");
+			var assignBox = Engine.GetGUIObjectByName("playerAssignment["+i+"]");
 			if (assignBox.list_data[assignBox.selected] == "local")
 				playerID = i+1;
 		}
@@ -907,40 +907,40 @@
 	// Update some controls for clients
 	if (!g_IsController)
 	{
-		getGUIObjectByName("mapFilterText").caption = g_GameAttributes.mapFilter;
-		var mapTypeSelection = getGUIObjectByName("mapTypeSelection");
+		Engine.GetGUIObjectByName("mapFilterText").caption = g_GameAttributes.mapFilter;
+		var mapTypeSelection = Engine.GetGUIObjectByName("mapTypeSelection");
 		var idx = mapTypeSelection.list_data.indexOf(g_GameAttributes.mapType);
-		getGUIObjectByName("mapTypeText").caption = mapTypeSelection.list[idx];
-		var mapSelectionBox = getGUIObjectByName("mapSelection");
+		Engine.GetGUIObjectByName("mapTypeText").caption = mapTypeSelection.list[idx];
+		var mapSelectionBox = Engine.GetGUIObjectByName("mapSelection");
 		mapSelectionBox.selected = mapSelectionBox.list_data.indexOf(mapName);
-		getGUIObjectByName("mapSelectionText").caption = getMapDisplayName(mapName);
-		var populationCapBox = getGUIObjectByName("populationCap");
+		Engine.GetGUIObjectByName("mapSelectionText").caption = getMapDisplayName(mapName);
+		var populationCapBox = Engine.GetGUIObjectByName("populationCap");
 		populationCapBox.selected = populationCapBox.list_data.indexOf(mapSettings.PopulationCap);
-		var startingResourcesBox = getGUIObjectByName("startingResources");
+		var startingResourcesBox = Engine.GetGUIObjectByName("startingResources");
 		startingResourcesBox.selected = startingResourcesBox.list_data.indexOf(mapSettings.StartingResources);
 		initMapNameList();
 	}
 
 	// Controls common to all map types
-	var numPlayersSelection = getGUIObjectByName("numPlayersSelection");
-	var revealMap = getGUIObjectByName("revealMap");
-	var victoryCondition = getGUIObjectByName("victoryCondition");
-	var lockTeams = getGUIObjectByName("lockTeams");
-	var mapSize = getGUIObjectByName("mapSize");
-	var enableCheats = getGUIObjectByName("enableCheats");
-	var populationCap = getGUIObjectByName("populationCap");
-	var startingResources = getGUIObjectByName("startingResources");
+	var numPlayersSelection = Engine.GetGUIObjectByName("numPlayersSelection");
+	var revealMap = Engine.GetGUIObjectByName("revealMap");
+	var victoryCondition = Engine.GetGUIObjectByName("victoryCondition");
+	var lockTeams = Engine.GetGUIObjectByName("lockTeams");
+	var mapSize = Engine.GetGUIObjectByName("mapSize");
+	var enableCheats = Engine.GetGUIObjectByName("enableCheats");
+	var populationCap = Engine.GetGUIObjectByName("populationCap");
+	var startingResources = Engine.GetGUIObjectByName("startingResources");
 
-	var numPlayersText= getGUIObjectByName("numPlayersText");
-	var mapSizeDesc = getGUIObjectByName("mapSizeDesc");
-	var mapSizeText = getGUIObjectByName("mapSizeText");
-	var revealMapText = getGUIObjectByName("revealMapText");
-	var victoryConditionText = getGUIObjectByName("victoryConditionText");
-	var lockTeamsText = getGUIObjectByName("lockTeamsText");
-	var enableCheatsText = getGUIObjectByName("enableCheatsText");
-	var populationCapText = getGUIObjectByName("populationCapText");
-	var startingResourcesText = getGUIObjectByName("startingResourcesText");
-	var gameSpeedText = getGUIObjectByName("gameSpeedText");
+	var numPlayersText= Engine.GetGUIObjectByName("numPlayersText");
+	var mapSizeDesc = Engine.GetGUIObjectByName("mapSizeDesc");
+	var mapSizeText = Engine.GetGUIObjectByName("mapSizeText");
+	var revealMapText = Engine.GetGUIObjectByName("revealMapText");
+	var victoryConditionText = Engine.GetGUIObjectByName("victoryConditionText");
+	var lockTeamsText = Engine.GetGUIObjectByName("lockTeamsText");
+	var enableCheatsText = Engine.GetGUIObjectByName("enableCheatsText");
+	var populationCapText = Engine.GetGUIObjectByName("populationCapText");
+	var startingResourcesText = Engine.GetGUIObjectByName("startingResourcesText");
+	var gameSpeedText = Engine.GetGUIObjectByName("gameSpeedText");
 
 	var sizeIdx = (g_MapSizes.tiles.indexOf(mapSettings.Size) != -1 ? g_MapSizes.tiles.indexOf(mapSettings.Size) : g_MapSizes["default"]);
 	var speedIdx = (g_GameAttributes.gameSpeed !== undefined && g_GameSpeeds.speeds.indexOf(g_GameAttributes.gameSpeed) != -1) ? g_GameSpeeds.speeds.indexOf(g_GameAttributes.gameSpeed) : g_GameSpeeds["default"];
@@ -954,7 +954,7 @@
 	startingResourcesText.caption = STARTING_RESOURCES[startingResources.selected];
 
 	// Update map preview
-	getGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);
+	Engine.GetGUIObjectByName("mapPreview").sprite = "cropped:(0.78125,0.5859375)session/icons/mappreview/" + getMapPreview(mapName);
 
 	// Handle map type specific logic
 	switch (g_GameAttributes.mapType)
@@ -1087,7 +1087,7 @@
 		revealMapText.caption = (mapSettings.RevealMap ? "Yes" : "No");
 		victoryConditionText.caption = VICTORY_TEXT[victoryIdx];
 		lockTeamsText.caption = (mapSettings.LockTeams ? "Yes" : "No");
-		getGUIObjectByName("populationCap").selected = POPULATION_CAP_DEFAULTIDX;
+		Engine.GetGUIObjectByName("populationCap").selected = POPULATION_CAP_DEFAULTIDX;
 
 		break;
 
@@ -1097,7 +1097,7 @@
 	}
 
 	// Display map name
-	getGUIObjectByName("mapInfoName").caption = getMapDisplayName(mapName);
+	Engine.GetGUIObjectByName("mapInfoName").caption = getMapDisplayName(mapName);
 
 	// Load the description from the map file, if there is one
 	var description = mapSettings.Description || "Sorry, no description available.";
@@ -1111,18 +1111,18 @@
 	for (var i = 0; i < MAX_PLAYERS; ++i)
 	{
 		// Show only needed player slots
-		getGUIObjectByName("playerBox["+i+"]").hidden = (i >= numPlayers);
+		Engine.GetGUIObjectByName("playerBox["+i+"]").hidden = (i >= numPlayers);
 
 		// Show player data or defaults as necessary
 		if (i >= numPlayers)
 			continue;
 
-		var pName = getGUIObjectByName("playerName["+i+"]");
-		var pCiv = getGUIObjectByName("playerCiv["+i+"]");
-		var pCivText = getGUIObjectByName("playerCivText["+i+"]");
-		var pTeam = getGUIObjectByName("playerTeam["+i+"]");
-		var pTeamText = getGUIObjectByName("playerTeamText["+i+"]");
-		var pColor = getGUIObjectByName("playerColour["+i+"]");
+		var pName = Engine.GetGUIObjectByName("playerName["+i+"]");
+		var pCiv = Engine.GetGUIObjectByName("playerCiv["+i+"]");
+		var pCivText = Engine.GetGUIObjectByName("playerCivText["+i+"]");
+		var pTeam = Engine.GetGUIObjectByName("playerTeam["+i+"]");
+		var pTeamText = Engine.GetGUIObjectByName("playerTeamText["+i+"]");
+		var pColor = Engine.GetGUIObjectByName("playerColour["+i+"]");
 
 		// Player data / defaults
 		var pData = mapSettings.PlayerData ? mapSettings.PlayerData[i] : {};
@@ -1162,7 +1162,7 @@
 		}
 	}
 
-	getGUIObjectByName("mapInfoDescription").caption = playerString + description;
+	Engine.GetGUIObjectByName("mapInfoDescription").caption = playerString + description;
 
 	g_IsInGuiUpdate = false;
 
@@ -1211,7 +1211,7 @@
 
 	// Only enable start button if we have enough assigned players
 	if (g_IsController)
-		getGUIObjectByName("startGame").enabled = (assignedCount > 0);
+		Engine.GetGUIObjectByName("startGame").enabled = (assignedCount > 0);
 
 	for each (var ai in g_AIs)
 	{
@@ -1247,7 +1247,7 @@
 
 		var selection = assignments[playerID];
 
-		var configButton = getGUIObjectByName("playerConfig["+i+"]");
+		var configButton = Engine.GetGUIObjectByName("playerConfig["+i+"]");
 		configButton.hidden = true;
 
 		// Look for valid player slots
@@ -1302,7 +1302,7 @@
 				Engine.SetNetworkGameAttributes(g_GameAttributes);
 		}
 
-		var assignBox = getGUIObjectByName("playerAssignment["+i+"]");
+		var assignBox = Engine.GetGUIObjectByName("playerAssignment["+i+"]");
 		assignBox.list = hostNameList;
 		assignBox.list_data = hostGuidList;
 		if (assignBox.selected != selection)
@@ -1403,7 +1403,7 @@
 
 function submitChatInput()
 {
-	var input = getGUIObjectByName("chatInput");
+	var input = Engine.GetGUIObjectByName("chatInput");
 	var text = input.caption;
 	if (text.length)
 	{
@@ -1454,12 +1454,12 @@
 
 	g_ChatMessages.push(formatted);
 
-	getGUIObjectByName("chatText").caption = g_ChatMessages.join("\n");
+	Engine.GetGUIObjectByName("chatText").caption = g_ChatMessages.join("\n");
 }
 
 function toggleMoreOptions()
 {
-	getGUIObjectByName("moreOptions").hidden = !getGUIObjectByName("moreOptions").hidden;
+	Engine.GetGUIObjectByName("moreOptions").hidden = !Engine.GetGUIObjectByName("moreOptions").hidden;
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1534,16 +1534,16 @@
 	if (!Engine.HasXmppClient())
 		return;
 
-	var selectedMapSize = getGUIObjectByName("mapSize").selected;
-	var selectedVictoryCondition = getGUIObjectByName("victoryCondition").selected;
+	var selectedMapSize = Engine.GetGUIObjectByName("mapSize").selected;
+	var selectedVictoryCondition = Engine.GetGUIObjectByName("victoryCondition").selected;
 
 	// Map sizes only apply to random maps.
 	if (g_GameAttributes.mapType == "random")
-		var mapSize = getGUIObjectByName("mapSize").list[selectedMapSize];
+		var mapSize = Engine.GetGUIObjectByName("mapSize").list[selectedMapSize];
 	else
 		var mapSize = "Default";
 
-	var victoryCondition = getGUIObjectByName("victoryCondition").list[selectedVictoryCondition];
+	var victoryCondition = Engine.GetGUIObjectByName("victoryCondition").list[selectedVictoryCondition];
 	var numberOfPlayers = Object.keys(g_PlayerAssignments).length;
 	var players = [ assignment.name for each (assignment in g_PlayerAssignments) ].join(", ");
 
Index: binaries/data/mods/public/gui/summary/summary.js
===================================================================
--- binaries/data/mods/public/gui/summary/summary.js	(Revision 14461)
+++ binaries/data/mods/public/gui/summary/summary.js	(Arbeitskopie)
@@ -14,22 +14,22 @@
 	{
 		if (i != panelNumber)
 		{
-			getGUIObjectByName(panelNames[i]).hidden = true;
-			getGUIObjectByName(panelButtonNames[i]).sprite = "BackgroundTab";
+			Engine.GetGUIObjectByName(panelNames[i]).hidden = true;
+			Engine.GetGUIObjectByName(panelButtonNames[i]).sprite = "BackgroundTab";
 		}
 		else
 		{
-			getGUIObjectByName(panelNames[i]).hidden = false;
-			getGUIObjectByName(panelButtonNames[i]).sprite = "ForegroundTab";
-			adjustTabDividers(getGUIObjectByName(panelButtonNames[i]).size);
+			Engine.GetGUIObjectByName(panelNames[i]).hidden = false;
+			Engine.GetGUIObjectByName(panelButtonNames[i]).sprite = "ForegroundTab";
+			adjustTabDividers(Engine.GetGUIObjectByName(panelButtonNames[i]).size);
 		}
 	}
 }
 
 function adjustTabDividers(tabSize)
 {
-	var leftSpacer = getGUIObjectByName("tabDividerLeft");
-	var rightSpacer = getGUIObjectByName("tabDividerRight");
+	var leftSpacer = Engine.GetGUIObjectByName("tabDividerLeft");
+	var rightSpacer = Engine.GetGUIObjectByName("tabDividerRight");
 	leftSpacer.size = "20 " + leftSpacer.size.top + " " + (tabSize.left + 2) + " " + leftSpacer.size.bottom;
 	rightSpacer.size = (tabSize.right - 2) + " " + rightSpacer.size.top + " 100%-20 " + rightSpacer.size.bottom;
 }
@@ -39,9 +39,9 @@
 	var civData = loadCivData();
 	var mapSize = "Scenario";
 
-	getGUIObjectByName("timeElapsed").caption = "Time elapsed: " + timeToString(data.timeElapsed);
+	Engine.GetGUIObjectByName("timeElapsed").caption = "Time elapsed: " + timeToString(data.timeElapsed);
 
-	getGUIObjectByName("summaryText").caption = data.gameResult;
+	Engine.GetGUIObjectByName("summaryText").caption = data.gameResult;
 
 	// This is only defined for random maps
 	if (data.mapSettings.Size)
@@ -60,7 +60,7 @@
 		}
 	}
 
-	getGUIObjectByName("mapName").caption = data.mapSettings.Name + " - " + mapSize;
+	Engine.GetGUIObjectByName("mapName").caption = data.mapSettings.Name + " - " + mapSize;
 
 	// Space player boxes
 	var boxSpacing = 32;
@@ -68,7 +68,7 @@
 	{
 		for (var j = 0; j < MAX_SLOTS; ++j)
 		{
-			var box = getGUIObjectByName("playerBox"+i+"["+j+"]");
+			var box = Engine.GetGUIObjectByName("playerBox"+i+"["+j+"]");
 			var boxSize = box.size;
 			var h = boxSize.bottom - boxSize.top;
 			boxSize.top = j * boxSpacing;
@@ -86,46 +86,46 @@
 	var playerNameHeadingWidth = 200;
 	// Special cased to make the (Sent / Received) part fit
 	var tributesWidth = 121;
-	getGUIObjectByName("playerName0Heading").size = left + " 26 " + (left + playerNameHeadingWidth) + " 100%"; left += playerNameHeadingWidth;
-	getGUIObjectByName("economyScoreHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("militaryScoreHeading").size = left +  " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("explorationScoreHeading").size = left +  " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("totalScoreHeading").size = left +  " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("playerName0Heading").size = left + " 26 " + (left + playerNameHeadingWidth) + " 100%"; left += playerNameHeadingWidth;
+	Engine.GetGUIObjectByName("economyScoreHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("militaryScoreHeading").size = left +  " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("explorationScoreHeading").size = left +  " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("totalScoreHeading").size = left +  " 16 " + (left + width) + " 100%"; left += width;
 	
 	left = 50;
-	getGUIObjectByName("playerName1Heading").size = left + " 26 " + (left + playerNameHeadingWidth) + " 100%"; left += playerNameHeadingWidth;
-	getGUIObjectByName("unitsTrainedHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("unitsLostHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("enemyUnitsKilledHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("buildingsConstructedHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("buildingsLostHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("enemyBuildingsDestroyedHeading").size = left + " 6 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("playerName1Heading").size = left + " 26 " + (left + playerNameHeadingWidth) + " 100%"; left += playerNameHeadingWidth;
+	Engine.GetGUIObjectByName("unitsTrainedHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("unitsLostHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("enemyUnitsKilledHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("buildingsConstructedHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("buildingsLostHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("enemyBuildingsDestroyedHeading").size = left + " 6 " + (left + width) + " 100%"; left += width;
 
 	left = 50;
-	getGUIObjectByName("playerName2Heading").size = left + " 26 " + (left + playerNameHeadingWidth) + " 100%"; left += playerNameHeadingWidth;
-	getGUIObjectByName("civCentresBuiltHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("enemyCivCentresDestroyedHeading").size = left +  " 6 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("mapExplorationHeading").size = left +  " 6 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("playerName2Heading").size = left + " 26 " + (left + playerNameHeadingWidth) + " 100%"; left += playerNameHeadingWidth;
+	Engine.GetGUIObjectByName("civCentresBuiltHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("enemyCivCentresDestroyedHeading").size = left +  " 6 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("mapExplorationHeading").size = left +  " 6 " + (left + width) + " 100%"; left += width;
 
 	left = 50;
-	getGUIObjectByName("playerName3Heading").size = left + " 26 " + (left + playerNameHeadingWidth) + " 100%"; left += playerNameHeadingWidth;
-	getGUIObjectByName("resourceHeading").size = left + " 16 " + (left + width * 4) + " 100%";
-	getGUIObjectByName("foodGatheredHeading").size = left + " 34 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("woodGatheredHeading").size = left + " 34 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("stoneGatheredHeading").size = left + " 34 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("metalGatheredHeading").size = left + " 34 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("vegetarianRatioHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("treasuresCollectedHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("resourcesTributedHeading").size = left + " 16 " + (left + tributesWidth) + " 100%"; left += tributesWidth;
+	Engine.GetGUIObjectByName("playerName3Heading").size = left + " 26 " + (left + playerNameHeadingWidth) + " 100%"; left += playerNameHeadingWidth;
+	Engine.GetGUIObjectByName("resourceHeading").size = left + " 16 " + (left + width * 4) + " 100%";
+	Engine.GetGUIObjectByName("foodGatheredHeading").size = left + " 34 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("woodGatheredHeading").size = left + " 34 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("stoneGatheredHeading").size = left + " 34 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("metalGatheredHeading").size = left + " 34 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("vegetarianRatioHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("treasuresCollectedHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("resourcesTributedHeading").size = left + " 16 " + (left + tributesWidth) + " 100%"; left += tributesWidth;
 
 	left = 50;
-	getGUIObjectByName("playerName4Heading").size = left + " 26 " + (left + playerNameHeadingWidth) + " 100%"; left += playerNameHeadingWidth;
-	getGUIObjectByName("exchangedFoodHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("exchangedWoodHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("exchangedStoneHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("exchangedMetalHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("barterEfficiencyHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
-	getGUIObjectByName("tradeIncomeHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("playerName4Heading").size = left + " 26 " + (left + playerNameHeadingWidth) + " 100%"; left += playerNameHeadingWidth;
+	Engine.GetGUIObjectByName("exchangedFoodHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("exchangedWoodHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("exchangedStoneHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("exchangedMetalHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("barterEfficiencyHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
+	Engine.GetGUIObjectByName("tradeIncomeHeading").size = left + " 16 " + (left + width) + " 100%"; left += width;
 
 	// Show counters
 	for (var i = 0; i < MAX_SLOTS; ++i)
@@ -136,7 +136,7 @@
 
 			for (var k = 0; k < panelNames.length; ++k)
 			{
-				var playerBox = getGUIObjectByName("playerBox"+k+"["+i+"]");
+				var playerBox = Engine.GetGUIObjectByName("playerBox"+k+"["+i+"]");
 				playerBox.hidden = false;
 
 				var colourString = "colour: "
@@ -144,48 +144,48 @@
 					+ Math.floor(playerState.colour.g * 255) + " "
 					+ Math.floor(playerState.colour.b * 255);
 				playerBox.sprite = colourString + " 32";
-				var playerColourBox = getGUIObjectByName("playerColourBox"+k+"["+i+"]");
+				var playerColourBox = Engine.GetGUIObjectByName("playerColourBox"+k+"["+i+"]");
 				playerColourBox.sprite = colourString + " 255";
 
 				// Show the multiplayer name, e.g. "Foobar" rather than "Player 1".
 				// TODO: Perhaps show both the multiplayer and map-specific name?
-				var playerName = getGUIObjectByName("playerName"+k+"["+i+"]");
+				var playerName = Engine.GetGUIObjectByName("playerName"+k+"["+i+"]");
 				playerName.caption = data.players[i+1].name;
 
-				getGUIObjectByName("civIcon"+k+"["+i+"]").sprite = "stretched:"+civData[playerState.civ].Emblem;
-				getGUIObjectByName("civIcon"+k+"["+i+"]").tooltip = civData[playerState.civ].Name;
+				Engine.GetGUIObjectByName("civIcon"+k+"["+i+"]").sprite = "stretched:"+civData[playerState.civ].Emblem;
+				Engine.GetGUIObjectByName("civIcon"+k+"["+i+"]").tooltip = civData[playerState.civ].Name;
 			}
 
-			var economyScore = getGUIObjectByName("economyScore["+i+"]");
-			var militaryScore = getGUIObjectByName("militaryScore["+i+"]");
-			var explorationScore = getGUIObjectByName("explorationScore["+i+"]");
-			var totalScore = getGUIObjectByName("totalScore["+i+"]");
+			var economyScore = Engine.GetGUIObjectByName("economyScore["+i+"]");
+			var militaryScore = Engine.GetGUIObjectByName("militaryScore["+i+"]");
+			var explorationScore = Engine.GetGUIObjectByName("explorationScore["+i+"]");
+			var totalScore = Engine.GetGUIObjectByName("totalScore["+i+"]");
 
-			var unitsTrained = getGUIObjectByName("unitsTrained["+i+"]");
-			var unitsLost = getGUIObjectByName("unitsLost["+i+"]");
-			var enemyUnitsKilled = getGUIObjectByName("enemyUnitsKilled["+i+"]");
-			var buildingsConstructed = getGUIObjectByName("buildingsConstructed["+i+"]");
-			var buildingsLost = getGUIObjectByName("buildingsLost["+i+"]");
-			var enemyBuildingsDestroyed = getGUIObjectByName("enemyBuildingsDestroyed["+i+"]");
+			var unitsTrained = Engine.GetGUIObjectByName("unitsTrained["+i+"]");
+			var unitsLost = Engine.GetGUIObjectByName("unitsLost["+i+"]");
+			var enemyUnitsKilled = Engine.GetGUIObjectByName("enemyUnitsKilled["+i+"]");
+			var buildingsConstructed = Engine.GetGUIObjectByName("buildingsConstructed["+i+"]");
+			var buildingsLost = Engine.GetGUIObjectByName("buildingsLost["+i+"]");
+			var enemyBuildingsDestroyed = Engine.GetGUIObjectByName("enemyBuildingsDestroyed["+i+"]");
 
-			var civCentresBuilt = getGUIObjectByName("civCentresBuilt["+i+"]");
-			var enemyCivCentresDestroyed = getGUIObjectByName("enemyCivCentresDestroyed["+i+"]");
-			var mapExploration = getGUIObjectByName("mapExploration["+i+"]");
+			var civCentresBuilt = Engine.GetGUIObjectByName("civCentresBuilt["+i+"]");
+			var enemyCivCentresDestroyed = Engine.GetGUIObjectByName("enemyCivCentresDestroyed["+i+"]");
+			var mapExploration = Engine.GetGUIObjectByName("mapExploration["+i+"]");
 
-			var foodGathered = getGUIObjectByName("foodGathered["+i+"]");
-			var woodGathered = getGUIObjectByName("woodGathered["+i+"]");
-			var stoneGathered = getGUIObjectByName("stoneGathered["+i+"]");
-			var metalGathered = getGUIObjectByName("metalGathered["+i+"]");
-			var vegetarianRatio = getGUIObjectByName("vegetarianRatio["+i+"]");
-			var treasuresCollected = getGUIObjectByName("treasuresCollected["+i+"]");
-			var resourcesTributed = getGUIObjectByName("resourcesTributed["+i+"]");
+			var foodGathered = Engine.GetGUIObjectByName("foodGathered["+i+"]");
+			var woodGathered = Engine.GetGUIObjectByName("woodGathered["+i+"]");
+			var stoneGathered = Engine.GetGUIObjectByName("stoneGathered["+i+"]");
+			var metalGathered = Engine.GetGUIObjectByName("metalGathered["+i+"]");
+			var vegetarianRatio = Engine.GetGUIObjectByName("vegetarianRatio["+i+"]");
+			var treasuresCollected = Engine.GetGUIObjectByName("treasuresCollected["+i+"]");
+			var resourcesTributed = Engine.GetGUIObjectByName("resourcesTributed["+i+"]");
 
-			var exchangedFood = getGUIObjectByName("exchangedFood["+i+"]");
-			var exchangedWood = getGUIObjectByName("exchangedWood["+i+"]");
-			var exchangedStone = getGUIObjectByName("exchangedStone["+i+"]");
-			var exchangedMetal = getGUIObjectByName("exchangedMetal["+i+"]");
-			var barterEfficiency = getGUIObjectByName("barterEfficiency["+i+"]");
-			var tradeIncome = getGUIObjectByName("tradeIncome["+i+"]");
+			var exchangedFood = Engine.GetGUIObjectByName("exchangedFood["+i+"]");
+			var exchangedWood = Engine.GetGUIObjectByName("exchangedWood["+i+"]");
+			var exchangedStone = Engine.GetGUIObjectByName("exchangedStone["+i+"]");
+			var exchangedMetal = Engine.GetGUIObjectByName("exchangedMetal["+i+"]");
+			var barterEfficiency = Engine.GetGUIObjectByName("barterEfficiency["+i+"]");
+			var tradeIncome = Engine.GetGUIObjectByName("tradeIncome["+i+"]");
 
 			// align counters
 
@@ -195,9 +195,9 @@
 			militaryScore.size = left + " 2 " + (left + width) + " 100%"; left += width;
 			explorationScore.size = left + " 2 " + (left + width) + " 100%"; left += width;
 			totalScore.size = left + " 2 " + (left + width) + " 100%"; left += width;
-			var size = getGUIObjectByName("playerBox0["+i+"]").size;
+			var size = Engine.GetGUIObjectByName("playerBox0["+i+"]").size;
 			size.right = left + 10;
-			getGUIObjectByName("playerBox0["+i+"]").size = size;
+			Engine.GetGUIObjectByName("playerBox0["+i+"]").size = size;
 			
 			left = 240;
 			unitsTrained.size = left + " 2 " + (left + width) + " 100%"; left += width;
@@ -206,17 +206,17 @@
 			buildingsConstructed.size = left + " 2 " + (left + width) + " 100%"; left += width;
 			buildingsLost.size = left + " 2 " + (left + width) + " 100%"; left += width;
 			enemyBuildingsDestroyed.size = left + " 2 " + (left + width) + " 100%"; left += width;
-			size = getGUIObjectByName("playerBox1["+i+"]").size;
+			size = Engine.GetGUIObjectByName("playerBox1["+i+"]").size;
 			size.right = left + 10;
-			getGUIObjectByName("playerBox1["+i+"]").size = size;
+			Engine.GetGUIObjectByName("playerBox1["+i+"]").size = size;
 
 			left = 240;
 			civCentresBuilt.size = left + " 2 " + (left + width) + " 100%"; left += width;
 			enemyCivCentresDestroyed.size = left + " 2 " + (left + width) + " 100%"; left += width;
 			mapExploration.size = left + " 2 " + (left + width) + " 100%"; left += width;
-			size = getGUIObjectByName("playerBox2["+i+"]").size;
+			size = Engine.GetGUIObjectByName("playerBox2["+i+"]").size;
 			size.right = left + 10;
-			getGUIObjectByName("playerBox2["+i+"]").size = size;
+			Engine.GetGUIObjectByName("playerBox2["+i+"]").size = size;
 
 			left = 240;
 			foodGathered.size = left + " 2 " + (left + width) + " 100%"; left += width;
@@ -226,9 +226,9 @@
 			vegetarianRatio.size = left + " 2 " + (left + width) + " 100%"; left += width;
 			treasuresCollected.size	= left + " 2 " + (left + width) + " 100%"; left += width;
 			resourcesTributed.size = left + " 2 " + (left + tributesWidth) + " 100%"; left += tributesWidth;
-			size = getGUIObjectByName("playerBox3["+i+"]").size;
+			size = Engine.GetGUIObjectByName("playerBox3["+i+"]").size;
 			size.right = left + 10;
-			getGUIObjectByName("playerBox3["+i+"]").size = size;
+			Engine.GetGUIObjectByName("playerBox3["+i+"]").size = size;
 
 			left = 240;
 			exchangedFood.size = left + " 2 " + (left + width) + " 100%"; left += width;
@@ -237,9 +237,9 @@
 			exchangedMetal.size = left + " 2 " + (left + width) + " 100%"; left += width;
 			barterEfficiency.size = left + " 2 " + (left + width) + " 100%"; left += width;
 			tradeIncome.size = left + " 2 " + (left + width) + " 100%"; left += width;
-			size = getGUIObjectByName("playerBox4["+i+"]").size;
+			size = Engine.GetGUIObjectByName("playerBox4["+i+"]").size;
 			size.right = left + 10;
-			getGUIObjectByName("playerBox4["+i+"]").size = size;
+			Engine.GetGUIObjectByName("playerBox4["+i+"]").size = size;
 
 			// display counters
 			economyScore.caption = Math.round((playerState.statistics.resourcesGathered.food + playerState.statistics.resourcesGathered.wood + 
@@ -297,7 +297,7 @@
 			// hide player boxes
 			for (var k = 0; k < panelNames.length; ++k)
 			{
-				var playerBox = getGUIObjectByName("playerBox"+k+"["+i+"]");
+				var playerBox = Engine.GetGUIObjectByName("playerBox"+k+"["+i+"]");
 				playerBox.hidden = true;
 			}
 		}
Index: binaries/data/mods/public/gui/msgbox/msgbox.xml
===================================================================
--- binaries/data/mods/public/gui/msgbox/msgbox.xml	(Revision 14461)
+++ binaries/data/mods/public/gui/msgbox/msgbox.xml	(Arbeitskopie)
@@ -4,13 +4,13 @@
 	<script><![CDATA[
 	function init(data)
 	{
-		var mbMainObj = getGUIObjectByName("mbMain");
-		var mbTitleObj = getGUIObjectByName("mbTitleBar");
-		var mbTextObj = getGUIObjectByName("mbText");
+		var mbMainObj = Engine.GetGUIObjectByName("mbMain");
+		var mbTitleObj = Engine.GetGUIObjectByName("mbTitleBar");
+		var mbTextObj = Engine.GetGUIObjectByName("mbText");
 
-		var mbButton1Obj = getGUIObjectByName("mbButton1");
-		var mbButton2Obj = getGUIObjectByName("mbButton2");
-		var mbButton3Obj = getGUIObjectByName("mbButton3");
+		var mbButton1Obj = Engine.GetGUIObjectByName("mbButton1");
+		var mbButton2Obj = Engine.GetGUIObjectByName("mbButton2");
+		var mbButton3Obj = Engine.GetGUIObjectByName("mbButton3");
 
 		// Calculate size
 		var mbLRDiff = data.width / 2;     // Message box left/right difference from 50% of screen
@@ -52,19 +52,37 @@
 		if (data.buttonCaptions.length >= 1)
 		{
 			mbButton1Obj.caption = data.buttonCaptions[0];
-			mbButton1Obj.onPress = function () { Engine.PopGuiPage(); if (codes && codes[0]) codes[0](); }
+			mbButton1Obj.onPress = function () 
+			{ 
+				if (data.callback) 
+					Engine.PopGuiPageCB(0); 
+				else
+					Engine.PopGuiPage(); 
+			};
 			mbButton1Obj.hidden = false;
 		}
 		if (data.buttonCaptions.length >= 2)
 		{
 			mbButton2Obj.caption = data.buttonCaptions[1];
-			mbButton2Obj.onPress = function () { Engine.PopGuiPage(); if (codes && codes[1]) codes[1](); }
+			mbButton2Obj.onPress = function () 
+			{ 
+				if (data.callback) 
+					Engine.PopGuiPageCB(1); 
+				else
+					Engine.PopGuiPage(); 
+			};
 			mbButton2Obj.hidden = false;
 		}
 		if (data.buttonCaptions.length >= 3)
 		{
 			mbButton3Obj.caption = data.buttonCaptions[2];
-			mbButton3Obj.onPress = function () { Engine.PopGuiPage(); if (codes && codes[2]) codes[2](); }
+			mbButton3Obj.onPress = function () 
+			{ 
+				if (data.callback) 
+					Engine.PopGuiPageCB(2); 
+				else
+					Engine.PopGuiPage(); 
+			};
 			mbButton3Obj.hidden = false;
 		}
 
Index: binaries/data/mods/public/gui/manual/manual.js
===================================================================
--- binaries/data/mods/public/gui/manual/manual.js	(Revision 14461)
+++ binaries/data/mods/public/gui/manual/manual.js	(Arbeitskopie)
@@ -2,7 +2,7 @@
 
 function init(data)
 {
-	getGUIObjectByName("mainText").caption = readFile("gui/manual/" + data.page + ".txt");
+	Engine.GetGUIObjectByName("mainText").caption = Engine.ReadFile("gui/manual/" + data.page + ".txt");
 	closeCallback = data.closeCallback;
 }
 
Index: binaries/data/mods/public/gui/savedgames/save.js
===================================================================
--- binaries/data/mods/public/gui/savedgames/save.js	(Revision 14461)
+++ binaries/data/mods/public/gui/savedgames/save.js	(Arbeitskopie)
@@ -5,12 +5,12 @@
 
 function selectDescription()
 {
-	var gameSelection = getGUIObjectByName("gameSelection");
+	var gameSelection = Engine.GetGUIObjectByName("gameSelection");
 	if (gameSelection.selected != -1)
 	{
-		getGUIObjectByName("deleteGameButton").enabled = true;
+		Engine.GetGUIObjectByName("deleteGameButton").enabled = true;
 		var gameID = gameSelection.list_data[gameSelection.selected];
-		getGUIObjectByName("saveGameDesc").caption = g_Descriptions[gameID];
+		Engine.GetGUIObjectByName("saveGameDesc").caption = g_Descriptions[gameID];
 	}
 }
 
@@ -24,8 +24,8 @@
 			gameDataCallback = data.gameDataCallback;
 	}
 
-	var gameSelection = getGUIObjectByName("gameSelection");
-	getGUIObjectByName("deleteGameButton").enabled = false;
+	var gameSelection = Engine.GetGUIObjectByName("gameSelection");
+	Engine.GetGUIObjectByName("deleteGameButton").enabled = false;
 
 	var savedGames = Engine.GetSavedGames();
 	if (savedGames.length == 0)
@@ -50,10 +50,10 @@
 
 function saveGame()
 {
-	var gameSelection = getGUIObjectByName("gameSelection");
+	var gameSelection = Engine.GetGUIObjectByName("gameSelection");
 	var gameLabel = gameSelection.list[gameSelection.selected];
 	var gameID = gameSelection.list_data[gameSelection.selected];
-	var desc = getGUIObjectByName("saveGameDesc").caption;
+	var desc = Engine.GetGUIObjectByName("saveGameDesc").caption;
 	var name = gameID ? gameID : "savegame";
 
 	if (gameSelection.selected != -1)
@@ -86,7 +86,7 @@
 
 function deleteGame()
 {
-	var gameSelection = getGUIObjectByName("gameSelection");
+	var gameSelection = Engine.GetGUIObjectByName("gameSelection");
 	var gameLabel = gameSelection.list[gameSelection.selected];
 	var gameID = gameSelection.list_data[gameSelection.selected];
 
Index: binaries/data/mods/public/gui/savedgames/load.js
===================================================================
--- binaries/data/mods/public/gui/savedgames/load.js	(Revision 14461)
+++ binaries/data/mods/public/gui/savedgames/load.js	(Arbeitskopie)
@@ -1,14 +1,14 @@
 function init()
 {
-	var gameSelection = getGUIObjectByName("gameSelection");
+	var gameSelection = Engine.GetGUIObjectByName("gameSelection");
 
 	var savedGames = Engine.GetSavedGames();
 	if (savedGames.length == 0)
 	{
 		gameSelection.list = [ "No saved games found" ];
 		gameSelection.selected = 0;
-		getGUIObjectByName("loadGameButton").enabled = false;
-		getGUIObjectByName("deleteGameButton").enabled = false;
+		Engine.GetGUIObjectByName("loadGameButton").enabled = false;
+		Engine.GetGUIObjectByName("deleteGameButton").enabled = false;
 		return;
 	}
 
@@ -24,7 +24,7 @@
 
 function loadGame()
 {
-	var gameSelection = getGUIObjectByName("gameSelection");
+	var gameSelection = Engine.GetGUIObjectByName("gameSelection");
 	var gameID = gameSelection.list_data[gameSelection.selected];
 
 	var metadata = Engine.StartSavedGame(gameID);
@@ -48,7 +48,7 @@
 
 function deleteGame()
 {
-	var gameSelection = getGUIObjectByName("gameSelection");
+	var gameSelection = Engine.GetGUIObjectByName("gameSelection");
 	var gameLabel = gameSelection.list[gameSelection.selected];
 	var gameID = gameSelection.list_data[gameSelection.selected];
 
Index: binaries/data/mods/public/gui/civinfo/civinfo.js
===================================================================
--- binaries/data/mods/public/gui/civinfo/civinfo.js	(Revision 14461)
+++ binaries/data/mods/public/gui/civinfo/civinfo.js	(Arbeitskopie)
@@ -44,7 +44,7 @@
 	var civListCodes = [ civ.code for each (civ in civList) ];
 
 	// Set civ control
-	var civSelection = getGUIObjectByName("civSelection");
+	var civSelection = Engine.GetGUIObjectByName("civSelection");
 	civSelection.list = civListNames;
 	civSelection.list_data = civListCodes;
 	civSelection.selected = 0;
@@ -85,7 +85,7 @@
 		error("Error loading civ data for \""+code+"\"");
 
 	// Update civ gameplay display
-	getGUIObjectByName("civGameplayHeading").caption = heading(civInfo.Name+" Gameplay", 16);
+	Engine.GetGUIObjectByName("civGameplayHeading").caption = heading(civInfo.Name+" Gameplay", 16);
 
 
 	// Bonuses
@@ -105,7 +105,7 @@
                     + civInfo.TeamBonuses[i].History + '" tooltip_style="civInfoTooltip"]\n     ' + civInfo.TeamBonuses[i].Description + '\n[/color]';
 	}
 	
-	getGUIObjectByName("civBonuses").caption = bonusCaption;
+	Engine.GetGUIObjectByName("civBonuses").caption = bonusCaption;
 
 
 	// Special techs / buildings
@@ -129,7 +129,7 @@
                     + civInfo.Structures[i].History + '" tooltip_style="civInfoTooltip"]\n';
 	}
 	
-	getGUIObjectByName("civTechs").caption = techCaption;
+	Engine.GetGUIObjectByName("civTechs").caption = techCaption;
 
 
 	// Heroes
@@ -146,10 +146,10 @@
 		heroCaption += '\n';
 	}
 	
-	getGUIObjectByName("civHeroes").caption = heroCaption;
+	Engine.GetGUIObjectByName("civHeroes").caption = heroCaption;
 
 
 	// Update civ history display
-	getGUIObjectByName("civHistoryHeading").caption = heading("History of the " + civInfo.Name, 16);
-	getGUIObjectByName("civHistoryText").caption = civInfo.History;
+	Engine.GetGUIObjectByName("civHistoryHeading").caption = heading("History of the " + civInfo.Name, 16);
+	Engine.GetGUIObjectByName("civHistoryText").caption = civInfo.History;
 }
Index: binaries/data/mods/public/gui/aiconfig/aiconfig.js
===================================================================
--- binaries/data/mods/public/gui/aiconfig/aiconfig.js	(Revision 14461)
+++ binaries/data/mods/public/gui/aiconfig/aiconfig.js	(Arbeitskopie)
@@ -9,7 +9,7 @@
 		{id: "", data: {name: "None", description: "AI will be disabled for this player."}}
 	].concat(settings.ais);
 
-	var aiSelection = getGUIObjectByName("aiSelection");
+	var aiSelection = Engine.GetGUIObjectByName("aiSelection");
 	aiSelection.list = [ ai.data.name for each (ai in g_AIs) ];
 
 	var selected = 0;
@@ -23,7 +23,7 @@
 	}
 	aiSelection.selected = selected;
 	
-	var aiDiff = getGUIObjectByName("aiDifficulty");
+	var aiDiff = Engine.GetGUIObjectByName("aiDifficulty");
 	aiDiff.list = [ "Sandbox", "Easy", "Medium", "Hard", "Very Hard" ];
 	aiDiff.selected = settings.difficulty;
 }
@@ -34,17 +34,17 @@
 	var name = g_AIs[idx].data.name;
 	var description = g_AIs[idx].data.description;
 
-	getGUIObjectByName("aiDescription").caption = description;
+	Engine.GetGUIObjectByName("aiDescription").caption = description;
 }
 
 function returnAI()
 {
-	var aiSelection = getGUIObjectByName("aiSelection");
+	var aiSelection = Engine.GetGUIObjectByName("aiSelection");
 	var idx = aiSelection.selected;
 	var id = g_AIs[idx].id;
 	var name = g_AIs[idx].data.name;
 
-	var difficulty = getGUIObjectByName("aiDifficulty").selected;
+	var difficulty = Engine.GetGUIObjectByName("aiDifficulty").selected;
 	
 	// Pop the page before calling the callback, so the callback runs
 	// in the parent GUI page's context
Index: binaries/data/mods/public/gui/common/functions_civinfo.js
===================================================================
--- binaries/data/mods/public/gui/common/functions_civinfo.js	(Revision 14461)
+++ binaries/data/mods/public/gui/common/functions_civinfo.js	(Arbeitskopie)
@@ -9,7 +9,7 @@
 function loadCivData()
 {	// Load all JSON files containing civ data
 	var civData = {};
-	var civFiles = buildDirEntList("civs/", "*.json", false);
+	var civFiles = Engine.BuildDirEntList("civs/", "*.json", false);
 	
 	for each (var filename in civFiles)
 	{	// Parse data if valid file
Index: binaries/data/mods/public/gui/common/functions_utility_music.js
===================================================================
--- binaries/data/mods/public/gui/common/functions_utility_music.js	(Revision 14461)
+++ binaries/data/mods/public/gui/common/functions_utility_music.js	(Arbeitskopie)
@@ -50,7 +50,7 @@
 	// Get names of sounds (attack, command, select, hit, pain).
 	// or
 	// Get names of "peace", "menu" (theme) and "battle" tracks.
-	var soundArray = buildDirEntList(randomSoundPath, "*" + soundSubType + "*", false);
+	var soundArray = Engine.BuildDirEntList(randomSoundPath, "*" + soundSubType + "*", false);
 	if (soundArray.length == 0)
 	{
 		Engine.Console_Write ("Failed to find sounds matching '*"+soundSubType+"*'");
Index: binaries/data/mods/public/gui/common/functions_utility_error.js
===================================================================
--- binaries/data/mods/public/gui/common/functions_utility_error.js	(Revision 14461)
+++ binaries/data/mods/public/gui/common/functions_utility_error.js	(Arbeitskopie)
@@ -7,7 +7,7 @@
 function cancelOnError(msg)
 {
 	// Delete game objects
-	endGame();
+	Engine.EndGame();
 	
 	// Return to pregame
 	Engine.SwitchGuiPage("page_pregame.xml");
@@ -25,5 +25,5 @@
 	}
 	
 	// Reset cursor
-	setCursor("arrow-default");
+	Engine.SetCursor("arrow-default");
 }
Index: binaries/data/mods/public/gui/common/functions_utility_list.js
===================================================================
--- binaries/data/mods/public/gui/common/functions_utility_list.js	(Revision 14461)
+++ binaries/data/mods/public/gui/common/functions_utility_list.js	(Arbeitskopie)
@@ -10,15 +10,15 @@
 // Remove the item at the given index (pos) from the given list object (objectName).
 function removeItem (objectName, pos)
 {
-	if (getGUIObjectByName (objectName) == null)
+	if (Engine.GetGUIObjectByName (objectName) == null)
 		Engine.Console_Write ("removeItem(): " + objectName + " not found.");
 
-	var list = getGUIObjectByName (objectName).list;
-	var selected = getGUIObjectByName (objectName).selected;
+	var list = Engine.GetGUIObjectByName (objectName).list;
+	var selected = Engine.GetGUIObjectByName (objectName).selected;
 
 	list.splice(pos, 1);
 
-	getGUIObjectByName (objectName).list = list;
+	Engine.GetGUIObjectByName (objectName).list = list;
 
 	// It's important that we update the selection *after*
 	//  we've committed the changes to the list.
@@ -26,12 +26,12 @@
 	// Update the selected so the same element remains selected.
 	if (selected == pos)
 	{
-		getGUIObjectByName (objectName).selected = -1;
+		Engine.GetGUIObjectByName (objectName).selected = -1;
 	}
 	else
 	if (selected > pos)
 	{
-		getGUIObjectByName (objectName).selected = selected - 1;
+		Engine.GetGUIObjectByName (objectName).selected = selected - 1;
 	}
 }
 
@@ -40,15 +40,15 @@
 // Add the item at the given index (pos) to the given list object (objectName) with the given value (value).
 function addItem (objectName, pos, value)
 {
-	if (getGUIObjectByName (objectName) == null)
+	if (Engine.GetGUIObjectByName (objectName) == null)
 		Engine.Console_Write ("addItem(): " + objectName + " not found.");
 
-	var list = getGUIObjectByName (objectName).list;
-	var selected = getGUIObjectByName (objectName).selected;
+	var list = Engine.GetGUIObjectByName (objectName).list;
+	var selected = Engine.GetGUIObjectByName (objectName).selected;
 
 	list.splice (pos, 0, value);
 
-	getGUIObjectByName (objectName).list = list;
+	Engine.GetGUIObjectByName (objectName).list = list;
 
 	// It's important that we update the selection *after*
 	//  we've committed the changes to the list.
@@ -56,7 +56,7 @@
 	// Update the selected so the same element remains selected.
 	if (selected >= pos)
 	{
-		getGUIObjectByName (objectName).selected = selected + 1;
+		Engine.GetGUIObjectByName (objectName).selected = selected + 1;
 	}
 }
 
@@ -65,14 +65,14 @@
 // Adds an element to the end of the list
 function pushItem (objectName, value)
 {
-	if (getGUIObjectByName (objectName) == null)
+	if (Engine.GetGUIObjectByName (objectName) == null)
 		Engine.Console_Write ("pushItem(): " + objectName + " not found.");
 
-	var list = getGUIObjectByName (objectName).list;
+	var list = Engine.GetGUIObjectByName (objectName).list;
 	list.push (value);
-	getGUIObjectByName (objectName).list = list;
+	Engine.GetGUIObjectByName (objectName).list = list;
 	// Point to the new item.
-	getGUIObjectByName(objectName).selected = getNumItems(objectName)-1;
+	Engine.GetGUIObjectByName(objectName).selected = getNumItems(objectName)-1;
 }
 
 // ====================================================================
@@ -80,15 +80,15 @@
 // Removes the last element
 function popItem (objectName)
 {
-	if (getGUIObjectByName (objectName) == null)
+	if (Engine.GetGUIObjectByName (objectName) == null)
 		Engine.Console_Write ("popItem(): " + objectName + " not found.");
 
-	var selected = getGUIObjectByName (objectName).selected;
+	var selected = Engine.GetGUIObjectByName (objectName).selected;
 	removeItem(objectName, getNumItems(objectName)-1);
 
 	if (selected == getNumItems(objectName)-1)
 	{
-		getGUIObjectByName(objectName).selected = -1;
+		Engine.GetGUIObjectByName(objectName).selected = -1;
 	}
 }
 
@@ -97,10 +97,10 @@
 // Retrieves the number of elements in the list
 function getNumItems (objectName)
 {
-	if (getGUIObjectByName (objectName) == null)
+	if (Engine.GetGUIObjectByName (objectName) == null)
 		Engine.Console_Write ("getNumItems(): " + objectName + " not found.");
 
-	var list = getGUIObjectByName(objectName).list;
+	var list = Engine.GetGUIObjectByName(objectName).list;
 	return list.length;
 }
 
@@ -109,10 +109,10 @@
 // Retrieves the value of the item at 'pos'
 function getItemValue (objectName, pos)
 {
-	if (getGUIObjectByName (objectName) == null)
+	if (Engine.GetGUIObjectByName (objectName) == null)
 		Engine.Console_Write ("getItemValue(): " + objectName + " not found.");
 
-	var list = getGUIObjectByName(objectName).list;
+	var list = Engine.GetGUIObjectByName(objectName).list;
 	return list[pos];
 }
 
@@ -121,13 +121,13 @@
 // Retrieves the value of the currently selected item
 function getCurrItemValue (objectName)
 {
-	if (getGUIObjectByName (objectName) == null)
+	if (Engine.GetGUIObjectByName (objectName) == null)
 		Engine.Console_Write ("getCurrItemValue(): " + objectName + " not found.");
 
-	if (getGUIObjectByName(objectName).selected == -1)
+	if (Engine.GetGUIObjectByName(objectName).selected == -1)
 		return "";
-	var list = getGUIObjectByName(objectName).list;
-	return list[getGUIObjectByName(objectName).selected];
+	var list = Engine.GetGUIObjectByName(objectName).list;
+	return list[Engine.GetGUIObjectByName(objectName).selected];
 }
 
 // ====================================================================
@@ -136,14 +136,14 @@
 // already in the list).
 function setCurrItemValue (objectName, string)
 {
-	if (getGUIObjectByName(objectName) == null) {
+	if (Engine.GetGUIObjectByName(objectName) == null) {
 		Engine.Console_Write ("setCurrItemValue(): " + objectName + " not found.");
 		return -1;
 	}
 
-	if (getGUIObjectByName(objectName).selected == -1)
+	if (Engine.GetGUIObjectByName(objectName).selected == -1)
 		return -1;	// Return -1 if nothing selected.
-	var list = getGUIObjectByName(objectName).list;
+	var list = Engine.GetGUIObjectByName(objectName).list;
 	// Seek through list.
 	for (var ctr = 0; ctr < list.length; ctr++)
 	{
@@ -151,7 +151,7 @@
 		if (list[ctr] == string)
 		{
 			// Point selected to this item.
-			getGUIObjectByName(objectName).selected = ctr;
+			Engine.GetGUIObjectByName(objectName).selected = ctr;
 			return ctr;	// Return position of item.
 		}
 	}
Index: binaries/data/mods/public/gui/common/functions_utility_test.js
===================================================================
--- binaries/data/mods/public/gui/common/functions_utility_test.js	(Revision 14461)
+++ binaries/data/mods/public/gui/common/functions_utility_test.js	(Arbeitskopie)
@@ -1,6 +1,6 @@
 function updateOrbital()
 {
-	if( !getGUIObjectByName( 'arena' ).hidden )
+	if( !Engine.GetGUIObjectByName( 'arena' ).hidden )
 	{
 		g_ballx += g_balldx;
 		g_bally += g_balldy;
@@ -36,7 +36,7 @@
 		g_balldx -= force * vect_x;
 		g_balldy -= force * vect_y;
 
-		var ball = getGUIObjectByName('ball');
+		var ball = Engine.GetGUIObjectByName('ball');
 		var r=5;
 		ball.size = new GUISize(g_ballx-r, g_bally-r, g_ballx+r, g_bally+r);
 	}
Index: binaries/data/mods/public/gui/common/functions_utility.js
===================================================================
--- binaries/data/mods/public/gui/common/functions_utility.js	(Revision 14461)
+++ binaries/data/mods/public/gui/common/functions_utility.js	(Arbeitskopie)
@@ -20,7 +20,7 @@
 // Get list of XML files in pathname with recursion, excepting those starting with _
 function getXMLFileList(pathname)
 {
-	var files = buildDirEntList(pathname, "*.xml", true);
+	var files = Engine.BuildDirEntList(pathname, "*.xml", true);
 
 	var result = [];
 
@@ -45,7 +45,7 @@
 // Get list of JSON files in pathname
 function getJSONFileList(pathname)
 {
-	var files = buildDirEntList(pathname, "*.json", false);
+	var files = Engine.BuildDirEntList(pathname, "*.json", false);
 
 	// Remove the path and extension from each name, since we just want the filename
 	files = [ n.substring(pathname.length, n.length-5) for each (n in files) ];
@@ -61,7 +61,7 @@
 {
 	var data = {};
 
-	var rawData = readFile(pathname);
+	var rawData = Engine.ReadFile(pathname);
 	if (!rawData)
 	{
 		error("Failed to read file: "+pathname);
@@ -139,7 +139,7 @@
 function parseJSONFromDataFile(filename)
 {
 	var path = "simulation/data/"+filename;
-	var rawData = readFile(path);
+	var rawData = Engine.ReadFile(path);
 	if (!rawData)
 		error("Failed to read file: "+path);
 
Index: binaries/data/mods/public/gui/common/functions_global_object.js
===================================================================
--- binaries/data/mods/public/gui/common/functions_global_object.js	(Revision 14461)
+++ binaries/data/mods/public/gui/common/functions_global_object.js	(Arbeitskopie)
@@ -6,28 +6,62 @@
 // *******************************************
 // messageBox
 // *******************************************
-// @params:     int mbWidth, int mbHeight, string mbMessage, string mbTitle, int mbMode, arr mbButtonCaptions, arr mbButtonsCode
+// @params:     int mbWidth, int mbHeight, string mbMessage, string mbTitle, int mbMode, arr mbButtonCaptions, function mbBtnCode, var mbCallbackArgs
 // @return:     void
 // @desc:       Displays a new modal message box.
 // *******************************************
 
-function messageBox (mbWidth, mbHeight, mbMessage, mbTitle, mbMode, mbButtonCaptions, mbButtonsCode)
+
+// We want to pass callback functions for the different buttons in a convenient way.
+// Because passing functions accross compartment boundaries is a pain, we just store them here together with some optional arguments.
+// The messageBox page will return the code of the pressed button and the according function will be called.
+var g_messageBoxBtnFunctions = [];
+var g_messageBoxCallbackArgs = []; 
+
+var g_messageBoxCallbackFunction = function(btnCode)
 {
+	if (btnCode !== undefined && g_messageBoxBtnFunctions[btnCode])
+	{
+		if (g_messageBoxCallbackArgs[btnCode])
+			g_messageBoxBtnFunctions[btnCode](g_messageBoxCallbackArgs[btnCode]);
+		else
+			g_messageBoxBtnFunctions[btnCode]();
+	}
 
-	Engine.PushGuiPage("page_msgbox.xml", {
+	g_messageBoxBtnFunctions  = [];
+	g_messageBoxCallbackArgs = [];
+}
+
+function messageBox (mbWidth, mbHeight, mbMessage, mbTitle, mbMode, mbButtonCaptions, mbBtnCode, mbCallbackArgs)
+{
+	if (g_messageBoxBtnFunctions.length != 0)
+	{
+		warn("A messagebox was called when a previous callback function is still set, aborting!");
+		return;	
+	}
+
+	g_messageBoxBtnFunctions = mbBtnCode;
+	if (mbCallbackArgs)
+		g_messageBoxCallbackArgs = mbCallbackArgs;
+
+	var initData = {
 		width: mbWidth,
 		height: mbHeight,
 		message: mbMessage,
 		title: mbTitle,
 		mode: mbMode,
 		buttonCaptions: mbButtonCaptions,
-		buttonCode: mbButtonsCode
-	});
+	}
+	if (mbBtnCode)
+		initData.callback = "g_messageBoxCallbackFunction";
+		
+
+	Engine.PushGuiPage("page_msgbox.xml", initData);
 }
 
 // ====================================================================
 
 function updateFPS()
 {	
-	getGUIObjectByName("fpsCounter").caption = "FPS: " + getFPS();
+	Engine.GetGUIObjectByName("fpsCounter").caption = "FPS: " + Engine.GetFPS();
 }
Index: build/premake/premake4.lua
===================================================================
--- build/premake/premake4.lua	(Revision 14461)
+++ build/premake/premake4.lua	(Arbeitskopie)
@@ -733,6 +733,9 @@
 		"opengl",
 		"boost",
 	}
+	if not _OPTIONS["without-audio"] then
+		table.insert(extern_libs, "openal")
+	end
 	setup_static_lib_project("gui", source_dirs, extern_libs, {})
 
 
Index: source/tools/atlas/GameInterface/ActorViewer.cpp
===================================================================
--- source/tools/atlas/GameInterface/ActorViewer.cpp	(Revision 14461)
+++ source/tools/atlas/GameInterface/ActorViewer.cpp	(Arbeitskopie)
@@ -67,7 +67,7 @@
 		MeshManager(ColladaManager),
 		SkeletonAnimManager(ColladaManager),
 		UnitManager(),
-		Simulation2(&UnitManager, &Terrain),
+		Simulation2(&UnitManager, g_ScriptRuntime, &Terrain),
 		ObjectManager(MeshManager, SkeletonAnimManager, Simulation2),
 		LOSTexture(Simulation2),
 		TerritoryTexture(Simulation2)
Index: source/tools/atlas/GameInterface/GameLoop.cpp
===================================================================
--- source/tools/atlas/GameInterface/GameLoop.cpp	(Revision 14461)
+++ source/tools/atlas/GameInterface/GameLoop.cpp	(Arbeitskopie)
@@ -39,7 +39,6 @@
 #include "ps/Profile.h"
 #include "ps/GameSetup/Paths.h"
 #include "renderer/Renderer.h"
-#include "scripting/ScriptingHost.h"
 
 using namespace AtlasMessage;
 
@@ -329,7 +328,6 @@
 
 	// Clean up
 	AtlasView::DestroyViews();
-	ScriptingHost::FinalShutdown();
 	AtlasMessage::g_MessagePasser = NULL;
 
 	return true;
Index: source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp
===================================================================
--- source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp	(Revision 14461)
+++ source/tools/atlas/GameInterface/Handlers/MiscHandlers.cpp	(Arbeitskopie)
@@ -25,6 +25,7 @@
 #include "graphics/CinemaTrack.h"
 #include "graphics/GameView.h"
 #include "gui/GUIManager.h"
+#include "gui/GUI.h"
 #include "lib/external_libraries/libsdl.h"
 #include "lib/sysdep/cpu.h"
 #include "maths/MathUtil.h"
@@ -33,7 +34,6 @@
 #include "ps/GameSetup/Config.h"
 #include "ps/GameSetup/GameSetup.h"
 #include "renderer/Renderer.h"
-#include "scripting/ScriptingHost.h"
 
 extern void (*Atlas_GLSwapBuffers)(void* context);
 
@@ -149,12 +149,12 @@
 
 MESSAGEHANDLER(JavaScript)
 {
-	g_ScriptingHost.ExecuteScript(*msg->command, L"Atlas");
+	g_GUI->GetActiveGUI()->GetScriptInterface()->LoadGlobalScript(L"Atlas", *msg->command);
 }
 
 MESSAGEHANDLER(GuiSwitchPage)
 {
-	g_GUI->SwitchPage(*msg->page, CScriptVal());
+	g_GUI->SwitchPage(*msg->page, NULL, JSVAL_VOID);
 }
 
 MESSAGEHANDLER(GuiMouseButtonEvent)
Index: source/graphics/tests/test_LOSTexture.h
===================================================================
--- source/graphics/tests/test_LOSTexture.h	(Revision 14461)
+++ source/graphics/tests/test_LOSTexture.h	(Arbeitskopie)
@@ -19,6 +19,7 @@
 
 #include "graphics/LOSTexture.h"
 #include "lib/timer.h"
+#include "scriptinterface/ScriptInterface.h"
 #include "simulation2/Simulation2.h"
 
 class TestLOSTexture : public CxxTest::TestSuite
@@ -26,7 +27,7 @@
 public:
 	void test_basic()
 	{
-		CSimulation2 sim(NULL, NULL);
+		CSimulation2 sim(NULL, ScriptInterface::CreateRuntime(), NULL);
 		CLOSTexture tex(sim);
 
 		const ssize_t size = 8;
@@ -60,7 +61,7 @@
 
 	void test_perf_DISABLED()
 	{
-		CSimulation2 sim(NULL, NULL);
+		CSimulation2 sim(NULL, ScriptInterface::CreateRuntime(), NULL);
 		CLOSTexture tex(sim);
 
 		const ssize_t size = 257;
Index: source/graphics/scripting/JSInterface_GameView.cpp
===================================================================
--- source/graphics/scripting/JSInterface_GameView.cpp	(Revision 14461)
+++ source/graphics/scripting/JSInterface_GameView.cpp	(Arbeitskopie)
@@ -24,7 +24,7 @@
 #include "scriptinterface/ScriptInterface.h"
 
 #define IMPLEMENT_BOOLEAN_SCRIPT_SETTING(NAME) \
-bool JSI_GameView::Get##NAME##Enabled(void* UNUSED(cbdata)) \
+bool JSI_GameView::Get##NAME##Enabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) \
 { \
 	if (!g_Game || !g_Game->GetView()) \
 	{ \
@@ -34,7 +34,7 @@
 	return g_Game->GetView()->Get##NAME##Enabled(); \
 } \
 \
-void JSI_GameView::Set##NAME##Enabled(void* UNUSED(cbdata), bool Enabled) \
+void JSI_GameView::Set##NAME##Enabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool Enabled) \
 { \
 	if (!g_Game || !g_Game->GetView()) \
 	{ \
Index: source/graphics/scripting/JSInterface_GameView.h
===================================================================
--- source/graphics/scripting/JSInterface_GameView.h	(Revision 14461)
+++ source/graphics/scripting/JSInterface_GameView.h	(Arbeitskopie)
@@ -20,11 +20,11 @@
 #define INCLUDED_JSINTERFACE_GAMEVIEW
 
 #include "ps/CStr.h"
-class ScriptInterface;
+#include "scriptinterface/ScriptInterface.h"
 
 #define DECLARE_BOOLEAN_SCRIPT_SETTING(NAME) \
-	bool Get##NAME##Enabled(void* cbdata); \
-	void Set##NAME##Enabled(void* cbdata, bool Enabled);
+	bool Get##NAME##Enabled(ScriptInterface::CxPrivate* pCxPrivate); \
+	void Set##NAME##Enabled(ScriptInterface::CxPrivate* pCxPrivate, bool Enabled);
 
 namespace JSI_GameView
 {
Index: source/graphics/MapGenerator.h
===================================================================
--- source/graphics/MapGenerator.h	(Revision 14461)
+++ source/graphics/MapGenerator.h	(Arbeitskopie)
@@ -120,11 +120,11 @@
 	bool LoadScripts(const std::wstring& libraryName);
 	
 	// callbacks for script functions
-	static bool LoadLibrary(void* cbdata, std::wstring name);
-	static void ExportMap(void* cbdata, CScriptValRooted data);
-	static void SetProgress(void* cbdata, int progress);
-	static void MaybeGC(void* cbdata);
-	static std::vector<std::string> GetCivData(void* cbdata);
+	static bool LoadLibrary(ScriptInterface::CxPrivate* pCxPrivate, std::wstring name);
+	static void ExportMap(ScriptInterface::CxPrivate* pCxPrivate, CScriptValRooted data);
+	static void SetProgress(ScriptInterface::CxPrivate* pCxPrivate, int progress);
+	static void MaybeGC(ScriptInterface::CxPrivate* pCxPrivate);
+	static std::vector<std::string> GetCivData(ScriptInterface::CxPrivate* pCxPrivate);
 
 	std::set<std::wstring> m_LoadedLibraries;
 	shared_ptr<ScriptInterface::StructuredClone> m_MapData;
Index: source/graphics/MapGenerator.cpp
===================================================================
--- source/graphics/MapGenerator.cpp	(Revision 14461)
+++ source/graphics/MapGenerator.cpp	(Arbeitskopie)
@@ -147,16 +147,15 @@
 	return m_MapData;
 }
 
-bool CMapGeneratorWorker::LoadLibrary(void* cbdata, std::wstring name)
+bool CMapGeneratorWorker::LoadLibrary(ScriptInterface::CxPrivate* pCxPrivate, std::wstring name)
 {
-	CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(cbdata);
-
+	CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCxPrivate->pCBData);
 	return self->LoadScripts(name);
 }
 
-void CMapGeneratorWorker::ExportMap(void* cbdata, CScriptValRooted data)
+void CMapGeneratorWorker::ExportMap(ScriptInterface::CxPrivate* pCxPrivate, CScriptValRooted data)
 {
-	CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(cbdata);
+	CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCxPrivate->pCBData);
 
 	// Copy results
 	CScopeLock lock(self->m_WorkerMutex);
@@ -164,22 +163,22 @@
 	self->m_Progress = 0;
 }
 
-void CMapGeneratorWorker::SetProgress(void* cbdata, int progress)
+void CMapGeneratorWorker::SetProgress(ScriptInterface::CxPrivate* pCxPrivate, int progress)
 {
-	CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(cbdata);
+	CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCxPrivate->pCBData);
 
 	// Copy data
 	CScopeLock lock(self->m_WorkerMutex);
 	self->m_Progress = progress;
 }
 
-void CMapGeneratorWorker::MaybeGC(void* cbdata)
+void CMapGeneratorWorker::MaybeGC(ScriptInterface::CxPrivate* pCxPrivate)
 {
-	CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(cbdata);
+	CMapGeneratorWorker* self = static_cast<CMapGeneratorWorker*>(pCxPrivate->pCBData);
 	self->m_ScriptInterface->MaybeGC();
 }
 
-std::vector<std::string> CMapGeneratorWorker::GetCivData(void* UNUSED(cbdata))
+std::vector<std::string> CMapGeneratorWorker::GetCivData(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	VfsPath path(L"civs/");
 	VfsPaths pathnames;
Index: source/scripting/ScriptingHost.cpp
===================================================================
--- source/scripting/ScriptingHost.cpp	(Revision 14461)
+++ source/scripting/ScriptingHost.cpp	(Arbeitskopie)
@@ -1,214 +0,0 @@
-/* Copyright (C) 2010 Wildfire Games.
- * This file is part of 0 A.D.
- *
- * 0 A.D. is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * 0 A.D. is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "precompiled.h"
-
-#include <sstream>
-
-#include "ScriptingHost.h"
-#include "ScriptGlue.h"
-#include "lib/utf8.h"
-#include "ps/Profile.h"
-#include "ps/CLogger.h"
-#include "ps/Filesystem.h"
-#include "scriptinterface/ScriptInterface.h"
-
-ScriptingHost::ScriptingHost()
-{
-	m_ScriptInterface = new ScriptInterface("Engine", "GUI", ScriptInterface::CreateRuntime());
-
-    m_Context = m_ScriptInterface->GetContext();
-
-	m_GlobalObject = JS_GetGlobalObject(m_Context);
-
-	if (!JS_DefineFunctions(m_Context, m_GlobalObject, ScriptFunctionTable))
-		throw PSERROR_Scripting_SetupFailed();
-}
-
-ScriptingHost::~ScriptingHost()
-{
-	delete m_ScriptInterface;
-}
-
-ScriptInterface& ScriptingHost::GetScriptInterface()
-{
-	return *m_ScriptInterface;
-}
-
-void ScriptingHost::FinalShutdown()
-{
-	// This should only be called once per process, just to clean up before
-	// we report memory leaks. (Otherwise, if it's called while there are
-	// other contexts active in other threads, things will break.)
-	JS_ShutDown();
-}
-
-// filename, line and globalObject default to 0 (in which case we execute
-// the whole script / use our m_GlobalObject)
-void ScriptingHost::RunMemScript(const char* script, size_t size, const char* filename, int line, JSObject* globalObject)
-{
-	if(!filename)
-		filename = "unspecified file";
-	if(!globalObject)
-		globalObject = m_GlobalObject;
-
-	// Maybe TODO: support Unicode input formats?
-
-	jsval rval;
-	JSBool ok = JS_EvaluateScript(m_Context, globalObject, script, (uintN)size, filename, line, &rval); 
-
-	if (ok == JS_FALSE)
-		throw PSERROR_Scripting_LoadFile_EvalErrors();
-}
-
-// globalObject defaults to 0 (in which case we use our m_GlobalObject).
-void ScriptingHost::RunScript(const VfsPath& pathname, JSObject* globalObject)
-{
-	if(!globalObject)
-		globalObject = m_GlobalObject;
-
-	shared_ptr<u8> buf; size_t size;
-	if(g_VFS->LoadFile(pathname, buf, size) != INFO::OK)	// ERRTODO: translate/pass it on
-		throw PSERROR_Scripting_LoadFile_OpenFailed();
-
-	std::wstring scriptw = wstring_from_utf8(std::string(buf.get(), buf.get() + size));
-	utf16string script(scriptw.begin(), scriptw.end());
-
-	jsval rval;
-	JSBool ok = JS_EvaluateUCScript(m_Context, globalObject,
-		reinterpret_cast<const jschar*>(script.c_str()), (uintN)script.size(),
-		utf8_from_wstring(pathname.string()).c_str(), 1, &rval);
-
-	if (ok == JS_FALSE)
-		throw PSERROR_Scripting_LoadFile_EvalErrors();
-}
-
-jsval ScriptingHost::ExecuteScript(const CStrW& script, const CStrW& calledFrom, JSObject* contextObject )
-{
-	jsval rval; 
-
-	JSBool ok = JS_EvaluateUCScript(m_Context, contextObject ? contextObject : m_GlobalObject,
-		reinterpret_cast<const jschar*>(script.utf16().c_str()), (int)script.length(),
-		calledFrom.ToUTF8().c_str(), 1, &rval);
-
-	if (!ok) return JSVAL_NULL;
-
-	return rval;
-}
-
-void ScriptingHost::DefineCustomObjectType(JSClass *clasp, JSNative constructor, uintN minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
-{
-	std::string typeName = clasp->name;
-
-	if (m_CustomObjectTypes.find(typeName) != m_CustomObjectTypes.end())
-	{
-		// This type already exists
-		throw PSERROR_Scripting_DefineType_AlreadyExists();
-	}
-
-	JSObject * obj = JS_InitClass(	m_Context, m_GlobalObject, 0, 
-									clasp,
-									constructor, minArgs,				// Constructor, min args
-									ps, fs,								// Properties, methods
-									static_ps, static_fs);				// Constructor properties, methods
-
-	if (obj == NULL)
-		throw PSERROR_Scripting_DefineType_CreationFailed();
-
-	CustomType type;
-	
-	type.m_Object = obj;
-	type.m_Class = clasp;
-
-	m_CustomObjectTypes[typeName] = type;
-}
-
-JSObject * ScriptingHost::CreateCustomObject(const std::string & typeName)
-{
-	std::map < std::string, CustomType > ::iterator it = m_CustomObjectTypes.find(typeName);
-
-	if (it == m_CustomObjectTypes.end())
-		throw PSERROR_Scripting_TypeDoesNotExist();
-
-	return JS_ConstructObject(m_Context, (*it).second.m_Class, (*it).second.m_Object, NULL);
-
-}
-
-
-
-void ScriptingHost::SetObjectProperty(JSObject * object, const std::string & propertyName, jsval value)
-{
-	JS_SetProperty(m_Context, object, propertyName.c_str(), &value);
-}
-
-jsval ScriptingHost::GetObjectProperty( JSObject* object, const std::string& propertyName )
-{
-	jsval vp;
-	JS_GetProperty( m_Context, object, propertyName.c_str(), &vp );
-	return( vp );
-}
-
-
-
-void ScriptingHost::SetObjectProperty_Double(JSObject* object, const char* propertyName, double value)
-{
-	jsval v;
-	if (! JS_NewNumberValue(m_Context, value, &v))
-		throw PSERROR_Scripting_ConversionFailed();
-
-	if (! JS_SetProperty(m_Context, object, propertyName, &v))
-		throw PSERROR_Scripting_ConversionFailed();
-}
-
-double ScriptingHost::GetObjectProperty_Double(JSObject* object, const char* propertyName)
-{
-	jsval v;
-	double d;
-
-	if (! JS_GetProperty(m_Context, object, propertyName, &v))
-		throw PSERROR_Scripting_ConversionFailed();
-	if (! JS_ValueToNumber(m_Context, v, &d))
-		throw PSERROR_Scripting_ConversionFailed();
-	return d;
-}
-
-
-
-void ScriptingHost::SetGlobal(const std::string &globalName, jsval value)
-{
-	JS_SetProperty(m_Context, m_GlobalObject, globalName.c_str(), &value);
-}
-
-
-
-//----------------------------------------------------------------------------
-// conversions
-//----------------------------------------------------------------------------
-
-CStrW ScriptingHost::ValueToUCString( const jsval value )
-{
-	JSString* string = JS_ValueToString(m_Context, value);
-	if (string == NULL)
-		throw PSERROR_Scripting_ConversionFailed();
-
-	size_t length;
-	const jschar *strptr = JS_GetStringCharsAndLength(m_Context, string, &length);
-	if (!strptr)
-		throw PSERROR_Scripting_ConversionFailed();
-
-	return std::wstring(strptr, strptr+length);
-}
Index: source/scripting/ScriptGlue.cpp
===================================================================
--- source/scripting/ScriptGlue.cpp	(Revision 14461)
+++ source/scripting/ScriptGlue.cpp	(Arbeitskopie)
@@ -1,405 +0,0 @@
-/* Copyright (C) 2013 Wildfire Games.
- * This file is part of 0 A.D.
- *
- * 0 A.D. is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * 0 A.D. is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-// This module defines the table of all functions callable from JS.
-// it's required by the interpreter; we make use of the opportunity to
-// document them all in one spot. we thus obviate having to dig through
-// all the other headers. most of the functions are implemented here;
-// as for the rest, we only link to their docs (duplication is bad).
-
-#include "precompiled.h"
-
-#include "ScriptGlue.h"
-
-#include "graphics/GameView.h"
-#include "graphics/LightEnv.h"
-#include "graphics/MapWriter.h"
-#include "graphics/Unit.h"
-#include "graphics/UnitManager.h"
-#include "gui/GUIManager.h"
-#include "gui/IGUIObject.h"
-#include "lib/frequency_filter.h"
-#include "lib/svn_revision.h"
-#include "lib/timer.h"
-#include "lib/sysdep/sysdep.h"	// sys_OpenFile
-#include "network/NetServer.h"
-#include "ps/CConsole.h"
-#include "ps/CLogger.h"
-#include "ps/CStr.h"
-#include "ps/Game.h"
-#include "ps/Globals.h"	// g_frequencyFilter
-#include "ps/GameSetup/GameSetup.h"
-#include "ps/Hotkey.h"
-#include "ps/ProfileViewer.h"
-#include "ps/World.h"
-#include "ps/scripting/JSInterface_Console.h"
-#include "ps/scripting/JSInterface_VFS.h"
-#include "renderer/Renderer.h"
-#include "scriptinterface/ScriptInterface.h"
-#include "simulation2/Simulation2.h"
-#include "soundmanager/ISoundManager.h"
-
-// rationale: the function table is now at the end of the source file to
-// avoid the need for forward declarations for every function.
-
-// all normal function wrappers have the following signature:
-//   JSBool func(JSContext* cx, JSObject* globalObject, uintN argc, jsval* argv, jsval* rval);
-// all property accessors have the following signature:
-//   JSBool accessor(JSContext* cx, JSObject* globalObject, jsval id, jsval* vp);
-
-
-//-----------------------------------------------------------------------------
-// Timer
-//-----------------------------------------------------------------------------
-
-
-// Script profiling functions: Begin timing a piece of code with StartJsTimer(num)
-// and stop timing with StopJsTimer(num). The results will be printed to stdout
-// when the game exits.
-
-static const size_t MAX_JS_TIMERS = 20;
-static TimerUnit js_start_times[MAX_JS_TIMERS];
-static TimerUnit js_timer_overhead;
-static TimerClient js_timer_clients[MAX_JS_TIMERS];
-static wchar_t js_timer_descriptions_buf[MAX_JS_TIMERS * 12];	// depends on MAX_JS_TIMERS and format string below
-
-static void InitJsTimers()
-{
-	wchar_t* pos = js_timer_descriptions_buf;
-	for(size_t i = 0; i < MAX_JS_TIMERS; i++)
-	{
-		const wchar_t* description = pos;
-		pos += swprintf_s(pos, 12, L"js_timer %d", (int)i)+1;
-		timer_AddClient(&js_timer_clients[i], description);
-	}
-
-	// call several times to get a good approximation of 'hot' performance.
-	// note: don't use a separate timer slot to warm up and then judge
-	// overhead from another: that causes worse results (probably some
-	// caching effects inside JS, but I don't entirely understand why).
-	static const char* calibration_script =
-		"startXTimer(0);\n"
-		"stopXTimer (0);\n"
-		"\n";
-	g_ScriptingHost.RunMemScript(calibration_script, strlen(calibration_script));
-	// slight hack: call RunMemScript twice because we can't average several
-	// TimerUnit values because there's no operator/. this way is better anyway
-	// because it hopefully avoids the one-time JS init overhead.
-	g_ScriptingHost.RunMemScript(calibration_script, strlen(calibration_script));
-	js_timer_overhead = js_timer_clients[0].sum;
-	js_timer_clients[0].sum.SetToZero();
-}
-
-JSBool StartJsTimer(JSContext* cx, uintN argc, jsval* vp)
-{
-	ONCE(InitJsTimers());
-
-	JSU_REQUIRE_PARAMS(1);
-	size_t slot;
-	ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], slot);
-	if (slot >= MAX_JS_TIMERS)
-		return JS_FALSE;
-
-	js_start_times[slot].SetFromTimer();
-
-	JS_SET_RVAL(cx, vp, JSVAL_VOID);
-	return JS_TRUE;
-}
-
-
-JSBool StopJsTimer(JSContext* cx, uintN argc, jsval* vp)
-{
-	JSU_REQUIRE_PARAMS(1);
-	size_t slot;
-	ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], slot);
-	if (slot >= MAX_JS_TIMERS)
-		return JS_FALSE;
-
-	TimerUnit now;
-	now.SetFromTimer();
-	now.Subtract(js_timer_overhead);
-	BillingPolicy_Default()(&js_timer_clients[slot], js_start_times[slot], now);
-	js_start_times[slot].SetToZero();
-
-	JS_SET_RVAL(cx, vp, JSVAL_VOID);
-	return JS_TRUE;
-}
-
-
-//-----------------------------------------------------------------------------
-// Game Setup
-//-----------------------------------------------------------------------------
-
-// Immediately ends the current game (if any).
-// params:
-// returns:
-JSBool EndGame(JSContext* cx, uintN argc, jsval* vp)
-{
-	JSU_REQUIRE_NO_PARAMS();
-
-	EndGame();
-
-	JS_SET_RVAL(cx, vp, JSVAL_VOID);
-	return JS_TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// Misc. Engine Interface
-//-----------------------------------------------------------------------------
-
-// Return the global frames-per-second value.
-// params:
-// returns: FPS [int]
-// notes:
-// - This value is recalculated once a frame. We take special care to
-//   filter it, so it is both accurate and free of jitter.
-JSBool GetFps(JSContext* cx, uintN argc, jsval* vp)
-{
-	JSU_REQUIRE_NO_PARAMS();
-	int freq = 0;
-	if (g_frequencyFilter)
-		freq = g_frequencyFilter->StableFrequency();
-	JS_SET_RVAL(cx, vp, INT_TO_JSVAL(freq));
-	return JS_TRUE;
-}
-
-
-// Cause the game to exit gracefully.
-// params:
-// returns:
-// notes:
-// - Exit happens after the current main loop iteration ends
-//   (since this only sets a flag telling it to end)
-JSBool ExitProgram(JSContext* cx, uintN argc, jsval* vp)
-{
-	JSU_REQUIRE_NO_PARAMS();
-
-	kill_mainloop();
-
-	JS_SET_RVAL(cx, vp, JSVAL_VOID);
-	return JS_TRUE;
-}
-
-
-// Change the mouse cursor.
-// params: cursor name [string] (i.e. basename of definition file and texture)
-// returns:
-// notes:
-// - Cursors are stored in "art\textures\cursors"
-JSBool SetCursor(JSContext* cx, uintN argc, jsval* vp)
-{
-	JSU_REQUIRE_PARAMS(1);
-	g_CursorName = g_ScriptingHost.ValueToUCString(JS_ARGV(cx, vp)[0]);
-
-	JS_SET_RVAL(cx, vp, JSVAL_VOID);
-	return JS_TRUE;
-}
-
-JSBool GetGUIObjectByName(JSContext* cx, uintN argc, jsval* vp)
-{
-	JSU_REQUIRE_PARAMS(1);
-
-	try
-	{
-		CStr name;
-		ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], name);
-		IGUIObject* guiObj = g_GUI->FindObjectByName(name);
-		if (guiObj)
-			JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(guiObj->GetJSObject()));
-		else
-			JS_SET_RVAL(cx, vp, JSVAL_NULL);
-		return JS_TRUE;
-	}
-	catch (PSERROR_Scripting&)
-	{
-		return JS_FALSE;
-	}
-}
-
-//-----------------------------------------------------------------------------
-// Miscellany
-//-----------------------------------------------------------------------------
-
-// Return the date/time at which the current executable was compiled.
-// params: none (-> "date time (svn revision)") OR an integer specifying
-//   what to display: 0 for date, 1 for time, 2 for svn revision
-// returns: string with the requested timestamp info
-// notes:
-// - Displayed on main menu screen; tells non-programmers which auto-build
-//   they are running. Could also be determined via .EXE file properties,
-//   but that's a bit more trouble.
-// - To be exact, the date/time returned is when scriptglue.cpp was
-//   last compiled, but the auto-build does full rebuilds.
-// - svn revision is generated by calling svnversion and cached in
-//   lib/svn_revision.cpp. it is useful to know when attempting to
-//   reproduce bugs (the main EXE and PDB should be temporarily reverted to
-//   that revision so that they match user-submitted crashdumps).
-JSBool GetBuildTimestamp(JSContext* cx, uintN argc, jsval* vp)
-{
-	JSU_REQUIRE_MAX_PARAMS(1);
-
-	char buf[200];
-
-	// see function documentation
-	const int mode = argc? JSVAL_TO_INT(JS_ARGV(cx, vp)[0]) : -1;
-	switch(mode)
-	{
-	case -1:
-		sprintf_s(buf, ARRAY_SIZE(buf), "%s %s (%ls)", __DATE__, __TIME__, svn_revision);
-		break;
-	case 0:
-		sprintf_s(buf, ARRAY_SIZE(buf), "%s", __DATE__);
-		break;
-	case 1:
-		sprintf_s(buf, ARRAY_SIZE(buf), "%s", __TIME__);
-		break;
-	case 2:
-		sprintf_s(buf, ARRAY_SIZE(buf), "%ls", svn_revision);
-		break;
-	}
-
-	JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, buf)));
-	return JS_TRUE;
-}
-
-#if MOZJS_DEBUG_ABI
-void DumpHeap(const char* basename, int idx, JSContext* cx)
-{
-	char filename[64];
-	sprintf_s(filename, ARRAY_SIZE(filename), "%s.%03d.txt", basename, idx);
-	OsPath pathname = psLogDir() / filename;
-	FILE* f = sys_OpenFile(pathname, "w");
-	ENSURE(f);
-	JS_DumpHeap(cx, f, NULL, 0, NULL, (size_t)-1, NULL);
-	fclose(f);
-}
-#endif
-
-JSBool DumpHeaps(JSContext* cx, uintN argc, jsval* vp)
-{
-	UNUSED2(cx);
-	UNUSED2(argc);
-
-#if MOZJS_DEBUG_ABI
-	static int i = 0;
-
-	if (ScriptingHost::IsInitialised())
-		DumpHeap("gui", i, g_ScriptingHost.GetContext());
-	if (g_Game)
-		DumpHeap("sim", i, g_Game->GetSimulation2()->GetScriptInterface().GetContext());
-
-	++i;
-#else
-	debug_warn(L"DumpHeaps only available in DEBUG mode");
-#endif
-
-	JS_SET_RVAL(cx, vp, JSVAL_VOID);
-	return JS_TRUE;
-}
-
-//-----------------------------------------------------------------------------
-
-// Is the game paused?
-JSBool IsPaused(JSContext* cx, uintN argc, jsval* vp)
-{
-	JSU_REQUIRE_NO_PARAMS();
-
-	if (!g_Game)
-	{
-		JS_ReportError(cx, "Game is not started");
-		return JS_FALSE;
-	}
-
-	JS_SET_RVAL(cx, vp, g_Game->m_Paused ? JSVAL_TRUE : JSVAL_FALSE);
-	return JS_TRUE;
-}
-
-// Pause/unpause the game
-JSBool SetPaused(JSContext* cx, uintN argc, jsval* vp)
-{
-	JSU_REQUIRE_PARAMS( 1 );
-
-	if (!g_Game)
-	{
-		JS_ReportError(cx, "Game is not started");
-		return JS_FALSE;
-	}
-
-	try
-	{
-		ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], g_Game->m_Paused);
-
-		if ( g_SoundManager )
-			g_SoundManager->Pause(g_Game->m_Paused);
-	}
-	catch (PSERROR_Scripting_ConversionFailed&)
-	{
-		JS_ReportError(cx, "Invalid parameter to SetPaused");
-	}
-
-	JS_SET_RVAL(cx, vp, JSVAL_VOID);
-	return JS_TRUE;
-}
-
-
-//-----------------------------------------------------------------------------
-// function table
-//-----------------------------------------------------------------------------
-
-// the JS interpreter expects the table to contain 5-tuples as follows:
-// - name the function will be called as from script;
-// - function which will be called;
-// - number of arguments this function expects
-// - Flags (deprecated, always zero)
-// - Extra (reserved for future use, always zero)
-//
-// we simplify this a bit with a macro:
-#define JS_FUNC(script_name, cpp_function, min_params) { script_name, cpp_function, min_params, 0 },
-
-JSFunctionSpec ScriptFunctionTable[] =
-{
-	// Profiling
-	JS_FUNC("startXTimer", StartJsTimer, 1)
-	JS_FUNC("stopXTimer", StopJsTimer, 1)
-
-	// Game Setup
-	JS_FUNC("endGame", EndGame, 0)
-
-	// VFS (external)
-	JS_FUNC("buildDirEntList", JSI_VFS::BuildDirEntList, 1)
-	JS_FUNC("fileExists", JSI_VFS::FileExists, 1)
-	JS_FUNC("getFileMTime", JSI_VFS::GetFileMTime, 1)
-	JS_FUNC("getFileSize", JSI_VFS::GetFileSize, 1)
-	JS_FUNC("readFile", JSI_VFS::ReadFile, 1)
-	JS_FUNC("readFileLines", JSI_VFS::ReadFileLines, 1)
-
-	// Misc. Engine Interface
-	JS_FUNC("exit", ExitProgram, 0)
-	JS_FUNC("isPaused", IsPaused, 0)
-	JS_FUNC("setPaused", SetPaused, 1)
-	JS_FUNC("setCursor", SetCursor, 1)
-	JS_FUNC("getFPS", GetFps, 0)
-	JS_FUNC("getGUIObjectByName", GetGUIObjectByName, 1)
-
-	// Miscellany
-	JS_FUNC("buildTime", GetBuildTimestamp, 0)
-	JS_FUNC("dumpHeaps", DumpHeaps, 0)
-
-	// end of table marker
-	{0}
-};
-#undef JS_FUNC
Index: source/scripting/ScriptingHost.h
===================================================================
--- source/scripting/ScriptingHost.h	(Revision 14461)
+++ source/scripting/ScriptingHost.h	(Arbeitskopie)
@@ -1,117 +0,0 @@
-/* Copyright (C) 2009 Wildfire Games.
- * This file is part of 0 A.D.
- *
- * 0 A.D. is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * 0 A.D. is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef INCLUDED_SCRIPTINGHOST
-#define INCLUDED_SCRIPTINGHOST
-
-#include "ps/Errors.h"
-
-ERROR_GROUP(Scripting);
-ERROR_TYPE(Scripting, SetupFailed);
-
-ERROR_SUBGROUP(Scripting, LoadFile);
-ERROR_TYPE(Scripting_LoadFile, OpenFailed);
-ERROR_TYPE(Scripting_LoadFile, EvalErrors);
-
-ERROR_TYPE(Scripting, ConversionFailed);
-ERROR_TYPE(Scripting, CallFunctionFailed);
-ERROR_TYPE(Scripting, RegisterFunctionFailed);
-ERROR_TYPE(Scripting, DefineConstantFailed);
-ERROR_TYPE(Scripting, CreateObjectFailed);
-ERROR_TYPE(Scripting, TypeDoesNotExist);
-
-ERROR_SUBGROUP(Scripting, DefineType);
-ERROR_TYPE(Scripting_DefineType, AlreadyExists);
-ERROR_TYPE(Scripting_DefineType, CreationFailed);
-
-#include "scripting/SpiderMonkey.h"
-#include "lib/file/vfs/vfs_path.h"
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include "ps/Singleton.h"
-#include "ps/CStr.h"
-
-class ScriptInterface;
-
-class IPropertyOwner
-{
-};
-
-class ScriptingHost : public Singleton < ScriptingHost >
-{
-private:
-	class CustomType
-	{
-	public:
-		JSObject *	m_Object;
-		JSClass *	m_Class;
-	};
-
-	JSContext *		m_Context;
-	JSObject *		m_GlobalObject;
-
-	std::map < std::string, CustomType >		m_CustomObjectTypes;
-
-	// The long-term plan is to migrate from ScriptingHost to the newer shinier ScriptInterface.
-	// For now, just have a ScriptInterface that hooks onto the ScriptingHost's context so they
-	// can both be used.
-	ScriptInterface* m_ScriptInterface;
-public:
-
-	ScriptingHost();
-	~ScriptingHost();
-
-	ScriptInterface& GetScriptInterface();
-
-	static void FinalShutdown();
-	
-	// Helpers:
-
-	// TODO: Remove one of these
-	inline JSContext *getContext() { return m_Context; }
-	inline JSContext *GetContext() { return m_Context; }
-
-	inline JSObject* GetGlobalObject() { return m_GlobalObject; }
-
-	void RunMemScript(const char* script, size_t size, const char* filename = 0, int line = 0, JSObject* globalObject = 0);
-	void RunScript(const VfsPath& filename, JSObject* globalObject = 0);
-
-
-	jsval ExecuteScript(const CStrW& script, const CStrW& calledFrom = L"Console", JSObject* contextObject = NULL );
-
-	void DefineCustomObjectType(JSClass *clasp, JSNative constructor, uintN nargs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
-
-	JSObject * CreateCustomObject(const std::string & typeName);
-
-	void  SetObjectProperty(JSObject * object, const std::string & propertyName, jsval value);
-	jsval GetObjectProperty(JSObject * object, const std::string & propertyName);
-
-	void   SetObjectProperty_Double(JSObject* object, const char* propertyName, double value);
-	double GetObjectProperty_Double(JSObject* object, const char* propertyName);
-
-	void SetGlobal(const std::string& globalName, jsval value);
-
-	CStrW ValueToUCString(const jsval value);
-};
-
-#define g_ScriptingHost ScriptingHost::GetSingleton()
-
-#endif
Index: source/scripting/ScriptGlue.h
===================================================================
--- source/scripting/ScriptGlue.h	(Revision 14461)
+++ source/scripting/ScriptGlue.h	(Arbeitskopie)
@@ -1,39 +0,0 @@
-/* Copyright (C) 2009 Wildfire Games.
- * This file is part of 0 A.D.
- *
- * 0 A.D. is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * 0 A.D. is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef INCLUDED_SCRIPTGLUE
-#define INCLUDED_SCRIPTGLUE
-
-#include "ScriptingHost.h"
-
-// referenced by ScriptingHost.cpp
-extern JSFunctionSpec ScriptFunctionTable[];
-
-// dependencies (moved to header to avoid L4 warnings)
-// .. from main.cpp:
-extern int fps;
-extern void kill_mainloop();
-extern CStrW g_CursorName;
-extern void StartGame();
-extern void EndGame();
-// .. other
-#if OS_WIN
-extern int GetVRAMInfo(int&, int&);
-#endif
-
-#endif	// #ifndef INCLUDED_SCRIPTGLUE
Index: source/test_setup.cpp
===================================================================
--- source/test_setup.cpp	(Revision 14461)
+++ source/test_setup.cpp	(Arbeitskopie)
@@ -116,7 +116,7 @@
 
 namespace
 {
-	void script_TS_FAIL(void*, std::wstring msg)
+	void script_TS_FAIL(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring msg)
 	{
 		TS_FAIL(msg);
 	}
Index: source/gui/scripting/JSInterface_IGUIObject.cpp
===================================================================
--- source/gui/scripting/JSInterface_IGUIObject.cpp	(Revision 14461)
+++ source/gui/scripting/JSInterface_IGUIObject.cpp	(Arbeitskopie)
@@ -86,11 +86,11 @@
 	if (propName.substr(0, 2) == "on")
 	{
 		CStr eventName (CStr(propName.substr(2)).LowerCase());
-		std::map<CStr, JSObject**>::iterator it = e->m_ScriptHandlers.find(eventName);
+		std::map<CStr, CScriptValRooted>::iterator it = e->m_ScriptHandlers.find(eventName);
 		if (it == e->m_ScriptHandlers.end())
 			*vp = JSVAL_NULL;
 		else
-			*vp = OBJECT_TO_JSVAL(*(it->second));
+			*vp = it->second.get();
 		return JS_TRUE;
 	}
 
@@ -182,7 +182,8 @@
 				*vp = OBJECT_TO_JSVAL(obj); // root it
 				try
 				{
-				#define P(x, y, z) g_ScriptingHost.SetObjectProperty_Double(obj, #z, area.x.y)
+					ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface;
+				#define P(x, y, z) pScriptInterface->SetProperty(OBJECT_TO_JSVAL(obj), #z, area.x.y, false, true)
 					P(pixel,	left,	left);
 					P(pixel,	top,	top);
 					P(pixel,	right,	right);
@@ -481,7 +482,8 @@
 				GUI<CClientArea>::GetSetting(e, propName, area);
 
 				JSObject* obj = JSVAL_TO_OBJECT(*vp);
-				#define P(x, y, z) area.x.y = (float)g_ScriptingHost.GetObjectProperty_Double(obj, #z)
+				ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface;
+				#define P(x, y, z) pScriptInterface->GetProperty(OBJECT_TO_JSVAL(obj), #z, area.x.y)
 					P(pixel,	left,	left);
 					P(pixel,	top,	top);
 					P(pixel,	right,	right);
@@ -603,9 +605,9 @@
 	return JS_TRUE;
 }
 
-void JSI_IGUIObject::init()
+void JSI_IGUIObject::init(ScriptInterface& scriptInterface)
 {
-	g_ScriptingHost.DefineCustomObjectType(&JSI_class, construct, 1, JSI_props, JSI_methods, NULL, NULL);
+	scriptInterface.DefineCustomObjectType(&JSI_class, construct, 1, JSI_props, JSI_methods, NULL, NULL);
 }
 
 JSBool JSI_IGUIObject::toString(JSContext* cx, uintN argc, jsval* vp)
@@ -654,7 +656,6 @@
 JSBool JSI_IGUIObject::getComputedSize(JSContext* cx, uintN argc, jsval* vp)
 {
 	UNUSED2(argc);
-
 	IGUIObject* e = (IGUIObject*)JS_GetInstancePrivate(cx, JS_THIS_OBJECT(cx, vp), &JSI_IGUIObject::JSI_class, NULL);
 	if (!e)
 		return JS_FALSE;
@@ -665,10 +666,11 @@
 	JSObject* obj = JS_NewObject(cx, NULL, NULL, NULL);
 	try
 	{
-		g_ScriptingHost.SetObjectProperty_Double(obj, "left", size.left);
-		g_ScriptingHost.SetObjectProperty_Double(obj, "right", size.right);
-		g_ScriptingHost.SetObjectProperty_Double(obj, "top", size.top);
-		g_ScriptingHost.SetObjectProperty_Double(obj, "bottom", size.bottom);
+		ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface;
+		pScriptInterface->SetProperty(OBJECT_TO_JSVAL(obj), "left", size.left, false, true);
+		pScriptInterface->SetProperty(OBJECT_TO_JSVAL(obj), "right", size.right, false, true);
+		pScriptInterface->SetProperty(OBJECT_TO_JSVAL(obj), "top", size.top, false, true);
+		pScriptInterface->SetProperty(OBJECT_TO_JSVAL(obj), "bottom", size.bottom, false, true);
 	}
 	catch (PSERROR_Scripting_ConversionFailed&)
 	{
Index: source/gui/scripting/JSInterface_IGUIObject.h
===================================================================
--- source/gui/scripting/JSInterface_IGUIObject.h	(Revision 14461)
+++ source/gui/scripting/JSInterface_IGUIObject.h	(Arbeitskopie)
@@ -15,7 +15,7 @@
  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "scripting/ScriptingHost.h"
+#include "scriptinterface/ScriptInterface.h"
 
 #ifndef INCLUDED_JSI_IGUIOBJECT
 #define INCLUDED_JSI_IGUIOBJECT
@@ -32,7 +32,7 @@
 	JSBool focus(JSContext* cx, uintN argc, jsval* vp);
 	JSBool blur(JSContext* cx, uintN argc, jsval* vp);
 	JSBool getComputedSize(JSContext* cx, uintN argc, jsval* vp);
-	void init();
+	void init(ScriptInterface& scriptInterface);
 }
 
 #endif
Index: source/gui/scripting/JSInterface_GUITypes.cpp
===================================================================
--- source/gui/scripting/JSInterface_GUITypes.cpp	(Revision 14461)
+++ source/gui/scripting/JSInterface_GUITypes.cpp	(Arbeitskopie)
@@ -110,7 +110,12 @@
 
 	try
 	{
-#define SIDE(side) buffer += ToPercentString(g_ScriptingHost.GetObjectProperty_Double(JS_THIS_OBJECT(cx, vp), #side), g_ScriptingHost.GetObjectProperty_Double(JS_THIS_OBJECT(cx, vp), "r"#side));
+		ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface;
+		double val, valr;
+#define SIDE(side) \
+		pScriptInterface->GetProperty(JS_THIS_VALUE(cx, vp), #side, val); \
+		pScriptInterface->GetProperty(JS_THIS_VALUE(cx, vp), "r"#side, valr); \
+		buffer += ToPercentString(val, valr);
 		SIDE(left);
 		buffer += " ";
 		SIDE(top);
@@ -191,12 +196,12 @@
 {
 	UNUSED2(argc);
 
-	jsdouble r, g, b, a;
-	if (!JS_ValueToNumber(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "r"), &r)) return JS_FALSE;
-	if (!JS_ValueToNumber(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "g"), &g)) return JS_FALSE;
-	if (!JS_ValueToNumber(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "b"), &b)) return JS_FALSE;
-	if (!JS_ValueToNumber(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "a"), &a)) return JS_FALSE;
-
+	double r, g, b, a;
+	ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface;
+	pScriptInterface->GetProperty(JS_THIS_VALUE(cx, vp), "r", r);
+	pScriptInterface->GetProperty(JS_THIS_VALUE(cx, vp), "g", g);
+	pScriptInterface->GetProperty(JS_THIS_VALUE(cx, vp), "b", b);
+	pScriptInterface->GetProperty(JS_THIS_VALUE(cx, vp), "a", a);
 	char buffer[256];
 	// Convert to integers, to be compatible with the GUI's string SetSetting
 	snprintf(buffer, 256, "%d %d %d %d",
@@ -261,9 +266,10 @@
 	UNUSED2(argc);
 
 	int32 x, y, buttons;
-	if (!JS_ValueToECMAInt32(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "x"), &x)) return JS_FALSE;
-	if (!JS_ValueToECMAInt32(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "y"), &y)) return JS_FALSE;
-	if (!JS_ValueToECMAInt32(cx, g_ScriptingHost.GetObjectProperty(JS_THIS_OBJECT(cx, vp), "buttons"), &buttons)) return JS_FALSE;
+	ScriptInterface* pScriptInterface = ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface;
+	pScriptInterface->GetProperty(JS_THIS_VALUE(cx, vp), "x", x);
+	pScriptInterface->GetProperty(JS_THIS_VALUE(cx, vp), "y", y);
+	pScriptInterface->GetProperty(JS_THIS_VALUE(cx, vp), "buttons", buttons);
 
 	char buffer[256];
 	snprintf(buffer, 256, "%d %d %d", x, y, buttons);
@@ -273,9 +279,9 @@
 
 
 // Initialise all the types at once:
-void JSI_GUITypes::init()
+void JSI_GUITypes::init(ScriptInterface& scriptInterface)
 {
-	g_ScriptingHost.DefineCustomObjectType(&JSI_GUISize::JSI_class,  JSI_GUISize::construct,  1, JSI_GUISize::JSI_props,  JSI_GUISize::JSI_methods,  NULL, NULL);
-	g_ScriptingHost.DefineCustomObjectType(&JSI_GUIColor::JSI_class, JSI_GUIColor::construct, 1, JSI_GUIColor::JSI_props, JSI_GUIColor::JSI_methods, NULL, NULL);
-	g_ScriptingHost.DefineCustomObjectType(&JSI_GUIMouse::JSI_class, JSI_GUIMouse::construct, 1, JSI_GUIMouse::JSI_props, JSI_GUIMouse::JSI_methods, NULL, NULL);
+	scriptInterface.DefineCustomObjectType(&JSI_GUISize::JSI_class,  JSI_GUISize::construct,  1, JSI_GUISize::JSI_props,  JSI_GUISize::JSI_methods,  NULL, NULL);
+	scriptInterface.DefineCustomObjectType(&JSI_GUIColor::JSI_class, JSI_GUIColor::construct, 1, JSI_GUIColor::JSI_props, JSI_GUIColor::JSI_methods, NULL, NULL);
+	scriptInterface.DefineCustomObjectType(&JSI_GUIMouse::JSI_class, JSI_GUIMouse::construct, 1, JSI_GUIMouse::JSI_props, JSI_GUIMouse::JSI_methods, NULL, NULL);
 }
Index: source/gui/scripting/JSInterface_GUITypes.h
===================================================================
--- source/gui/scripting/JSInterface_GUITypes.h	(Revision 14461)
+++ source/gui/scripting/JSInterface_GUITypes.h	(Arbeitskopie)
@@ -15,7 +15,7 @@
  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "scripting/ScriptingHost.h"
+#include "scriptinterface/ScriptInterface.h"
 
 #ifndef INCLUDED_JSI_GUITYPES
 #define INCLUDED_JSI_GUITYPES
@@ -38,7 +38,7 @@
 
 namespace JSI_GUITypes
 {
-	void init();
+	void init(ScriptInterface& scriptInterface);
 }
 
 #endif
Index: source/gui/scripting/ScriptFunctions.cpp
===================================================================
--- source/gui/scripting/ScriptFunctions.cpp	(Revision 14461)
+++ source/gui/scripting/ScriptFunctions.cpp	(Arbeitskopie)
@@ -23,9 +23,13 @@
 #include "graphics/GameView.h"
 #include "graphics/MapReader.h"
 #include "gui/GUIManager.h"
+#include "gui/GUI.h"
+#include "gui/IGUIObject.h"
+#include "gui/scripting/JSInterface_GUITypes.h"
 #include "graphics/scripting/JSInterface_GameView.h"
 #include "lib/timer.h"
 #include "lib/utf8.h"
+#include "lib/svn_revision.h"
 #include "lib/sysdep/sysdep.h"
 #include "lobby/scripting/JSInterface_Lobby.h"
 #include "maths/FixedVector3D.h"
@@ -36,6 +40,7 @@
 #include "ps/CConsole.h"
 #include "ps/Errors.h"
 #include "ps/Game.h"
+#include "ps/Globals.h"	// g_frequencyFilter
 #include "ps/GUID.h"
 #include "ps/World.h"
 #include "ps/Hotkey.h"
@@ -45,6 +50,7 @@
 #include "ps/SavedGame.h"
 #include "ps/scripting/JSInterface_ConfigDB.h"
 #include "ps/scripting/JSInterface_Console.h"
+#include "ps/scripting/JSInterface_VFS.h"
 #include "ps/UserReport.h"
 #include "ps/GameSetup/Atlas.h"
 #include "ps/GameSetup/Config.h"
@@ -60,6 +66,8 @@
 #include "simulation2/components/ICmpTemplateManager.h"
 #include "simulation2/components/ICmpSelectable.h"
 #include "simulation2/helpers/Selection.h"
+#include "soundmanager/SoundManager.h"
+#include "soundmanager/scripting/JSInterface_Sound.h"
 
 #include "js/jsapi.h"
 /*
@@ -70,33 +78,39 @@
  */
 
 extern void restart_mainloop_in_atlas(); // from main.cpp
+extern void EndGame();
+extern void kill_mainloop();
 
 namespace {
 
-CScriptVal GetActiveGui(void* UNUSED(cbdata))
+// Note that the initData argument may only contain clonable data.
+// Functions aren't supported for example!
+// TODO: Use LOGERROR to print a friendly error message when the requirements aren't met instead of failing with debug_warn when cloning.
+void PushGuiPage(ScriptInterface::CxPrivate* pCxPrivate, std::wstring name, CScriptVal initData)
 {
-	return OBJECT_TO_JSVAL(g_GUI->GetScriptObject());
+	g_GUI->PushPage(name, pCxPrivate->pScriptInterface->WriteStructuredClone(initData.get()));
 }
 
-void PushGuiPage(void* UNUSED(cbdata), std::wstring name, CScriptVal initData)
+void SwitchGuiPage(ScriptInterface::CxPrivate* pCxPrivate, std::wstring name, CScriptVal initData)
 {
-	g_GUI->PushPage(name, initData);
+	g_GUI->SwitchPage(name, pCxPrivate->pScriptInterface, initData);
 }
 
-void SwitchGuiPage(void* UNUSED(cbdata), std::wstring name, CScriptVal initData)
+void PopGuiPage(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
-	g_GUI->SwitchPage(name, initData);
+	g_GUI->PopPage();
 }
 
-void PopGuiPage(void* UNUSED(cbdata))
+// Note that the args argument may only contain clonable data.
+// Functions aren't supported for example!
+// TODO: Use LOGERROR to print a friendly error message when the requirements aren't met instead of failing with debug_warn when cloning.
+void PopGuiPageCB(ScriptInterface::CxPrivate* pCxPrivate, CScriptVal args)
 {
-	g_GUI->PopPage();
+	g_GUI->PopPageCB(pCxPrivate->pScriptInterface->WriteStructuredClone(args.get()));
 }
 
-CScriptVal GuiInterfaceCall(void* cbdata, std::wstring name, CScriptVal data)
+CScriptVal GuiInterfaceCall(ScriptInterface::CxPrivate* pCxPrivate, std::wstring name, CScriptVal data)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
 	if (!g_Game)
 		return JSVAL_VOID;
 	CSimulation2* sim = g_Game->GetSimulation2();
@@ -110,15 +124,13 @@
 	if (g_Game)
 		player = g_Game->GetPlayerID();
 
-	CScriptValRooted arg (sim->GetScriptInterface().GetContext(), sim->GetScriptInterface().CloneValueFromOtherContext(guiManager->GetScriptInterface(), data.get()));
+	CScriptValRooted arg (sim->GetScriptInterface().GetContext(), sim->GetScriptInterface().CloneValueFromOtherContext(*(pCxPrivate->pScriptInterface), data.get()));
 	CScriptVal ret (cmpGuiInterface->ScriptCall(player, name, arg.get()));
-	return guiManager->GetScriptInterface().CloneValueFromOtherContext(sim->GetScriptInterface(), ret.get());
+	return pCxPrivate->pScriptInterface->CloneValueFromOtherContext(sim->GetScriptInterface(), ret.get());
 }
 
-void PostNetworkCommand(void* cbdata, CScriptVal cmd)
+void PostNetworkCommand(ScriptInterface::CxPrivate* pCxPrivate, CScriptVal cmd)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
 	if (!g_Game)
 		return;
 	CSimulation2* sim = g_Game->GetSimulation2();
@@ -128,67 +140,65 @@
 	if (!cmpCommandQueue)
 		return;
 
-	jsval cmd2 = sim->GetScriptInterface().CloneValueFromOtherContext(guiManager->GetScriptInterface(), cmd.get());
+	jsval cmd2 = sim->GetScriptInterface().CloneValueFromOtherContext(*(pCxPrivate->pScriptInterface), cmd.get());
 
 	cmpCommandQueue->PostNetworkCommand(cmd2);
 }
 
-std::vector<entity_id_t> PickEntitiesAtPoint(void* UNUSED(cbdata), int x, int y)
+std::vector<entity_id_t> PickEntitiesAtPoint(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int x, int y)
 {
 	return EntitySelection::PickEntitiesAtPoint(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x, y, g_Game->GetPlayerID(), false);
 }
 
-std::vector<entity_id_t> PickFriendlyEntitiesInRect(void* UNUSED(cbdata), int x0, int y0, int x1, int y1, int player)
+std::vector<entity_id_t> PickFriendlyEntitiesInRect(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int x0, int y0, int x1, int y1, int player)
 {
 	return EntitySelection::PickEntitiesInRect(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), x0, y0, x1, y1, player, false);
 }
 
-std::vector<entity_id_t> PickFriendlyEntitiesOnScreen(void* cbdata, int player)
+std::vector<entity_id_t> PickFriendlyEntitiesOnScreen(ScriptInterface::CxPrivate* pCxPrivate, int player)
 {
-	return PickFriendlyEntitiesInRect(cbdata, 0, 0, g_xres, g_yres, player);
+	return PickFriendlyEntitiesInRect(pCxPrivate, 0, 0, g_xres, g_yres, player);
 }
 
-std::vector<entity_id_t> PickSimilarFriendlyEntities(void* UNUSED(cbdata), std::string templateName, bool includeOffScreen, bool matchRank, bool allowFoundations)
+std::vector<entity_id_t> PickSimilarFriendlyEntities(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::string templateName, bool includeOffScreen, bool matchRank, bool allowFoundations)
 {
 	return EntitySelection::PickSimilarEntities(*g_Game->GetSimulation2(), *g_Game->GetView()->GetCamera(), templateName, g_Game->GetPlayerID(), includeOffScreen, matchRank, false, allowFoundations);
 }
 
-CFixedVector3D GetTerrainAtScreenPoint(void* UNUSED(cbdata), int x, int y)
+CFixedVector3D GetTerrainAtScreenPoint(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int x, int y)
 {
 	CVector3D pos = g_Game->GetView()->GetCamera()->GetWorldCoordinates(x, y, true);
 	return CFixedVector3D(fixed::FromFloat(pos.X), fixed::FromFloat(pos.Y), fixed::FromFloat(pos.Z));
 }
 
-std::wstring SetCursor(void* UNUSED(cbdata), std::wstring name)
+std::wstring SetCursor(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring name)
 {
 	std::wstring old = g_CursorName;
 	g_CursorName = name;
 	return old;
 }
 
-int GetPlayerID(void* UNUSED(cbdata))
+int GetPlayerID(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	if (g_Game)
 		return g_Game->GetPlayerID();
 	return -1;
 }
 
-void SetPlayerID(void* UNUSED(cbdata), int id)
+void SetPlayerID(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int id)
 {
 	if (g_Game)
 		g_Game->SetPlayerID(id);
 }
 
-void StartNetworkGame(void* UNUSED(cbdata))
+void StartNetworkGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	ENSURE(g_NetServer);
 	g_NetServer->StartGame();
 }
 
-void StartGame(void* cbdata, CScriptVal attribs, int playerID)
+void StartGame(ScriptInterface::CxPrivate* pCxPrivate, CScriptVal attribs, int playerID)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
 	ENSURE(!g_NetServer);
 	ENSURE(!g_NetClient);
 
@@ -198,16 +208,14 @@
 	// Convert from GUI script context to sim script context
 	CSimulation2* sim = g_Game->GetSimulation2();
 	CScriptValRooted gameAttribs (sim->GetScriptInterface().GetContext(),
-			sim->GetScriptInterface().CloneValueFromOtherContext(guiManager->GetScriptInterface(), attribs.get()));
+			sim->GetScriptInterface().CloneValueFromOtherContext(*(pCxPrivate->pScriptInterface), attribs.get()));
 
 	g_Game->SetPlayerID(playerID);
 	g_Game->StartGame(gameAttribs, "");
 }
 
-CScriptVal StartSavedGame(void* cbdata, std::wstring name)
+CScriptVal StartSavedGame(ScriptInterface::CxPrivate* pCxPrivate, std::wstring name)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
 	ENSURE(!g_NetServer);
 	ENSURE(!g_NetClient);
 
@@ -216,7 +224,7 @@
 	// Load the saved game data from disk
 	CScriptValRooted metadata;
 	std::string savedState;
-	Status err = SavedGames::Load(name, guiManager->GetScriptInterface(), metadata, savedState);
+	Status err = SavedGames::Load(name, *(pCxPrivate->pScriptInterface), metadata, savedState);
 	if (err < 0)
 		return CScriptVal();
 
@@ -225,7 +233,7 @@
 	// Convert from GUI script context to sim script context
 	CSimulation2* sim = g_Game->GetSimulation2();
 	CScriptValRooted gameMetadata (sim->GetScriptInterface().GetContext(),
-		sim->GetScriptInterface().CloneValueFromOtherContext(guiManager->GetScriptInterface(), metadata.get()));
+		sim->GetScriptInterface().CloneValueFromOtherContext(*(pCxPrivate->pScriptInterface), metadata.get()));
 
 	CScriptValRooted gameInitAttributes;
 	sim->GetScriptInterface().GetProperty(gameMetadata.get(), "initAttributes", gameInitAttributes);
@@ -240,35 +248,31 @@
 	return metadata.get();
 }
 
-void SaveGame(void* cbdata, std::wstring filename, std::wstring description)
+void SaveGame(ScriptInterface::CxPrivate* pCxPrivate, std::wstring filename, std::wstring description)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
+	CGUIManager* guiManager = static_cast<CGUIManager*> (pCxPrivate->pCBData);
 
 	if (SavedGames::Save(filename, description, *g_Game->GetSimulation2(), guiManager, g_Game->GetPlayerID()) < 0)
 		LOGERROR(L"Failed to save game");
 }
 
-void SaveGamePrefix(void* cbdata, std::wstring prefix, std::wstring description)
+void SaveGamePrefix(ScriptInterface::CxPrivate* pCxPrivate, std::wstring prefix, std::wstring description)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
+	CGUIManager* guiManager = static_cast<CGUIManager*> (pCxPrivate->pCBData);
 
 	if (SavedGames::SavePrefix(prefix, description, *g_Game->GetSimulation2(), guiManager, g_Game->GetPlayerID()) < 0)
 		LOGERROR(L"Failed to save game");
 }
 
-void SetNetworkGameAttributes(void* cbdata, CScriptVal attribs)
+void SetNetworkGameAttributes(ScriptInterface::CxPrivate* pCxPrivate, CScriptVal attribs)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
 	ENSURE(g_NetServer);
 
-	g_NetServer->UpdateGameAttributes(attribs, guiManager->GetScriptInterface());
+	g_NetServer->UpdateGameAttributes(attribs, *(pCxPrivate->pScriptInterface));
 }
 
-void StartNetworkHost(void* cbdata, std::wstring playerName)
+void StartNetworkHost(ScriptInterface::CxPrivate* pCxPrivate, std::wstring playerName)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
 	ENSURE(!g_NetClient);
 	ENSURE(!g_NetServer);
 	ENSURE(!g_Game);
@@ -276,7 +280,7 @@
 	g_NetServer = new CNetServer();
 	if (!g_NetServer->SetupConnection())
 	{
-		guiManager->GetScriptInterface().ReportError("Failed to start server");
+		pCxPrivate->pScriptInterface->ReportError("Failed to start server");
 		SAFE_DELETE(g_NetServer);
 		return;
 	}
@@ -287,16 +291,14 @@
 
 	if (!g_NetClient->SetupConnection("127.0.0.1"))
 	{
-		guiManager->GetScriptInterface().ReportError("Failed to connect to server");
+		pCxPrivate->pScriptInterface->ReportError("Failed to connect to server");
 		SAFE_DELETE(g_NetClient);
 		SAFE_DELETE(g_Game);
 	}
 }
 
-void StartNetworkJoin(void* cbdata, std::wstring playerName, std::string serverAddress)
+void StartNetworkJoin(ScriptInterface::CxPrivate* pCxPrivate, std::wstring playerName, std::string serverAddress)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
 	ENSURE(!g_NetClient);
 	ENSURE(!g_NetServer);
 	ENSURE(!g_Game);
@@ -306,13 +308,13 @@
 	g_NetClient->SetUserName(playerName);
 	if (!g_NetClient->SetupConnection(serverAddress))
 	{
-		guiManager->GetScriptInterface().ReportError("Failed to connect to server");
+		pCxPrivate->pScriptInterface->ReportError("Failed to connect to server");
 		SAFE_DELETE(g_NetClient);
 		SAFE_DELETE(g_Game);
 	}
 }
 
-void DisconnectNetworkGame(void* UNUSED(cbdata))
+void DisconnectNetworkGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	// TODO: we ought to do async reliable disconnections
 
@@ -321,97 +323,87 @@
 	SAFE_DELETE(g_Game);
 }
 
-CScriptVal PollNetworkClient(void* cbdata)
+CScriptVal PollNetworkClient(ScriptInterface::CxPrivate* pCxPrivate)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
 	if (!g_NetClient)
 		return CScriptVal();
 
 	CScriptValRooted poll = g_NetClient->GuiPoll();
 
 	// Convert from net client context to GUI script context
-	return guiManager->GetScriptInterface().CloneValueFromOtherContext(g_NetClient->GetScriptInterface(), poll.get());
+	return pCxPrivate->pScriptInterface->CloneValueFromOtherContext(g_NetClient->GetScriptInterface(), poll.get());
 }
 
-void AssignNetworkPlayer(void* UNUSED(cbdata), int playerID, std::string guid)
+void AssignNetworkPlayer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int playerID, std::string guid)
 {
 	ENSURE(g_NetServer);
 
 	g_NetServer->AssignPlayer(playerID, guid);
 }
 
-void SendNetworkChat(void* UNUSED(cbdata), std::wstring message)
+void SendNetworkChat(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring message)
 {
 	ENSURE(g_NetClient);
 
 	g_NetClient->SendChatMessage(message);
 }
 
-std::vector<CScriptValRooted> GetAIs(void* cbdata)
+std::vector<CScriptValRooted> GetAIs(ScriptInterface::CxPrivate* pCxPrivate)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
-	return ICmpAIManager::GetAIs(guiManager->GetScriptInterface());
+	return ICmpAIManager::GetAIs(*(pCxPrivate->pScriptInterface));
 }
 
-std::vector<CScriptValRooted> GetSavedGames(void* cbdata)
+std::vector<CScriptValRooted> GetSavedGames(ScriptInterface::CxPrivate* pCxPrivate)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
-	return SavedGames::GetSavedGames(guiManager->GetScriptInterface());
+	return SavedGames::GetSavedGames(*(pCxPrivate->pScriptInterface));
 }
 
-bool DeleteSavedGame(void* UNUSED(cbdata), std::wstring name)
+bool DeleteSavedGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring name)
 {
 	return SavedGames::DeleteSavedGame(name);
 }
 
-void OpenURL(void* UNUSED(cbdata), std::string url)
+void OpenURL(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::string url)
 {
 	sys_open_url(url);
 }
 
-std::wstring GetMatchID(void* UNUSED(cbdata))
+std::wstring GetMatchID(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	return ps_generate_guid().FromUTF8();
 }
 
-void RestartInAtlas(void* UNUSED(cbdata))
+void RestartInAtlas(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	restart_mainloop_in_atlas();
 }
 
-bool AtlasIsAvailable(void* UNUSED(cbdata))
+bool AtlasIsAvailable(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	return ATLAS_IsAvailable();
 }
 
-bool IsAtlasRunning(void* UNUSED(cbdata))
+bool IsAtlasRunning(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	return (g_AtlasGameLoop && g_AtlasGameLoop->running);
 }
 
-CScriptVal LoadMapSettings(void* cbdata, VfsPath pathname)
+CScriptVal LoadMapSettings(ScriptInterface::CxPrivate* pCxPrivate, VfsPath pathname)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
 	CMapSummaryReader reader;
 
 	if (reader.LoadMap(pathname) != PSRETURN_OK)
 		return CScriptVal();
 
-	return reader.GetMapSettings(guiManager->GetScriptInterface()).get();
+	return reader.GetMapSettings(*(pCxPrivate->pScriptInterface)).get();
 }
 
-CScriptVal GetMapSettings(void* cbdata)
+CScriptVal GetMapSettings(ScriptInterface::CxPrivate* pCxPrivate)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
 	if (!g_Game)
 		return CScriptVal();
 
-	return guiManager->GetScriptInterface().CloneValueFromOtherContext(
+	return pCxPrivate->pScriptInterface->CloneValueFromOtherContext(
 		g_Game->GetSimulation2()->GetScriptInterface(),
 		g_Game->GetSimulation2()->GetMapSettings().get());
 }
@@ -419,7 +411,7 @@
 /**
  * Get the current X coordinate of the camera.
  */
-float CameraGetX(void* UNUSED(cbdata))
+float CameraGetX(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	if (g_Game && g_Game->GetView())
 		return g_Game->GetView()->GetCameraX();
@@ -429,7 +421,7 @@
 /**
  * Get the current Z coordinate of the camera.
  */
-float CameraGetZ(void* UNUSED(cbdata))
+float CameraGetZ(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	if (g_Game && g_Game->GetView())
 		return g_Game->GetView()->GetCameraZ();
@@ -440,7 +432,7 @@
  * Start / stop camera following mode
  * @param entityid unit id to follow. If zero, stop following mode
  */
-void CameraFollow(void* UNUSED(cbdata), entity_id_t entityid)
+void CameraFollow(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), entity_id_t entityid)
 {
 	if (g_Game && g_Game->GetView())
 		g_Game->GetView()->CameraFollow(entityid, false);
@@ -450,14 +442,14 @@
  * Start / stop first-person camera following mode
  * @param entityid unit id to follow. If zero, stop following mode
  */
-void CameraFollowFPS(void* UNUSED(cbdata), entity_id_t entityid)
+void CameraFollowFPS(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), entity_id_t entityid)
 {
 	if (g_Game && g_Game->GetView())
 		g_Game->GetView()->CameraFollow(entityid, true);
 }
 
 /// Move camera to a 2D location
-void CameraMoveTo(void* UNUSED(cbdata), entity_pos_t x, entity_pos_t z)
+void CameraMoveTo(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), entity_pos_t x, entity_pos_t z)
 {
 	// called from JS; must not fail
 	if(!(g_Game && g_Game->GetWorld() && g_Game->GetView() && g_Game->GetWorld()->GetTerrain()))
@@ -473,7 +465,7 @@
 	g_Game->GetView()->MoveCameraTarget(target);
 }
 
-entity_id_t GetFollowedEntity(void* UNUSED(cbdata))
+entity_id_t GetFollowedEntity(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	if (g_Game && g_Game->GetView())
 		return g_Game->GetView()->GetFollowedEntity();
@@ -481,57 +473,52 @@
 	return INVALID_ENTITY;
 }
 
-bool HotkeyIsPressed_(void* UNUSED(cbdata), std::string hotkeyName)
+bool HotkeyIsPressed_(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::string hotkeyName)
 {
 	return HotkeyIsPressed(hotkeyName);
 }
 
-void DisplayErrorDialog(void* UNUSED(cbdata), std::wstring msg)
+void DisplayErrorDialog(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring msg)
 {
 	debug_DisplayError(msg.c_str(), DE_NO_DEBUG_INFO, NULL, NULL, NULL, 0, NULL, NULL);
 }
 
-CScriptVal GetProfilerState(void* cbdata)
+CScriptVal GetProfilerState(ScriptInterface::CxPrivate* pCxPrivate)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
-	return g_ProfileViewer.SaveToJS(guiManager->GetScriptInterface());
+	return g_ProfileViewer.SaveToJS(*(pCxPrivate->pScriptInterface));
 }
 
-
-bool IsUserReportEnabled(void* UNUSED(cbdata))
+bool IsUserReportEnabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	return g_UserReporter.IsReportingEnabled();
 }
 
-void SetUserReportEnabled(void* UNUSED(cbdata), bool enabled)
+void SetUserReportEnabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool enabled)
 {
 	g_UserReporter.SetReportingEnabled(enabled);
 }
 
-std::string GetUserReportStatus(void* UNUSED(cbdata))
+std::string GetUserReportStatus(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	return g_UserReporter.GetStatus();
 }
 
-void SubmitUserReport(void* UNUSED(cbdata), std::string type, int version, std::wstring data)
+void SubmitUserReport(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::string type, int version, std::wstring data)
 {
 	g_UserReporter.SubmitReport(type.c_str(), version, utf8_from_wstring(data));
 }
 
-
-
-void SetSimRate(void* UNUSED(cbdata), float rate)
+void SetSimRate(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float rate)
 {
 	g_Game->SetSimRate(rate);
 }
 
-float GetSimRate(void* UNUSED(cbdata))
+float GetSimRate(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	return g_Game->GetSimRate();
 }
 
-void SetTurnLength(void* UNUSED(cbdata), int length)
+void SetTurnLength(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int length)
 {
 	if (g_NetServer)
 		g_NetServer->SetTurnLength(length);
@@ -540,7 +527,7 @@
 }
 
 // Focus the game camera on a given position.
-void SetCameraTarget(void* UNUSED(cbdata), float x, float y, float z)
+void SetCameraTarget(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), float x, float y, float z)
 {
 	g_Game->GetView()->ResetCameraTarget(CVector3D(x, y, z));
 }
@@ -548,37 +535,35 @@
 // Deliberately cause the game to crash.
 // Currently implemented via access violation (read of address 0).
 // Useful for testing the crashlog/stack trace code.
-int Crash(void* UNUSED(cbdata))
+int Crash(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	debug_printf(L"Crashing at user's request.\n");
 	return *(volatile int*)0;
 }
 
-void DebugWarn(void* UNUSED(cbdata))
+void DebugWarn(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	debug_warn(L"Warning at user's request.");
 }
 
 // Force a JS garbage collection cycle to take place immediately.
 // Writes an indication of how long this took to the console.
-void ForceGC(void* cbdata)
+void ForceGC(ScriptInterface::CxPrivate* pCxPrivate)
 {
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-
 	double time = timer_Time();
-	JS_GC(guiManager->GetScriptInterface().GetContext());
+	JS_GC(pCxPrivate->pScriptInterface->GetContext());
 	time = timer_Time() - time;
 	g_Console->InsertMessage(L"Garbage collection completed in: %f", time);
 }
 
-void DumpSimState(void* UNUSED(cbdata))
+void DumpSimState(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	OsPath path = psLogDir()/"sim_dump.txt";
 	std::ofstream file (OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc);
 	g_Game->GetSimulation2()->DumpDebugState(file);
 }
 
-void DumpTerrainMipmap(void* UNUSED(cbdata))
+void DumpTerrainMipmap(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	VfsPath filename(L"screenshots/terrainmipmap.png");
 	g_Game->GetWorld()->GetTerrain()->GetHeightMipmap().DumpToDisk(filename);
@@ -587,45 +572,231 @@
 	LOGMESSAGERENDER(L"Terrain mipmap written to '%ls'", realPath.string().c_str());
 }
 
-void EnableTimeWarpRecording(void* UNUSED(cbdata), unsigned int numTurns)
+void EnableTimeWarpRecording(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), unsigned int numTurns)
 {
 	g_Game->GetTurnManager()->EnableTimeWarpRecording(numTurns);
 }
 
-void RewindTimeWarp(void* UNUSED(cbdata))
+void RewindTimeWarp(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	g_Game->GetTurnManager()->RewindTimeWarp();
 }
 
-void QuickSave(void* UNUSED(cbdata))
+void QuickSave(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	g_Game->GetTurnManager()->QuickSave();
 }
 
-void QuickLoad(void* UNUSED(cbdata))
+void QuickLoad(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	g_Game->GetTurnManager()->QuickLoad();
 }
 
-void SetBoundingBoxDebugOverlay(void* UNUSED(cbdata), bool enabled)
+void SetBoundingBoxDebugOverlay(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool enabled)
 {
 	ICmpSelectable::ms_EnableDebugOverlays = enabled;
 }
 
+void Script_EndGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
+{
+	EndGame();
+}
+
+// Cause the game to exit gracefully.
+// params:
+// returns:
+// notes:
+// - Exit happens after the current main loop iteration ends
+//   (since this only sets a flag telling it to end)
+void ExitProgram(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
+{
+	kill_mainloop();
+}
+
+// Is the game paused?
+bool IsPaused(ScriptInterface::CxPrivate* pCxPrivate)
+{
+	if (!g_Game)
+	{
+		JS_ReportError(pCxPrivate->pScriptInterface->GetContext(), "Game is not started");
+		return false;
+	}
+
+	return g_Game->m_Paused;
+}
+
+// Pause/unpause the game
+void SetPaused(ScriptInterface::CxPrivate* pCxPrivate, bool pause)
+{
+	if (!g_Game)
+	{
+		JS_ReportError(pCxPrivate->pScriptInterface->GetContext(), "Game is not started");
+		return;
+	}
+	g_Game->m_Paused = pause;
+#if CONFIG2_AUDIO
+	if ( g_SoundManager )
+		g_SoundManager->Pause(pause);
+#endif
+}
+
+// Return the global frames-per-second value.
+// params:
+// returns: FPS [int]
+// notes:
+// - This value is recalculated once a frame. We take special care to
+//   filter it, so it is both accurate and free of jitter.
+int GetFps(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
+{
+	int freq = 0;
+	if (g_frequencyFilter)
+		freq = g_frequencyFilter->StableFrequency();
+	return freq;
+}
+
+CScriptVal GetGUIObjectByName(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), CStr name)
+{
+		IGUIObject* guiObj = g_GUI->FindObjectByName(name);
+		if (guiObj)
+			return OBJECT_TO_JSVAL(guiObj->GetJSObject());
+		else
+			return JSVAL_VOID;
+}
+
+// Return the date/time at which the current executable was compiled.
+// params: mode OR an integer specifying
+//   what to display: -1 for "date time (svn revision)", 0 for date, 1 for time, 2 for svn revision
+// returns: string with the requested timestamp info
+// notes:
+// - Displayed on main menu screen; tells non-programmers which auto-build
+//   they are running. Could also be determined via .EXE file properties,
+//   but that's a bit more trouble.
+// - To be exact, the date/time returned is when scriptglue.cpp was
+//   last compiled, but the auto-build does full rebuilds.
+// - svn revision is generated by calling svnversion and cached in
+//   lib/svn_revision.cpp. it is useful to know when attempting to
+//   reproduce bugs (the main EXE and PDB should be temporarily reverted to
+//   that revision so that they match user-submitted crashdumps).
+CStr GetBuildTimestamp(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), int mode)
+{
+	char buf[200];
+
+	// see function documentation
+	switch(mode)
+	{
+	case -1:
+		sprintf_s(buf, ARRAY_SIZE(buf), "%s %s (%ls)", __DATE__, __TIME__, svn_revision);
+		break;
+	case 0:
+		sprintf_s(buf, ARRAY_SIZE(buf), "%s", __DATE__);
+		break;
+	case 1:
+		sprintf_s(buf, ARRAY_SIZE(buf), "%s", __TIME__);
+		break;
+	case 2:
+		sprintf_s(buf, ARRAY_SIZE(buf), "%ls", svn_revision);
+		break;
+	}
+
+	return CStr(buf);
+}
+
+//-----------------------------------------------------------------------------
+// Timer
+//-----------------------------------------------------------------------------
+
+
+// Script profiling functions: Begin timing a piece of code with StartJsTimer(num)
+// and stop timing with StopJsTimer(num). The results will be printed to stdout
+// when the game exits.
+
+static const size_t MAX_JS_TIMERS = 20;
+static TimerUnit js_start_times[MAX_JS_TIMERS];
+static TimerUnit js_timer_overhead;
+static TimerClient js_timer_clients[MAX_JS_TIMERS];
+static wchar_t js_timer_descriptions_buf[MAX_JS_TIMERS * 12];	// depends on MAX_JS_TIMERS and format string below
+
+static void InitJsTimers(ScriptInterface& scriptInterface)
+{
+	wchar_t* pos = js_timer_descriptions_buf;
+	for(size_t i = 0; i < MAX_JS_TIMERS; i++)
+	{
+		const wchar_t* description = pos;
+		pos += swprintf_s(pos, 12, L"js_timer %d", (int)i)+1;
+		timer_AddClient(&js_timer_clients[i], description);
+	}
+
+	// call several times to get a good approximation of 'hot' performance.
+	// note: don't use a separate timer slot to warm up and then judge
+	// overhead from another: that causes worse results (probably some
+	// caching effects inside JS, but I don't entirely understand why).
+	std::wstring calibration_script =
+		L"Engine.StartXTimer(0);\n" \
+		L"Engine.StopXTimer (0);\n" \
+		L"\n";
+	scriptInterface.LoadGlobalScript("timer_calibration_script", calibration_script);
+	// slight hack: call LoadGlobalScript twice because we can't average several
+	// TimerUnit values because there's no operator/. this way is better anyway
+	// because it hopefully avoids the one-time JS init overhead.
+	js_timer_clients[0].sum.SetToZero();
+	scriptInterface.LoadGlobalScript("timer_calibration_script", calibration_script);
+	js_timer_clients[0].sum.SetToZero();
+	js_timer_clients[0].num_calls = 0;
+}
+
+void StartJsTimer(ScriptInterface::CxPrivate* pCxPrivate, unsigned int slot)
+{
+	ONCE(InitJsTimers(*(pCxPrivate->pScriptInterface)));
+	
+	if (slot >= MAX_JS_TIMERS)
+		LOGERROR(L"Exceeded the maximum number of timer slots for scripts!");
+
+	js_start_times[slot].SetFromTimer();
+}
+
+
+void StopJsTimer(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), unsigned int slot)
+{
+	if (slot >= MAX_JS_TIMERS)
+		LOGERROR(L"Exceeded the maximum number of timer slots for scripts!");
+
+	TimerUnit now;
+	now.SetFromTimer();
+	now.Subtract(js_timer_overhead);
+	BillingPolicy_Default()(&js_timer_clients[slot], js_start_times[slot], now);
+	js_start_times[slot].SetToZero();
+}
+
+
+
 } // namespace
 
+
+
 void GuiScriptingInit(ScriptInterface& scriptInterface)
 {
+	JSI_IGUIObject::init(scriptInterface);
+	JSI_GUITypes::init(scriptInterface);
+	
 	JSI_GameView::RegisterScriptFunctions(scriptInterface);
 	JSI_Renderer::RegisterScriptFunctions(scriptInterface);
 	JSI_Console::RegisterScriptFunctions(scriptInterface);
 	JSI_ConfigDB::RegisterScriptFunctions(scriptInterface);
-
+	JSI_Sound::RegisterScriptFunctions(scriptInterface);
+ 
+	// VFS (external)
+	scriptInterface.RegisterFunction<CScriptVal, std::wstring, std::wstring, bool, &JSI_VFS::BuildDirEntList>("BuildDirEntList");
+	scriptInterface.RegisterFunction<bool, CStrW, JSI_VFS::FileExists>("FileExists");
+	scriptInterface.RegisterFunction<double, std::wstring, &JSI_VFS::GetFileMTime>("GetFileMTime");
+	scriptInterface.RegisterFunction<unsigned int, std::wstring, &JSI_VFS::GetFileSize>("GetFileSize");
+	scriptInterface.RegisterFunction<CScriptVal, std::wstring, &JSI_VFS::ReadFile>("ReadFile");
+	scriptInterface.RegisterFunction<CScriptVal, std::wstring, &JSI_VFS::ReadFileLines>("ReadFileLines");
 	// GUI manager functions:
-	scriptInterface.RegisterFunction<CScriptVal, &GetActiveGui>("GetActiveGui");
 	scriptInterface.RegisterFunction<void, std::wstring, CScriptVal, &PushGuiPage>("PushGuiPage");
 	scriptInterface.RegisterFunction<void, std::wstring, CScriptVal, &SwitchGuiPage>("SwitchGuiPage");
 	scriptInterface.RegisterFunction<void, &PopGuiPage>("PopGuiPage");
+	scriptInterface.RegisterFunction<void, CScriptVal, &PopGuiPageCB>("PopGuiPageCB");
+	scriptInterface.RegisterFunction<CScriptVal, CStr, &GetGUIObjectByName>("GetGUIObjectByName");
 
 	// Simulation<->GUI interface functions:
 	scriptInterface.RegisterFunction<CScriptVal, std::wstring, CScriptVal, &GuiInterfaceCall>("GuiInterfaceCall");
@@ -641,6 +812,7 @@
 	// Network / game setup functions
 	scriptInterface.RegisterFunction<void, &StartNetworkGame>("StartNetworkGame");
 	scriptInterface.RegisterFunction<void, CScriptVal, int, &StartGame>("StartGame");
+	scriptInterface.RegisterFunction<void, &Script_EndGame>("EndGame");
 	scriptInterface.RegisterFunction<void, std::wstring, &StartNetworkHost>("StartNetworkHost");
 	scriptInterface.RegisterFunction<void, std::wstring, std::string, &StartNetworkJoin>("StartNetworkJoin");
 	scriptInterface.RegisterFunction<void, &DisconnectNetworkGame>("DisconnectNetworkGame");
@@ -679,6 +851,11 @@
 	scriptInterface.RegisterFunction<bool, std::string, &HotkeyIsPressed_>("HotkeyIsPressed");
 	scriptInterface.RegisterFunction<void, std::wstring, &DisplayErrorDialog>("DisplayErrorDialog");
 	scriptInterface.RegisterFunction<CScriptVal, &GetProfilerState>("GetProfilerState");
+	scriptInterface.RegisterFunction<void, &ExitProgram>("Exit");
+	scriptInterface.RegisterFunction<bool, &IsPaused>("IsPaused");
+	scriptInterface.RegisterFunction<void, bool, &SetPaused>("SetPaused");
+	scriptInterface.RegisterFunction<int, &GetFps>("GetFPS");
+	scriptInterface.RegisterFunction<CStr, int, &GetBuildTimestamp>("BuildTime");
 
 	// User report functions
 	scriptInterface.RegisterFunction<bool, &IsUserReportEnabled>("IsUserReportEnabled");
@@ -687,6 +864,8 @@
 	scriptInterface.RegisterFunction<void, std::string, int, std::wstring, &SubmitUserReport>("SubmitUserReport");
 
 	// Development/debugging functions
+	scriptInterface.RegisterFunction<void, unsigned int, &StartJsTimer>("StartXTimer");
+	scriptInterface.RegisterFunction<void, unsigned int, &StopJsTimer>("StopXTimer");
 	scriptInterface.RegisterFunction<void, float, &SetSimRate>("SetSimRate");
 	scriptInterface.RegisterFunction<float, &GetSimRate>("GetSimRate");
 	scriptInterface.RegisterFunction<void, int, &SetTurnLength>("SetTurnLength");
Index: source/gui/GUIManager.h
===================================================================
--- source/gui/GUIManager.h	(Revision 14461)
+++ source/gui/GUIManager.h	(Arbeitskopie)
@@ -22,8 +22,10 @@
 
 #include "lib/input.h"
 #include "lib/file/vfs/vfs_path.h"
+#include "ps/CLogger.h"
 #include "ps/CStr.h"
 #include "scriptinterface/ScriptVal.h"
+#include "scriptinterface/ScriptInterface.h"
 
 #include <set>
 
@@ -46,10 +48,15 @@
 {
 	NONCOPYABLE(CGUIManager);
 public:
-	CGUIManager(ScriptInterface& scriptInterface);
+	CGUIManager();
 	~CGUIManager();
 
-	ScriptInterface& GetScriptInterface() { return m_ScriptInterface; }
+	shared_ptr<ScriptInterface> GetScriptInterface() 
+	{ 
+		return m_ScriptInterface; 
+	}
+	shared_ptr<ScriptRuntime> GetRuntime() { return m_ScriptRuntime; }
+	shared_ptr<CGUI> GetActiveGUI() { return top(); }
 
 	/**
 	 * Returns whether there are any current pages.
@@ -59,20 +66,21 @@
 	/**
 	 * Load a new GUI page and make it active. All current pages will be destroyed.
 	 */
-	void SwitchPage(const CStrW& name, CScriptVal initData);
+	void SwitchPage(const CStrW& name, ScriptInterface* srcScriptInterface, CScriptVal initData);
 
 	/**
 	 * Load a new GUI page and make it active. All current pages will be retained,
 	 * and will still be drawn and receive tick events, but will not receive
 	 * user inputs.
 	 */
-	void PushPage(const CStrW& name, CScriptVal initData);
+	void PushPage(const CStrW& pageName, shared_ptr<ScriptInterface::StructuredClone> initData);
 
 	/**
 	 * Unload the currently active GUI page, and make the previous page active.
 	 * (There must be at least two pages when you call this.)
 	 */
 	void PopPage();
+	void PopPageCB(shared_ptr<ScriptInterface::StructuredClone> args);
 
 	/**
 	 * Display a modal message box with an "OK" button.
@@ -115,11 +123,6 @@
 	void SendEventToAll(const CStr& eventName);
 
 	/**
-	 * See CGUI::GetScriptObject; applies to the currently active page.
-	 */
-	JSObject* GetScriptObject();
-
-	/**
 	 * See CGUI::TickObjects; applies to @em all loaded pages.
 	 */
 	void TickObjects();
@@ -134,10 +137,14 @@
 	 */
 	void UpdateResolution();
 
-	/**
-	 * Calls the current page's script function getSavedGameData() and returns the result.
-	 */
-	CScriptVal GetSavedGameData();
+ 	/**
+ 	 * Calls the current page's script function getSavedGameData() and returns the result.
+	 * The first overload also returns a pointer to the ScriptInterface the returned CScriptVal belongs to.
+ 	 */
+	CScriptVal GetSavedGameData(ScriptInterface*& pPageScriptInterface);
+	std::string GetSavedGameData();
+ 
+	void RestoreSavedGameData(std::string jsonData);
 
 private:
 	struct SGUIPage
@@ -146,7 +153,8 @@
 		boost::unordered_set<VfsPath> inputs; // for hotloading
 
 		JSContext* cx;
-		CScriptValRooted initData; // data to be passed to the init() function
+		shared_ptr<ScriptInterface::StructuredClone> initData; // data to be passed to the init() function
+		CStrW callbackPageName;
 
 		shared_ptr<CGUI> gui; // the actual GUI page
 	};
@@ -154,13 +162,13 @@
 	void LoadPage(SGUIPage& page);
 
 	shared_ptr<CGUI> top() const;
+	
+	shared_ptr<CGUI> m_CurrentGUI; // used to latch state during TickObjects/LoadPage (this is kind of ugly)
+	shared_ptr<ScriptRuntime> m_ScriptRuntime;
+	shared_ptr<ScriptInterface> m_ScriptInterface;
 
 	typedef std::vector<SGUIPage> PageStackType;
 	PageStackType m_PageStack;
-
-	shared_ptr<CGUI> m_CurrentGUI; // used to latch state during TickObjects/LoadPage (this is kind of ugly)
-
-	ScriptInterface& m_ScriptInterface;
 };
 
 extern CGUIManager* g_GUI;
Index: source/gui/GUIManager.cpp
===================================================================
--- source/gui/GUIManager.cpp	(Revision 14461)
+++ source/gui/GUIManager.cpp	(Arbeitskopie)
@@ -26,7 +26,6 @@
 #include "ps/CLogger.h"
 #include "ps/Profile.h"
 #include "ps/XML/Xeromyces.h"
-#include "scripting/ScriptingHost.h"
 #include "scriptinterface/ScriptInterface.h"
 
 CGUIManager* g_GUI = NULL;
@@ -48,13 +47,12 @@
 	return g_GUI->HandleEvent(ev);
 }
 
-CGUIManager::CGUIManager(ScriptInterface& scriptInterface) :
-	m_ScriptInterface(scriptInterface)
+CGUIManager::CGUIManager()
 {
-	ENSURE(ScriptInterface::GetCallbackData(scriptInterface.GetContext()) == NULL);
-	scriptInterface.SetCallbackData(this);
-
-	scriptInterface.LoadGlobalScripts();
+	m_ScriptRuntime = g_ScriptRuntime;
+	m_ScriptInterface.reset(new ScriptInterface("Engine", "GUIManager", m_ScriptRuntime));
+	m_ScriptInterface->SetCallbackData(this);
+	m_ScriptInterface->LoadGlobalScripts();
 }
 
 CGUIManager::~CGUIManager()
@@ -66,17 +64,25 @@
 	return !m_PageStack.empty();
 }
 
-void CGUIManager::SwitchPage(const CStrW& pageName, CScriptVal initData)
+void CGUIManager::SwitchPage(const CStrW& pageName, ScriptInterface* srcScriptInterface, CScriptVal initData)
 {
+	// The page stack is cleared (including the script context where initData came from),
+	// therefore we have to clone initData.
+	shared_ptr<ScriptInterface::StructuredClone> initDataClone;
+	if (initData.get() != JSVAL_VOID)
+	{
+		ENSURE(srcScriptInterface);
+		initDataClone = srcScriptInterface->WriteStructuredClone(initData.get());
+	}
 	m_PageStack.clear();
-	PushPage(pageName, initData);
+	PushPage(pageName, initDataClone);
 }
 
-void CGUIManager::PushPage(const CStrW& pageName, CScriptVal initData)
+void CGUIManager::PushPage(const CStrW& pageName, shared_ptr<ScriptInterface::StructuredClone> initData)
 {
 	m_PageStack.push_back(SGUIPage());
 	m_PageStack.back().name = pageName;
-	m_PageStack.back().initData = CScriptValRooted(m_ScriptInterface.GetContext(), initData);
+	m_PageStack.back().initData = initData;
 	LoadPage(m_PageStack.back());
 }
 
@@ -91,30 +97,80 @@
 	m_PageStack.pop_back();
 }
 
+void CGUIManager::PopPageCB(shared_ptr<ScriptInterface::StructuredClone> args)
+{
+	shared_ptr<ScriptInterface::StructuredClone> initDataClone = m_PageStack.back().initData;
+	PopPage();
+	
+	shared_ptr<ScriptInterface> scriptInterface = m_PageStack.back().gui->GetScriptInterface();
+	CScriptVal initDataVal;
+	if (initDataClone)
+		initDataVal = scriptInterface->ReadStructuredClone(initDataClone);
+	else
+	{
+		LOGERROR(L"Called PopPageCB when initData (which should contain the callback function name) isn't set!");
+		return;
+	}
+	
+	if (!scriptInterface->HasProperty(initDataVal.get(), "callback"))
+	{
+		LOGERROR(L"Called PopPageCB when the callback function name isn't set!");
+		return;
+	}
+	
+	std::string callback;
+	if (!scriptInterface->GetProperty(initDataVal.get(), "callback", callback))
+	{
+		LOGERROR(L"Failed to get the callback property as a string from initData in PopPageCB!");
+		return;
+	}
+	
+	if (!scriptInterface->HasProperty(scriptInterface->GetGlobalObject(), callback.c_str()))
+	{
+		LOGERROR(L"The specified callback function %hs does not exist in the page %ls", callback.c_str(), m_PageStack.back().name.c_str());
+		return;
+	}
+
+	CScriptVal argVal;
+	if (args)
+		argVal = scriptInterface->ReadStructuredClone(args);
+	if (!scriptInterface->CallFunctionVoid(scriptInterface->GetGlobalObject(), callback.c_str(), argVal))
+	{
+		LOGERROR(L"Failed to call the callback function %hs in the page %ls", callback.c_str(), m_PageStack.back().name.c_str());
+		return;
+	}
+}
+
 void CGUIManager::DisplayMessageBox(int width, int height, const CStrW& title, const CStrW& message)
 {
 	// Set up scripted init data for the standard message box window
 	CScriptValRooted data;
-	m_ScriptInterface.Eval("({})", data);
-	m_ScriptInterface.SetProperty(data.get(), "width", width, false);
-	m_ScriptInterface.SetProperty(data.get(), "height", height, false);
-	m_ScriptInterface.SetProperty(data.get(), "mode", 2, false);
-	m_ScriptInterface.SetProperty(data.get(), "title", std::wstring(title), false);
-	m_ScriptInterface.SetProperty(data.get(), "message", std::wstring(message), false);
+	m_ScriptInterface->Eval("({})", data);
+	m_ScriptInterface->SetProperty(data.get(), "width", width, false);
+	m_ScriptInterface->SetProperty(data.get(), "height", height, false);
+	m_ScriptInterface->SetProperty(data.get(), "mode", 2, false);
+	m_ScriptInterface->SetProperty(data.get(), "title", std::wstring(title), false);
+	m_ScriptInterface->SetProperty(data.get(), "message", std::wstring(message), false);
 
 	// Display the message box
-	PushPage(L"page_msgbox.xml", data.get());
+	PushPage(L"page_msgbox.xml", m_ScriptInterface->WriteStructuredClone(data.get()));
 }
 
 void CGUIManager::LoadPage(SGUIPage& page)
 {
 	// If we're hotloading then try to grab some data from the previous page
-	CScriptValRooted hotloadData;
+	shared_ptr<ScriptInterface::StructuredClone> hotloadData;
 	if (page.gui)
-		m_ScriptInterface.CallFunction(OBJECT_TO_JSVAL(page.gui->GetScriptObject()), "getHotloadData", hotloadData);
+	{	
+		CScriptVal hotloadDataVal;
+		shared_ptr<ScriptInterface> scriptInterface = page.gui->GetScriptInterface();
+		scriptInterface->CallFunction(scriptInterface->GetGlobalObject(), "getHotloadData", hotloadDataVal);
+		hotloadData = scriptInterface->WriteStructuredClone(hotloadDataVal.get());
+	}
+		
+	page.inputs.clear();
+	page.gui.reset(new CGUI(m_ScriptRuntime));
 
-	page.inputs.clear();
-	page.gui.reset(new CGUI());
 	page.gui->Initialize();
 
 	VfsPath path = VfsPath("gui") / page.name;
@@ -160,8 +216,21 @@
 
 	page.gui->SendEventToAll("load");
 
+	shared_ptr<ScriptInterface> scriptInterface = page.gui->GetScriptInterface();
+	CScriptVal initDataVal;
+	CScriptVal hotloadDataVal;
+	if (page.initData) 
+		initDataVal = scriptInterface->ReadStructuredClone(page.initData);
+	if (hotloadData)
+		hotloadDataVal = scriptInterface->ReadStructuredClone(hotloadData);
+	
 	// Call the init() function
-	if (!m_ScriptInterface.CallFunctionVoid(OBJECT_TO_JSVAL(page.gui->GetScriptObject()), "init", page.initData, hotloadData))
+	if (!scriptInterface->CallFunctionVoid(
+			scriptInterface->GetGlobalObject(), 
+			"init", 
+			initDataVal, 
+			hotloadDataVal)
+		)
 	{
 		LOGERROR(L"GUI page '%ls': Failed to call init() function", page.name.c_str());
 	}
@@ -184,14 +253,28 @@
 	return INFO::OK;
 }
 
-CScriptVal CGUIManager::GetSavedGameData()
+CScriptVal CGUIManager::GetSavedGameData(ScriptInterface*& pPageScriptInterface)
 {
 	CScriptVal data;
-	if (!m_ScriptInterface.CallFunction(OBJECT_TO_JSVAL(top()->GetScriptObject()), "getSavedGameData", data))
+	if (!top()->GetScriptInterface()->CallFunction(top()->GetGlobalObject(), "getSavedGameData", data))
 		LOGERROR(L"Failed to call getSavedGameData() on the current GUI page");
+	pPageScriptInterface = GetScriptInterface().get();
 	return data;
 }
 
+std::string CGUIManager::GetSavedGameData()
+{
+	CScriptVal data;
+	top()->GetScriptInterface()->CallFunction(top()->GetGlobalObject(), "getSavedGameData", data);
+	return top()->GetScriptInterface()->StringifyJSON(data.get(), false);
+}
+
+void CGUIManager::RestoreSavedGameData(std::string jsonData)
+{
+	top()->GetScriptInterface()->CallFunctionVoid(top()->GetGlobalObject(), "restoreSavedGameData",
+														top()->GetScriptInterface()->ParseJSON(jsonData));
+}
+
 InReaction CGUIManager::HandleEvent(const SDL_Event_* ev)
 {
 	// We want scripts to have access to the raw input events, so they can do complex
@@ -205,7 +288,7 @@
 
 	{
 		PROFILE("handleInputBeforeGui");
-		if (m_ScriptInterface.CallFunction(OBJECT_TO_JSVAL(top()->GetScriptObject()), "handleInputBeforeGui", *ev, top()->FindObjectUnderMouse(), handled))
+		if (top()->GetScriptInterface()->CallFunction(top()->GetGlobalObject(), "handleInputBeforeGui", *ev, top()->FindObjectUnderMouse(), handled))
 			if (handled)
 				return IN_HANDLED;
 	}
@@ -219,8 +302,7 @@
 
 	{
 		PROFILE("handleInputAfterGui");
-		if (m_ScriptInterface.CallFunction(OBJECT_TO_JSVAL(top()->GetScriptObject()), "handleInputAfterGui", *ev, handled))
-			if (handled)
+		if (top()->GetScriptInterface()->CallFunction(top()->GetGlobalObject(), "handleInputAfterGui", *ev, handled))			if (handled)
 				return IN_HANDLED;
 	}
 
@@ -287,11 +369,6 @@
 		it->gui->UpdateResolution();
 }
 
-JSObject* CGUIManager::GetScriptObject()
-{
-	return top()->GetScriptObject();
-}
-
 // This returns a shared_ptr to make sure the CGUI doesn't get deallocated
 // while we're in the middle of calling a function on it (e.g. if a GUI script
 // calls SwitchPage)
Index: source/gui/IGUIObject.cpp
===================================================================
--- source/gui/IGUIObject.cpp	(Revision 14461)
+++ source/gui/IGUIObject.cpp	(Arbeitskopie)
@@ -43,8 +43,7 @@
 IGUIObject::IGUIObject() : 
 	m_pGUI(NULL), 
 	m_pParent(NULL),
-	m_MouseHovering(false),
-	m_JSObject(NULL)
+	m_MouseHovering(false)
 {
 	AddSetting(GUIST_bool,			"enabled");
 	AddSetting(GUIST_bool,			"hidden");
@@ -84,18 +83,6 @@
 			}
 		}
 	}
-
-	{
-		std::map<CStr, JSObject**>::iterator it;
-		for (it = m_ScriptHandlers.begin(); it != m_ScriptHandlers.end(); ++it)
-		{
-			JS_RemoveObjectRoot(g_ScriptingHost.getContext(), it->second);
-			delete it->second;
-		}
-	}
-	
-	if (m_JSObject)
-		JS_RemoveObjectRoot(g_ScriptingHost.getContext(), &m_JSObject);
 }
 
 //-------------------------------------------------------------------
@@ -429,6 +416,11 @@
 
 void IGUIObject::RegisterScriptHandler(const CStr& Action, const CStr& Code, CGUI* pGUI)
 {
+	if(!GetGUI())
+		throw PSERROR_GUI_OperationNeedsGUIObject();
+		
+	JSContext* cx = pGUI->GetScriptInterface()->GetContext();
+	
 	const int paramCount = 1;
 	const char* paramNames[paramCount] = { "mouse" };
 
@@ -440,7 +432,7 @@
 	char buf[64];
 	sprintf_s(buf, ARRAY_SIZE(buf), "__eventhandler%d (%s)", x++, Action.c_str());
 
-	JSFunction* func = JS_CompileFunction(g_ScriptingHost.getContext(), pGUI->m_ScriptObject,
+	JSFunction* func = JS_CompileFunction(cx, JSVAL_TO_OBJECT(pGUI->GetGlobalObject()),
 		buf, paramCount, paramNames, Code.c_str(), Code.length(), CodeName.c_str(), 0);
 
 	if (!func)
@@ -451,16 +443,7 @@
 
 void IGUIObject::SetScriptHandler(const CStr& Action, JSObject* Function)
 {
-	JSObject** obj = new JSObject*;
-	*obj = Function;
-	JS_AddObjectRoot(g_ScriptingHost.getContext(), obj);
-
-	if (m_ScriptHandlers[Action])
-	{
-		JS_RemoveObjectRoot(g_ScriptingHost.getContext(), m_ScriptHandlers[Action]);
-		delete m_ScriptHandlers[Action];
-	}
-	m_ScriptHandlers[Action] = obj;
+	m_ScriptHandlers[Action] = CScriptValRooted(m_pGUI->GetScriptInterface()->GetContext(), OBJECT_TO_JSVAL(Function));
 }
 
 InReaction IGUIObject::SendEvent(EGUIMessageType type, const CStr& EventName)
@@ -479,21 +462,23 @@
 
 void IGUIObject::ScriptEvent(const CStr& Action)
 {
-	std::map<CStr, JSObject**>::iterator it = m_ScriptHandlers.find(Action);
+	std::map<CStr, CScriptValRooted>::iterator it = m_ScriptHandlers.find(Action);
 	if (it == m_ScriptHandlers.end())
 		return;
 
+	JSContext* cx = m_pGUI->GetScriptInterface()->GetContext();
+
 	// Set up the 'mouse' parameter
 	CScriptVal mouse;
-	g_ScriptingHost.GetScriptInterface().Eval("({})", mouse);
-	g_ScriptingHost.GetScriptInterface().SetProperty(mouse.get(), "x", m_pGUI->m_MousePos.x, false);
-	g_ScriptingHost.GetScriptInterface().SetProperty(mouse.get(), "y", m_pGUI->m_MousePos.y, false);
-	g_ScriptingHost.GetScriptInterface().SetProperty(mouse.get(), "buttons", m_pGUI->m_MouseButtons, false);
+	m_pGUI->GetScriptInterface()->Eval("({})", mouse);
+	m_pGUI->GetScriptInterface()->SetProperty(mouse.get(), "x", m_pGUI->m_MousePos.x, false);
+	m_pGUI->GetScriptInterface()->SetProperty(mouse.get(), "y", m_pGUI->m_MousePos.y, false);
+	m_pGUI->GetScriptInterface()->SetProperty(mouse.get(), "buttons", m_pGUI->m_MouseButtons, false);
 
 	jsval paramData[] = { mouse.get() };
 
 	jsval result;
-	JSBool ok = JS_CallFunctionValue(g_ScriptingHost.getContext(), GetJSObject(), OBJECT_TO_JSVAL(*it->second), ARRAY_SIZE(paramData), paramData, &result);
+	JSBool ok = JS_CallFunctionValue(cx, GetJSObject(), (*it).second.get(), ARRAY_SIZE(paramData), paramData, &result);
 	if (!ok)
 	{
 		// We have no way to propagate the script exception, so just ignore it
@@ -503,7 +488,8 @@
 
 void IGUIObject::ScriptEvent(const CStr& Action, const CScriptValRooted& Argument)
 {
-	std::map<CStr, JSObject**>::iterator it = m_ScriptHandlers.find(Action);
+	JSContext* cx = m_pGUI->GetScriptInterface()->GetContext();
+	std::map<CStr, CScriptValRooted>::iterator it = m_ScriptHandlers.find(Action);
 	if (it == m_ScriptHandlers.end())
 		return;
 
@@ -512,25 +498,26 @@
 	jsval arg = Argument.get();
 
 	jsval result;
-	JSBool ok = JS_CallFunctionValue(g_ScriptingHost.getContext(), object, OBJECT_TO_JSVAL(*it->second), 1, &arg, &result);
+	JSBool ok = JS_CallFunctionValue(cx, object, (*it).second.get(), 1, &arg, &result);
 	if (!ok)
 	{
-		JS_ReportError(g_ScriptingHost.getContext(), "Errors executing script action \"%s\"", Action.c_str());
+		JS_ReportError(cx, "Errors executing script action \"%s\"", Action.c_str());
 	}
 }
 
 JSObject* IGUIObject::GetJSObject()
 {
+	JSContext* cx = m_pGUI->GetScriptInterface()->GetContext();
 	// Cache the object when somebody first asks for it, because otherwise
 	// we end up doing far too much object allocation. TODO: Would be nice to
 	// not have these objects hang around forever using up memory, though.
-	if (! m_JSObject)
+	if (m_JSObject.uninitialised())
 	{
-		m_JSObject = JS_NewObject(g_ScriptingHost.getContext(), &JSI_IGUIObject::JSI_class, NULL, NULL);
-		JS_AddObjectRoot(g_ScriptingHost.getContext(), &m_JSObject);
-		JS_SetPrivate(g_ScriptingHost.getContext(), m_JSObject, this);
+		JSObject* obj = JS_NewObject(cx, &JSI_IGUIObject::JSI_class, NULL, NULL);
+		m_JSObject = CScriptValRooted(cx, OBJECT_TO_JSVAL(obj));
+		JS_SetPrivate(cx, JSVAL_TO_OBJECT(m_JSObject.get()), this);
 	}
-	return m_JSObject;
+	return JSVAL_TO_OBJECT(m_JSObject.get());;
 }
 
 CStr IGUIObject::GetPresentableName() const
Index: source/gui/MiniMap.cpp
===================================================================
--- source/gui/MiniMap.cpp	(Revision 14461)
+++ source/gui/MiniMap.cpp	(Arbeitskopie)
@@ -28,6 +28,8 @@
 #include "graphics/TerrainTextureEntry.h"
 #include "graphics/TerrainTextureManager.h"
 #include "graphics/TerritoryTexture.h"
+#include "gui/GUI.h"
+#include "gui/GUIManager.h"
 #include "lib/ogl.h"
 #include "lib/external_libraries/libsdl.h"
 #include "lib/bits.h"
@@ -241,9 +243,9 @@
 	GetMouseWorldCoordinates(x, z);
 
 	CScriptValRooted coords;
-	g_ScriptingHost.GetScriptInterface().Eval("({})", coords);
-	g_ScriptingHost.GetScriptInterface().SetProperty(coords.get(), "x", x, false);
-	g_ScriptingHost.GetScriptInterface().SetProperty(coords.get(), "z", z, false);
+	g_GUI->GetActiveGUI()->GetScriptInterface()->Eval("({})", coords);
+	g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(coords.get(), "x", x, false);
+	g_GUI->GetActiveGUI()->GetScriptInterface()->SetProperty(coords.get(), "z", z, false);
 	ScriptEvent("worldclick", coords);
 
 	UNUSED2(button);
Index: source/gui/CGUI.h
===================================================================
--- source/gui/CGUI.h	(Revision 14461)
+++ source/gui/CGUI.h	(Arbeitskopie)
@@ -40,6 +40,7 @@
 
 #include "GUITooltip.h"
 #include "GUIbase.h"
+#include "scriptinterface/ScriptInterface.h"
 
 #include "ps/Overlay.h" // CPos and CRect
 
@@ -107,15 +108,10 @@
 	typedef IGUIObject *(*ConstructObjectFunction)();
 
 public:
-	CGUI();
+	CGUI(const shared_ptr<ScriptRuntime>& runtime);
 	~CGUI();
 
 	/**
-	 * Initializes GUI script classes
-	 */
-	static void ScriptingInit();
-
-	/**
 	 * Initializes the GUI, needs to be called before the GUI is used
 	 */
 	void Initialize();
@@ -260,12 +256,6 @@
 						  const float &Width, const float &BufferZone,
 						  const IGUIObject *pObject=NULL);
 
-	/**
-	 * Returns the JSObject* associated with the GUI
-	 *
-	 * @return The relevant JS object
-	 */
-	JSObject* GetScriptObject() { return m_ScriptObject; }
 
 	/**
 	 * Check if an icon exists
@@ -282,6 +272,9 @@
 	 * Returns false if it fails.
 	 */
 	bool GetPreDefinedColor(const CStr& name, CColor &Output);
+	
+	shared_ptr<ScriptInterface> GetScriptInterface() { return m_ScriptInterface; };
+	jsval GetGlobalObject() { return m_ScriptInterface->GetGlobalObject(); };
 
 private:
 
@@ -581,15 +574,10 @@
 	/** @name Miscellaneous */
 	//--------------------------------------------------------
 	//@{
+	
+	shared_ptr<ScriptInterface> m_ScriptInterface;
 
 	/**
-	 * An JSObject* under which all GUI JavaScript things will
-	 * be created, so that they can be garbage-collected
-	 * when the GUI shuts down.
-	 */
-	JSObject* m_ScriptObject;
-
-	/**
 	 * don't want to pass this around with the 
 	 * ChooseMouseOverAndClosest broadcast -
 	 * we'd need to pack this and pNearest in a struct
Index: source/gui/CGUI.cpp
===================================================================
--- source/gui/CGUI.cpp	(Revision 14461)
+++ source/gui/CGUI.cpp	(Arbeitskopie)
@@ -40,7 +40,7 @@
 #include "CProgressBar.h"
 #include "CTooltip.h"
 #include "MiniMap.h"
-#include "scripting/JSInterface_GUITypes.h"
+#include "scripting/ScriptFunctions.h"
 
 #include "graphics/FontMetrics.h"
 #include "graphics/ShaderManager.h"
@@ -58,19 +58,12 @@
 #include "ps/Pyrogenesis.h"
 #include "ps/XML/Xeromyces.h"
 #include "renderer/Renderer.h"
-#include "scripting/ScriptingHost.h"
 #include "scriptinterface/ScriptInterface.h"
 
 extern int g_yres;
 
 const double SELECT_DBLCLICK_RATE = 0.5;
 
-void CGUI::ScriptingInit()
-{
-	JSI_IGUIObject::init();
-	JSI_GUITypes::init();
-}
-
 InReaction CGUI::HandleEvent(const SDL_Event_* ev)
 {
 	InReaction ret = IN_PASS;
@@ -321,83 +314,12 @@
 //  Constructor / Destructor
 //-------------------------------------------------------------------
 
-// To isolate the vars declared by each GUI page, we need to create
-// a pseudo-global object to declare them in. In particular, it must
-// have no parent object, so it must be declared with JS_NewGlobalObject.
-// But GUI scripts should have access to the real global's properties
-// (Array, undefined, getGUIObjectByName, etc), so we add a custom resolver
-// that defers to the real global object when necessary.
-
-static JSBool GetGlobalProperty(JSContext* cx, JSObject* UNUSED(obj), jsid id, jsval* vp)
+CGUI::CGUI(const shared_ptr<ScriptRuntime>& runtime) : m_MouseButtons(0), m_FocusedObject(NULL), m_InternalNameNumber(0)
 {
-	return JS_GetPropertyById(cx, g_ScriptingHost.GetGlobalObject(), id, vp);
-}
-
-static JSBool SetGlobalProperty(JSContext* cx, JSObject* UNUSED(obj), jsid id, JSBool UNUSED(strict), jsval* vp)
-{
-	return JS_SetPropertyById(cx, g_ScriptingHost.GetGlobalObject(), id, vp);
-}
-
-static JSBool ResolveGlobalProperty(JSContext* cx, JSObject* obj, jsid id, uintN flags, JSObject** objp)
-{
-	// This gets called when the property can't be resolved in the page_global object.
-
-	// Warning: The interaction between this resolution stuff and the JITs appears
-	// to be quite fragile, and I don't quite understand what the constraints are.
-	// If changing it, be careful to test with each JIT to make sure it works.
-	// (This code is somewhat based on GPSEE's module system.)
-
-	// Declarations and assignments shouldn't affect the real global
-	if (flags & (JSRESOLVE_DECLARING | JSRESOLVE_ASSIGNING))
-	{
-		// Can't be resolved - return NULL
-		*objp = NULL;
-		return JS_TRUE;
-	}
-
-	// Check whether the real global object defined this property
-	uintN attrs;
-	JSBool found;
-	if (!JS_GetPropertyAttrsGetterAndSetterById(cx, g_ScriptingHost.GetGlobalObject(), id, &attrs, &found, NULL, NULL))
-		return JS_FALSE;
-
-	if (!found)
-	{
-		// Not found on real global, so can't be resolved - return NULL
-		*objp = NULL;
-		return JS_TRUE;
-	}
-
-	// Retrieve the property value from the global
-	jsval v;
-	if (!JS_GetPropertyById(cx, g_ScriptingHost.GetGlobalObject(), id, &v))
-		return JS_FALSE;
-
-	// Add the global's property value onto this object, with getter/setter that will
-	// update the global's copy instead of this copy, and then return this object
-	if (!JS_DefinePropertyById(cx, obj, id, v, GetGlobalProperty, SetGlobalProperty, attrs))
-		return JS_FALSE;
-
-	*objp = obj;
-	return JS_TRUE;
-}
-
-static JSClass page_global_class = {
-	"page_global", JSCLASS_GLOBAL_FLAGS | JSCLASS_NEW_RESOLVE,
-	JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
-	JS_EnumerateStub, (JSResolveOp)ResolveGlobalProperty, JS_ConvertStub, JS_FinalizeStub,
-	NULL, NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL
-};
-
-CGUI::CGUI() : m_MouseButtons(0), m_FocusedObject(NULL), m_InternalNameNumber(0)
-{
+	m_ScriptInterface.reset(new ScriptInterface("Engine", "GUIPage", runtime));
+	GuiScriptingInit(*m_ScriptInterface);
 	m_BaseObject = new CGUIDummyObject;
-	m_BaseObject->SetGUI(this);
-
-	// Construct the root object for all GUI JavaScript things
-	m_ScriptObject = JS_NewGlobalObject(g_ScriptingHost.getContext(), &page_global_class);
-	JS_AddObjectRoot(g_ScriptingHost.getContext(), &m_ScriptObject);
+	m_BaseObject->SetGUI(this);	
 }
 
 CGUI::~CGUI()
@@ -406,12 +328,6 @@
 
 	if (m_BaseObject)
 		delete m_BaseObject;
-
-	if (m_ScriptObject)
-	{
-		// Let it be garbage-collected
-		JS_RemoveObjectRoot(g_ScriptingHost.getContext(), &m_ScriptObject);
-	}
 }
 
 //-------------------------------------------------------------------
@@ -1337,6 +1253,9 @@
 			code += CStr(child.GetText());
 
 			CStr action = CStr(child.GetAttributes().GetNamedItem(attr_on));
+			
+			// We need to set the GUI this object belongs to because RegisterScriptHandler requires an associated GUI.
+			object->SetGUI(this);
 			object->RegisterScriptHandler(action.LowerCase(), code, this);
 		}
 		else if (element_name == elmt_repeat)
@@ -1430,7 +1349,7 @@
 		Paths.insert(file);
 		try
 		{
-			g_ScriptingHost.RunScript(file, m_ScriptObject);
+			m_ScriptInterface->LoadGlobalScriptFile(file);
 		}
 		catch (PSERROR_Scripting& e)
 		{
@@ -1443,7 +1362,7 @@
 	{
 		CStr code (Element.GetText());
 		if (! code.empty())
-			g_ScriptingHost.RunMemScript(code.c_str(), code.length(), "Some XML file", Element.GetLineNumber(), m_ScriptObject);
+			m_ScriptInterface->LoadGlobalScript(L"Some XML file", code.FromUTF8());
 	}
 	catch (PSERROR_Scripting& e)
 	{
Index: source/gui/IGUIObject.h
===================================================================
--- source/gui/IGUIObject.h	(Revision 14461)
+++ source/gui/IGUIObject.h	(Arbeitskopie)
@@ -554,10 +554,10 @@
 	CGUI									*m_pGUI;
 
 	// Internal storage for registered script handlers.
-	std::map<CStr, JSObject**> m_ScriptHandlers;
+	std::map<CStr, CScriptValRooted> m_ScriptHandlers;
 	
 	// Cached JSObject representing this GUI object
-	JSObject								*m_JSObject;
+	CScriptValRooted						m_JSObject;
 };
 
 
Index: source/main.cpp
===================================================================
--- source/main.cpp	(Revision 14461)
+++ source/main.cpp	(Arbeitskopie)
@@ -71,7 +71,6 @@
 #include "graphics/TextureManager.h"
 #include "gui/GUIManager.h"
 #include "renderer/Renderer.h"
-#include "scripting/ScriptingHost.h"
 #include "simulation2/Simulation2.h"
 
 #if OS_UNIX
@@ -185,8 +184,8 @@
 		PROFILE2("event");
 		if (g_GUI)
 		{
-			std::string data = g_GUI->GetScriptInterface().StringifyJSON(
-				ScriptInterface::ToJSVal(g_GUI->GetScriptInterface().GetContext(), ev));
+			std::string data = g_GUI->GetScriptInterface()->StringifyJSON(
+				ScriptInterface::ToJSVal(g_GUI->GetScriptInterface()->GetContext(), ev));
 			PROFILE2_ATTR("%s", data.c_str());
 		}
 		in_dispatch_event(&ev);
@@ -472,7 +471,6 @@
 	while(!quit)
 		Frame();
 	Shutdown(0);
-	ScriptingHost::FinalShutdown(); // this can't go in Shutdown() because that could be called multiple times per process, so stick it here instead
 	MainControllerShutdown();
 
 	if (restart_in_atlas)
Index: source/simulation2/Simulation2.h
===================================================================
--- source/simulation2/Simulation2.h	(Revision 14461)
+++ source/simulation2/Simulation2.h	(Arbeitskopie)
@@ -38,6 +38,7 @@
 class CMessage;
 class SceneCollector;
 class CFrustum;
+class ScriptRuntime;
 
 /**
  * Public API for simulation system.
@@ -48,7 +49,7 @@
 public:
 	// TODO: CUnitManager should probably be handled automatically by this
 	// module, but for now we'll have it passed in externally instead
-	CSimulation2(CUnitManager*, CTerrain*);
+	CSimulation2(CUnitManager* unitManager, shared_ptr<ScriptRuntime> rt, CTerrain* terrain);
 	~CSimulation2();
 
 	void EnableOOSLog();
Index: source/simulation2/tests/test_ComponentManager.h
===================================================================
--- source/simulation2/tests/test_ComponentManager.h	(Revision 14461)
+++ source/simulation2/tests/test_ComponentManager.h	(Arbeitskopie)
@@ -59,14 +59,14 @@
 	void test_Load()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 	}
 
 	void test_LookupCID()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 
 		TS_ASSERT_EQUALS(man.LookupCID("Test1A"), (int)CID_Test1A);
@@ -76,7 +76,7 @@
 	void test_AllocateNewEntity()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 
 		TS_ASSERT_EQUALS(man.AllocateNewEntity(), (u32)2);
 		TS_ASSERT_EQUALS(man.AllocateNewEntity(), (u32)3);
@@ -99,7 +99,7 @@
 	void test_AddComponent_errors()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		CEntityHandle hnd1 = man.AllocateEntityHandle(1);
 
@@ -122,7 +122,7 @@
 	void test_QueryInterface()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 
 		entity_id_t ent1 = 1, ent2 = 2;
@@ -147,7 +147,7 @@
 	void test_SendMessage()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 
 		entity_id_t ent1 = 1, ent2 = 2, ent3 = 3, ent4 = 4;
@@ -221,7 +221,7 @@
 	void test_ParamNode()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 
 		entity_id_t ent1 = 1, ent2 = 2;
@@ -242,7 +242,7 @@
 	void test_script_basic()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test.js"));
 
@@ -286,7 +286,7 @@
 	void test_script_helper_basic()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-helper.js"));
 		TS_ASSERT(man.LoadScript(L"simulation/helpers/test-helper.js"));
@@ -303,7 +303,7 @@
 	void test_script_global_helper()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-global-helper.js"));
 
@@ -319,7 +319,7 @@
 	void test_script_interface()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/interfaces/test-interface.js"));
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-interface.js"));
@@ -337,7 +337,7 @@
 	void test_script_errors()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		ScriptTestSetup(man.m_ScriptInterface);
 		man.LoadComponentTypes();
 
@@ -354,7 +354,7 @@
 	void test_script_entityID()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		ScriptTestSetup(man.m_ScriptInterface);
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-entityid.js"));
@@ -374,7 +374,7 @@
 	void test_script_QueryInterface()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-query.js"));
 
@@ -395,7 +395,7 @@
 	void test_script_AddEntity()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-addentity.js"));
 		TS_ASSERT(man.LoadScript(L"simulation/components/addentity/test-addentity.js"));
@@ -428,7 +428,7 @@
 	void test_script_AddLocalEntity()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-addentity.js"));
 		TS_ASSERT(man.LoadScript(L"simulation/components/addentity/test-addentity.js"));
@@ -461,7 +461,7 @@
 	void test_script_DestroyEntity()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-destroyentity.js"));
 
@@ -481,7 +481,7 @@
 	void test_script_messages()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-msg.js"));
 
@@ -514,7 +514,7 @@
 	void test_script_template()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-param.js"));
 
@@ -536,7 +536,7 @@
 	void test_script_template_readonly()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-param.js"));
 
@@ -558,7 +558,7 @@
 	void test_script_hotload()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-hotload1.js"));
@@ -594,7 +594,7 @@
 	void test_serialization()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 
 		entity_id_t ent1 = 1, ent2 = 2, ent3 = FIRST_LOCAL_ENTITY;
@@ -664,7 +664,7 @@
 		);
 
 		CSimContext context2;
-		CComponentManager man2(context2);
+		CComponentManager man2(context2, ScriptInterface::CreateRuntime());
 		man2.LoadComponentTypes();
 
 		TS_ASSERT(man2.QueryInterface(ent1, IID_Test1) == NULL);
@@ -683,7 +683,7 @@
 	void test_script_serialization()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		ScriptTestSetup(man.m_ScriptInterface);
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-serialize.js"));
@@ -754,7 +754,7 @@
 		TS_ASSERT(man.SerializeState(stateStream));
 
 		CSimContext context2;
-		CComponentManager man2(context2);
+		CComponentManager man2(context2, ScriptInterface::CreateRuntime());
 		man2.LoadComponentTypes();
 		TS_ASSERT(man2.LoadScript(L"simulation/components/test-serialize.js"));
 
@@ -771,7 +771,7 @@
 	void test_script_serialization_errors()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-serialize.js"));
 
@@ -789,7 +789,7 @@
 	void test_script_serialization_template()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 		TS_ASSERT(man.LoadScript(L"simulation/components/test-serialize.js"));
 		man.InitSystemEntity();
@@ -813,7 +813,7 @@
 		TS_ASSERT(man.SerializeState(stateStream));
 
 		CSimContext context2;
-		CComponentManager man2(context2);
+		CComponentManager man2(context2, ScriptInterface::CreateRuntime());
 		man2.LoadComponentTypes();
 		TS_ASSERT(man2.LoadScript(L"simulation/components/test-serialize.js"));
 
Index: source/simulation2/tests/test_Simulation2.h
===================================================================
--- source/simulation2/tests/test_Simulation2.h	(Revision 14461)
+++ source/simulation2/tests/test_Simulation2.h	(Arbeitskopie)
@@ -17,6 +17,7 @@
 
 #include "lib/self_test.h"
 
+#include "scriptinterface/ScriptInterface.h"
 #include "simulation2/Simulation2.h"
 #include "simulation2/MessageTypes.h"
 #include "simulation2/components/ICmpTest.h"
@@ -56,7 +57,7 @@
 
 	void test_AddEntity()
 	{
-		CSimulation2 sim(NULL, &m_Terrain);
+		CSimulation2 sim(NULL, ScriptInterface::CreateRuntime(), &m_Terrain);
 		TS_ASSERT(sim.LoadScripts(L"simulation/components/addentity/"));
 
 		sim.ResetState(true, true);
@@ -76,7 +77,7 @@
 
 	void test_DestroyEntity()
 	{
-		CSimulation2 sim(NULL, &m_Terrain);
+		CSimulation2 sim(NULL, ScriptInterface::CreateRuntime(), &m_Terrain);
 		TS_ASSERT(sim.LoadScripts(L"simulation/components/addentity/"));
 
 		sim.ResetState(true, true);
@@ -128,7 +129,7 @@
 
 	void test_hotload_scripts()
 	{
-		CSimulation2 sim(NULL, &m_Terrain);
+		CSimulation2 sim(NULL, ScriptInterface::CreateRuntime(), &m_Terrain);
 
 		TS_ASSERT_OK(CreateDirectories(DataDir()/"mods"/"_test.sim"/"simulation"/"components"/"hotload"/"", 0700));
 
Index: source/simulation2/tests/test_CmpTemplateManager.h
===================================================================
--- source/simulation2/tests/test_CmpTemplateManager.h	(Revision 14461)
+++ source/simulation2/tests/test_CmpTemplateManager.h	(Arbeitskopie)
@@ -52,7 +52,7 @@
 	void test_LoadTemplate()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 
 		entity_id_t ent1 = 1, ent2 = 2;
@@ -114,7 +114,7 @@
 	void test_LoadTemplate_scriptcache()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 
 		entity_id_t ent1 = 1, ent2 = 2;
@@ -152,7 +152,7 @@
 	void test_LoadTemplate_errors()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 
 		entity_id_t ent1 = 1, ent2 = 2;
@@ -184,7 +184,7 @@
 	void test_LoadTemplate_multiple()
 	{
 		CSimContext context;
-		CComponentManager man(context);
+		CComponentManager man(context, ScriptInterface::CreateRuntime());
 		man.LoadComponentTypes();
 
 		entity_id_t ent1 = 1, ent2 = 2;
@@ -243,7 +243,7 @@
 	void test_load_all_DISABLED() // disabled since it's a bit slow and noisy
 	{
 		CTerrain dummy;
-		CSimulation2 sim(NULL, &dummy);
+		CSimulation2 sim(NULL, ScriptInterface::CreateRuntime(), &dummy);
 		sim.LoadDefaultScripts();
 		sim.ResetState();
 
Index: source/simulation2/tests/test_Serializer.h
===================================================================
--- source/simulation2/tests/test_Serializer.h	(Revision 14461)
+++ source/simulation2/tests/test_Serializer.h	(Arbeitskopie)
@@ -644,7 +644,7 @@
 
 		CTerrain terrain;
 
-		CSimulation2 sim2(NULL, &terrain);
+		CSimulation2 sim2(NULL, ScriptInterface::CreateRuntime(), &terrain);
 		sim2.LoadDefaultScripts();
 		sim2.ResetState();
 
Index: source/simulation2/system/ComponentManager.cpp
===================================================================
--- source/simulation2/system/ComponentManager.cpp	(Revision 14461)
+++ source/simulation2/system/ComponentManager.cpp	(Arbeitskopie)
@@ -52,9 +52,9 @@
 	CScriptValRooted msg;
 };
 
-CComponentManager::CComponentManager(CSimContext& context, bool skipScriptFunctions) :
+CComponentManager::CComponentManager(CSimContext& context, shared_ptr<ScriptRuntime> rt, bool skipScriptFunctions) :
 	m_NextScriptComponentTypeId(CID__LastNative),
-	m_ScriptInterface("Engine", "Simulation", ScriptInterface::CreateRuntime(128*MiB)),
+	m_ScriptInterface("Engine", "Simulation", rt),
 	m_SimContext(context), m_CurrentlyHotloading(false)
 {
 	context.SetComponentManager(this);
@@ -143,9 +143,9 @@
 	return ok;
 }
 
-void CComponentManager::Script_RegisterComponentType(void* cbdata, int iid, std::string cname, CScriptVal ctor)
+void CComponentManager::Script_RegisterComponentType(ScriptInterface::CxPrivate* pCxPrivate, int iid, std::string cname, CScriptVal ctor)
 {
-	CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+	CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 
 	// Find the C++ component that wraps the interface
 	int cidWrapper = componentManager->GetScriptWrapper(iid);
@@ -294,9 +294,9 @@
 	}
 }
 
-void CComponentManager::Script_RegisterInterface(void* cbdata, std::string name)
+void CComponentManager::Script_RegisterInterface(ScriptInterface::CxPrivate* pCxPrivate, std::string name)
 {
-	CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+	CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 
 	std::map<std::string, InterfaceId>::iterator it = componentManager->m_InterfaceIdsByName.find(name);
 	if (it != componentManager->m_InterfaceIdsByName.end())
@@ -315,9 +315,9 @@
 	componentManager->m_ScriptInterface.SetGlobal(("IID_" + name).c_str(), (int)id);
 }
 
-void CComponentManager::Script_RegisterMessageType(void* cbdata, std::string name)
+void CComponentManager::Script_RegisterMessageType(ScriptInterface::CxPrivate* pCxPrivate, std::string name)
 {
-	CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+	CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 
 	std::map<std::string, MessageTypeId>::iterator it = componentManager->m_MessageTypeIdsByName.find(name);
 	if (it != componentManager->m_MessageTypeIdsByName.end())
@@ -335,25 +335,25 @@
 	componentManager->m_ScriptInterface.SetGlobal(("MT_" + name).c_str(), (int)id);
 }
 
-void CComponentManager::Script_RegisterGlobal(void* cbdata, std::string name, CScriptVal value)
+void CComponentManager::Script_RegisterGlobal(ScriptInterface::CxPrivate* pCxPrivate, std::string name, CScriptVal value)
 {
-	CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+	CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 
 	// Set the value, and accept duplicates only if hotloading (otherwise it's an error,
 	// in order to detect accidental duplicate definitions of globals)
 	componentManager->m_ScriptInterface.SetGlobal(name.c_str(), value, componentManager->m_CurrentlyHotloading);
 }
 
-IComponent* CComponentManager::Script_QueryInterface(void* cbdata, int ent, int iid)
+IComponent* CComponentManager::Script_QueryInterface(ScriptInterface::CxPrivate* pCxPrivate, int ent, int iid)
 {
-	CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+	CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 	IComponent* component = componentManager->QueryInterface((entity_id_t)ent, iid);
 	return component;
 }
 
-std::vector<int> CComponentManager::Script_GetEntitiesWithInterface(void* cbdata, int iid)
+std::vector<int> CComponentManager::Script_GetEntitiesWithInterface(ScriptInterface::CxPrivate* pCxPrivate, int iid)
 {
-	CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+	CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 
 	std::vector<int> ret;
 	const InterfaceListUnordered& ents = componentManager->GetEntitiesWithInterfaceUnordered(iid);
@@ -364,9 +364,9 @@
 	return ret;
 }
 
-std::vector<IComponent*> CComponentManager::Script_GetComponentsWithInterface(void* cbdata, int iid)
+std::vector<IComponent*> CComponentManager::Script_GetComponentsWithInterface(ScriptInterface::CxPrivate* pCxPrivate, int iid)
 {
-	CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+	CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 
 	std::vector<IComponent*> ret;
 	InterfaceList ents = componentManager->GetEntitiesWithInterface(iid);
@@ -391,9 +391,9 @@
 	}
 }
 
-void CComponentManager::Script_PostMessage(void* cbdata, int ent, int mtid, CScriptVal data)
+void CComponentManager::Script_PostMessage(ScriptInterface::CxPrivate* pCxPrivate, int ent, int mtid, CScriptVal data)
 {
-	CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+	CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 
 	CMessage* msg = componentManager->ConstructMessage(mtid, data);
 	if (!msg)
@@ -404,9 +404,9 @@
 	delete msg;
 }
 
-void CComponentManager::Script_BroadcastMessage(void* cbdata, int mtid, CScriptVal data)
+void CComponentManager::Script_BroadcastMessage(ScriptInterface::CxPrivate* pCxPrivate, int mtid, CScriptVal data)
 {
-	CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+	CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 
 	CMessage* msg = componentManager->ConstructMessage(mtid, data);
 	if (!msg)
@@ -417,9 +417,9 @@
 	delete msg;
 }
 
-int CComponentManager::Script_AddEntity(void* cbdata, std::string templateName)
+int CComponentManager::Script_AddEntity(ScriptInterface::CxPrivate* pCxPrivate, std::string templateName)
 {
-	CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+	CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 
 	std::wstring name(templateName.begin(), templateName.end());
 	// TODO: should validate the string to make sure it doesn't contain scary characters
@@ -429,9 +429,9 @@
 	return (int)ent;
 }
 
-int CComponentManager::Script_AddLocalEntity(void* cbdata, std::string templateName)
+int CComponentManager::Script_AddLocalEntity(ScriptInterface::CxPrivate* pCxPrivate, std::string templateName)
 {
-	CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+	CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 
 	std::wstring name(templateName.begin(), templateName.end());
 	// TODO: should validate the string to make sure it doesn't contain scary characters
@@ -441,9 +441,9 @@
 	return (int)ent;
 }
 
-void CComponentManager::Script_DestroyEntity(void* cbdata, int ent)
+void CComponentManager::Script_DestroyEntity(ScriptInterface::CxPrivate* pCxPrivate, int ent)
 {
-	CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+	CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 
 	componentManager->DestroyComponentsSoon(ent);
 }
@@ -1001,19 +1001,19 @@
 	return schema;
 }
 
-CScriptVal CComponentManager::Script_ReadJSONFile(void* cbdata, std::wstring fileName)
+CScriptVal CComponentManager::Script_ReadJSONFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring fileName)
 {
-	return ReadJSONFile(cbdata, L"simulation/data", fileName);
+	return ReadJSONFile(pCxPrivate, L"simulation/data", fileName);
 }
 
-CScriptVal CComponentManager::Script_ReadCivJSONFile(void* cbdata, std::wstring fileName)
+CScriptVal CComponentManager::Script_ReadCivJSONFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring fileName)
 {
-	return ReadJSONFile(cbdata, L"civs", fileName);
+	return ReadJSONFile(pCxPrivate, L"civs", fileName);
 }
 
-CScriptVal CComponentManager::ReadJSONFile(void* cbdata, std::wstring filePath, std::wstring fileName)
+CScriptVal CComponentManager::ReadJSONFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring filePath, std::wstring fileName)
 {
-	CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+	CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 
 	VfsPath path = VfsPath(filePath) / fileName;
 
@@ -1033,7 +1033,7 @@
 	return INFO::OK;
 }
 
-std::vector<std::string> CComponentManager::Script_FindJSONFiles(void* UNUSED(cbdata), std::wstring subPath, bool recursive)
+std::vector<std::string> CComponentManager::Script_FindJSONFiles(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring subPath, bool recursive)
 {
 	FindJSONFilesCallbackData cbData;
 	cbData.path = VfsPath(L"simulation/data/" + subPath + L"/");
Index: source/simulation2/system/ComponentManager.h
===================================================================
--- source/simulation2/system/ComponentManager.h	(Revision 14461)
+++ source/simulation2/system/ComponentManager.h	(Arbeitskopie)
@@ -78,7 +78,7 @@
 	};
 
 public:
-	CComponentManager(CSimContext&, bool skipScriptFunctions = false);
+	CComponentManager(CSimContext&, shared_ptr<ScriptRuntime> rt, bool skipScriptFunctions = false);
 	~CComponentManager();
 
 	void LoadComponentTypes();
@@ -242,23 +242,22 @@
 
 private:
 	// Implementations of functions exposed to scripts
-	static void Script_RegisterComponentType(void* cbdata, int iid, std::string cname, CScriptVal ctor);
-	static void Script_RegisterInterface(void* cbdata, std::string name);
-	static void Script_RegisterMessageType(void* cbdata, std::string name);
-	static void Script_RegisterGlobal(void* cbdata, std::string name, CScriptVal value);
-	static IComponent* Script_QueryInterface(void* cbdata, int ent, int iid);
-	static std::vector<int> Script_GetEntitiesWithInterface(void* cbdata, int iid);
-	static std::vector<IComponent*> Script_GetComponentsWithInterface(void* cbdata, int iid);
-	static void Script_PostMessage(void* cbdata, int ent, int mtid, CScriptVal data);
-	static void Script_BroadcastMessage(void* cbdata, int mtid, CScriptVal data);
-	static int Script_AddEntity(void* cbdata, std::string templateName);
-	static int Script_AddLocalEntity(void* cbdata, std::string templateName);
-	static void Script_DestroyEntity(void* cbdata, int ent);
-	static CScriptVal Script_ReadJSONFile(void* cbdata, std::wstring fileName);
-	static CScriptVal Script_ReadCivJSONFile(void* cbdata, std::wstring fileName);
-	static std::vector<std::string> Script_FindJSONFiles(void* cbdata, std::wstring subPath, bool recursive);
-
-	static CScriptVal ReadJSONFile(void *cbdata, std::wstring filePath, std::wstring fileName);
+	static void Script_RegisterComponentType(ScriptInterface::CxPrivate* pCxPrivate, int iid, std::string cname, CScriptVal ctor);
+	static void Script_RegisterInterface(ScriptInterface::CxPrivate* pCxPrivate, std::string name);
+	static void Script_RegisterMessageType(ScriptInterface::CxPrivate* pCxPrivate, std::string name);
+	static void Script_RegisterGlobal(ScriptInterface::CxPrivate* pCxPrivate, std::string name, CScriptVal value);
+	static IComponent* Script_QueryInterface(ScriptInterface::CxPrivate* pCxPrivate, int ent, int iid);
+	static std::vector<int> Script_GetEntitiesWithInterface(ScriptInterface::CxPrivate* pCxPrivate, int iid);
+	static std::vector<IComponent*> Script_GetComponentsWithInterface(ScriptInterface::CxPrivate* pCxPrivate, int iid);
+	static void Script_PostMessage(ScriptInterface::CxPrivate* pCxPrivate, int ent, int mtid, CScriptVal data);
+	static void Script_BroadcastMessage(ScriptInterface::CxPrivate* pCxPrivate, int mtid, CScriptVal data);
+	static int Script_AddEntity(ScriptInterface::CxPrivate* pCxPrivate, std::string templateName);
+	static int Script_AddLocalEntity(ScriptInterface::CxPrivate* pCxPrivate, std::string templateName);
+	static void Script_DestroyEntity(ScriptInterface::CxPrivate* pCxPrivate, int ent);
+	static CScriptVal Script_ReadJSONFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring fileName);
+	static CScriptVal Script_ReadCivJSONFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring fileName);
+	static std::vector<std::string> Script_FindJSONFiles(ScriptInterface::CxPrivate* pCxPrivate, std::wstring subPath, bool recursive);
+	static CScriptVal ReadJSONFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring filePath, std::wstring fileName);
 	
 	// callback function to handle recursively finding files in a directory
 	static Status FindJSONFilesCallback(const VfsPath&, const CFileInfo&, const uintptr_t);
Index: source/simulation2/system/ComponentTest.h
===================================================================
--- source/simulation2/system/ComponentTest.h	(Revision 14461)
+++ source/simulation2/system/ComponentTest.h	(Arbeitskopie)
@@ -53,7 +53,7 @@
 
 public:
 	ComponentTestHelper() :
-		m_Context(), m_ComponentManager(m_Context), m_Cmp(NULL)
+		m_Context(), m_ComponentManager(m_Context, ScriptInterface::CreateRuntime()), m_Cmp(NULL)
 	{
 		m_ComponentManager.LoadComponentTypes();
 	}
Index: source/simulation2/components/CCmpAIManager.cpp
===================================================================
--- source/simulation2/components/CCmpAIManager.cpp	(Revision 14461)
+++ source/simulation2/components/CCmpAIManager.cpp	(Arbeitskopie)
@@ -270,15 +270,17 @@
 		return true;
 	}
 	
-	static void IncludeModule(void* cbdata, std::wstring name)
+	static void IncludeModule(ScriptInterface::CxPrivate* pCxPrivate, std::wstring name)
 	{
-		CAIWorker* self = static_cast<CAIWorker*> (cbdata);
+		ENSURE(pCxPrivate->pCBData);
+		CAIWorker* self = static_cast<CAIWorker*> (pCxPrivate->pCBData);
 		self->LoadScripts(name);
 	}
 
-	static void PostCommand(void* cbdata, int playerid, CScriptValRooted cmd)
+	static void PostCommand(ScriptInterface::CxPrivate* pCxPrivate, int playerid, CScriptValRooted cmd)
 	{
-		CAIWorker* self = static_cast<CAIWorker*> (cbdata);
+		ENSURE(pCxPrivate->pCBData);
+		CAIWorker* self = static_cast<CAIWorker*> (pCxPrivate->pCBData);
 		self->PostCommand(playerid, cmd);
 	}
 	
@@ -296,30 +298,20 @@
 		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)
+	static void DumpHeap(ScriptInterface::CxPrivate* pCxPrivate)
 	{
-		if (cbdata == NULL) {
-			debug_warn(L"Warning: the shared component has asked for DumpHeap. Ignoring.");
-			return;
-		}
-		CAIWorker* self = static_cast<CAIWorker*> (cbdata);
-		self->m_ScriptInterface->DumpHeap();
+		pCxPrivate->pScriptInterface->DumpHeap();
 	}
-	static void ForceGC(void* cbdata)
+	static void ForceGC(ScriptInterface::CxPrivate* pCxPrivate)
 	{
-		if (cbdata == NULL) {
-			debug_warn(L"Warning: the shared component has asked for ForceGC. Ignoring.");
-			return;
-		}
-		CAIWorker* self = static_cast<CAIWorker*> (cbdata);
 		PROFILE3("AI compute GC");
-		JS_GC(self->m_ScriptInterface->GetContext());
+		JS_GC(pCxPrivate->pScriptInterface->GetContext());
 	}
 	
 	/**
 	 * Debug function for AI scripts to dump 2D array data (e.g. terrain tile weights).
 	 */
-	static void DumpImage(void* UNUSED(cbdata), std::wstring name, std::vector<u32> data, u32 w, u32 h, u32 max)
+	static void DumpImage(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), 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;
@@ -763,7 +755,7 @@
 		}
 
 		// Run GC if we are about to overflow
-		if (JS_GetGCParameter(m_ScriptInterface->GetRuntime(), JSGC_BYTES) > 33000000)
+		if (JS_GetGCParameter(m_ScriptInterface->GetJSRuntime(), JSGC_BYTES) > 33000000)
 		{
 			PROFILE3("AI compute GC");
 
Index: source/simulation2/components/tests/test_Pathfinder.h
===================================================================
--- source/simulation2/components/tests/test_Pathfinder.h	(Revision 14461)
+++ source/simulation2/components/tests/test_Pathfinder.h	(Arbeitskopie)
@@ -61,7 +61,7 @@
 	{
 		CTerrain terrain;
 
-		CSimulation2 sim2(NULL, &terrain);
+		CSimulation2 sim2(NULL, ScriptInterface::CreateRuntime(), &terrain);
 		sim2.LoadDefaultScripts();
 		sim2.ResetState();
 
@@ -114,7 +114,7 @@
 		CTerrain terrain;
 		terrain.Initialize(5, NULL);
 
-		CSimulation2 sim2(NULL, &terrain);
+		CSimulation2 sim2(NULL, ScriptInterface::CreateRuntime(), &terrain);
 		sim2.LoadDefaultScripts();
 		sim2.ResetState();
 
Index: source/simulation2/components/tests/test_scripts.h
===================================================================
--- source/simulation2/components/tests/test_scripts.h	(Revision 14461)
+++ source/simulation2/components/tests/test_scripts.h	(Arbeitskopie)
@@ -43,15 +43,15 @@
 		TSM_ASSERT(L"Running script "+pathname.string(), scriptInterface.LoadScript(pathname, content));
 	}
 
-	static void Script_LoadComponentScript(void* cbdata, VfsPath pathname)
+	static void Script_LoadComponentScript(ScriptInterface::CxPrivate* pCxPrivate, VfsPath pathname)
 	{
-		CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+		CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 		TS_ASSERT(componentManager->LoadScript(VfsPath(L"simulation/components") / pathname));
 	}
 
-	static void Script_LoadHelperScript(void* cbdata, VfsPath pathname)
+	static void Script_LoadHelperScript(ScriptInterface::CxPrivate* pCxPrivate, VfsPath pathname)
 	{
-		CComponentManager* componentManager = static_cast<CComponentManager*> (cbdata);
+		CComponentManager* componentManager = static_cast<CComponentManager*> (pCxPrivate->pCBData);
 		TS_ASSERT(componentManager->LoadScript(VfsPath(L"simulation/helpers") / pathname));
 	}
 
@@ -68,7 +68,7 @@
 		for (size_t i = 0; i < paths.size(); ++i)
 		{
 			CSimContext context;
-			CComponentManager componentManager(context, true);
+			CComponentManager componentManager(context, ScriptInterface::CreateRuntime(), true);
 
 			ScriptTestSetup(componentManager.GetScriptInterface());
 
Index: source/simulation2/Simulation2.cpp
===================================================================
--- source/simulation2/Simulation2.cpp	(Revision 14461)
+++ source/simulation2/Simulation2.cpp	(Arbeitskopie)
@@ -59,8 +59,8 @@
 class CSimulation2Impl
 {
 public:
-	CSimulation2Impl(CUnitManager* unitManager, CTerrain* terrain) :
-		m_SimContext(), m_ComponentManager(m_SimContext),
+	CSimulation2Impl(CUnitManager* unitManager, shared_ptr<ScriptRuntime> rt, CTerrain* terrain) :
+		m_SimContext(), m_ComponentManager(m_SimContext, rt),
 		m_EnableOOSLog(false), m_EnableSerializationTest(false)
 	{
 		m_SimContext.m_UnitManager = unitManager;
@@ -376,7 +376,7 @@
 		CTerrain secondaryTerrain;
 		CSimContext secondaryContext;
 		secondaryContext.m_Terrain = &secondaryTerrain;
-		CComponentManager secondaryComponentManager(secondaryContext);
+		CComponentManager secondaryComponentManager(secondaryContext, m_ComponentManager.GetScriptInterface().GetRuntime());
 		secondaryComponentManager.LoadComponentTypes();
 		ENSURE(LoadDefaultScripts(secondaryComponentManager, NULL));
 		ResetComponentState(secondaryComponentManager, false, false);
@@ -565,8 +565,8 @@
 
 ////////////////////////////////////////////////////////////////
 
-CSimulation2::CSimulation2(CUnitManager* unitManager, CTerrain* terrain) :
-	m(new CSimulation2Impl(unitManager, terrain))
+CSimulation2::CSimulation2(CUnitManager* unitManager, shared_ptr<ScriptRuntime> rt, CTerrain* terrain) :
+	m(new CSimulation2Impl(unitManager, rt, terrain))
 {
 }
 
Index: source/renderer/scripting/JSInterface_Renderer.h
===================================================================
--- source/renderer/scripting/JSInterface_Renderer.h	(Revision 14461)
+++ source/renderer/scripting/JSInterface_Renderer.h	(Arbeitskopie)
@@ -19,16 +19,16 @@
 #ifndef INCLUDED_JSINTERFACE_RENDERER
 #define INCLUDED_JSINTERFACE_RENDERER
 
-class ScriptInterface;
+#include "scriptinterface/ScriptInterface.h"
 
 #define DECLARE_BOOLEAN_SCRIPT_SETTING(NAME) \
-	bool Get##NAME##Enabled(void* cbdata); \
-	void Set##NAME##Enabled(void* cbdata, bool Enabled);
+	bool Get##NAME##Enabled(ScriptInterface::CxPrivate* pCxPrivate); \
+	void Set##NAME##Enabled(ScriptInterface::CxPrivate* pCxPrivate, bool Enabled);
 
 namespace JSI_Renderer
 {
-	std::string GetRenderPath(void* cbdata);
-	void SetRenderPath(void* cbdata, std::string name);
+	std::string GetRenderPath(ScriptInterface::CxPrivate* pCxPrivate);
+	void SetRenderPath(ScriptInterface::CxPrivate* pCxPrivate, std::string name);
 
 	DECLARE_BOOLEAN_SCRIPT_SETTING(Shadows);
 	DECLARE_BOOLEAN_SCRIPT_SETTING(ShadowPCF);
Index: source/renderer/scripting/JSInterface_Renderer.cpp
===================================================================
--- source/renderer/scripting/JSInterface_Renderer.cpp	(Revision 14461)
+++ source/renderer/scripting/JSInterface_Renderer.cpp	(Arbeitskopie)
@@ -21,12 +21,12 @@
 #include "renderer/Renderer.h"
 
 #define IMPLEMENT_BOOLEAN_SCRIPT_SETTING(NAME, SCRIPTNAME) \
-bool JSI_Renderer::Get##SCRIPTNAME##Enabled(void* UNUSED(cbdata)) \
+bool JSI_Renderer::Get##SCRIPTNAME##Enabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) \
 { \
 	return g_Renderer.GetOptionBool(CRenderer::OPT_##NAME); \
 } \
 \
-void JSI_Renderer::Set##SCRIPTNAME##Enabled(void* UNUSED(cbdata), bool Enabled) \
+void JSI_Renderer::Set##SCRIPTNAME##Enabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool Enabled) \
 { \
 	g_Renderer.SetOptionBool(CRenderer::OPT_##NAME, Enabled); \
 }
@@ -47,12 +47,12 @@
 
 #undef IMPLEMENT_BOOLEAN_SCRIPT_SETTING
 
-std::string JSI_Renderer::GetRenderPath(void* UNUSED(cbdata))
+std::string JSI_Renderer::GetRenderPath(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	return CRenderer::GetRenderPathName(g_Renderer.GetRenderPath());
 }
 
-void JSI_Renderer::SetRenderPath(void* UNUSED(cbdata), std::string name)
+void JSI_Renderer::SetRenderPath(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::string name)
 {
 	g_Renderer.SetRenderPath(CRenderer::GetRenderPathByName(name));
 }
Index: source/lobby/scripting/JSInterface_Lobby.h
===================================================================
--- source/lobby/scripting/JSInterface_Lobby.h	(Revision 14461)
+++ source/lobby/scripting/JSInterface_Lobby.h	(Arbeitskopie)
@@ -18,48 +18,47 @@
 #ifndef INCLUDED_JSI_LOBBY
 #define INCLUDED_JSI_LOBBY
 
+#include "scriptinterface/ScriptInterface.h"
 #include "scriptinterface/ScriptVal.h"
 #include "lib/config2.h" // for CONFIG2_LOBBY
 
-class ScriptInterface;
-
 namespace JSI_Lobby
 {
-	bool HasXmppClient(void* cbdata);
+	bool HasXmppClient(ScriptInterface::CxPrivate* pCxPrivate);
 	
 #if CONFIG2_LOBBY 
-	void StartXmppClient(void* cbdata, std::wstring username, std::wstring password, std::wstring room, std::wstring nick);
-	void StartRegisterXmppClient(void* cbdata, std::wstring username, std::wstring password);
-	void StopXmppClient(void* cbdata);
-	void ConnectXmppClient(void* cbdata);
-	void DisconnectXmppClient(void* cbdata);
-	void RecvXmppClient(void* cbdata);
-	void SendGetGameList(void* cbdata);
-	void SendGetBoardList(void* cbdata);
-	void SendGameReport(void* cbdata, CScriptVal data);
-	void SendRegisterGame(void* cbdata, CScriptVal data);
-	void SendUnregisterGame(void* cbdata);
-	void SendChangeStateGame(void* cbdata, std::wstring nbp, std::wstring players);
-	CScriptVal GetPlayerList(void* cbdata);
-	CScriptVal GetGameList(void* cbdata);
-	CScriptVal GetBoardList(void* cbdata);
-	CScriptVal LobbyGuiPollMessage(void* cbdata);
-	void LobbySendMessage(void* cbdata, std::wstring message);
-	void LobbySetPlayerPresence(void* cbdata, std::wstring presence);
-	void LobbySetNick(void* cbdata, std::wstring nick);
-	std::wstring LobbyGetNick(void* cbdata);
-	void LobbyKick(void* cbdata, std::wstring nick, std::wstring reason);
-	void LobbyBan(void* cbdata, std::wstring nick, std::wstring reason);
-	std::wstring LobbyGetPlayerPresence(void* cbdata, std::wstring nickname);
+	void StartXmppClient(ScriptInterface::CxPrivate* pCxPrivate, std::wstring username, std::wstring password, std::wstring room, std::wstring nick);
+	void StartRegisterXmppClient(ScriptInterface::CxPrivate* pCxPrivate, std::wstring username, std::wstring password);
+	void StopXmppClient(ScriptInterface::CxPrivate* pCxPrivate);
+	void ConnectXmppClient(ScriptInterface::CxPrivate* pCxPrivate);
+	void DisconnectXmppClient(ScriptInterface::CxPrivate* pCxPrivate);
+	void RecvXmppClient(ScriptInterface::CxPrivate* pCxPrivate);
+	void SendGetGameList(ScriptInterface::CxPrivate* pCxPrivate);
+	void SendGetBoardList(ScriptInterface::CxPrivate* pCxPrivate);
+	void SendGameReport(ScriptInterface::CxPrivate* pCxPrivate, CScriptVal data);
+	void SendRegisterGame(ScriptInterface::CxPrivate* pCxPrivate, CScriptVal data);
+	void SendUnregisterGame(ScriptInterface::CxPrivate* pCxPrivate);
+	void SendChangeStateGame(ScriptInterface::CxPrivate* pCxPrivate, std::wstring nbp, std::wstring players);
+	CScriptVal GetPlayerList(ScriptInterface::CxPrivate* pCxPrivate);
+	CScriptVal GetGameList(ScriptInterface::CxPrivate* pCxPrivate);
+	CScriptVal GetBoardList(ScriptInterface::CxPrivate* pCxPrivate);
+	CScriptVal LobbyGuiPollMessage(ScriptInterface::CxPrivate* pCxPrivate);
+	void LobbySendMessage(ScriptInterface::CxPrivate* pCxPrivate, std::wstring message);
+	void LobbySetPlayerPresence(ScriptInterface::CxPrivate* pCxPrivate, std::wstring presence);
+	void LobbySetNick(ScriptInterface::CxPrivate* pCxPrivate, std::wstring nick);
+	std::wstring LobbyGetNick(ScriptInterface::CxPrivate* pCxPrivate);
+	void LobbyKick(ScriptInterface::CxPrivate* pCxPrivate, std::wstring nick, std::wstring reason);
+	void LobbyBan(ScriptInterface::CxPrivate* pCxPrivate, std::wstring nick, std::wstring reason);
+	std::wstring LobbyGetPlayerPresence(ScriptInterface::CxPrivate* pCxPrivate, std::wstring nickname);
 
 	// Non-public secure PBKDF2 hash function with salting and 1,337 iterations
 	std::string EncryptPassword(const std::string& password, const std::string& username);
 
 	// Public hash interface.
-	std::wstring EncryptPassword(void* cbdata, std::wstring pass, std::wstring user);
+	std::wstring EncryptPassword(ScriptInterface::CxPrivate* pCxPrivate, std::wstring pass, std::wstring user);
 	
-	bool IsRankedGame(void* cbdata);
-	void SetRankedGame(void* cbdata, bool isRanked);
+	bool IsRankedGame(ScriptInterface::CxPrivate* pCxPrivate);
+	void SetRankedGame(ScriptInterface::CxPrivate* pCxPrivate, bool isRanked);
 #endif // CONFIG2_LOBBY 
 }
 
Index: source/lobby/scripting/JSInterface_Lobby.cpp
===================================================================
--- source/lobby/scripting/JSInterface_Lobby.cpp	(Revision 14461)
+++ source/lobby/scripting/JSInterface_Lobby.cpp	(Arbeitskopie)
@@ -27,14 +27,14 @@
 
 #include "scriptinterface/ScriptInterface.h"
 
-bool JSI_Lobby::HasXmppClient(void* UNUSED(cbdata))
+bool JSI_Lobby::HasXmppClient(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	return (g_XmppClient ? true : false);
 }
 
 #if CONFIG2_LOBBY
 
-void JSI_Lobby::StartXmppClient(void* UNUSED(cbdata), std::wstring username, std::wstring password, std::wstring room, std::wstring nick)
+void JSI_Lobby::StartXmppClient(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring username, std::wstring password, std::wstring room, std::wstring nick)
 {
 	ENSURE(!g_XmppClient);
 
@@ -43,7 +43,7 @@
 	g_rankedGame = true;
 }
 
-void JSI_Lobby::StartRegisterXmppClient(void* UNUSED(cbdata), std::wstring username, std::wstring password)
+void JSI_Lobby::StartRegisterXmppClient(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring username, std::wstring password)
 {
 	ENSURE(!g_XmppClient);
 
@@ -51,123 +51,117 @@
 		"", "", true);
 }
 
-void JSI_Lobby::StopXmppClient(void* UNUSED(cbdata))
+void JSI_Lobby::StopXmppClient(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	ENSURE(g_XmppClient);
 	SAFE_DELETE(g_XmppClient);
 	g_rankedGame = false;
 }
 
-void JSI_Lobby::ConnectXmppClient(void* UNUSED(cbdata))
+void JSI_Lobby::ConnectXmppClient(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	ENSURE(g_XmppClient);
 	g_XmppClient->connect();
 }
 
-void JSI_Lobby::DisconnectXmppClient(void* UNUSED(cbdata))
+void JSI_Lobby::DisconnectXmppClient(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	ENSURE(g_XmppClient);
 	g_XmppClient->disconnect();
 }
 
-void JSI_Lobby::RecvXmppClient(void* UNUSED(cbdata))
+void JSI_Lobby::RecvXmppClient(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	if (!g_XmppClient)
 		return;
 	g_XmppClient->recv();
 }
 
-void JSI_Lobby::SendGetGameList(void* UNUSED(cbdata))
+void JSI_Lobby::SendGetGameList(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	if (!g_XmppClient)
 		return;
 	g_XmppClient->SendIqGetGameList();
 }
 
-void JSI_Lobby::SendGetBoardList(void* UNUSED(cbdata))
+void JSI_Lobby::SendGetBoardList(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	if (!g_XmppClient)
 		return;
 	g_XmppClient->SendIqGetBoardList();
 }
 
-void JSI_Lobby::SendGameReport(void* cbdata, CScriptVal data)
+void JSI_Lobby::SendGameReport(ScriptInterface::CxPrivate* pCxPrivate, CScriptVal data)
 {
 	if (!g_XmppClient)
 		return;
 
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-	g_XmppClient->SendIqGameReport(guiManager->GetScriptInterface(), data);
+	g_XmppClient->SendIqGameReport(*(pCxPrivate->pScriptInterface), data);
 }
 
-void JSI_Lobby::SendRegisterGame(void* cbdata, CScriptVal data)
+void JSI_Lobby::SendRegisterGame(ScriptInterface::CxPrivate* pCxPrivate, CScriptVal data)
 {
 	if (!g_XmppClient)
 		return;
-	
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-	g_XmppClient->SendIqRegisterGame(guiManager->GetScriptInterface(), data);
+
+	g_XmppClient->SendIqRegisterGame(*(pCxPrivate->pScriptInterface), data);
 }
 
-void JSI_Lobby::SendUnregisterGame(void* UNUSED(cbdata))
+void JSI_Lobby::SendUnregisterGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	if (!g_XmppClient)
 		return;
 	g_XmppClient->SendIqUnregisterGame();
 }
 
-void JSI_Lobby::SendChangeStateGame(void* UNUSED(cbdata), std::wstring nbp, std::wstring players)
+void JSI_Lobby::SendChangeStateGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring nbp, std::wstring players)
 {
 	if (!g_XmppClient)
 		return;
 	g_XmppClient->SendIqChangeStateGame(utf8_from_wstring(nbp), utf8_from_wstring(players));
 }
 
-CScriptVal JSI_Lobby::GetPlayerList(void* cbdata)
+CScriptVal JSI_Lobby::GetPlayerList(ScriptInterface::CxPrivate* pCxPrivate)
 {
 	if (!g_XmppClient)
 		return CScriptVal();
 		
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-	CScriptValRooted playerList = g_XmppClient->GUIGetPlayerList(guiManager->GetScriptInterface());
+	CScriptValRooted playerList = g_XmppClient->GUIGetPlayerList(*(pCxPrivate->pScriptInterface));
 
 	return playerList.get();
 }
 
-CScriptVal JSI_Lobby::GetGameList(void* cbdata)
+CScriptVal JSI_Lobby::GetGameList(ScriptInterface::CxPrivate* pCxPrivate)
 {
 	if (!g_XmppClient)
 		return CScriptVal();
 
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-	CScriptValRooted gameList = g_XmppClient->GUIGetGameList(guiManager->GetScriptInterface());
+	CScriptValRooted gameList = g_XmppClient->GUIGetGameList(*(pCxPrivate->pScriptInterface));
 
 	return gameList.get();
 }
 
-CScriptVal JSI_Lobby::GetBoardList(void* cbdata)
+CScriptVal JSI_Lobby::GetBoardList(ScriptInterface::CxPrivate* pCxPrivate)
 {
 	if (!g_XmppClient)
 		return CScriptVal();
 
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-	CScriptValRooted boardList = g_XmppClient->GUIGetBoardList(guiManager->GetScriptInterface());
+	CScriptValRooted boardList = g_XmppClient->GUIGetBoardList(*(pCxPrivate->pScriptInterface));
 
 	return boardList.get();
 }
 
-CScriptVal JSI_Lobby::LobbyGuiPollMessage(void* cbdata)
+CScriptVal JSI_Lobby::LobbyGuiPollMessage(ScriptInterface::CxPrivate* pCxPrivate)
 {
 	if (!g_XmppClient)
 		return CScriptVal();
-		
-	CGUIManager* guiManager = static_cast<CGUIManager*> (cbdata);
-	CScriptValRooted poll = g_XmppClient->GuiPollMessage(guiManager->GetScriptInterface());
+	
+	CScriptValRooted poll = g_XmppClient->GuiPollMessage(*(pCxPrivate->pScriptInterface));
 
 	return poll.get();
 }
 
-void JSI_Lobby::LobbySendMessage(void* UNUSED(cbdata), std::wstring message)
+void JSI_Lobby::LobbySendMessage(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring message)
 {
 	if (!g_XmppClient)
 		return;
@@ -175,7 +169,7 @@
 	g_XmppClient->SendMUCMessage(utf8_from_wstring(message));
 }
 
-void JSI_Lobby::LobbySetPlayerPresence(void* UNUSED(cbdata), std::wstring presence)
+void JSI_Lobby::LobbySetPlayerPresence(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring presence)
 {
 	if (!g_XmppClient)
 		return;
@@ -183,7 +177,7 @@
 	g_XmppClient->SetPresence(utf8_from_wstring(presence));
 }
 
-void JSI_Lobby::LobbySetNick(void* UNUSED(cbdata), std::wstring nick)
+void JSI_Lobby::LobbySetNick(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring nick)
 {
 	if (!g_XmppClient)
 		return;
@@ -191,7 +185,7 @@
 	g_XmppClient->SetNick(utf8_from_wstring(nick));
 }
 
-std::wstring JSI_Lobby::LobbyGetNick(void* UNUSED(cbdata))
+std::wstring JSI_Lobby::LobbyGetNick(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	if (!g_XmppClient)
 		return L"";
@@ -201,7 +195,7 @@
 	return wstring_from_utf8(nick);
 }
 
-void JSI_Lobby::LobbyKick(void* UNUSED(cbdata), std::wstring nick, std::wstring reason)
+void JSI_Lobby::LobbyKick(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring nick, std::wstring reason)
 {
 	if (!g_XmppClient)
 		return;
@@ -209,7 +203,7 @@
 	g_XmppClient->kick(utf8_from_wstring(nick), utf8_from_wstring(reason));
 }
 
-void JSI_Lobby::LobbyBan(void* UNUSED(cbdata), std::wstring nick, std::wstring reason)
+void JSI_Lobby::LobbyBan(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring nick, std::wstring reason)
 {
 	if (!g_XmppClient)
 		return;
@@ -217,7 +211,7 @@
 	g_XmppClient->ban(utf8_from_wstring(nick), utf8_from_wstring(reason));
 }
 
-std::wstring JSI_Lobby::LobbyGetPlayerPresence(void* UNUSED(cbdata), std::wstring nickname)
+std::wstring JSI_Lobby::LobbyGetPlayerPresence(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring nickname)
 {
 	if (!g_XmppClient)
 		return L"";
@@ -258,17 +252,17 @@
 	return std::string(hex, sizeof(hex));
 }
 
-std::wstring JSI_Lobby::EncryptPassword(void* UNUSED(cbdata), std::wstring pass, std::wstring user)
+std::wstring JSI_Lobby::EncryptPassword(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring pass, std::wstring user)
 {
 	return wstring_from_utf8(JSI_Lobby::EncryptPassword(utf8_from_wstring(pass), utf8_from_wstring(user)));
 }
 
-bool JSI_Lobby::IsRankedGame(void* UNUSED(cbdata))
+bool JSI_Lobby::IsRankedGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	return g_rankedGame;
 }
 
-void JSI_Lobby::SetRankedGame(void* UNUSED(cbdata), bool isRanked)
+void JSI_Lobby::SetRankedGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool isRanked)
 {
 	g_rankedGame = isRanked;
 }
Index: source/ps/GameSetup/GameSetup.cpp
===================================================================
--- source/ps/GameSetup/GameSetup.cpp	(Revision 14461)
+++ source/ps/GameSetup/GameSetup.cpp	(Arbeitskopie)
@@ -44,8 +44,6 @@
 #include "graphics/TerrainTextureManager.h"
 #include "gui/GUI.h"
 #include "gui/GUIManager.h"
-#include "gui/scripting/JSInterface_IGUIObject.h"
-#include "gui/scripting/JSInterface_GUITypes.h"
 #include "gui/scripting/ScriptFunctions.h"
 #include "maths/MathUtil.h"
 #include "network/NetServer.h"
@@ -81,8 +79,6 @@
 #include "renderer/Renderer.h"
 #include "renderer/VertexBufferManager.h"
 #include "renderer/ModelRenderer.h"
-#include "scripting/ScriptingHost.h"
-#include "scripting/ScriptGlue.h"
 #include "scriptinterface/DebuggingServer.h"
 #include "scriptinterface/ScriptInterface.h"
 #include "scriptinterface/ScriptStats.h"
@@ -115,6 +111,8 @@
 bool g_DoRenderLogger = true;
 bool g_DoRenderCursor = true;
 
+shared_ptr<ScriptRuntime> g_ScriptRuntime;
+
 static const int SANE_TEX_QUALITY_DEFAULT = 5;	// keep in sync with code
 
 static void SetTextureQuality(int quality)
@@ -182,9 +180,9 @@
 // display progress / description in loading screen
 void GUI_DisplayLoadProgress(int percent, const wchar_t* pending_task)
 {
-	g_ScriptingHost.GetScriptInterface().SetGlobal("g_Progress", percent, true);
-	g_ScriptingHost.GetScriptInterface().SetGlobal("g_LoadDescription", pending_task, true);
-	g_GUI->SendEventToAll("progress");
+	g_GUI->GetActiveGUI()->GetScriptInterface()->SetGlobal("g_Progress", percent, true);
+	g_GUI->GetActiveGUI()->GetScriptInterface()->SetGlobal("g_LoadDescription", pending_task, true);
+	g_GUI->GetActiveGUI()->SendEventToAll("progress");
 }
 
 
@@ -320,28 +318,6 @@
 }
 
 
-static void RegisterJavascriptInterfaces()
-{
-	// GUI
-	CGUI::ScriptingInit();
-
-	GuiScriptingInit(g_ScriptingHost.GetScriptInterface());
-	JSI_Sound::RegisterScriptFunctions(g_ScriptingHost.GetScriptInterface());
-}
-
-
-static void InitScripting()
-{
-	TIMER(L"InitScripting");
-
-	// Create the scripting host.  This needs to be done before the GUI is created.
-	// [7ms]
-	new ScriptingHost;
-	
-	RegisterJavascriptInterfaces();
-}
-
-
 static size_t OperatingSystemFootprint()
 {
 #if OS_WIN
@@ -499,7 +475,7 @@
 }
 
 
-static void InitPs(bool setup_gui, const CStrW& gui_page, CScriptVal initData)
+static void InitPs(bool setup_gui, const CStrW& gui_page, ScriptInterface* srcScriptInterface, CScriptVal initData)
 {
 	{
 		// console
@@ -530,12 +506,12 @@
 	{
 		// We do actually need *some* kind of GUI loaded, so use the
 		// (currently empty) Atlas one
-		g_GUI->SwitchPage(L"page_atlas.xml", initData);
+		g_GUI->SwitchPage(L"page_atlas.xml", srcScriptInterface, initData);
 		return;
 	}
 
 	// GUI uses VFS, so this must come after VFS init.
-	g_GUI->SwitchPage(gui_page, initData);
+	g_GUI->SwitchPage(gui_page, srcScriptInterface, initData);
 }
 
 
@@ -687,7 +663,7 @@
 
 	SAFE_DELETE(g_XmppClient);
 
-	ShutdownPs(); // Must delete g_GUI before g_ScriptingHost
+	ShutdownPs();
 
 	in_reset_handlers();
 
@@ -718,10 +694,9 @@
 	g_UserReporter.Deinitialize();
 	TIMER_END(L"shutdown UserReporter");
 
-	TIMER_BEGIN(L"shutdown ScriptingHost");
-	delete &g_ScriptingHost;
+	TIMER_BEGIN(L"shutdown DebuggingServer (if active)");
 	delete g_DebuggingServer;
-	TIMER_END(L"shutdown ScriptingHost");
+	TIMER_END(L"shutdown DebuggingServer (if active)");
 
 	TIMER_BEGIN(L"shutdown ConfigDB");
 	delete &g_ConfigDB;
@@ -875,13 +850,16 @@
 	// This must come after VFS init, which sets the current directory
 	// (required for finding our output log files).
 	g_Logger = new CLogger;
+	
+	// Workaround until Simulation and AI use their own threads and also their own runtimes
+	g_ScriptRuntime = ScriptInterface::CreateRuntime(128 * 1024 * 1024);
 
 	// Special command-line mode to dump the entity schemas instead of running the game.
 	// (This must be done after loading VFS etc, but should be done before wasting time
 	// on anything else.)
 	if (args.Has("dumpSchema"))
 	{
-		CSimulation2 sim(NULL, NULL);
+		CSimulation2 sim(NULL, g_ScriptRuntime, NULL);
 		sim.LoadDefaultScripts();
 		std::ofstream f("entity.rng", std::ios_base::out | std::ios_base::trunc);
 		f << sim.GenerateSchema();
@@ -920,8 +898,6 @@
 	if (g_JSDebuggerEnabled)
 		g_DebuggingServer = new CDebuggingServer();
 
-	InitScripting();	// before GUI
-
 	// Optionally start profiler HTTP output automatically
 	// (By default it's only enabled by a hotkey, for security/performance)
 	bool profilerHTTPEnable = false;
@@ -977,7 +953,7 @@
 	if(g_DisableAudio)
 		ISoundManager::SetEnabled(false);
 
-	g_GUI = new CGUIManager(g_ScriptingHost.GetScriptInterface());
+	g_GUI = new CGUIManager();
 
 	// (must come after SetVideoMode, since it calls ogl_Init)
 	if (ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", NULL) != 0 // ARB
@@ -1036,11 +1012,11 @@
 			CScriptValRooted data;
 			if (g_GUI)
 			{
-				ScriptInterface& scriptInterface = g_GUI->GetScriptInterface();
-				scriptInterface.Eval("({})", data);
-				scriptInterface.SetProperty(data.get(), "isStartup", true);
+				shared_ptr<ScriptInterface> scriptInterface = g_GUI->GetScriptInterface();
+				scriptInterface->Eval("({})", data);
+				scriptInterface->SetProperty(data.get(), "isStartup", true);
 			}
-			InitPs(setup_gui, L"page_pregame.xml", data.get());
+			InitPs(setup_gui, L"page_pregame.xml", g_GUI->GetScriptInterface().get(), data.get());
 		}
 	}
 	catch (PSERROR_Game_World_MapLoadFailed& e)
@@ -1048,7 +1024,7 @@
 		// Map Loading failed
 
 		// Start the engine so we have a GUI
-		InitPs(true, L"page_pregame.xml", JSVAL_VOID);
+		InitPs(true, L"page_pregame.xml", NULL, JSVAL_VOID);
 
 		// Call script function to do the actual work
 		//	(delete game data, switch GUI page, show error, etc.)
@@ -1262,9 +1238,8 @@
 	scriptInterface.SetProperty(attrs.get(), "settings", settings);
 
 	CScriptVal mpInitData;
-	g_GUI->GetScriptInterface().Eval("({isNetworked:true, playerAssignments:{}})", mpInitData);
-	g_GUI->GetScriptInterface().SetProperty(mpInitData.get(), "attribs",
-			CScriptVal(g_GUI->GetScriptInterface().CloneValueFromOtherContext(scriptInterface, attrs.get())));
+	scriptInterface.Eval("({isNetworked:true, playerAssignments:{}})", mpInitData);
+	scriptInterface.SetProperty(mpInitData.get(), "attribs", attrs);
 
 	// Get optional playername
 	CStrW userName = L"anonymous";
@@ -1275,7 +1250,7 @@
 
 	if (args.Has("autostart-host"))
 	{
-		InitPs(true, L"page_loading.xml", mpInitData.get());
+		InitPs(true, L"page_loading.xml", &scriptInterface, mpInitData.get());
 
 		size_t maxPlayers = 2;
 		if (args.Has("autostart-players"))
@@ -1296,7 +1271,7 @@
 	}
 	else if (args.Has("autostart-client"))
 	{
-		InitPs(true, L"page_loading.xml", mpInitData.get());
+		InitPs(true, L"page_loading.xml", &scriptInterface, mpInitData.get());
 
 		g_NetClient = new CNetClient(g_Game);
 		g_NetClient->SetUserName(userName);
@@ -1320,7 +1295,7 @@
 		PSRETURN ret = g_Game->ReallyStartGame();
 		ENSURE(ret == PSRETURN_OK);
 
-		InitPs(true, L"page_session.xml", JSVAL_VOID);
+		InitPs(true, L"page_session.xml", NULL, JSVAL_VOID);
 	}
 
 	return true;
@@ -1335,14 +1310,7 @@
 	// So all GUI pages that load games should include this script
 	if (g_GUI && g_GUI->HasPages())
 	{
-		JSContext* cx = g_ScriptingHost.getContext();
-		jsval fval, rval;
-		JSBool ok = JS_GetProperty(cx, g_GUI->GetScriptObject(), "cancelOnError", &fval);
-		ENSURE(ok);
-
-		jsval msgval = ScriptInterface::ToJSVal(cx, message);
-
-		if (ok && !JSVAL_IS_VOID(fval))
-			JS_CallFunctionValue(cx, g_GUI->GetScriptObject(), fval, 1, &msgval, &rval);
+		if (g_GUI->GetActiveGUI()->GetScriptInterface()->HasProperty(g_GUI->GetActiveGUI()->GetGlobalObject(), "cancelOnError" ))
+			g_GUI->GetActiveGUI()->GetScriptInterface()->CallFunctionVoid(g_GUI->GetActiveGUI()->GetGlobalObject(), "cancelOnError", message);
 	}
 }
Index: source/ps/GameSetup/HWDetect.cpp
===================================================================
--- source/ps/GameSetup/HWDetect.cpp	(Revision 14461)
+++ source/ps/GameSetup/HWDetect.cpp	(Arbeitskopie)
@@ -17,7 +17,6 @@
 
 #include "precompiled.h"
 
-#include "scripting/ScriptingHost.h"
 #include "scriptinterface/ScriptInterface.h"
 
 #include "lib/ogl.h"
@@ -123,30 +122,30 @@
 	return !(ns == CFG_LAST || ns == CFG_DEFAULT);
 }
 
-void SetDisableAudio(void* UNUSED(cbdata), bool disabled)
+void SetDisableAudio(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool disabled)
 {
 	g_DisableAudio = disabled;
 }
 
-void SetDisableS3TC(void* UNUSED(cbdata), bool disabled)
+void SetDisableS3TC(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool disabled)
 {
 	if (!IsOverridden("nos3tc"))
 		ogl_tex_override(OGL_TEX_S3TC, disabled ? OGL_TEX_DISABLE : OGL_TEX_ENABLE);
 }
 
-void SetDisableShadows(void* UNUSED(cbdata), bool disabled)
+void SetDisableShadows(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool disabled)
 {
 	if (!IsOverridden("shadows"))
 		g_Shadows = !disabled;
 }
 
-void SetDisableShadowPCF(void* UNUSED(cbdata), bool disabled)
+void SetDisableShadowPCF(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool disabled)
 {
 	if (!IsOverridden("shadowpcf"))
 		g_ShadowPCF = !disabled;
 }
 
-void SetDisableAllWater(void* UNUSED(cbdata), bool disabled)
+void SetDisableAllWater(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool disabled)
 {
 	if (!IsOverridden("waternormals"))
 		g_WaterNormal = !disabled;
@@ -163,7 +162,7 @@
 	if (!IsOverridden("watershadows"))
 		g_WaterShadows = !disabled;
 }
-void SetDisableFancyWater(void* UNUSED(cbdata), bool disabled)
+void SetDisableFancyWater(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool disabled)
 {
 	if (!IsOverridden("waterrealdepth"))
 		g_WaterRealDepth = !disabled;
@@ -174,7 +173,7 @@
 	if (!IsOverridden("watershadows"))
 		g_WaterShadows = !disabled;
 }
-void SetDisableFBOWater(void* UNUSED(cbdata), bool disabled)
+void SetDisableFBOWater(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool disabled)
 {
 	if (!IsOverridden("waterfoam"))
 		g_WaterFoam = !disabled;
@@ -182,7 +181,7 @@
 		g_WaterCoastalWaves = !disabled;
 }
 
-void SetRenderPath(void* UNUSED(cbdata), std::string renderpath)
+void SetRenderPath(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::string renderpath)
 {
 	g_RenderPath = renderpath;
 }
@@ -191,7 +190,7 @@
 {
 	TIMER(L"RunHardwareDetection");
 
-	ScriptInterface& scriptInterface = g_ScriptingHost.GetScriptInterface();
+	ScriptInterface scriptInterface("Engine", "HWDetect", g_ScriptRuntime);
 
 	scriptInterface.RegisterFunction<void, bool, &SetDisableAudio>("SetDisableAudio");
 	scriptInterface.RegisterFunction<void, bool, &SetDisableS3TC>("SetDisableS3TC");
Index: source/ps/SavedGame.cpp
===================================================================
--- source/ps/SavedGame.cpp	(Revision 14461)
+++ source/ps/SavedGame.cpp	(Arbeitskopie)
@@ -81,7 +81,10 @@
 	simulation.GetScriptInterface().SetProperty(metadata.get(), "initAttributes", simulation.GetInitAttributes());
 	if (gui)
 	{
-		CScriptVal guiMetadata = simulation.GetScriptInterface().CloneValueFromOtherContext(gui->GetScriptInterface(), gui->GetSavedGameData().get());
+		ScriptInterface* pPageScriptInterface = NULL;
+		CScriptVal guiMetadataPageCx = gui->GetSavedGameData(pPageScriptInterface);
+
+		CScriptVal guiMetadata = simulation.GetScriptInterface().CloneValueFromOtherContext(*pPageScriptInterface, guiMetadataPageCx.get());
 		simulation.GetScriptInterface().SetProperty(metadata.get(), "gui", guiMetadata);
 	}
 	simulation.GetScriptInterface().SetProperty(metadata.get(), "description", description);
Index: source/ps/Game.cpp
===================================================================
--- source/ps/Game.cpp	(Revision 14461)
+++ source/ps/Game.cpp	(Arbeitskopie)
@@ -24,6 +24,7 @@
 #include "graphics/ParticleManager.h"
 #include "graphics/UnitManager.h"
 #include "gui/GUIManager.h"
+#include "gui/CGUI.h"
 #include "lib/config2.h"
 #include "lib/timer.h"
 #include "network/NetClient.h"
@@ -41,7 +42,6 @@
 #include "ps/GameSetup/GameSetup.h"
 #include "renderer/Renderer.h"
 #include "renderer/TimeManager.h"
-#include "scripting/ScriptingHost.h"
 #include "scriptinterface/ScriptInterface.h"
 #include "simulation2/Simulation2.h"
 #include "simulation2/components/ICmpPlayer.h"
@@ -64,7 +64,7 @@
  **/
 CGame::CGame(bool disableGraphics):
 	m_World(new CWorld(this)),
-	m_Simulation2(new CSimulation2(&m_World->GetUnitManager(), m_World->GetTerrain())),
+	m_Simulation2(new CSimulation2(&m_World->GetUnitManager(), g_ScriptRuntime, m_World->GetTerrain())),
 	m_GameView(disableGraphics ? NULL : new CGameView(this)),
 	m_GameStarted(false),
 	m_Paused(false),
@@ -233,11 +233,8 @@
 	// Call the reallyStartGame GUI function, but only if it exists
 	if (g_GUI && g_GUI->HasPages())
 	{
-		jsval fval, rval;
-		JSBool ok = JS_GetProperty(g_ScriptingHost.getContext(), g_GUI->GetScriptObject(), "reallyStartGame", &fval);
-		ENSURE(ok);
-		if (ok && !JSVAL_IS_VOID(fval))
-			JS_CallFunctionValue(g_ScriptingHost.getContext(), g_GUI->GetScriptObject(), fval, 0, NULL, &rval);
+		if (g_GUI->GetActiveGUI()->GetScriptInterface()->HasProperty(g_GUI->GetActiveGUI()->GetGlobalObject(), "reallyStartGame"))
+			g_GUI->GetActiveGUI()->GetScriptInterface()->CallFunctionVoid(g_GUI->GetActiveGUI()->GetGlobalObject(), "reallyStartGame");
 	}
 
 	if (g_NetClient)
Index: source/ps/scripting/JSInterface_VFS.cpp
===================================================================
--- source/ps/scripting/JSInterface_VFS.cpp	(Revision 14461)
+++ source/ps/scripting/JSInterface_VFS.cpp	(Arbeitskopie)
@@ -19,9 +19,10 @@
 
 #include <sstream>
 
+#include "ps/CLogger.h"
 #include "ps/CStr.h"
 #include "ps/Filesystem.h"
-#include "scripting/ScriptingHost.h"
+#include "scriptinterface/ScriptVal.h"
 #include "scriptinterface/ScriptInterface.h"
 #include "ps/scripting/JSInterface_VFS.h"
 #include "lib/file/vfs/vfs_util.h"
@@ -31,13 +32,11 @@
 	/* this is liable to happen often, so don't complain */\
 	if (err == ERR::VFS_FILE_NOT_FOUND)\
 	{\
-		JS_SET_RVAL(cx, vp, JSVAL_NULL);\
-		return JS_TRUE;\
+		return 0; \
 	}\
-	/* unknown failure. we return an error (akin to an exception in JS) that
-	   stops the script to make sure this error is noticed. */\
+	/* unknown failure. We output an error message. */\
 	else if (err < 0)\
-		return JS_FALSE;\
+		LOGERROR(L"Unknown failure in VFS %i", err );
 	/* else: success */
 
 
@@ -85,61 +84,30 @@
 //
 // note: full pathnames of each file/subdirectory are returned,
 // ready for use as a "filename" for the other functions.
-JSBool JSI_VFS::BuildDirEntList(JSContext* cx, uintN argc, jsval* vp)
+CScriptVal JSI_VFS::BuildDirEntList(ScriptInterface::CxPrivate* pCxPrivate, std::wstring path, std::wstring filterStr, bool recurse)
 {
-	//
-	// get arguments
-	//
-
-	JSU_REQUIRE_PARAM_RANGE(1, 3);
-
-	CStrW path;
-	if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], path))
-		return JS_FALSE;
-
-	CStrW filter_str = L"";
-	if (argc >= 2)
-	{
-		if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[1], filter_str))
-			return JS_FALSE;
-	}
 	// convert to const wchar_t*; if there's no filter, pass 0 for speed
 	// (interpreted as: "accept all files without comparing").
 	const wchar_t* filter = 0;
-	if (!filter_str.empty())
-		filter = filter_str.c_str();
+	if (!filterStr.empty())
+		filter = filterStr.c_str();
+ 
+	int flags = recurse ? vfs::DIR_RECURSIVE : 0;
 
-	bool recursive = false;
-	if (argc >= 3)
-	{
-		if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[2], recursive))
-			return JS_FALSE;
-	}
-	int flags = recursive ? vfs::DIR_RECURSIVE : 0;
-
-
 	// build array in the callback function
-	BuildDirEntListState state(cx);
+	BuildDirEntListState state(pCxPrivate->pScriptInterface->GetContext());
 	vfs::ForEachFile(g_VFS, path, BuildDirEntListCB, (uintptr_t)&state, filter, flags);
 
-	JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(state.filename_array));
-	return JS_TRUE;
+	return OBJECT_TO_JSVAL(state.filename_array);
 }
 
 // Return true iff the file exits
 //
 // if (fileExists(filename)) { ... }
 //   filename: VFS filename (may include path)
-JSBool JSI_VFS::FileExists(JSContext* cx, uintN argc, jsval* vp)
+bool JSI_VFS::FileExists(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), CStrW filename)
 {
-	JSU_REQUIRE_PARAMS(1);
-
-	CStrW filename;
-	if (!ScriptInterface::FromJSVal<CStrW> (cx, JS_ARGV(cx, vp)[0], filename))
-		return JS_FALSE;
-
-	JS_SET_RVAL(cx, vp, g_VFS->GetFileInfo(filename, 0) == INFO::OK ? JSVAL_TRUE : JSVAL_FALSE);
-	return JS_TRUE;
+	return (g_VFS->GetFileInfo(filename, 0) == INFO::OK);
 }
 
 
@@ -147,20 +115,13 @@
 //
 // mtime = getFileMTime(filename);
 //   filename: VFS filename (may include path)
-JSBool JSI_VFS::GetFileMTime(JSContext* cx, uintN argc, jsval* vp)
+double JSI_VFS::GetFileMTime(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring filename)
 {
-	JSU_REQUIRE_PARAMS(1);
-
-	CStrW filename;
-	if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], filename))
-		return JS_FALSE;
-
 	CFileInfo fileInfo;
 	Status err = g_VFS->GetFileInfo(filename, &fileInfo);
 	JS_CHECK_FILE_ERR(err);
 
-	JS_SET_RVAL(cx, vp, ScriptInterface::ToJSVal(cx, (double)fileInfo.MTime()));
-	return JS_TRUE;
+	return (double)fileInfo.MTime();
 }
 
 
@@ -168,20 +129,13 @@
 //
 // size = getFileSize(filename);
 //   filename: VFS filename (may include path)
-JSBool JSI_VFS::GetFileSize(JSContext* cx, uintN argc, jsval* vp)
+unsigned int JSI_VFS::GetFileSize(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring filename)
 {
-	JSU_REQUIRE_PARAMS(1);
-
-	CStrW filename;
-	if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], filename))
-		return JS_FALSE;
-
 	CFileInfo fileInfo;
 	Status err = g_VFS->GetFileInfo(filename, &fileInfo);
 	JS_CHECK_FILE_ERR(err);
 
-	JS_SET_RVAL(cx, vp, ScriptInterface::ToJSVal(cx, (unsigned)fileInfo.Size()));
-	return JS_TRUE;
+	return (unsigned int)fileInfo.Size();
 }
 
 
@@ -189,23 +143,11 @@
 //
 // contents = readFile(filename);
 //   filename: VFS filename (may include path)
-JSBool JSI_VFS::ReadFile(JSContext* cx, uintN argc, jsval* vp)
+CScriptVal JSI_VFS::ReadFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring filename)
 {
-	JSU_REQUIRE_PARAMS(1);
-
-	CStrW filename;
-	if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], filename))
-		return JS_FALSE;
-
-	//
-	// read file
-	//
 	CVFSFile file;
 	if (file.Load(g_VFS, filename) != PSRETURN_OK)
-	{
-		JS_SET_RVAL(cx, vp, JSVAL_NULL);
-		return JS_TRUE;
-	}
+		return JSVAL_NULL;
 
 	CStr contents = file.DecodeUTF8(); // assume it's UTF-8
 
@@ -213,8 +155,7 @@
 	contents.Replace("\r\n", "\n");
 
 	// Decode as UTF-8
-	JS_SET_RVAL(cx, vp, ScriptInterface::ToJSVal(cx, contents.FromUTF8()));
-	return JS_TRUE;
+	return ScriptInterface::ToJSVal( pCxPrivate->pScriptInterface->GetContext(), contents.FromUTF8() );
 }
 
 
@@ -222,23 +163,14 @@
 //
 // lines = readFileLines(filename);
 //   filename: VFS filename (may include path)
-JSBool JSI_VFS::ReadFileLines(JSContext* cx, uintN argc, jsval* vp)
+CScriptVal JSI_VFS::ReadFileLines(ScriptInterface::CxPrivate* pCxPrivate, std::wstring filename)
 {
-	JSU_REQUIRE_PARAMS(1);
-
-	CStrW filename;
-	if (!ScriptInterface::FromJSVal(cx, JS_ARGV(cx, vp)[0], filename))
-		return (JS_FALSE);
-
 	//
 	// read file
 	//
 	CVFSFile file;
 	if (file.Load(g_VFS, filename) != PSRETURN_OK)
-	{
-		JS_SET_RVAL(cx, vp, JSVAL_NULL);
-		return JS_TRUE;
-	}
+		return JSVAL_NULL;
 
 	CStr contents = file.DecodeUTF8(); // assume it's UTF-8
 
@@ -251,6 +183,7 @@
 
 	std::stringstream ss(contents);
 
+	JSContext* cx = pCxPrivate->pScriptInterface->GetContext();
 	JSObject* line_array = JS_NewArrayObject(cx, 0, NULL);
 
 	std::string line;
@@ -262,6 +195,5 @@
 		JS_SetElement(cx, line_array, cur_line++, &val);
 	}
 
-	JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL( line_array ));
-	return JS_TRUE ;
+	return OBJECT_TO_JSVAL( line_array );
 }
Index: source/ps/scripting/JSInterface_ConfigDB.h
===================================================================
--- source/ps/scripting/JSInterface_ConfigDB.h	(Revision 14461)
+++ source/ps/scripting/JSInterface_ConfigDB.h	(Arbeitskopie)
@@ -18,18 +18,17 @@
 #ifndef INCLUDED_JSI_CONFIGDB
 #define INCLUDED_JSI_CONFIGDB
 
+#include "scriptinterface/ScriptInterface.h"
 #include "ps/ConfigDB.h"
 
-class ScriptInterface;
-
 namespace JSI_ConfigDB
 {
 	bool GetConfigNamespace(std::wstring cfgNsString, EConfigNamespace& cfgNs);
-	std::string GetValue(void* cbdata, std::wstring cfgNsString, std::string name);
-	bool CreateValue(void* cbdata, std::wstring cfgNsString, std::string name, std::string value);
-	bool WriteFile(void* cbdata, std::wstring cfgNsString, Path path);
-	bool Reload(void* cbdata, std::wstring cfgNsString);
-	bool SetFile(void* cbdata, std::wstring cfgNsString, Path path);
+	std::string GetValue(ScriptInterface::CxPrivate* pCxPrivate, std::wstring cfgNsString, std::string name);
+	bool CreateValue(ScriptInterface::CxPrivate* pCxPrivate, std::wstring cfgNsString, std::string name, std::string value);
+	bool WriteFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring cfgNsString, Path path);
+	bool Reload(ScriptInterface::CxPrivate* pCxPrivate, std::wstring cfgNsString);
+	bool SetFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring cfgNsString, Path path);
 	void RegisterScriptFunctions(ScriptInterface& scriptInterface);
 }
 
Index: source/ps/scripting/JSInterface_Console.cpp
===================================================================
--- source/ps/scripting/JSInterface_Console.cpp	(Revision 14461)
+++ source/ps/scripting/JSInterface_Console.cpp	(Arbeitskopie)
@@ -32,21 +32,21 @@
 	return true;
 }
 
-bool JSI_Console::GetVisibleEnabled(void* UNUSED(cbdata))
+bool JSI_Console::GetVisibleEnabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
 {
 	if (!CheckGlobalInitialized())
 		return false;
 	return g_Console->IsActive();
 }
 
-void JSI_Console::SetVisibleEnabled(void* UNUSED(cbdata), bool Enabled)
+void JSI_Console::SetVisibleEnabled(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool Enabled)
 {
 	if (!CheckGlobalInitialized())
 		return;
 	g_Console->SetVisible(Enabled);
 }
 
-void JSI_Console::Write(void* UNUSED(cbdata), std::wstring output)
+void JSI_Console::Write(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring output)
 {
 	if (!CheckGlobalInitialized())
 		return;
Index: source/ps/scripting/JSInterface_VFS.h
===================================================================
--- source/ps/scripting/JSInterface_VFS.h	(Revision 14461)
+++ source/ps/scripting/JSInterface_VFS.h	(Arbeitskopie)
@@ -22,9 +22,9 @@
 #ifndef INCLUDED_JSI_VFS
 #define INCLUDED_JSI_VFS
 
-#include "scripting/ScriptingHost.h"
+#include "scriptinterface/ScriptInterface.h"
 
-// these are registered in ScriptGlue.cpp, hence the need for a header.
+// these are registered in ScriptFunctions.cpp, hence the need for a header.
 
 namespace JSI_VFS
 {
@@ -38,37 +38,37 @@
 	//
 	// note: full pathnames of each file/subdirectory are returned,
 	// ready for use as a "filename" for the other functions.
-	JSBool BuildDirEntList(JSContext* cx, uintN argc, jsval* vp);
+	CScriptVal BuildDirEntList(ScriptInterface::CxPrivate* pCxPrivate, std::wstring path, std::wstring filterStr, bool recurse);
 
 	// Return true iff the file exists
 	//
 	// if (fileExists(filename) { ... }
 	//   filename: VFS filename (may include path)
-	JSBool FileExists(JSContext* cx, uintN argc, jsval* vp);
+	bool FileExists(ScriptInterface::CxPrivate* pCxPrivate, CStrW filename);
 
 	// Return time [seconds since 1970] of the last modification to the specified file.
 	//
 	// mtime = getFileMTime(filename);
 	//   filename: VFS filename (may include path)
-	JSBool GetFileMTime(JSContext* cx, uintN argc, jsval* vp);
+	double GetFileMTime(ScriptInterface::CxPrivate* pCxPrivate, std::wstring filename);
 
 	// Return current size of file.
 	//
 	// size = getFileSize(filename);
 	//   filename: VFS filename (may include path)
-	JSBool GetFileSize(JSContext* cx, uintN argc, jsval* vp);
+	unsigned int GetFileSize(ScriptInterface::CxPrivate* pCxPrivate, std::wstring filename);
 
 	// Return file contents in a string.
 	//
 	// contents = readFile(filename);
 	//   filename: VFS filename (may include path)
-	JSBool ReadFile(JSContext* cx, uintN argc, jsval* vp);
+	CScriptVal ReadFile(ScriptInterface::CxPrivate* pCxPrivate, std::wstring filename);
 
 	// Return file contents as an array of lines.
 	//
 	// lines = readFileLines(filename);
 	//   filename: VFS filename (may include path)
-	JSBool ReadFileLines(JSContext* cx, uintN argc, jsval* vp);
+	CScriptVal ReadFileLines(ScriptInterface::CxPrivate* pCxPrivate, std::wstring filename);
 }
 
 #endif
Index: source/ps/scripting/JSInterface_Console.h
===================================================================
--- source/ps/scripting/JSInterface_Console.h	(Revision 14461)
+++ source/ps/scripting/JSInterface_Console.h	(Arbeitskopie)
@@ -23,9 +23,9 @@
 namespace JSI_Console
 {
 	bool CheckGlobalInitialized();
-	bool GetVisibleEnabled(void* cbdata);
-	void SetVisibleEnabled(void* cbdata, bool Enabled);
-	void Write(void* cbdata, std::wstring output);
+	bool GetVisibleEnabled(ScriptInterface::CxPrivate* pCxPrivate);
+	void SetVisibleEnabled(ScriptInterface::CxPrivate* pCxPrivate, bool Enabled);
+	void Write(ScriptInterface::CxPrivate* pCxPrivate, std::wstring output);
 	
 	void RegisterScriptFunctions(ScriptInterface& scriptInterface);
 }
Index: source/ps/scripting/JSInterface_ConfigDB.cpp
===================================================================
--- source/ps/scripting/JSInterface_ConfigDB.cpp	(Revision 14461)
+++ source/ps/scripting/JSInterface_ConfigDB.cpp	(Arbeitskopie)
@@ -42,7 +42,7 @@
 	return true;
 }
 
-std::string JSI_ConfigDB::GetValue(void* UNUSED(cbdata), std::wstring cfgNsString, std::string name)
+std::string JSI_ConfigDB::GetValue(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring cfgNsString, std::string name)
 {
 	EConfigNamespace cfgNs;
 	if (!GetConfigNamespace(cfgNsString, cfgNs))
@@ -53,7 +53,7 @@
 	return value;
 }
 
-bool JSI_ConfigDB::CreateValue(void* UNUSED(cbdata), std::wstring cfgNsString, std::string name, std::string value)
+bool JSI_ConfigDB::CreateValue(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring cfgNsString, std::string name, std::string value)
 {
 	EConfigNamespace cfgNs;
 	if (!GetConfigNamespace(cfgNsString, cfgNs))
@@ -63,7 +63,7 @@
 	return true;
 }
 
-bool JSI_ConfigDB::WriteFile(void* UNUSED(cbdata), std::wstring cfgNsString, Path path)
+bool JSI_ConfigDB::WriteFile(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring cfgNsString, Path path)
 {
 	EConfigNamespace cfgNs;
 	if (!GetConfigNamespace(cfgNsString, cfgNs))
@@ -73,7 +73,7 @@
 	return ret;
 }
 
-bool JSI_ConfigDB::Reload(void* UNUSED(cbdata), std::wstring cfgNsString)
+bool JSI_ConfigDB::Reload(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring cfgNsString)
 {
 	EConfigNamespace cfgNs;
 	if (!GetConfigNamespace(cfgNsString, cfgNs))
@@ -83,7 +83,7 @@
 	return ret;
 }
 
-bool JSI_ConfigDB::SetFile(void* UNUSED(cbdata), std::wstring cfgNsString, Path path)
+bool JSI_ConfigDB::SetFile(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring cfgNsString, Path path)
 {
 	EConfigNamespace cfgNs;
 	if (!GetConfigNamespace(cfgNsString, cfgNs))
Index: source/ps/CConsole.cpp
===================================================================
--- source/ps/CConsole.cpp	(Revision 14461)
+++ source/ps/CConsole.cpp	(Arbeitskopie)
@@ -28,6 +28,7 @@
 #include "graphics/ShaderManager.h"
 #include "graphics/TextRenderer.h"
 #include "gui/GUIutil.h"
+#include "gui/GUIManager.h"
 #include "lib/ogl.h"
 #include "lib/sysdep/clipboard.h"
 #include "lib/timer.h"
@@ -40,7 +41,6 @@
 #include "ps/Hotkey.h"
 #include "ps/Pyrogenesis.h"
 #include "renderer/Renderer.h"
-#include "scripting/ScriptingHost.h"
 #include "scriptinterface/ScriptInterface.h"
 
 CConsole* g_Console = 0;
@@ -603,10 +603,11 @@
 	               // a crash it's a useful record.
 
 	// Process it as JavaScript
-
-	jsval rval = g_ScriptingHost.ExecuteScript(szLine, L"Console");
-	if (!JSVAL_IS_VOID(rval))
-		InsertMessage(L"%ls", g_ScriptingHost.GetScriptInterface().ToString(rval).c_str());
+	
+	CScriptVal rval;
+	g_GUI->GetActiveGUI()->GetScriptInterface()->Eval(szLine, rval);
+	if (!rval.undefined())
+		InsertMessage(L"%ls", g_GUI->GetActiveGUI()->GetScriptInterface()->ToString(rval.get()).c_str());
 }
 
 void CConsole::LoadHistory()
Index: source/ps/Replay.cpp
===================================================================
--- source/ps/Replay.cpp	(Revision 14461)
+++ source/ps/Replay.cpp	(Arbeitskopie)
@@ -127,6 +127,7 @@
 	new CProfileManager;
 	g_ScriptStatsTable = new CScriptStatsTable;
 	g_ProfileViewer.AddRootTable(g_ScriptStatsTable);
+	g_ScriptRuntime = ScriptInterface::CreateRuntime(128 * 1024 * 1024);
 
 	CGame game(true);
 	g_Game = &game;
Index: source/soundmanager/SoundManager.h
===================================================================
--- source/soundmanager/SoundManager.h	(Revision 14461)
+++ source/soundmanager/SoundManager.h	(Arbeitskopie)
@@ -108,7 +108,6 @@
 	void StartPlayList( bool doLoop );
 	void AddPlayListItem(const VfsPath& itemPath);
 
-	static void ScriptingInit();
 	static void CreateSoundManager();
 	static void SetEnabled(bool doEnable);
 	static Status ReloadChangedFileCB(void* param, const VfsPath& path);
Index: source/soundmanager/scripting/JSInterface_Sound.cpp
===================================================================
--- source/soundmanager/scripting/JSInterface_Sound.cpp	(Revision 14461)
+++ source/soundmanager/scripting/JSInterface_Sound.cpp	(Arbeitskopie)
@@ -31,55 +31,55 @@
 {
   #if CONFIG2_AUDIO
 
-  void StartMusic(void* UNUSED(cbdata))
+  void StartMusic(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
   {
     if ( CSoundManager* sndManager = (CSoundManager*)g_SoundManager )
       sndManager->SetMusicEnabled(true);
   }
 
-  void StopMusic(void* UNUSED(cbdata))
+  void StopMusic(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
   {
     if ( CSoundManager* sndManager = (CSoundManager*)g_SoundManager )
       sndManager->SetMusicEnabled(false);
   }
 
-  void ClearPlaylist(void* UNUSED(cbdata))
+  void ClearPlaylist(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
   {
     if ( CSoundManager* sndManager = (CSoundManager*)g_SoundManager )
       sndManager->ClearPlayListItems();
   }
 
-  void AddPlaylistItem(void* UNUSED(cbdata), std::wstring filename)
+  void AddPlaylistItem(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring filename)
   {  
     if ( CSoundManager* sndManager = (CSoundManager*)g_SoundManager )
       sndManager->AddPlayListItem(VfsPath(filename));
   }
 
-  void StartPlaylist(void* UNUSED(cbdata), bool looping)
+  void StartPlaylist(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool looping)
   {
     if ( CSoundManager* sndManager = (CSoundManager*)g_SoundManager )
       sndManager->StartPlayList( looping );
   }
 
-  void PlayMusic(void* UNUSED(cbdata), std::wstring filename, bool looping)
+  void PlayMusic(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring filename, bool looping)
   {
     if ( CSoundManager* sndManager = (CSoundManager*)g_SoundManager )
       sndManager->PlayAsMusic( filename, looping);
   }
 
-  void PlayUISound(void* UNUSED(cbdata), std::wstring filename, bool looping)
+  void PlayUISound(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring filename, bool looping)
   {
     if ( CSoundManager* sndManager = (CSoundManager*)g_SoundManager )
       sndManager->PlayAsUI( filename, looping);
   }
 
-  void PlayAmbientSound(void* UNUSED(cbdata), std::wstring filename, bool looping)
+  void PlayAmbientSound(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring filename, bool looping)
   {
     if ( CSoundManager* sndManager = (CSoundManager*)g_SoundManager )
       sndManager->PlayAsAmbient( filename, looping);
   }
 
-  bool MusicPlaying(void* UNUSED(cbdata))
+  bool MusicPlaying(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
   {
     return true;
   }
@@ -87,15 +87,15 @@
 
 
   #else
-    bool MusicPlaying(void* UNUSED(cbdata) ){ return false; }
-    void PlayAmbientSound(void* UNUSED(cbdata), std::wstring UNUSED(filename), bool UNUSED(looping) ){}
-    void PlayUISound(void* UNUSED(cbdata), std::wstring UNUSED(filename), bool UNUSED(looping) ) {}
-    void PlayMusic(void* UNUSED(cbdata), std::wstring UNUSED(filename), bool UNUSED(looping) ) {}
-    void StartPlaylist(void* UNUSED(cbdata), bool UNUSED(looping) ){}
-    void AddPlaylistItem(void* UNUSED(cbdata), std::wstring UNUSED(filename) ){}
-    void ClearPlaylist(void* UNUSED(cbdata) ){}
-    void StopMusic(void* UNUSED(cbdata) ){}
-    void StartMusic(void* UNUSED(cbdata) ){}
+	bool MusicPlaying(ScriptInterface::CxPrivate* UNUSED(pCxPrivate) ){ return false; }
+	void PlayAmbientSound(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring UNUSED(filename), bool UNUSED(looping) ){}
+	void PlayUISound(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring UNUSED(filename), bool UNUSED(looping) ) {}
+	void PlayMusic(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring UNUSED(filename), bool UNUSED(looping) ) {}
+	void StartPlaylist(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), bool UNUSED(looping) ){}
+	void AddPlaylistItem(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), std::wstring UNUSED(filename) ){}
+	void ClearPlaylist(ScriptInterface::CxPrivate* UNUSED(pCxPrivate) ){}
+	void StopMusic(ScriptInterface::CxPrivate* UNUSED(pCxPrivate) ){}
+	void StartMusic(ScriptInterface::CxPrivate* UNUSED(pCxPrivate) ){}
 
   #endif
 
Index: source/scriptinterface/ThreadDebugger.cpp
===================================================================
--- source/scriptinterface/ThreadDebugger.cpp	(Revision 14461)
+++ source/scriptinterface/ThreadDebugger.cpp	(Arbeitskopie)
@@ -289,10 +289,10 @@
 	ReturnActiveBreakPoints(NULL);
 
 	// Remove all the hooks because they store a pointer to this object
-	JS_SetExecuteHook(m->m_pScriptInterface->GetRuntime(), NULL, NULL);
-	JS_SetCallHook(m->m_pScriptInterface->GetRuntime(), NULL, NULL);
-	JS_SetNewScriptHook(m->m_pScriptInterface->GetRuntime(), NULL, NULL);
-	JS_SetDestroyScriptHook(m->m_pScriptInterface->GetRuntime(), NULL, NULL);
+	JS_SetExecuteHook(m->m_pScriptInterface->GetJSRuntime(), NULL, NULL);
+	JS_SetCallHook(m->m_pScriptInterface->GetJSRuntime(), NULL, NULL);
+	JS_SetNewScriptHook(m->m_pScriptInterface->GetJSRuntime(), NULL, NULL);
+	JS_SetDestroyScriptHook(m->m_pScriptInterface->GetJSRuntime(), NULL, NULL);
 }
 
 void CThreadDebugger::ReturnActiveBreakPoints(jsbytecode* pBytecode)
@@ -329,16 +329,16 @@
 	m->m_Name = name;
 	m->m_pScriptInterface = pScriptInterface;
 	m->m_pDebuggingServer = pDebuggingServer;
-	JS_SetExecuteHook(m->m_pScriptInterface->GetRuntime(), CallHook_, (void*)this);
-	JS_SetCallHook(m->m_pScriptInterface->GetRuntime(), CallHook_, (void*)this);
-	JS_SetNewScriptHook(m->m_pScriptInterface->GetRuntime(), NewScriptHook_, (void*)this);
-	JS_SetDestroyScriptHook(m->m_pScriptInterface->GetRuntime(), DestroyScriptHook_, (void*)this);
-	JS_SetThrowHook(m->m_pScriptInterface->GetRuntime(), ThrowHandler_, (void*)this);
+	JS_SetExecuteHook(m->m_pScriptInterface->GetJSRuntime(), CallHook_, (void*)this);
+	JS_SetCallHook(m->m_pScriptInterface->GetJSRuntime(), CallHook_, (void*)this);
+	JS_SetNewScriptHook(m->m_pScriptInterface->GetJSRuntime(), NewScriptHook_, (void*)this);
+	JS_SetDestroyScriptHook(m->m_pScriptInterface->GetJSRuntime(), DestroyScriptHook_, (void*)this);
+	JS_SetThrowHook(m->m_pScriptInterface->GetJSRuntime(), ThrowHandler_, (void*)this);
 	
 	if (m->m_pDebuggingServer->GetSettingSimultaneousThreadBreak())
 	{
 		// Setup a handler to check for break-requests from the DebuggingServer regularly
-		JS_SetInterrupt(m->m_pScriptInterface->GetRuntime(), CheckForBreakRequestHandler_, (void*)this);
+		JS_SetInterrupt(m->m_pScriptInterface->GetJSRuntime(), CheckForBreakRequestHandler_, (void*)this);
 	}
 }
 
@@ -456,7 +456,7 @@
 	
 	if (breakSrc == BREAK_SRC_INTERRUP)
 	{
-		JS_ClearInterrupt(m->m_pScriptInterface->GetRuntime(), NULL, NULL);
+		JS_ClearInterrupt(m->m_pScriptInterface->GetJSRuntime(), NULL, NULL);
 		JS_SetSingleStepMode(cx, script, false);
 	}
 	
@@ -496,17 +496,17 @@
 			{
 				if (nextDbgCmd == DBG_CMD_SINGLESTEP)
 				{
-					JS_SetInterrupt(m->m_pScriptInterface->GetRuntime(), StepHandler_, this);
+					JS_SetInterrupt(m->m_pScriptInterface->GetJSRuntime(), StepHandler_, this);
 					break;
 				}
 				else if (nextDbgCmd == DBG_CMD_STEPINTO)
 				{
-					JS_SetInterrupt(m->m_pScriptInterface->GetRuntime(), StepIntoHandler_, this);
+					JS_SetInterrupt(m->m_pScriptInterface->GetJSRuntime(), StepIntoHandler_, this);
 					break;
 				}
 				else if (nextDbgCmd == DBG_CMD_STEPOUT)
 				{
-					JS_SetInterrupt(m->m_pScriptInterface->GetRuntime(), StepOutHandler_, this);
+					JS_SetInterrupt(m->m_pScriptInterface->GetJSRuntime(), StepOutHandler_, this);
 					break;
 				}
 			}
@@ -518,7 +518,7 @@
 			else
 			{
 				// Setup a handler to check for break-requests from the DebuggingServer regularly
-				JS_SetInterrupt(m->m_pScriptInterface->GetRuntime(), CheckForBreakRequestHandler_, this);
+				JS_SetInterrupt(m->m_pScriptInterface->GetJSRuntime(), CheckForBreakRequestHandler_, this);
 			}
 			break;
 		}
Index: source/scriptinterface/ScriptInterface.h
===================================================================
--- source/scriptinterface/ScriptInterface.h	(Revision 14461)
+++ source/scriptinterface/ScriptInterface.h	(Arbeitskopie)
@@ -27,6 +27,25 @@
 
 #include "js/jsapi.h"
 
+#include "ps/Errors.h"
+ERROR_GROUP(Scripting);
+ERROR_TYPE(Scripting, SetupFailed);
+
+ERROR_SUBGROUP(Scripting, LoadFile);
+ERROR_TYPE(Scripting_LoadFile, OpenFailed);
+ERROR_TYPE(Scripting_LoadFile, EvalErrors);
+
+ERROR_TYPE(Scripting, ConversionFailed);
+ERROR_TYPE(Scripting, CallFunctionFailed);
+ERROR_TYPE(Scripting, RegisterFunctionFailed);
+ERROR_TYPE(Scripting, DefineConstantFailed);
+ERROR_TYPE(Scripting, CreateObjectFailed);
+ERROR_TYPE(Scripting, TypeDoesNotExist);
+
+ERROR_SUBGROUP(Scripting, DefineType);
+ERROR_TYPE(Scripting_DefineType, AlreadyExists);
+ERROR_TYPE(Scripting_DefineType, CreationFailed);
+
 #include "lib/file/vfs/vfs_path.h"
 #include "ps/Profile.h"
 #include "ps/utf16string.h"
@@ -47,6 +66,8 @@
 
 class ScriptRuntime;
 
+extern shared_ptr<ScriptRuntime> g_ScriptRuntime;
+
 class CDebuggingServer;
 
 /**
@@ -87,11 +108,18 @@
 	 */
 	static void ShutDown();
 
-	void SetCallbackData(void* cbdata);
-	static void* GetCallbackData(JSContext* cx);
+	struct CxPrivate
+	{
+		ScriptInterface* pScriptInterface; // the ScriptInterface object the current context belongs to
+		void* pCBData; // meant to be used as the "this" object for callback functions
+	} m_CxPrivate;
 
+	void SetCallbackData(void* pCBData);
+	static CxPrivate* GetScriptInterfaceAndCBData(JSContext* cx);
+
 	JSContext* GetContext() const;
-	JSRuntime* GetRuntime() const;
+	JSRuntime* GetJSRuntime() const;
+	shared_ptr<ScriptRuntime> GetRuntime() const;
 
 	/**
 	 * Load global scripts that most script contexts need,
@@ -170,6 +198,9 @@
 	template<typename T0, typename T1, typename T2, typename T3, typename R>
 	bool CallFunction(jsval val, const char* name, const T0& a0, const T1& a1, const T2& a2, const T3& a3, R& ret);
 
+	JSObject* CreateCustomObject(const std::string & typeName);
+	void DefineCustomObjectType(JSClass *clasp, JSNative constructor, uint minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
+
 	jsval GetGlobalObject();
 
 	JSClass* GetGlobalClass();
@@ -268,7 +299,7 @@
 	 * @param code JS code to execute
 	 * @return true on successful compilation and execution; false otherwise
 	 */
-	bool LoadGlobalScript(const VfsPath& filename, const std::string& code);
+	bool LoadGlobalScript(const VfsPath& filename, const std::wstring& code);
 
 	/**
 	 * Load and execute the given script in the global scope.
@@ -342,8 +373,17 @@
 	static JSClass* GetClass(JSContext* cx, JSObject* obj);
 	static void* GetPrivate(JSContext* cx, JSObject* obj);
 
+	class CustomType
+	{
+	public:
+		JSObject *	m_Object;
+		JSClass *	m_Class;
+		JSNative 	m_Constructor;
+	};
 	void Register(const char* name, JSNative fptr, size_t nargs);
 	std::auto_ptr<ScriptInterface_impl> m;
+	
+	std::map<std::string, CustomType> m_CustomObjectTypes;
 
 // The nasty macro/template bits are split into a separate file so you don't have to look at them
 public:
Index: source/scriptinterface/NativeWrapperDecls.h
===================================================================
--- source/scriptinterface/NativeWrapperDecls.h	(Revision 14461)
+++ source/scriptinterface/NativeWrapperDecls.h	(Arbeitskopie)
@@ -40,7 +40,7 @@
 
 // Define RegisterFunction<TR, T0..., f>
 #define OVERLOADS(z, i, data) \
-	template <typename R, TYPENAME_T0_HEAD(z,i)  R (*fptr) ( void* T0_TAIL(z,i) )> \
+	template <typename R, TYPENAME_T0_HEAD(z,i)  R (*fptr) ( ScriptInterface::CxPrivate* T0_TAIL(z,i) )> \
 	void RegisterFunction(const char* name) { \
 		Register(name, call<R, T0_HEAD(z,i)  fptr>, nargs<0 T0_TAIL(z,i)>()); \
 	}
@@ -50,7 +50,7 @@
 // JSFastNative-compatible function that wraps the function identified in the template argument list
 // (Definition comes later, since it depends on some things we haven't defined yet)
 #define OVERLOADS(z, i, data) \
-	template <typename R, TYPENAME_T0_HEAD(z,i)  R (*fptr) ( void* T0_TAIL(z,i) )> \
+	template <typename R, TYPENAME_T0_HEAD(z,i)  R (*fptr) ( ScriptInterface::CxPrivate* T0_TAIL(z,i) )> \
 	static JSBool call(JSContext* cx, uintN argc, jsval* vp);
 BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
 #undef OVERLOADS
Index: source/scriptinterface/NativeWrapperDefns.h
===================================================================
--- source/scriptinterface/NativeWrapperDefns.h	(Revision 14461)
+++ source/scriptinterface/NativeWrapperDefns.h	(Arbeitskopie)
@@ -27,7 +27,7 @@
 	#define OVERLOADS(z, i, data) \
 		template<TYPENAME_T0_HEAD(z,i)  typename F> \
 		static void call(JSContext* cx, jsval& rval, F fptr  T0_A0(z,i)) { \
-			rval = ScriptInterface::ToJSVal<R>(cx, fptr(ScriptInterface::GetCallbackData(cx)  A0_TAIL(z,i))); \
+			rval = ScriptInterface::ToJSVal<R>(cx, fptr(ScriptInterface::GetScriptInterfaceAndCBData(cx) A0_TAIL(z,i))); \
 		}
 
 	BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
@@ -40,7 +40,7 @@
 	#define OVERLOADS(z, i, data) \
 		template<TYPENAME_T0_HEAD(z,i)  typename F> \
 		static void call(JSContext* cx, jsval& /*rval*/, F fptr  T0_A0(z,i)) { \
-			fptr(ScriptInterface::GetCallbackData(cx)  A0_TAIL(z,i)); \
+			fptr(ScriptInterface::GetScriptInterfaceAndCBData(cx) A0_TAIL(z,i)); \
 		}
 	BOOST_PP_REPEAT(SCRIPT_INTERFACE_MAX_ARGS, OVERLOADS, ~)
 	#undef OVERLOADS
@@ -90,7 +90,7 @@
 
 // JSFastNative-compatible function that wraps the function identified in the template argument list
 #define OVERLOADS(z, i, data) \
-	template <typename R, TYPENAME_T0_HEAD(z,i)  R (*fptr) ( void* T0_TAIL(z,i) )> \
+	template <typename R, TYPENAME_T0_HEAD(z,i)  R (*fptr) ( ScriptInterface::CxPrivate* T0_TAIL(z,i) )> \
 	JSBool ScriptInterface::call(JSContext* cx, uintN argc, jsval* vp) { \
 		UNUSED2(argc); \
 		SCRIPT_PROFILE \
Index: source/scriptinterface/ScriptStats.cpp
===================================================================
--- source/scriptinterface/ScriptStats.cpp	(Revision 14461)
+++ source/scriptinterface/ScriptStats.cpp	(Arbeitskopie)
@@ -86,28 +86,28 @@
 	{
 		if (col == 0)
 			return "max nominal heap bytes";
-		uint32_t n = JS_GetGCParameter(m_ScriptInterfaces.at(col-1).first->GetRuntime(), JSGC_MAX_BYTES);
+		uint32_t n = JS_GetGCParameter(m_ScriptInterfaces.at(col-1).first->GetJSRuntime(), JSGC_MAX_BYTES);
 		return CStr::FromUInt(n);
 	}
 	case Row_MaxMallocBytes:
 	{
 		if (col == 0)
 			return "max JS_malloc bytes";
-		uint32_t n = JS_GetGCParameter(m_ScriptInterfaces.at(col-1).first->GetRuntime(), JSGC_MAX_MALLOC_BYTES);
+		uint32_t n = JS_GetGCParameter(m_ScriptInterfaces.at(col-1).first->GetJSRuntime(), JSGC_MAX_MALLOC_BYTES);
 		return CStr::FromUInt(n);
 	}
 	case Row_Bytes:
 	{
 		if (col == 0)
 			return "allocated bytes";
-		uint32_t n = JS_GetGCParameter(m_ScriptInterfaces.at(col-1).first->GetRuntime(), JSGC_BYTES);
+		uint32_t n = JS_GetGCParameter(m_ScriptInterfaces.at(col-1).first->GetJSRuntime(), JSGC_BYTES);
 		return CStr::FromUInt(n);
 	}
 	case Row_NumberGC:
 	{
 		if (col == 0)
 			return "number of GCs";
-		uint32_t n = JS_GetGCParameter(m_ScriptInterfaces.at(col-1).first->GetRuntime(), JSGC_NUMBER);
+		uint32_t n = JS_GetGCParameter(m_ScriptInterfaces.at(col-1).first->GetJSRuntime(), JSGC_NUMBER);
 		return CStr::FromUInt(n);
 	}
 	default:
Index: source/scriptinterface/ScriptInterface.cpp
===================================================================
--- source/scriptinterface/ScriptInterface.cpp	(Revision 14461)
+++ source/scriptinterface/ScriptInterface.cpp	(Arbeitskopie)
@@ -69,7 +69,7 @@
 {
 public:
 	ScriptRuntime(int runtimeSize) :
-		m_rooter(NULL), m_compartmentGlobal(NULL)
+		m_rooter(NULL)
 	{
 		m_rt = JS_NewRuntime(runtimeSize);
 		ENSURE(m_rt); // TODO: error handling
@@ -98,8 +98,6 @@
 	JSRuntime* m_rt;
 	AutoGCRooter* m_rooter;
 
-	JSObject* m_compartmentGlobal;
-
 private:
 
 
@@ -241,7 +239,6 @@
 	JSContext* m_cx;
 	JSObject* m_glob; // global scope object
 	JSObject* m_nativeScope; // native function scope object
-	JSCrossCompartmentCall* m_call;
 };
 
 namespace
@@ -507,25 +504,10 @@
 	}
 
 	JS_SetOptions(m_cx, options);
-
 	JS_SetVersion(m_cx, JSVERSION_LATEST);
 
-	// Threadsafe SpiderMonkey requires that we have a request before doing anything much
-	JS_BeginRequest(m_cx);
+	m_glob = JS_NewCompartmentAndGlobalObject(m_cx, &global_class, NULL);
 
-	// We only want a single compartment per runtime
-	if (m_runtime->m_compartmentGlobal)
-	{
-		m_call = JS_EnterCrossCompartmentCall(m_cx, m_runtime->m_compartmentGlobal);
-		m_glob = JS_NewGlobalObject(m_cx, &global_class);
-	}
-	else
-	{
-		m_call = NULL;
-		m_glob = JS_NewCompartmentAndGlobalObject(m_cx, &global_class, NULL);
-		m_runtime->m_compartmentGlobal = m_glob;
-	}
-
 	ok = JS_InitStandardClasses(m_cx, m_glob);
 	ENSURE(ok);
 
@@ -547,9 +529,6 @@
 
 ScriptInterface_impl::~ScriptInterface_impl()
 {
-	if (m_call)
-		JS_LeaveCrossCompartmentCall(m_call);
-	JS_EndRequest(m_cx);
 	JS_DestroyContext(m_cx);
 }
 
@@ -594,6 +573,9 @@
 		else
 			g_DebuggingServer->RegisterScriptinterface(debugName, this);
 	}
+
+	m_CxPrivate.pScriptInterface = this;
+	JS_SetContextPrivate(m->m_cx, (void*)&m_CxPrivate);
 }
 
 ScriptInterface::~ScriptInterface()
@@ -614,14 +596,15 @@
 	JS_ShutDown();
 }
 
-void ScriptInterface::SetCallbackData(void* cbdata)
+void ScriptInterface::SetCallbackData(void* pCBData)
 {
-	JS_SetContextPrivate(m->m_cx, cbdata);
+	m_CxPrivate.pCBData = pCBData;
 }
 
-void* ScriptInterface::GetCallbackData(JSContext* cx)
+ScriptInterface::CxPrivate* ScriptInterface::GetScriptInterfaceAndCBData(JSContext* cx)
 {
-	return JS_GetContextPrivate(cx);
+	CxPrivate* pCxPrivate = (CxPrivate*)JS_GetContextPrivate(cx);
+	return pCxPrivate;
 }
 
 bool ScriptInterface::LoadGlobalScripts()
@@ -674,11 +657,16 @@
 	return m->m_cx;
 }
 
-JSRuntime* ScriptInterface::GetRuntime() const
+JSRuntime* ScriptInterface::GetJSRuntime() const
 {
 	return m->m_runtime->m_rt;
 }
 
+shared_ptr<ScriptRuntime> ScriptInterface::GetRuntime() const
+{
+	return m->m_runtime;
+}
+
 AutoGCRooter* ScriptInterface::ReplaceAutoGCRooter(AutoGCRooter* rooter)
 {
 	AutoGCRooter* ret = m->m_runtime->m_rooter;
@@ -734,6 +722,47 @@
 	return OBJECT_TO_JSVAL(obj);
 }
 
+void ScriptInterface::DefineCustomObjectType(JSClass *clasp, JSNative constructor, uint minArgs, JSPropertySpec *ps, JSFunctionSpec *fs, JSPropertySpec *static_ps, JSFunctionSpec *static_fs)
+{
+	std::string typeName = clasp->name;
+
+	if (m_CustomObjectTypes.find(typeName) != m_CustomObjectTypes.end())
+	{
+		// This type already exists
+		throw PSERROR_Scripting_DefineType_AlreadyExists();
+	}
+
+	JSObject * obj = JS_InitClass(	m->m_cx, JSVAL_TO_OBJECT(GetGlobalObject()), 0,
+									clasp,
+									constructor, minArgs,				// Constructor, min args
+									ps, fs,								// Properties, methods
+									static_ps, static_fs);				// Constructor properties, methods
+
+	if (obj == NULL)
+		throw PSERROR_Scripting_DefineType_CreationFailed();
+
+	CustomType type;
+
+	type.m_Object = obj;
+	type.m_Class = clasp;
+	type.m_Constructor = constructor;
+
+	m_CustomObjectTypes[typeName] = type;
+}
+
+JSObject* ScriptInterface::CreateCustomObject(const std::string & typeName)
+{
+	std::map < std::string, CustomType > ::iterator it = m_CustomObjectTypes.find(typeName);
+
+	if (it == m_CustomObjectTypes.end())
+		throw PSERROR_Scripting_TypeDoesNotExist();
+
+	JSFunction* ctor = JS_NewFunction(m->m_cx, (*it).second.m_Constructor, 0, 0,
+               NULL, "ctor_fun");
+	return JS_New(m->m_cx, JS_GetFunctionObject(ctor), 0, NULL);
+}
+
+
 bool ScriptInterface::CallFunctionVoid(jsval val, const char* name)
 {
 	jsval jsRet;
@@ -951,11 +980,11 @@
 	return ok ? true : false;
 }
 
-bool ScriptInterface::LoadGlobalScript(const VfsPath& filename, const std::string& code)
+bool ScriptInterface::LoadGlobalScript(const VfsPath& filename, const std::wstring& code)
 {
 	// Compile the code in strict mode, to encourage better coding practices and
 	// to possibly help SpiderMonkey with optimisations
-	std::wstring codeStrict = L"\"use strict\";\n" + wstring_from_utf8(code);
+	std::wstring codeStrict = L"\"use strict\";\n" + code;
 	utf16string codeUtf16(codeStrict.begin(), codeStrict.end());
 	uintN lineNo = 0; // put the automatic 'use strict' on line 0, so the real code starts at line 1
 
@@ -1187,9 +1216,9 @@
 #if MOZJS_DEBUG_ABI
 	JS_DumpHeap(m->m_cx, stderr, NULL, 0, NULL, (size_t)-1, NULL);
 #endif
-	fprintf(stderr, "# Bytes allocated: %u\n", JS_GetGCParameter(GetRuntime(), JSGC_BYTES));
+	fprintf(stderr, "# Bytes allocated: %u\n", JS_GetGCParameter(GetJSRuntime(), JSGC_BYTES));
 	JS_GC(m->m_cx);
-	fprintf(stderr, "# Bytes allocated after GC: %u\n", JS_GetGCParameter(GetRuntime(), JSGC_BYTES));
+	fprintf(stderr, "# Bytes allocated after GC: %u\n", JS_GetGCParameter(GetJSRuntime(), JSGC_BYTES));
 }
 
 void ScriptInterface::MaybeGC()
@@ -1337,9 +1366,10 @@
 	uint64* data = NULL;
 	size_t nbytes = 0;
 	if (!JS_WriteStructuredClone(m->m_cx, v, &data, &nbytes, NULL, NULL))
+	{
+		debug_warn(L"Writing a structured clone with JS_WriteStructuredClone failed!");
 		return shared_ptr<StructuredClone>();
-	// TODO: should we have better error handling?
-	// Currently we'll probably continue and then crash in ReadStructuredClone
+	}
 
 	shared_ptr<StructuredClone> ret (new StructuredClone);
 	ret->m_Context = m->m_cx;
Index: source/network/NetTurnManager.cpp
===================================================================
--- source/network/NetTurnManager.cpp	(Revision 14461)
+++ source/network/NetTurnManager.cpp	(Arbeitskopie)
@@ -333,7 +333,7 @@
 
 	m_QuickSaveState = stream.str();
 	if (g_GUI)
-		m_QuickSaveMetadata = g_GUI->GetScriptInterface().StringifyJSON(g_GUI->GetSavedGameData().get(), false);
+		m_QuickSaveMetadata = g_GUI->GetSavedGameData();
 	else
 		m_QuickSaveMetadata = std::string();
 
@@ -360,8 +360,7 @@
 	}
 
 	if (g_GUI && !m_QuickSaveMetadata.empty())
-		g_GUI->GetScriptInterface().CallFunctionVoid(OBJECT_TO_JSVAL(g_GUI->GetScriptObject()),
-		"restoreSavedGameData", g_GUI->GetScriptInterface().ParseJSON(m_QuickSaveMetadata));
+		g_GUI->RestoreSavedGameData(m_QuickSaveMetadata);
 
 	LOGMESSAGERENDER(L"Quickloaded game");
 
