diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index aa4503879573e82d3e61b1cc418e678708cb08f9..7744487782a623cde4c5084372b6a84b2586a573 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -409,6 +409,9 @@ ranging in value from 0 to 1.
 The name field is not yet used, but should contain a description of what the HUD element represents.
 The direction field is the direction in which something is drawn.
 0 draws from left to right, 1 draws from right to left, 2 draws from top to bottom, and 3 draws from bottom to top.
+The alignment field specifies how the item will be aligned. It ranges from -1 to 1,
+with 0 being the center, -1 is moved to the left/up, and 1 is to the right/down. Fractional
+values can be used.
 Below are the specific uses for fields in each type; fields not listed for that type are ignored.
 
 Note: Future revisions to the HUD API may be incompatible; the HUD API is still in the experimental stages.
@@ -418,6 +421,7 @@ Note: Future revisions to the HUD API may be incompatible; the HUD API is still
 	- scale: The scale of the image, with 1 being the original texture size.
              Only the X coordinate scale is used.
     - text: The name of the texture that is displayed.
+    - alignment: The alignment of the image.
 - text
     Displays text on the HUD.
     - scale: Defines the bounding rectangle of the text.
@@ -425,6 +429,7 @@ Note: Future revisions to the HUD API may be incompatible; the HUD API is still
     - text: The text to be displayed in the HUD element.
     - number: An integer containing the RGB value of the color used to draw the text.
               Specify 0xFFFFFF for white text, 0xFF0000 for red, and so on.
+    - alignment: The alignment of the text.
 - statbar
     Displays a horizontal bar made up of half-images.
     - text: The name of the texture that is used.
@@ -1857,4 +1862,6 @@ HUD Definition (hud_add, hud_get)
     ^ Selected item in inventory.  0 for no item selected.
     direction = 0,
     ^ Direction: 0: left-right, 1: right-left, 2: top-bottom, 3: bottom-top
+    alignment = {x=0, y=0},
+    ^ See "HUD Element Types"
 }
diff --git a/src/client.cpp b/src/client.cpp
index 03a710599a4af4b3c035910013e21a96bbbf407c..8db6f2f4009123238a06fe3e622146dc9f9c4e5c 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -2054,6 +2054,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
 		u32 number       = readU32(is);
 		u32 item         = readU32(is);
 		u32 dir          = readU32(is);
+		v2f align        = readV2F1000(is);
 
 		ClientEvent event;
 		event.type = CE_HUDADD;
@@ -2066,6 +2067,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
 		event.hudadd.number = number;
 		event.hudadd.item   = item;
 		event.hudadd.dir    = dir;
+		event.hudadd.align  = new v2f(align);
 		m_client_event_queue.push_back(event);
 	}
 	else if(command == TOCLIENT_HUDRM)
diff --git a/src/client.h b/src/client.h
index f59588680729f523b519aff24409e7ae1f530738..ff42f3e05a65808453d3b7915507547e66fe5a8f 100644
--- a/src/client.h
+++ b/src/client.h
@@ -230,6 +230,7 @@ struct ClientEvent
 			u32 number;
 			u32 item;
 			u32 dir;
+			v2f *align;
 		} hudadd;
 		struct{
 			u32 id;
diff --git a/src/clientserver.h b/src/clientserver.h
index 6f7bb4402c109e4e18bd228a35be5e34593ca0bb..0418d10b3a0f312826f0cffe2606c8f1ee5fd2ab 100644
--- a/src/clientserver.h
+++ b/src/clientserver.h
@@ -452,6 +452,7 @@ enum ToClientCommand
 		u32 number
 		u32 item
 		u32 dir
+		v2f1000 align
 	*/
 
 	TOCLIENT_HUDRM = 0x50,
diff --git a/src/game.cpp b/src/game.cpp
index a2d94ac0a0f07e57750d17bea756a236d751a736..2c73dfa6fed74bb97447129a6c7696ef9142eb50 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -2106,6 +2106,7 @@ void the_game(
 						delete event.hudadd.name;
 						delete event.hudadd.scale;
 						delete event.hudadd.text;
+						delete event.hudadd.align;
 						continue;
 					}
 					
@@ -2118,6 +2119,7 @@ void the_game(
 					e->number = event.hudadd.number;
 					e->item   = event.hudadd.item;
 					e->dir    = event.hudadd.dir;
+					e->align  = *event.hudadd.align;
 					
 					if (id == nhudelem)
 						player->hud.push_back(e);
@@ -2128,6 +2130,7 @@ void the_game(
 					delete event.hudadd.name;
 					delete event.hudadd.scale;
 					delete event.hudadd.text;
+					delete event.hudadd.align;
 				}
 				else if (event.type == CE_HUDRM)
 				{
@@ -2169,6 +2172,9 @@ void the_game(
 						case HUD_STAT_DIR:
 							e->dir = event.hudchange.data;
 							break;
+						case HUD_STAT_ALIGN:
+							e->align = *event.hudchange.v2fdata;
+							break;
 					}
 					
 					delete event.hudchange.v2fdata;
diff --git a/src/hud.cpp b/src/hud.cpp
index 77cf23173569d381e0ad47357c3ee390fc47ba3d..0f3ab40d2d2a8b7fd9daf18e111f5d176d559ed1 100644
--- a/src/hud.cpp
+++ b/src/hud.cpp
@@ -186,6 +186,9 @@ void Hud::drawLuaElements() {
 				core::rect<s32> rect(0, 0, imgsize.Width  * e->scale.X,
 									       imgsize.Height * e->scale.X);
 				rect += pos;
+				v2s32 offset((e->align.X - 1.0) * ((imgsize.Width  * e->scale.X) / 2),
+				             (e->align.Y - 1.0) * ((imgsize.Height * e->scale.X) / 2));
+				rect += offset;
 				driver->draw2DImage(texture, rect,
 					core::rect<s32>(core::position2d<s32>(0,0), imgsize),
 					NULL, colors, true);
@@ -195,7 +198,11 @@ void Hud::drawLuaElements() {
 										 (e->number >> 8)  & 0xFF,
 										 (e->number >> 0)  & 0xFF);
 				core::rect<s32> size(0, 0, e->scale.X, text_height * e->scale.Y);
-				font->draw(narrow_to_wide(e->text).c_str(), size + pos, color);
+				std::wstring text = narrow_to_wide(e->text);
+				core::dimension2d<u32> textsize = font->getDimension(text.c_str());
+				v2s32 offset((e->align.X - 1.0) * (textsize.Width / 2),
+				             (e->align.Y - 1.0) * (textsize.Height / 2));
+				font->draw(text.c_str(), size + pos + offset, color);
 				break; }
 			case HUD_ELEM_STATBAR:
 				drawStatbar(pos, HUD_CORNER_UPPER, e->dir, e->text, e->number);
diff --git a/src/hud.h b/src/hud.h
index 274a669c49e4c432a99e5446bfa39b6d857b7b19..7a1dff3d82a46e06c98e026403ae7a4bd38b294c 100644
--- a/src/hud.h
+++ b/src/hud.h
@@ -47,7 +47,8 @@ enum HudElementStat {
 	HUD_STAT_TEXT,
 	HUD_STAT_NUMBER,
 	HUD_STAT_ITEM,
-	HUD_STAT_DIR
+	HUD_STAT_DIR,
+	HUD_STAT_ALIGN
 };
 
 struct HudElement {
@@ -59,6 +60,7 @@ struct HudElement {
 	u32 number;
 	u32 item;
 	u32 dir;
+	v2f align;
 };
 
 
diff --git a/src/scriptapi_object.cpp b/src/scriptapi_object.cpp
index 9152c9eb357c498d7290d21924cdb500072e2bc3..c07f6565dad3c657ee9d0af9a3f6485b7fecac5e 100644
--- a/src/scriptapi_object.cpp
+++ b/src/scriptapi_object.cpp
@@ -47,6 +47,7 @@ struct EnumString es_HudElementStat[] =
 	{HUD_STAT_NUMBER, "number"},
 	{HUD_STAT_ITEM,   "item"},
 	{HUD_STAT_DIR,    "direction"},
+	{HUD_STAT_ALIGN,  "alignment"},
 	{0, NULL},
 };
 
@@ -751,6 +752,10 @@ int ObjectRef::l_hud_add(lua_State *L)
 	elem->item   = getintfield_default(L, 2, "item", 0);
 	elem->dir    = getintfield_default(L, 2, "direction", 0);
 
+	lua_getfield(L, 2, "alignment");
+	elem->align = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
+	lua_pop(L, 1);
+
 	u32 id = get_server(L)->hudAdd(player, elem);
 	if (id == (u32)-1) {
 		delete elem;
@@ -833,6 +838,9 @@ int ObjectRef::l_hud_change(lua_State *L)
 		case HUD_STAT_DIR:
 			e->dir = lua_tonumber(L, 4);
 			value = &e->dir;
+		case HUD_STAT_ALIGN:
+			e->align = read_v2f(L, 4);
+			value = &e->align;
 	}
 
 	get_server(L)->hudChange(player, id, stat, value);
diff --git a/src/server.cpp b/src/server.cpp
index 7fad623c2213b620d875c20194a70d44a43091d4..b8f3e4da890d48ae3f74a0fcbd7ad95e4fc9c51a 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -3616,6 +3616,7 @@ void Server::SendHUDAdd(u16 peer_id, u32 id, HudElement *form)
 	writeU32(os, form->number);
 	writeU32(os, form->item);
 	writeU32(os, form->dir);
+	writeV2F1000(os, form->align);
 
 	// Make data buffer
 	std::string s = os.str();
@@ -3650,6 +3651,7 @@ void Server::SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value
 	switch (stat) {
 		case HUD_STAT_POS:
 		case HUD_STAT_SCALE:
+		case HUD_STAT_ALIGN:
 			writeV2F1000(os, *(v2f *)value);
 			break;
 		case HUD_STAT_NAME: