Index: binaries/data/mods/public/gui/common/functions_utility.js
===================================================================
--- binaries/data/mods/public/gui/common/functions_utility.js	(revision 17027)
+++ binaries/data/mods/public/gui/common/functions_utility.js	(working copy)
@@ -146,10 +146,17 @@
 	return ret;
 }
 
 // ====================================================================
 
+function sameColor(color1, color2)
+{
+    return color1.r === color2.r && color1.g === color2.g && color1.b === color2.b;
+}
+
+// ====================================================================
+
 /**
  * Convert time in milliseconds to [hh:]mm:ss string representation.
  * @param time Time period in milliseconds (integer)
  * @return String representing time period
  */
Index: binaries/data/mods/public/gui/gamesetup/gamesetup.js
===================================================================
--- binaries/data/mods/public/gui/gamesetup/gamesetup.js	(revision 17027)
+++ binaries/data/mods/public/gui/gamesetup/gamesetup.js	(working copy)
@@ -7,10 +7,13 @@
 const g_GameSpeeds = prepareForDropdown(g_Settings ? g_Settings.GameSpeeds.filter(speed => !speed.ReplayOnly) : undefined);
 const g_VictoryConditions = prepareForDropdown(g_Settings ? g_Settings.VictoryConditions : undefined);
 const g_PopulationCapacities = prepareForDropdown(g_Settings ? g_Settings.PopulationCapacities : undefined);
 const g_StartingResources = prepareForDropdown(g_Settings ? g_Settings.StartingResources : undefined);
 
+// All colors except gaia
+const g_PlayerColors = initPlayerDefaults().slice(1).map(playerData => playerData.Color);
+
 ////////////////////////////////////////////////////////////////////////////////////////////////
 
 // Is this is a networked game, or offline
 var g_IsNetworked;
 
@@ -373,10 +376,17 @@
 				g_GameAttributes.settings.PlayerData[playerSlot].Team = this.selected - 1;
 
 			updateGameAttributes();
 		};
 
+		// Populate color drop-down lists.
+		var colorPicker = Engine.GetGUIObjectByName("playerColorPicker["+i+"]");
+		colorPicker.list = g_PlayerColors.map(color => '[font="sans-stroke-14"][color="' + color.r + ' ' + color.g + ' ' + color.b + '"] ■[/color][/font]');
+		colorPicker.list_data = g_PlayerColors.map((color, index) => index);
+		colorPicker.onSelectionChange = function() { selectPlayerColor(playerSlot, colorPicker.selected); };
+		colorPicker.selected = -1;
+
 		// Set events
 		var civ = Engine.GetGUIObjectByName("playerCiv["+i+"]");
 		civ.onSelectionChange = function() {
 			if ((this.selected != -1)&&(g_GameAttributes.mapType !== "scenario"))
 				g_GameAttributes.settings.PlayerData[playerSlot].Civ = this.list_data[this.selected];
@@ -886,10 +896,47 @@
 	}
 
 	updateGameAttributes();
 }
 
+function selectPlayerColor(playerSlot, selectedColorIdx)
+{
+	if (selectedColorIdx == -1)
+		return;
+
+	// Add missing properties
+	g_GameAttributes.settings.PlayerData.forEach((pData, index) => {
+		if (!pData.Color)
+			pData.Color = g_PlayerColors[index];
+	});
+
+	// If someone else has that color, give him/her the old one
+	var playerID = g_GameAttributes.settings.PlayerData.findIndex(pData => sameColor(g_PlayerColors[selectedColorIdx], pData.Color));
+	if (playerID != -1)
+		g_GameAttributes.settings.PlayerData[playerID].Color = g_GameAttributes.settings.PlayerData[playerSlot].Color;
+
+	// Assign the new player color
+	g_GameAttributes.settings.PlayerData[playerSlot].Color = g_PlayerColors[selectedColorIdx];
+
+	// Ensure colors are not used twice (would be possible by selecting any unused color and then increasing the number of players)
+	do
+	{
+		// Find a player with a color that is used twice
+		playerID = g_GameAttributes.settings.PlayerData.findIndex((pData, index) =>
+			g_GameAttributes.settings.PlayerData.some((pData2, index2) => index != index2 && sameColor(pData.Color, pData2.Color)));
+
+		// Assign an unused color
+		if (playerID != -1)
+			g_GameAttributes.settings.PlayerData[playerID].Color =
+				g_PlayerColors.find(color => g_GameAttributes.settings.PlayerData.every(pData => !sameColor(color, pData.Color)));
+
+	} while (playerID != -1);
+
+	if (!g_IsInGuiUpdate)
+		updateGameAttributes();
+}
+
 // Called when the user selects a map type from the list
 function selectMapType(type)
 {
 	// Avoid recursion
 	if (g_IsInGuiUpdate)
@@ -1422,18 +1469,20 @@
 		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("playerColor["+i+"]");
+		var pColorPicker = Engine.GetGUIObjectByName("playerColorPicker["+i+"]");
+		var pColorPickerHeading = Engine.GetGUIObjectByName("playerColorHeading");
 
 		// Player data / defaults
 		var pData = mapSettings.PlayerData ? mapSettings.PlayerData[i] : {};
 		var pDefs = g_DefaultPlayerData ? g_DefaultPlayerData[i] : {};
 
 		// Common to all game types
-		var color = rgbToGuiColor(getSetting(pData, pDefs, "Color"));
-		pColor.sprite = "color:" + color + " 100";
+		var color = getSetting(pData, pDefs, "Color");
+		pColor.sprite = "color:" + rgbToGuiColor(color) + " 100";
 		pName.caption = translate(getSetting(pData, pDefs, "Name"));
 
 		var team = getSetting(pData, pDefs, "Team");
 		var civ = getSetting(pData, pDefs, "Civ");
 
@@ -1449,10 +1498,12 @@
 		// TODO: Allow clients to choose their own civ and team
 		if (!g_IsController || g_GameAttributes.mapType == "scenario")
 		{
 			pCivText.hidden = false;
 			pCiv.hidden = true;
+			pColorPicker.hidden = true;
+			pColorPickerHeading.hidden = true;
 			pTeamText.hidden = false;
 			pTeam.hidden = true;
 			// Set text values
 			if (civ == "random")
 				pCivText.caption = "[color=\"orange\"]" + translateWithContext("civilization", "Random");
@@ -1464,10 +1515,13 @@
 		{
 			pCivText.hidden = true;
 			pCiv.hidden = false;
 			pTeamText.hidden = true;
 			pTeam.hidden = false;
+			pColorPicker.hidden = false;
+			pColorPickerHeading.hidden = false;
+			pColorPicker.selected = g_PlayerColors.findIndex(col => sameColor(col, color));
 			// Set dropdown values
 			pCiv.selected = (civ ? pCiv.list_data.indexOf(civ) : 0);
 			pTeam.selected = (team !== undefined && team >= 0) ? team+1 : 0;
 		}
 	}
Index: binaries/data/mods/public/gui/gamesetup/gamesetup.xml
===================================================================
--- binaries/data/mods/public/gui/gamesetup/gamesetup.xml	(revision 17027)
+++ binaries/data/mods/public/gui/gamesetup/gamesetup.xml	(working copy)
@@ -40,11 +40,14 @@
 			<object size="24 49 100%-440 345" type="image" sprite="ModernDarkBoxGold" name="playerAssignmentsPanel">
 				<object size="0 6 100% 30">
 					<object name="playerNameHeading" type="text" style="ModernLabelText" size="0 0 22% 100%">
 						<translatableAttribute id="caption">Player Name</translatableAttribute>
 					</object>
-					<object name="playerPlacementHeading" type="text" style="ModernLabelText" size="22%+5 0 50%+35 100%">
+					<object name="playerColorHeading" type="text" style="ModernLabelText" size="22%+5 0 22%+40 100%">
+						<translatableAttribute id="caption">Color</translatableAttribute>
+					</object>
+					<object name="playerPlacementHeading" type="text" style="ModernLabelText" size="22%+45 0 50%+35 100%">
 						<translatableAttribute id="caption">Player Placement</translatableAttribute>
 					</object>
 					<object name="playerCivHeading" type="text" style="ModernLabelText" size="50%+65 0 85%-26 100%">
 						<translatableAttribute id="caption">Civilization</translatableAttribute>
 					</object>
@@ -67,11 +70,14 @@
 				<object size="1 36 100%-1 100%">
 					<repeat count="8">
 						<object name="playerBox[n]" size="0 0 100% 32" hidden="true">
 							<object name="playerColor[n]" type="image" size="0 0 100% 100%"/>
 							<object name="playerName[n]" type="text" style="ModernLabelText" size="0 2 22% 30"/>
-							<object name="playerAssignment[n]" type="dropdown" style="ModernDropDown" size="22%+5 2 50%+35 30" tooltip_style="onscreenToolTip">
+							<object name="playerColorPicker[n]" type="dropdown" style="ModernDropDown" size="22%+5 2 22%+40 30" scrollbar="false" tooltip_style="onscreenToolTip">
+								<translatableAttribute id="tooltip">Pick a color.</translatableAttribute>
+							</object>
+							<object name="playerAssignment[n]" type="dropdown" style="ModernDropDown" size="22%+45 2 50%+35 30" tooltip_style="onscreenToolTip">
 								<translatableAttribute id="tooltip">Select player.</translatableAttribute>
 							</object>
 							<object name="playerAssignmentText[n]" type="text" style="ModernLabelText" size="22%+5 0 50%+35 30"/>
 							<object name="playerConfig[n]" type="button" style="StoneButton" size="50%+40 4 50%+64 28"
 								tooltip_style="onscreenToolTip"
