Index: gui/common/settings.js
===================================================================
--- gui/common/settings.js	(revision 17006)
+++ gui/common/settings.js	(working copy)
@@ -32,6 +32,7 @@
 	var settings = {};
 
 	settings.Ceasefire = loadCeasefire();
+	settings.Player_Colors =  loadPlayerColors();
 	if (!settings.Ceasefire)
 		return undefined;
 
@@ -62,6 +63,24 @@
 }
 
 /**
+ * Loads available colors settings.
+ *
+ * @returns {Array|undefined}
+ */
+function loadPlayerColors()
+{
+	var json = Engine.ReadJSONFile("simulation/data/player_defaults.json");
+
+	if (!json || !json.PlayerData || !Array.isArray(json.PlayerData))
+	{
+		error("Could not load player_defaults.json");
+		return undefined;
+	}
+	
+	return json.PlayerData.map(player => player.Color);
+}
+
+/**
  * Creates an object with all values of that property of the given setting and
  * finds the index of the default value.
  *
Index: gui/gamesetup/gamesetup.js
===================================================================
--- gui/gamesetup/gamesetup.js	(revision 17006)
+++ gui/gamesetup/gamesetup.js	(working copy)
@@ -16,6 +16,7 @@
 const STARTING_RESOURCES_DEFAULTIDX = 1;
 
 const g_Ceasefire = prepareForDropdown(g_Settings ? g_Settings.Ceasefire : undefined);
+const g_PlayerColors = prepareForDropdown(g_Settings ? g_Settings.Player_Colors : undefined);
 
 ////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -60,6 +61,9 @@
 
 var g_ChatMessages = [];
 
+var g_PlayerColorsSorted = [];
+var g_PlayerColorIdsSorted = [];
+var g_PlayerColorDisplayNamesSorted = [];
 // Data caches
 var g_MapData = {};
 var g_CivData = {};
@@ -389,6 +393,37 @@
 			updateGameAttributes();
 		};
 
+		// Populate color drop-down lists.
+		var colorPicker = Engine.GetGUIObjectByName("playerColorPicker["+i+"]");
+		colorPicker.list = getPlayerColorLabelsSorted();
+		colorPicker.list_data = getPlayerColorIdsSorted();
+		colorPicker.selected = -1;
+		colorPicker.onSelectionChange = function()
+		{       // Update color
+			if (this.selected !== -1)
+			{
+				var numPlayers = g_GameAttributes.settings.PlayerData.length;
+				var used = 0;
+				var playerColorsSorted = getPlayerColorsSorted();
+				for (var o = 0; o < numPlayers; o++)
+				{
+					if (rgbValuesMatch(playerColorsSorted[this.list_data[this.selected]], g_GameAttributes.settings.PlayerData[o].Color))
+					{
+						++used;
+						break;
+					}
+				}
+				if (!used)
+				{
+					copyRgbValuesFromColorIntoColor(playerColorsSorted[this.list_data[this.selected]], g_GameAttributes.settings.PlayerData[playerSlot].Color);
+				}
+			}
+			if (!g_IsInGuiUpdate)
+			{
+				updateGameAttributes();
+			}
+		};
+
 		// Set events
 		var civ = Engine.GetGUIObjectByName("playerCiv["+i+"]");
 		civ.onSelectionChange = function() {
@@ -421,7 +456,122 @@
 		updateGameAttributes();
 	}
 }
+// Returns the index of the specified color.
+function getIndexOfColor(color)
+{
+    for (var i = 0; i < g_PlayerColors.length; ++i)
+    {
+        var playerColorsSorted = getPlayerColorsSorted();
+        if (rgbValuesMatch(playerColorsSorted[i], color))
+        {
+            return i;
+        }
+    }
+    return -1;
+}
 
+function rgbToHsl(color){
+		var r = color.r/255, g = color.g/255, b = color.b/255;
+		var max = Math.max(r, g, b), min = Math.min(r, g, b);
+		var h, s, l = (max + min) / 2;
+		if (max === min)
+		{
+				h = s = 0; // achromatic
+		}
+		else
+		{
+				var d = max - min;
+				s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+				switch(max)
+				{
+						case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+						case g: h = (b - r) / d + 2; break;
+						case b: h = (r - g) / d + 4; break;
+				}
+				h /= 6;
+		}
+		return new Array(h * 360, s * 100, l * 100);
+}
+
+// Get list of player colors sorted by color value.
+// See http://stackoverflow.com/a/11923973/939364
+function getPlayerColorsSorted()
+{
+    if (g_PlayerColorsSorted.length === 0)
+    {
+        var hslArray = new Array();
+        for (var i = 0; i < g_PlayerColors.length; ++i)
+        {
+            //Transforming rgb to hsl
+            //`hslArray[i][1]` (`i`) is a reference to the rgb color, in order to retrieve it later
+            hslArray[i] = [rgbToHsl(g_PlayerColors[i]),i];
+        }
+
+        var sortedHslArray = new Array();
+        outerloop:
+        for (var i = 0; i < hslArray.length; ++i)
+        {
+            for (var j = 0; j < sortedHslArray.length; ++j)
+            {
+                if (sortedHslArray[j][0][0] > hslArray[i][0][0])
+                {
+                    sortedHslArray.splice(j, 0, hslArray[i]);
+                    continue outerloop;
+                }
+            }
+            sortedHslArray.push(hslArray[i]);
+        }
+
+        for (var i = 0; i < sortedHslArray.length; ++i)
+        {
+            g_PlayerColorsSorted[i] = g_PlayerColors[sortedHslArray[i][1]];
+        }
+    }
+    return g_PlayerColorsSorted;
+}
+
+// Get a list of player color display names.
+function getPlayerColorLabelsSorted()
+{
+    if (g_PlayerColorDisplayNamesSorted.length === 0)
+    {
+        var playerColorsSorted = getPlayerColorsSorted();
+        for (var i = 0; i < playerColorsSorted.length; ++i)
+        {
+            g_PlayerColorDisplayNamesSorted[i] = "[color=\"" + playerColorsSorted[i].r + " " + playerColorsSorted[i].g + " " + playerColorsSorted[i].b + " 255\"]" + playerColorsSorted[i].displayName;
+        }
+    }
+    return g_PlayerColorDisplayNamesSorted;
+}
+
+// Get a simple list of color IDs, basically a list of indexes that has as many members as colors there are.
+function getPlayerColorIdsSorted()
+{
+    if (g_PlayerColorIdsSorted.length === 0)
+    {
+        var playerColorsSorted = getPlayerColorsSorted();
+        for (var i = 0; i < playerColorsSorted.length; ++i)
+        {
+          g_PlayerColorIdsSorted[i] = i;
+        }
+    }
+    return g_PlayerColorIdsSorted;
+}
+
+// Determine whether two specified variables contain the same RGB data.
+function rgbValuesMatch(color1, color2)
+{
+    return color1.r === color2.r && color1.g === color2.g && color1.b === color2.b;
+}
+
+// Copy the RGB data from the first color into the second color.
+function copyRgbValuesFromColorIntoColor(color1, color2)
+{
+    color2.r = color1.r;
+	    color2.g = color1.g;
+    color2.b = color1.b;
+}
+
 function handleNetMessage(message)
 {
 	log("Net message: " + uneval(message));
@@ -1430,6 +1580,7 @@
 		var pTeam = Engine.GetGUIObjectByName("playerTeam["+i+"]");
 		var pTeamText = Engine.GetGUIObjectByName("playerTeamText["+i+"]");
 		var pColor = Engine.GetGUIObjectByName("playerColor["+i+"]");
+		var pColorPicker = Engine.GetGUIObjectByName("playerColorPicker["+i+"]")
 
 		// Player data / defaults
 		var pData = mapSettings.PlayerData ? mapSettings.PlayerData[i] : {};
@@ -1436,8 +1587,8 @@
 		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");
@@ -1459,6 +1610,7 @@
 			pCiv.hidden = true;
 			pTeamText.hidden = false;
 			pTeam.hidden = true;
+			pColorPicker.hidden = true;
 			// Set text values
 			if (civ == "random")
 				pCivText.caption = "[color=\"orange\"]" + translateWithContext("civilization", "Random");
@@ -1472,9 +1624,11 @@
 			pCiv.hidden = false;
 			pTeamText.hidden = true;
 			pTeam.hidden = false;
+			pColorPicker.hidden = false;
 			// Set dropdown values
 			pCiv.selected = (civ ? pCiv.list_data.indexOf(civ) : 0);
 			pTeam.selected = (team !== undefined && team >= 0) ? team+1 : 0;
+			pColorPicker.selected = getIndexOfColor(color);
 		}
 	}
 
Index: gui/gamesetup/gamesetup.xml
===================================================================
--- gui/gamesetup/gamesetup.xml	(revision 17006)
+++ gui/gamesetup/gamesetup.xml	(working copy)
@@ -72,9 +72,12 @@
 						<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="playerAssignment[n]" type="dropdown" style="ModernDropDown" size="20%+5 2 50%+35 30" tooltip_style="onscreenToolTip">
 								<translatableAttribute id="tooltip">Select player.</translatableAttribute>
 							</object>
+							<object name="playerColorPicker[n]" type="dropdown" style="ModernLabelText" size="20%+5 2 50%+35 30" tooltip_style="onscreenToolTip">
+							<translatableAttribute id="tooltip">Pick Color.</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"
@@ -152,7 +155,7 @@
 					tooltip_style="onscreenToolTip">
 					<translatableAttribute id="tooltip">Select a map to play on.</translatableAttribute>
 					<action on="SelectionChange">
-						if (this.list_data[this.selected]) 
+						if (this.list_data[this.selected])
 							selectMap(this.list_data[this.selected]);
 					</action>
 				</object>
@@ -179,7 +182,7 @@
 
 			<!-- Map Description -->
 			<object size="100%-425 529 100%-25 100%-60">
-				<object name="mapInfoName" type="text" style="ModernLeftLabelText" size="0 0 100%-120 30"/> 
+				<object name="mapInfoName" type="text" style="ModernLeftLabelText" size="0 0 100%-120 30"/>
 				<object type="image" sprite="ModernDarkBoxGold" size="0 30 100% 100%">
 					<object name="mapInfoDescription" type="text" style="MapDescription" size="0 0 100% 100%"/>
 				</object>
Index: simulation/data/settings/player_colors.json
===================================================================
--- simulation/data/settings/player_colors.json	(revision 0)
+++ simulation/data/settings/player_colors.json	(working copy)
@@ -0,0 +1,50 @@
+{
+    "Comment": "Default colors are Blue, Red, Green, Yellow, Cyan, Purple, Orange, Grey, Fandango",
+    "Data": [
+        {
+            "r": 46,
+            "g": 46,
+            "b": 200
+        },
+        {
+            "r": 150,
+            "g": 20,
+            "b": 20
+        },
+        {
+            "r": 50,
+            "g": 165,
+            "b": 5
+        },
+        {
+            "r": 230,
+            "g": 230,
+            "b": 75
+        },
+        {
+            "r": 50,
+            "g": 170,
+            "b": 170
+        },
+        {
+            "r": 160,
+            "g": 80,
+            "b": 200
+        },
+        {
+            "r": 235,
+            "g": 120,
+            "b": 20
+        },
+        {
+            "r": 64,
+            "g": 64,
+            "b": 64
+        },
+        {
+            "r": 230,
+            "g": 60,
+            "b": 105
+        }
+    ]
+}
