diff --git a/game/engine/Object.lua b/game/engine/Object.lua
index 669fef42ed163af7f9eb1d58b65ee20da8dc1738..b1eeee9ee8557d20210551284210761e5a493edf 100644
--- a/game/engine/Object.lua
+++ b/game/engine/Object.lua
@@ -43,7 +43,12 @@ end
 
 --- Gets the full name of the object
 function _M:getName()
-	return self.name
+	local qty = self:getNumber()
+	local name = self.name
+
+	if qty == 1 then return name
+	else return qty.." "..name
+	end
 end
 
 --- Gets the full desc of the object
@@ -91,8 +96,8 @@ function _M:stack(o)
 
 	-- Merge stacks
 	if o.stacked then
-		for i, so in ipairs(o.stacked) do
-			self.stacked[#self.stacked+1] = so
+		for i = 1, #o.stacked do
+			self.stacked[#self.stacked+1] = o.stacked[i]
 		end
 		o.stacked = nil
 	end
diff --git a/game/engine/dialogs/ShowEquipment.lua b/game/engine/dialogs/ShowEquipment.lua
index 5ebb5d0fdd800b52653417f9e904afbb31f47431..b670148d76e2a1f69975fd9753806a9f3e267cfc 100644
--- a/game/engine/dialogs/ShowEquipment.lua
+++ b/game/engine/dialogs/ShowEquipment.lua
@@ -57,9 +57,7 @@ function _M:generateList()
 			for item, o in ipairs(self.actor.inven[inven_id]) do
 				if not self.filter or self.filter(o) then
 					local char = string.char(string.byte('a') + i)
-					local nb = o:getNumber()
-					nb = (nb == 1) and "" or nb.." "
-					list[#list+1] = { name=char..")  "..nb..o:getName(), object=o, inven=inven_id, item=item }
+					list[#list+1] = { name=char..")  "..o:getName(), object=o, inven=inven_id, item=item }
 					chars[char] = #list
 					i = i + 1
 				end
diff --git a/game/engine/dialogs/ShowInventory.lua b/game/engine/dialogs/ShowInventory.lua
index a07e6cd4540c496bf898d5b5655d0806c829f051..07873132a1f04ee4a2e8225b1e8d0cff2841556a 100644
--- a/game/engine/dialogs/ShowInventory.lua
+++ b/game/engine/dialogs/ShowInventory.lua
@@ -97,9 +97,7 @@ function _M:generateList()
 	local i = 0
 	for item, o in ipairs(self.inven) do
 		if not self.filter or self.filter(o) then
-			local nb = o:getNumber()
-			nb = (nb == 1) and "" or nb.." "
-			list[#list+1] = { name=string.char(string.byte('a') + i)..")  "..nb..o:getName(), object=o, item=item }
+			list[#list+1] = { name=string.char(string.byte('a') + i)..")  "..o:getName(), object=o, item=item }
 			i = i + 1
 		end
 	end
diff --git a/game/engine/dialogs/ShowPickupFloor.lua b/game/engine/dialogs/ShowPickupFloor.lua
index ed610862ff3c805cc65ae90ff0a7cecbf4cf78c3..6d56c866bd35ba471a1ed8797b6a04dccdc3f323 100644
--- a/game/engine/dialogs/ShowPickupFloor.lua
+++ b/game/engine/dialogs/ShowPickupFloor.lua
@@ -60,9 +60,7 @@ function _M:generateList()
 		local o = game.level.map:getObject(self.x, self.y, idx)
 		if not o then break end
 		if not self.filter or self.filter(o) then
-			local nb = o:getNumber()
-			nb = (nb == 1) and "" or nb.." "
-			list[#list+1] = { name=string.char(string.byte('a') + i)..")  "..nb..o:getName(), object=o, item=idx }
+			list[#list+1] = { name=string.char(string.byte('a') + i)..")  "..o:getName(), object=o, item=idx }
 			i = i + 1
 		end
 		idx = idx + 1
diff --git a/game/engine/interface/ActorInventory.lua b/game/engine/interface/ActorInventory.lua
index 2eb2046ce2492870fa732d5538e8cd6bce92120f..5caf32b4d72384e630df496265aae10e7c09685c 100644
--- a/game/engine/interface/ActorInventory.lua
+++ b/game/engine/interface/ActorInventory.lua
@@ -96,17 +96,19 @@ end
 --- Removes an object from inventory
 -- @param inven the inventory to drop from
 -- @param item the item id to drop
+-- @param no_unstack if the item was a stack takes off the whole stack if true
 -- @return the object removed or nil if no item existed
-function _M:removeObject(inven, item)
+function _M:removeObject(inven, item, no_unstack)
 	if type(inven) == "number" then inven = self.inven[inven] end
-	local o = inven[item]
-	local o, finish = o:unstack()
+	local o, finish = inven[item], true
+	if not no_unstack then
+		o, finish = o:unstack()
+	end
 	if finish then
 		table.remove(inven, item)
 	end
 
 	-- Do whatever is needed when takingoff this object
-	print("remove object", inven, inven.max, inven.worn, item, o)
 	if inven.worn then self:onTakeoff(o) end
 
 	return o
@@ -217,8 +219,13 @@ function _M:wearObject(o, replace, vocal)
 		-- Warning: assume there is now space
 		self:addObject(self:getInven(o.offslot), o)
 	elseif replace then
-		local ro = self:removeObject(inven, 1)
+		local ro = self:removeObject(inven, 1, true)
+
 		if vocal then game.logSeen(self, "%s wears: %s.", self.name:capitalize(), o:getName()) end
+
+		-- Can we stack the old and new one ?
+		if o:stack(ro) then ro = true end
+
 		-- Warning: assume there is now space
 		self:addObject(inven, o)
 		return ro
@@ -230,7 +237,7 @@ end
 
 --- Takeoff item
 function _M:takeoffObject(inven, item)
-	local o = self:removeObject(inven, item)
+	local o = self:removeObject(inven, item, true)
 	return o
 end
 
@@ -263,7 +270,9 @@ function _M:sortInven(inven)
 	for i = #inven, 1, -1 do
 		-- If it is stackable, look for obejcts before it that it could stack into
 		if inven[i]:stackable() then
+print("sorting", #inven, i, i-1)
 			for j = i - 1, 1, -1 do
+			print("j",j)
 				if inven[j]:stack(inven[i]) then
 					print("Stacked objects", i, inven[i].name, "into", j, inven[j].name)
 					table.remove(inven, i)
diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua
index e5b77b93d027e2de492de0bb0f5d7ce1777fc88f..17f41acb4eaf631f12162e5dbcaeabf97d2bcb1c 100644
--- a/game/modules/tome/class/Object.lua
+++ b/game/modules/tome/class/Object.lua
@@ -74,7 +74,7 @@ end
 
 --- Gets the full name of the object
 function _M:getName()
-	local qty = 1
+	local qty = self:getNumber()
 	local name = self.name
 
 	if not self:isIdentified() and self:getUnidentifiedName() then name = self:getUnidentifiedName() end
@@ -90,7 +90,11 @@ function _M:getName()
 		end)
 	end
 
-	return name
+	if qty == 1 then
+		return name
+	else
+		return qty.." "..name
+	end
 end
 
 --- Gets the full desc of the object
diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua
index bf0b251d7877e9e2f25349c74fd1fddd5e10dfab..6b680b613276611d3d4302686c256c2b52401b07 100644
--- a/game/modules/tome/class/Player.lua
+++ b/game/modules/tome/class/Player.lua
@@ -234,10 +234,12 @@ function _M:playerWear()
 	self:showInventory("Wield/wear object", inven, function(o)
 		return o:wornInven() and true or false
 	end, function(o, item)
+		self:removeObject(self.INVEN_INVEN, item, true)
 		local ro = self:wearObject(o, true, true)
 		if ro then
 			if type(ro) == "table" then self:addObject(self.INVEN_INVEN, ro) end
-			self:removeObject(self.INVEN_INVEN, item)
+		else
+			self:addObject(self.INVEN_INVEN, o)
 		end
 		self:sortInven()
 		self:useEnergy()
diff --git a/game/modules/tome/data/talents/techniques/archery.lua b/game/modules/tome/data/talents/techniques/archery.lua
index 97a6995a843226c3b7aaa9b74e51c832c2b74b58..046b3c11b7ba76cb0344fcb60d17a8f60fb45cda 100644
--- a/game/modules/tome/data/talents/techniques/archery.lua
+++ b/game/modules/tome/data/talents/techniques/archery.lua
@@ -154,7 +154,7 @@ newTalent{
 			o:identify(true)
 			o:forAllStack(function(so) so.cost = 0 end)
 			self:addObject(self.INVEN_INVEN, o)
-			game.logPlayer(self, "You create some ammo: %d %s", o:getNumber(), o:getName())
+			game.logPlayer(self, "You create some ammo: %s", o:getName())
 		else
 			game.logPlayer(self, "You found nothing!")
 		end
diff --git a/ideas/classes.ods b/ideas/classes.ods
index 2480c82ce39e2dc13f1bcf39cd5c7f63eb69ad16..194e657f80c10017014ccba566857bbcad599091 100644
Binary files a/ideas/classes.ods and b/ideas/classes.ods differ