Index: binaries/data/mods/public/simulation/components/StatusBars.js
===================================================================
--- binaries/data/mods/public/simulation/components/StatusBars.js	(revision 16623)
+++ binaries/data/mods/public/simulation/components/StatusBars.js	(working copy)
@@ -138,15 +138,15 @@
 
 	var AddBar = function(type, amount)
 	{
-		cmpOverlayRenderer.AddSprite(
-			"art/textures/ui/session/icons/"+type+"_bg.png",
+		cmpOverlayRenderer.AddColorSprite(
+			"255 0 0 255",
 			{ "x": -width/2, "y":yoffset },
 			{ "x": width/2, "y": height + yoffset },
 			offset
 		);
 
-		cmpOverlayRenderer.AddSprite(
-			"art/textures/ui/session/icons/"+type+"_fg.png",
+		cmpOverlayRenderer.AddColorSprite(
+			"255 0 0 255",
 			{ "x": -width/2, "y": yoffset },
 			{ "x": width*(amount - 0.5), "y": height + yoffset },
 			offset
Index: source/graphics/Overlay.h
===================================================================
--- source/graphics/Overlay.h	(revision 16623)
+++ source/graphics/Overlay.h	(working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012 Wildfire Games.
+/* Copyright (C) 2015 Wildfire Games.
  * This file is part of 0 A.D.
  *
  * 0 A.D. is free software: you can redistribute it and/or modify
@@ -141,6 +141,16 @@
 };
 
 /**
+ * Similar to SOverlaySprite, but with custom defined colors instead of texturs
+ */
+struct SOverlayColoredSprite
+{
+	CColor m_Color;
+	CVector3D m_Position; // base position
+	float m_X0, m_Y0, m_X1, m_Y1; // billboard corner coordinates, relative to base position
+};
+
+/**
  * Rectangular single-quad terrain overlay, in world space coordinates. The vertices of the quad
  * are not required to be coplanar; the quad is arbitrarily triangulated with no effort being made
  * to find a best fit to the underlying terrain.
Index: source/renderer/OverlayRenderer.cpp
===================================================================
--- source/renderer/OverlayRenderer.cpp	(revision 16623)
+++ source/renderer/OverlayRenderer.cpp	(working copy)
@@ -29,6 +29,7 @@
 #include "maths/Quaternion.h"
 #include "ps/Game.h"
 #include "ps/Profile.h"
+#include "ps/CLogger.h"
 #include "renderer/Renderer.h"
 #include "renderer/TexturedLineRData.h"
 #include "renderer/VertexArray.h"
@@ -87,6 +88,7 @@
 	std::vector<SOverlayLine*> lines;
 	std::vector<SOverlayTexturedLine*> texlines;
 	std::vector<SOverlaySprite*> sprites;
+	std::vector<SOverlayColoredSprite*> coloredSprites;
 	std::vector<SOverlayQuad*> quads;
 	std::vector<SOverlaySphere*> spheres;
 
@@ -224,6 +226,11 @@
 	m->sprites.push_back(overlay);
 }
 
+void OverlayRenderer::Submit(SOverlayColoredSprite* overlay)
+{
+	m->coloredSprites.push_back(overlay);
+}
+
 void OverlayRenderer::Submit(SOverlayQuad* overlay)
 {
 	m->quads.push_back(overlay);
@@ -640,6 +647,31 @@
 		g_Renderer.GetStats().m_DrawCalls++;
 		g_Renderer.GetStats().m_OverlayTris += 2;
 	}
+
+	for (size_t i = 0; i < m->coloredSprites.size(); ++i)
+	{
+		SOverlayColoredSprite* sprite = m->coloredSprites[i];
+
+		shader->Uniform(str_color, sprite->m_Color);
+		
+		LOGWARNING("r: %f, g:%f, b: %f,a: %f", sprite->m_Color.r, sprite->m_Color.g, sprite->m_Color.b, sprite->m_Color.a);
+		CVector3D pos[4] = {
+			sprite->m_Position + right*sprite->m_X0 + up*sprite->m_Y0,
+			sprite->m_Position + right*sprite->m_X1 + up*sprite->m_Y0,
+			sprite->m_Position + right*sprite->m_X1 + up*sprite->m_Y1,
+			sprite->m_Position + right*sprite->m_X0 + up*sprite->m_Y1
+		};
+
+		if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
+			shader->VertexPointer(3, GL_FLOAT, sizeof(float)*3, &pos[0].X);
+		else
+			glVertexPointer(3, GL_FLOAT, sizeof(float)*3, &pos[0].X);
+		
+		glDrawArrays(GL_QUADS, 0, (GLsizei)4);
+
+		g_Renderer.GetStats().m_DrawCalls++;
+		g_Renderer.GetStats().m_OverlayTris += 2;
+	}
 	
 	if (g_Renderer.GetRenderPath() == CRenderer::RP_SHADER)
 		tech->EndPass();
Index: source/renderer/OverlayRenderer.h
===================================================================
--- source/renderer/OverlayRenderer.h	(revision 16623)
+++ source/renderer/OverlayRenderer.h	(working copy)
@@ -23,6 +23,7 @@
 struct SOverlayLine;
 struct SOverlayTexturedLine;
 struct SOverlaySprite;
+struct SOverlayColoredSprite;
 struct SOverlayQuad;
 struct SOverlaySphere;
 class CCamera;
@@ -69,6 +70,13 @@
 	void Submit(SOverlaySprite* overlay);
 
 	/**
+	 * Add a colored sprite overlay for rendering in this frame.
+	 * @param overlay Must be non-null. The pointed-to object must remain valid at least
+	 *                until the end of the frame.
+	 */
+	void Submit(SOverlayColoredSprite* overlay);
+
+	/**
 	 * Add a textured quad overlay for rendering in this frame.
 	 * @param overlay Must be non-null. The pointed-to object must remain valid at least
 	 *                until the end of the frame.
Index: source/renderer/Renderer.cpp
===================================================================
--- source/renderer/Renderer.cpp	(revision 16623)
+++ source/renderer/Renderer.cpp	(working copy)
@@ -1739,6 +1739,12 @@
 		m->overlayRenderer.Submit(overlay);
 }
 
+void CRenderer::Submit(SOverlayColoredSprite* overlay)
+{
+	if (m_CurrentCullGroup == CULL_DEFAULT)
+		m->overlayRenderer.Submit(overlay);
+}
+
 void CRenderer::Submit(SOverlayQuad* overlay)
 {
 	if (m_CurrentCullGroup == CULL_DEFAULT)
Index: source/renderer/Renderer.h
===================================================================
--- source/renderer/Renderer.h	(revision 16623)
+++ source/renderer/Renderer.h	(working copy)
@@ -356,6 +356,7 @@
 	void Submit(SOverlayLine* overlay);
 	void Submit(SOverlayTexturedLine* overlay);
 	void Submit(SOverlaySprite* overlay);
+	void Submit(SOverlayColoredSprite* overlay);
 	void Submit(SOverlayQuad* overlay);
 	void Submit(CModelDecal* decal);
 	void Submit(CParticleEmitter* emitter);
Index: source/renderer/Scene.h
===================================================================
--- source/renderer/Scene.h	(revision 16623)
+++ source/renderer/Scene.h	(working copy)
@@ -39,6 +39,7 @@
 struct SOverlayLine;
 struct SOverlayTexturedLine;
 struct SOverlaySprite;
+struct SOverlayColoredSprite;
 struct SOverlayQuad;
 struct SOverlaySphere;
 
@@ -106,6 +107,11 @@
 	virtual void Submit(SOverlaySprite* overlay) = 0;
 
 	/**
+	 * Submit a colored sprite overlay.
+	 */
+	virtual void Submit(SOverlayColoredSprite* overlay) = 0;
+
+	/**
 	 * Submit a textured quad overlay.
 	 */
 	virtual void Submit(SOverlayQuad* overlay) = 0;
Index: source/simulation2/components/CCmpOverlayRenderer.cpp
===================================================================
--- source/simulation2/components/CCmpOverlayRenderer.cpp	(revision 16623)
+++ source/simulation2/components/CCmpOverlayRenderer.cpp	(working copy)
@@ -27,6 +27,8 @@
 #include "graphics/TextureManager.h"
 #include "renderer/Renderer.h"
 
+#include "ps/CLogger.h"
+
 class CCmpOverlayRenderer : public ICmpOverlayRenderer
 {
 public:
@@ -38,10 +40,12 @@
 
 	// Currently-enabled set of sprites
 	std::vector<SOverlaySprite> m_Sprites;
+	std::vector<SOverlayColoredSprite> m_ColorSprites;
 
 	// For each entry in m_Sprites, store the offset of the sprite from the unit's position
 	// (so we can recompute the sprite position after the unit moves)
 	std::vector<CVector3D> m_SpriteOffsets;
+	std::vector<CVector3D> m_ColorSpriteOffsets;
 
 	// Whether the sprites should be drawn (only valid between Interpolate and RenderSubmit)
 	bool m_Enabled;
@@ -98,7 +102,7 @@
 	 */
 	void UpdateMessageSubscriptions()
 	{
-		bool needRender = !m_Sprites.empty();
+		bool needRender = !m_Sprites.empty() || !m_ColorSprites.empty();
 
 		GetSimContext().GetComponentManager().DynamicSubscriptionNonsync(MT_Interpolate, this, needRender);
 		GetSimContext().GetComponentManager().DynamicSubscriptionNonsync(MT_RenderSubmit, this, needRender);
@@ -107,7 +111,9 @@
 	virtual void Reset()
 	{
 		m_Sprites.clear();
+		m_ColorSprites.clear();
 		m_SpriteOffsets.clear();
+		m_ColorSpriteOffsets.clear();
 
 		UpdateMessageSubscriptions();
 	}
@@ -129,10 +135,29 @@
 		UpdateMessageSubscriptions();
 	}
 
+	virtual void AddColorSprite(std::string color, CFixedVector2D corner0, CFixedVector2D corner1, CFixedVector3D position)
+	{
+		CColor colorObj;
+		if (!colorObj.ParseString(color, 1))
+			LOGERROR("OverlayRenderer: Error parsing '%s'", color);
+
+		SOverlayColoredSprite sprite;
+		sprite.m_Color = colorObj;
+		sprite.m_X0 = corner0.X.ToFloat();
+		sprite.m_Y0 = corner0.Y.ToFloat();
+		sprite.m_X1 = corner1.X.ToFloat();
+		sprite.m_Y1 = corner1.Y.ToFloat();
+
+		m_ColorSprites.push_back(sprite);
+		m_ColorSpriteOffsets.push_back(CVector3D(position));
+
+		UpdateMessageSubscriptions();
+	}
+
 	void Interpolate(float UNUSED(frameTime), float frameOffset)
 	{
 		// Skip all the following computations if we have no sprites
-		if (m_Sprites.empty())
+		if (m_Sprites.empty() && m_ColorSprites.empty())
 		{
 			m_Enabled = false;
 			return;
@@ -154,6 +179,9 @@
 		for (size_t i = 0; i < m_Sprites.size(); ++i)
 			m_Sprites[i].m_Position = position + m_SpriteOffsets[i];
 
+		for (size_t i = 0; i < m_ColorSprites.size(); ++i)
+			m_ColorSprites[i].m_Position = position + m_ColorSpriteOffsets[i];
+
 		m_Enabled = true;
 	}
 
@@ -164,6 +192,9 @@
 
 		for (size_t i = 0; i < m_Sprites.size(); ++i)
 			collector.Submit(&m_Sprites[i]);
+
+		for (size_t i = 0; i < m_ColorSprites.size(); ++i)
+			collector.Submit(&m_ColorSprites[i]);
 	}
 };
 
Index: source/simulation2/components/ICmpOverlayRenderer.cpp
===================================================================
--- source/simulation2/components/ICmpOverlayRenderer.cpp	(revision 16623)
+++ source/simulation2/components/ICmpOverlayRenderer.cpp	(working copy)
@@ -24,4 +24,5 @@
 BEGIN_INTERFACE_WRAPPER(OverlayRenderer)
 DEFINE_INTERFACE_METHOD_0("Reset", void, ICmpOverlayRenderer, Reset)
 DEFINE_INTERFACE_METHOD_4("AddSprite", void, ICmpOverlayRenderer, AddSprite, VfsPath, CFixedVector2D, CFixedVector2D, CFixedVector3D)
+DEFINE_INTERFACE_METHOD_4("AddColorSprite", void, ICmpOverlayRenderer, AddColorSprite, std::string, CFixedVector2D, CFixedVector2D, CFixedVector3D)
 END_INTERFACE_WRAPPER(OverlayRenderer)
Index: source/simulation2/components/ICmpOverlayRenderer.h
===================================================================
--- source/simulation2/components/ICmpOverlayRenderer.h	(revision 16623)
+++ source/simulation2/components/ICmpOverlayRenderer.h	(working copy)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2010 Wildfire Games.
+/* Copyright (C) 2015 Wildfire Games.
  * This file is part of 0 A.D.
  *
  * 0 A.D. is free software: you can redistribute it and/or modify
@@ -26,6 +26,8 @@
 #include "maths/FixedVector2D.h"
 #include "maths/FixedVector3D.h"
 
+struct CColor;
+
 /**
  * Interface for rendering 'overlay' objects (typically sprites), automatically
  * positioned relative to the entity.
@@ -45,12 +47,24 @@
 	/**
 	 * Add a new textured billboard sprite to be rendered.
 	 * @param textureName filename of texture to render.
-	 * @param corner0,corner1 coordinates of sprite's corners, in world-space units oriented with the camera plane,
+	 * @param corner0,corner1 coordinates of sprite's corners,
+	 *        in world-space units oriented with the camera plane,
 	 *        relative to the sprite position.
 	 * @param offset world-space offset of sprite position from the entity's base position.
 	 */
 	virtual void AddSprite(VfsPath textureName, CFixedVector2D corner0, CFixedVector2D corner1, CFixedVector3D offset) = 0;
 
+	/**
+	 * Add a new colored billboard sprite to be rendered.
+	 * @param color color to use on the sprite, 
+	 *        coded as r,g,b[,a] values separated with spaces
+	 * @param corner0,corner1 coordinates of sprite's corners,
+	 *        in world-space units oriented with the camera plane,
+	 *        relative to the sprite position.
+	 * @param offset world-space offset of sprite position from the entity's base position.
+	 */
+	virtual void AddColorSprite(std::string color, CFixedVector2D corner0, CFixedVector2D corner1, CFixedVector3D offset) = 0;
+
 	DECLARE_INTERFACE_TYPE(OverlayRenderer)
 };
 
