Index: binaries/data/config/default.cfg
===================================================================
--- binaries/data/config/default.cfg	(revision 17523)
+++ binaries/data/config/default.cfg	(working copy)
@@ -220,6 +220,10 @@
 ;9 =
 ;10 =
 
+[hotkey.loading]    ; > LOADING SCREEN TOOLTIP HOTKEYS
+previoustip = "LeftArrow"
+nexttip = "RightArrow"
+
 [hotkey.profile]
 toggle = "F11"               ; Enable/disable real-time profiler
 save = "Shift+F11"           ; Save current profiler data to logs/profile.txt
@@ -316,6 +320,9 @@
 cursorblinkrate = 0.5             ; Cursor blink rate in seconds (0.0 to disable blinking)
 scale = 1.0                       ; GUI scaling factor, for improved compatibility with 4K displays
 
+[gui.loadingtips]    ; > LOADING SCREEN TIP CONTROLS
+enabled = true
+
 [gui.menu]
 limitfps = true                   ; Limit FPS in the menus and loading screen
 
Index: binaries/data/mods/public/gui/loading/loading.js
===================================================================
--- binaries/data/mods/public/gui/loading/loading.js	(revision 17523)
+++ binaries/data/mods/public/gui/loading/loading.js	(working copy)
@@ -1,4 +1,6 @@
 let g_Data;
+let g_TipIndex;
+let g_Tips;
 const g_EndPieceWidth = 16;
 
 function init(data)
@@ -5,65 +7,59 @@
 {
 	g_Data = data;
 
-	// Set to "hourglass" cursor.
-	Engine.SetCursor("cursor-wait");
+	if (!g_Data)
+		return;
 
-	// Get tip image and corresponding tip text
-	let tipTextLoadingArray = Engine.BuildDirEntList("gui/text/tips/", "*.txt", false);
+	// Main loop now sets progress/description, but that won't
+	// happen until the first timeslice completes, so set initial values.
+	Engine.GetGUIObjectByName("loadingMapName").caption = sprintf(
+		data.attribs.mapType === "random" ? translate("Generating “%(map)s”") : translate("Loading “%(map)s”"),
+		{ "map": translate(data.attribs.settings.Name) });
 
-	if (tipTextLoadingArray.length > 0)
-	{
-		// Set tip text
-		let tipTextFilePath = tipTextLoadingArray[getRandom (0, tipTextLoadingArray.length-1)];
-		let tipText = Engine.TranslateLines(Engine.ReadFile(tipTextFilePath));
+	// Pick a random quote of the day (one quote per line).
+	let quoteArray = Engine.ReadFileLines("gui/text/quotes.txt");
+	Engine.GetGUIObjectByName("quoteText").caption = translate(quoteArray[getRandom(0, quoteArray.length-1)]);
 
-		if (tipText)
-		{
-			let index = tipText.indexOf("\n");
-			let tipTextTitle = tipText.substring(0, index);
-			let tipTextMessage = tipText.substring(index);
-			Engine.GetGUIObjectByName("tipTitle").caption = tipTextTitle? tipTextTitle : "";
-			Engine.GetGUIObjectByName("tipText").caption = tipTextMessage? tipTextMessage : "";
-		}
+	g_Tips = Engine.BuildDirEntList("gui/text/tips/", "*.txt", false);
+	let tipControlsEnabled = !data.isNetworked &&
+		Engine.ConfigDB_GetValue("user", "gui.loadingtips.enabled") === "true" && 
+		g_Tips && g_Tips.length > 0;
 
-		// Set tip image
-		let fileName = tipTextFilePath.substring(tipTextFilePath.lastIndexOf("/")+1).replace(".txt", ".png");
-		let tipImageFilePath = "loading/tips/" + fileName;
-		let sprite = "stretched:" + tipImageFilePath;
-		Engine.GetGUIObjectByName("tipImage").sprite = sprite? sprite : "";
-	}
-	else
-		error("Failed to find any matching tips for the loading screen.");
+	Engine.GetGUIObjectByName("prevTipButton").hidden = !tipControlsEnabled;
+	Engine.GetGUIObjectByName("nextTipButton").hidden = !tipControlsEnabled;
 
-	// janwas: main loop now sets progress / description, but that won't
-	// happen until the first timeslice completes, so set initial values.
-	let loadingMapName = Engine.GetGUIObjectByName("loadingMapName");
+	if (g_Tips && g_Tips.length > 0)
+		updateTip(getRandom(0, g_Tips.length - 1));
+}
 
-	if (data)
-	{
-		let mapName = translate(data.attribs.settings.Name);
-		switch (data.attribs.mapType)
-		{
-		case "skirmish":
-		case "scenario":
-			loadingMapName.caption = sprintf(translate("Loading “%(map)s”"), { "map": mapName });
-			break;
+function nextTip()
+{
+	updateTip((g_TipIndex + 1) % g_Tips.length);
+}
 
-		case "random":
-			loadingMapName.caption = sprintf(translate("Generating “%(map)s”"), { "map": mapName });
-			break;
+function prevTip()
+{
+	updateTip((g_Tips.length + g_TipIndex - 1) % g_Tips.length);
+}
 
-		default:
-			error("Unknown map type: " + data.attribs.mapType);
-		}
+function updateTip(nextTipIndex)
+{
+	// Set tip text
+	g_TipIndex = nextTipIndex;
+	let tipTextFilePath = g_Tips[g_TipIndex];
+	let tipText = Engine.TranslateLines(Engine.ReadFile(tipTextFilePath));
+	if (!tipText)
+	{
+		error("Failed to read tip text for the loading screen.");
+		return;
 	}
 
-	Engine.GetGUIObjectByName("progressText").caption = "";
-	Engine.GetGUIObjectByName("progressbar").caption = 0;
+	let index = tipText.indexOf("\n");
+	let fileName = tipTextFilePath.substring(tipTextFilePath.lastIndexOf("/")+1).replace(".txt", ".png");
 
-	// Pick a random quote of the day (each line is a separate tip).
-	let quoteArray = Engine.ReadFileLines("gui/text/quotes.txt");
-	Engine.GetGUIObjectByName("quoteText").caption = translate(quoteArray[getRandom(0, quoteArray.length-1)]);
+	Engine.GetGUIObjectByName("tipTitle").caption = tipText.substring(0, index);
+	Engine.GetGUIObjectByName("tipText").caption = tipText.substring(index);
+	Engine.GetGUIObjectByName("tipImage").sprite = "stretched:" + "loading/tips/" + fileName;
 }
 
 function displayProgress()
@@ -78,9 +74,6 @@
 	Engine.GetGUIObjectByName("progressbar").caption = progress; // display current progress
 	Engine.GetGUIObjectByName("progressText").caption = progress + "%";
 
-	// Displays detailed loading info rather than a percent
-	// 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
 	let middle = Engine.GetGUIObjectByName("progressbar");
 	let rightSide = Engine.GetGUIObjectByName("progressbar_right");
@@ -100,12 +93,29 @@
  */
 function reallyStartGame()
 {
-	// Switch GUI from loading screen to game session.
+	if (Engine.GetGUIObjectByName("prevTipButton").hidden && Engine.GetGUIObjectByName("nextTipButton"))
+	{
+		startGame();
+		return;
+	}
+
+	// Save the Camera Data
+	// TODO : Currently there is no function that returns the full camera position so if you zoom that will not be reset.
+	// We cannot prevent hotkeys from working because else the changing tooltip hotkeys wouldn't work.
+	g_Data.posZ = Engine.CameraGetZ();
+	g_Data.posX = Engine.CameraGetX();
+	// Pause the game so it doesn't run while we read tips
+	Engine.SetPaused(true);
+	Engine.GetGUIObjectByName("startGameButton").hidden = false;
+}
+
+function startGame()
+{
+	Engine.SetPaused(false);
+	Engine.CameraMoveTo(g_Data.posX,g_Data.posZ);
+	// Switch GUI from loading screen to game session
 	Engine.SwitchGuiPage("page_session.xml", g_Data);
 
-	// Restore default cursor.
-	Engine.SetCursor("arrow-default");
-
 	// Notify the other clients that we have finished the loading screen
 	if (g_Data.isNetworked && g_Data.isRejoining)
 		Engine.SendNetworkRejoined();
Index: binaries/data/mods/public/gui/loading/loading.xml
===================================================================
--- binaries/data/mods/public/gui/loading/loading.xml	(revision 17523)
+++ binaries/data/mods/public/gui/loading/loading.xml	(working copy)
@@ -40,6 +40,18 @@
 		<object size="50%+128 50%-193 50%+448 50%+193" type="image" sprite="LoadingTipText">
 			<object name="tipTitle" size="30 30 100% 50" type="text" style="LoadingTipTitleText"/>
 			<object name="tipText" size="30 50 100%-30 100%" type="text" style="LoadingTipText"/>
+			
+			<!-- LOADING SCREEN TIP SHOW PREVIOUS -->
+			<object name="prevTipButton" type="button" size="20 100% 100 100%+30" z="99" hotkey="loading.previoustip" style="ModernButtonRed">
+				<translatableAttribute id="caption">Previous</translatableAttribute>
+				<action on="Press">prevTip();</action>
+			</object>
+
+			<!-- LOADING SCREEN TIP SHOW NEXT -->
+			<object name="nextTipButton" type="button" size="100%-90 100% 100%-30 100%+30" z="99" hotkey="loading.nexttip" style="ModernButtonRed">
+				<translatableAttribute id="caption">Next</translatableAttribute>
+				<action on="Press">nextTip();</action>
+			</object>
 		</object>
 
 		<!-- LOADING SCREEN QUOTE (needs increased z value to overcome the transparent area of the tip image above it -->
@@ -50,4 +62,11 @@
 			<object name="quoteText" size="0 30 100% 100%" type="text" style="LoadingText"></object>
 		</object>
 	</object>
+
+	<!-- LOADING SCREEN READY (needs increased z value to overcome the quote area -->
+	<object name="startGameButton" type="button" size="50%-200 80%+80 50%+200 80%+120" z="99" hidden="true" hotkey="confirm" style="ModernButtonRed">
+		<translatableAttribute id="caption">I'm ready</translatableAttribute>
+		<action on="Press">startGame();</action>
+	</object>
+
 </objects>
Index: binaries/data/mods/public/gui/options/options.js
===================================================================
--- binaries/data/mods/public/gui/options/options.js	(revision 17523)
+++ binaries/data/mods/public/gui/options/options.js	(working copy)
@@ -15,6 +15,7 @@
 		[translate("Gametime Overlay"), translate("Show current simulation time in top right corner."), {"config":"gui.session.timeelapsedcounter"}, "boolean"],
 		[translate("Ceasefire Time Overlay"), translate("Always show the remaining ceasefire time."), {"config":"gui.session.ceasefirecounter"}, "boolean"],
 		[translate("Persist Match Settings"), translate("Save and restore match settings for quick reuse when hosting another game"), {"config":"persistmatchsettings"}, "boolean"],
+		[translate("Tip Controls"), translate("Allow navigating through loading screen tips and wait for the user before entering game."), {"config":"gui.loadingtips.enabled"}, "boolean"], 
 	],
 	"graphicsSetting":
 	[
@@ -116,7 +117,7 @@
 					case "config":
 						// Load initial value if not yet loaded.
 						if (!checked || typeof checked != "boolean")
-							checked = Engine.ConfigDB_GetValue("user", option[2][action]) === "true" ? true : false;
+							checked = Engine.ConfigDB_GetValue("user", option[2][action]) === "true";
 						// Hacky macro to create the callback.
 						var callback = function(key)
 						{
