diff --git a/src/content_cao.cpp b/src/content_cao.cpp
index 20f5fd3db4781a1d50fa06e05847dde224b85958..bb8dad032eb7777e61305b8c00c56cd9e82133f2 100644
--- a/src/content_cao.cpp
+++ b/src/content_cao.cpp
@@ -1739,8 +1739,29 @@ class GenericCAO : public ClientActiveObject
 		{
 			/*s16 damage =*/ readS16(is);
 			s16 result_hp = readS16(is);
-			
+
+			// Use this instead of the send damage to not interfere with prediction
+			s16 damage = m_hp - result_hp;
+
 			m_hp = result_hp;
+
+			if (damage > 0) {
+				if (m_hp <= 0) {
+					// TODO: Execute defined fast response
+					// As there is no definition, make a smoke puff
+					ClientSimpleObject *simple = createSmokePuff(
+							m_smgr, m_env, m_position,
+							m_prop.visual_size * BS);
+					m_env->addSimpleObject(simple);
+				} else {
+					// TODO: Execute defined fast response
+					// Flashing shall suffice as there is no definition
+					m_reset_textures_timer = 0.05;
+					if(damage >= 2)
+						m_reset_textures_timer += 0.05 * damage;
+					updateTextures("^[brighten");
+				}
+			}
 		}
 		else if(cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS)
 		{
diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index 347e8892949c5d48fcc0898dc33f81dd9d6e3d02..9b4ae6100e0eec7d422de0f94f4e4558b7576468 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -942,6 +942,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
 	m_player(player_),
 	m_peer_id(peer_id_),
 	m_inventory(NULL),
+	m_damage(0),
 	m_last_good_position(0,0,0),
 	m_time_from_last_punch(0),
 	m_nocheat_dig_pos(32767, 32767, 32767),
@@ -1298,14 +1299,6 @@ int PlayerSAO::punch(v3f dir,
 
 	setHP(getHP() - hitparams.hp);
 
-	if(hitparams.hp != 0)
-	{
-		std::string str = gob_cmd_punched(hitparams.hp, getHP());
-		// create message and add to list
-		ActiveObjectMessage aom(getId(), true, str);
-		m_messages_out.push_back(aom);
-	}
-
 	return hitparams.wear;
 }
 
@@ -1318,6 +1311,13 @@ s16 PlayerSAO::getHP() const
 	return m_player->hp;
 }
 
+s16 PlayerSAO::readDamage()
+{
+	s16 damage = m_damage;
+	m_damage = 0;
+	return damage;
+}
+
 void PlayerSAO::setHP(s16 hp)
 {
 	s16 oldhp = m_player->hp;
@@ -1335,19 +1335,15 @@ void PlayerSAO::setHP(s16 hp)
 
 	m_player->hp = hp;
 
-	if(hp != oldhp)
+	if(hp != oldhp) {
 		m_hp_not_sent = true;
+		if(oldhp > hp)
+			m_damage += oldhp - hp;
+	}
 
-	// On death or reincarnation send an active object message
+	// Update properties on death
 	if((hp == 0) != (oldhp == 0))
-	{
-		// Will send new is_visible value based on (getHP()!=0)
 		m_properties_sent = false;
-		// Send new HP
-		std::string str = gob_cmd_punched(0, getHP());
-		ActiveObjectMessage aom(getId(), true, str);
-		m_messages_out.push_back(aom);
-	}
 }
 
 u16 PlayerSAO::getBreath() const
diff --git a/src/content_sao.h b/src/content_sao.h
index de4ac2d39475d365bbd6f6e3ec34011c9df1ecb2..6b97cb1488ddd6ad92688af7d9cd3a672ea0c490 100644
--- a/src/content_sao.h
+++ b/src/content_sao.h
@@ -193,6 +193,7 @@ class PlayerSAO : public ServerActiveObject
 	void rightClick(ServerActiveObject *clicker);
 	s16 getHP() const;
 	void setHP(s16 hp);
+	s16 readDamage();
 	u16 getBreath() const;
 	void setBreath(u16 breath);
 	void setArmorGroups(const ItemGroupList &armor_groups);
@@ -283,6 +284,7 @@ class PlayerSAO : public ServerActiveObject
 	Player *m_player;
 	u16 m_peer_id;
 	Inventory *m_inventory;
+	s16 m_damage;
 
 	// Cheat prevention
 	LagPool m_dig_pool;
diff --git a/src/server.cpp b/src/server.cpp
index 5ecdddcbc3019c57ce751f8c1e019c4be0c07ee7..561e03c7a9dd42fa29b498a364db2fe6601cea2c 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "filesys.h"
 #include "mapblock.h"
 #include "serverobject.h"
+#include "genericobject.h"
 #include "settings.h"
 #include "profiler.h"
 #include "log.h"
@@ -3828,6 +3829,11 @@ void Server::SendPlayerHP(u16 peer_id)
 	assert(playersao);
 	playersao->m_hp_not_sent = false;
 	SendHP(m_con, peer_id, playersao->getHP());
+
+	// Send to other clients
+	std::string str = gob_cmd_punched(playersao->readDamage(), playersao->getHP());
+	ActiveObjectMessage aom(playersao->getId(), true, str);
+	playersao->m_messages_out.push_back(aom);
 }
 
 void Server::SendPlayerBreath(u16 peer_id)