diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index 386b7e070d160fb4d083b452c67b48029d9eff70..eab1e62795d4e7e5907eee383da619a8bee0bcbc 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -591,6 +591,21 @@ void LuaEntitySAO::getAttachment(int *parent_id, std::string *bone, v3f *positio
 	*rotation = m_attachment_rotation;
 }
 
+void LuaEntitySAO::addAttachmentChild(int child_id)
+{
+	m_attachment_child_ids.insert(child_id);
+}
+
+void LuaEntitySAO::removeAttachmentChild(int child_id)
+{
+	m_attachment_child_ids.erase(child_id);
+}
+
+std::set<int> LuaEntitySAO::getAttachmentChildIds()
+{
+	return m_attachment_child_ids;
+}
+
 ObjectProperties* LuaEntitySAO::accessObjectProperties()
 {
 	return &m_prop;
@@ -1231,6 +1246,21 @@ void PlayerSAO::getAttachment(int *parent_id, std::string *bone, v3f *position,
 	*rotation = m_attachment_rotation;
 }
 
+void PlayerSAO::addAttachmentChild(int child_id)
+{
+	m_attachment_child_ids.insert(child_id);
+}
+
+void PlayerSAO::removeAttachmentChild(int child_id)
+{
+	m_attachment_child_ids.erase(child_id);
+}
+
+std::set<int> PlayerSAO::getAttachmentChildIds()
+{
+	return m_attachment_child_ids;
+}
+
 ObjectProperties* PlayerSAO::accessObjectProperties()
 {
 	return &m_prop;
diff --git a/src/content_sao.h b/src/content_sao.h
index f61566665310061e5b316536a52300988ff89e9a..1f0a68cd859ae80993f0389c84caa2f419beedc7 100644
--- a/src/content_sao.h
+++ b/src/content_sao.h
@@ -65,6 +65,9 @@ class LuaEntitySAO : public ServerActiveObject
 	void getBonePosition(const std::string &bone, v3f *position, v3f *rotation);
 	void setAttachment(int parent_id, const std::string &bone, v3f position, v3f rotation);
 	void getAttachment(int *parent_id, std::string *bone, v3f *position, v3f *rotation);
+	void addAttachmentChild(int child_id);
+	void removeAttachmentChild(int child_id);
+	std::set<int> getAttachmentChildIds();
 	ObjectProperties* accessObjectProperties();
 	void notifyObjectPropertiesModified();
 	/* LuaEntitySAO-specific */
@@ -113,6 +116,7 @@ class LuaEntitySAO : public ServerActiveObject
 	bool m_bone_position_sent;
 
 	int m_attachment_parent_id;
+	std::set<int> m_attachment_child_ids;
 	std::string m_attachment_bone;
 	v3f m_attachment_position;
 	v3f m_attachment_rotation;
@@ -204,6 +208,9 @@ class PlayerSAO : public ServerActiveObject
 	void getBonePosition(const std::string &bone, v3f *position, v3f *rotation);
 	void setAttachment(int parent_id, const std::string &bone, v3f position, v3f rotation);
 	void getAttachment(int *parent_id, std::string *bone, v3f *position, v3f *rotation);
+	void addAttachmentChild(int child_id);
+	void removeAttachmentChild(int child_id);
+	std::set<int> getAttachmentChildIds();
 	ObjectProperties* accessObjectProperties();
 	void notifyObjectPropertiesModified();
 	void setNametagColor(video::SColor color);
@@ -320,6 +327,7 @@ class PlayerSAO : public ServerActiveObject
 	bool m_bone_position_sent;
 
 	int m_attachment_parent_id;
+	std::set<int> m_attachment_child_ids;
 	std::string m_attachment_bone;
 	v3f m_attachment_position;
 	v3f m_attachment_rotation;
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index e407ef162d0a8034283150f9a7fa129e57a54c4b..96fb0c5791d97bdbf7a2effc99ff0b32ad294377 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -132,10 +132,22 @@ int ObjectRef::gc_object(lua_State *L) {
 int ObjectRef::l_remove(lua_State *L)
 {
 	NO_MAP_LOCK_REQUIRED;
+	GET_ENV_PTR;
+
 	ObjectRef *ref = checkobject(L, 1);
 	ServerActiveObject *co = getobject(ref);
-	if(co == NULL) return 0;
-	if(co->getType() == ACTIVEOBJECT_TYPE_PLAYER) return 0;
+	if (co == NULL)
+		return 0;
+	if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
+		return 0;
+
+	std::set<int> child_ids = co->getAttachmentChildIds();
+	std::set<int>::iterator it;
+	for (it = child_ids.begin(); it != child_ids.end(); ++it) {
+		ServerActiveObject *child = env->getActiveObject(*it);
+		child->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0));
+	}
+
 	verbosestream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
 	co->m_removed = true;
 	return 0;
@@ -630,23 +642,38 @@ int ObjectRef::l_get_bone_position(lua_State *L)
 int ObjectRef::l_set_attach(lua_State *L)
 {
 	NO_MAP_LOCK_REQUIRED;
+	GET_ENV_PTR;
+
 	ObjectRef *ref = checkobject(L, 1);
 	ObjectRef *parent_ref = checkobject(L, 2);
 	ServerActiveObject *co = getobject(ref);
 	ServerActiveObject *parent = getobject(parent_ref);
-	if(co == NULL) return 0;
-	if(parent == NULL) return 0;
+	if (co == NULL)
+		return 0;
+	if (parent == NULL)
+		return 0;
 	// Do it
+	int parent_id = 0;
 	std::string bone = "";
-	if(!lua_isnil(L, 3))
-		bone = lua_tostring(L, 3);
 	v3f position = v3f(0, 0, 0);
-	if(!lua_isnil(L, 4))
-		position = read_v3f(L, 4);
 	v3f rotation = v3f(0, 0, 0);
-	if(!lua_isnil(L, 5))
+	co->getAttachment(&parent_id, &bone, &position, &rotation);
+	if (parent_id) {
+		ServerActiveObject *old_parent = env->getActiveObject(parent_id);
+		old_parent->removeAttachmentChild(co->getId());
+	}
+
+	bone = "";
+	if (!lua_isnil(L, 3))
+		bone = lua_tostring(L, 3);
+	position = v3f(0, 0, 0);
+	if (!lua_isnil(L, 4))
+		position = read_v3f(L, 4);
+	rotation = v3f(0, 0, 0);
+	if (!lua_isnil(L, 5))
 		rotation = read_v3f(L, 5);
 	co->setAttachment(parent->getId(), bone, position, rotation);
+	parent->addAttachmentChild(co->getId());
 	return 0;
 }
 
@@ -682,11 +709,26 @@ int ObjectRef::l_get_attach(lua_State *L)
 int ObjectRef::l_set_detach(lua_State *L)
 {
 	NO_MAP_LOCK_REQUIRED;
+	GET_ENV_PTR;
+
 	ObjectRef *ref = checkobject(L, 1);
 	ServerActiveObject *co = getobject(ref);
-	if(co == NULL) return 0;
+	if (co == NULL)
+		return 0;
+
+	int parent_id = 0;
+	std::string bone = "";
+	v3f position;
+	v3f rotation;
+	co->getAttachment(&parent_id, &bone, &position, &rotation);
+	ServerActiveObject *parent = NULL;
+	if (parent_id)
+		parent = env->getActiveObject(parent_id);
+
 	// Do it
 	co->setAttachment(0, "", v3f(0,0,0), v3f(0,0,0));
+	if (parent != NULL)
+		parent->removeAttachmentChild(co->getId());
 	return 0;
 }
 
diff --git a/src/serverobject.h b/src/serverobject.h
index 7204fe3aedd2416922f85b5b05160273987d6edf..597eb63a8180be8bf76fd176a212eb16e6132606 100644
--- a/src/serverobject.h
+++ b/src/serverobject.h
@@ -163,6 +163,12 @@ class ServerActiveObject : public ActiveObject
 	{}
 	virtual void getAttachment(int *parent_id, std::string *bone, v3f *position, v3f *rotation)
 	{}
+	virtual void addAttachmentChild(int child_id)
+	{}
+	virtual void removeAttachmentChild(int child_id)
+	{}
+	virtual std::set<int> getAttachmentChildIds()
+	{ return std::set<int>(); }
 	virtual ObjectProperties* accessObjectProperties()
 	{ return NULL; }
 	virtual void notifyObjectPropertiesModified()