diff --git a/CHANGELOG b/CHANGELOG
index 67560049f6..78695bb072 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -84,6 +84,7 @@ NEW:
Added a new Launch.Replay=$FILEPATH parameter for OpenRA.Game.exe to instantly start watching a *.rep file.
Added HackyAI settings: ExcessPowerFactor, MinimumExcessPower, IdleBaseUnitsMaximum, RushAttackScanRadius, ProtectUnitScanRadius, RallyPointScanRadius. See the traits documentation for more information.
Added HitAnimPalette trait for LaserZap projectiles. Laser hit animations can now specify individual palettes. Defaults to effect palette.
+ Added RenderNameTag trait to show the player's name above an actor.
Fixed performance issues with units pathing to naval transports.
Fixed unit moving to transports that have moved.
Server:
diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
index 335d20d315..dfc81f6973 100644
--- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
+++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
@@ -341,6 +341,7 @@
+
diff --git a/OpenRA.Mods.RA/Render/RenderNameTag.cs b/OpenRA.Mods.RA/Render/RenderNameTag.cs
new file mode 100644
index 0000000000..1081ad20ba
--- /dev/null
+++ b/OpenRA.Mods.RA/Render/RenderNameTag.cs
@@ -0,0 +1,52 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
+ * This file is part of OpenRA, which is free software. It is made
+ * available to you under the terms of the GNU General Public License
+ * as published by the Free Software Foundation. For more information,
+ * see COPYING.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Drawing;
+using OpenRA.Graphics;
+using OpenRA.Traits;
+
+namespace OpenRA.Mods.RA.Render
+{
+ class RenderNameTagInfo : ITraitInfo
+ {
+ public readonly int MaxLength = 10;
+ public object Create(ActorInitializer init) { return new RenderNameTag(init.self, this); }
+ }
+
+ class RenderNameTag : IRender
+ {
+ readonly SpriteFont font;
+ readonly Color color;
+ readonly string name;
+
+ public RenderNameTag(Actor self, RenderNameTagInfo info)
+ {
+ font = Game.Renderer.Fonts["TinyBold"];
+ color = self.Owner.Color.RGB;
+
+ if (self.Owner.PlayerName.Length > info.MaxLength)
+ name = self.Owner.PlayerName.Substring(0, info.MaxLength);
+ else
+ name = self.Owner.PlayerName;
+ }
+
+ public IEnumerable Render(Actor self, WorldRenderer wr)
+ {
+ var pos = wr.ScreenPxPosition(self.CenterPosition);
+ var bounds = self.Bounds.Value;
+ bounds.Offset(pos.X, pos.Y);
+ var spaceBuffer = (int)(10 / wr.Viewport.Zoom);
+ var effectPos = wr.Position(new int2(pos.X, bounds.Y - spaceBuffer));
+
+ yield return new TextRenderable(font, effectPos, 0, color, name);
+ }
+ }
+}