diff --git a/game/engines/default/engine/PlayerProfile.lua b/game/engines/default/engine/PlayerProfile.lua
index c61a46c6d916979335953aeea0f367405924f9df..3103fcd5c3649c48ec6e59945640af2207329a56 100644
--- a/game/engines/default/engine/PlayerProfile.lua
+++ b/game/engines/default/engine/PlayerProfile.lua
@@ -627,6 +627,20 @@ function _M:registerNewCharacter(module)
 	return uuid
 end
 
+function _M:getCharball(id_profile, uuid)
+	if not self.auth then return end
+	local dialog = Dialog:simpleWaiter("Retrieving data from the server", "Retrieving...")
+	core.display.forceRedraw()
+
+	local data = nil
+	core.profile.pushOrder(table.serialize{o="GetCharball", module=game.__mod_info.short_name, uuid=uuid, id_profile=id_profile})
+	self:waitEvent("GetCharball", function(e) data = e.data end, 30000)
+
+	dialog:done()
+	if not data then return end
+	return data
+end
+
 function _M:registerSaveCharball(module, uuid, data)
 	if not self.auth or not self.hash_valid then return end
 	core.profile.pushOrder(table.serialize{o="SaveCharball",
diff --git a/game/profile-thread/Client.lua b/game/profile-thread/Client.lua
index f1d9517369daa3b8a51d348a567d6ff8bfff9644..6b2de89e5aff547184f42aec41d3342a1e01ee31 100644
--- a/game/profile-thread/Client.lua
+++ b/game/profile-thread/Client.lua
@@ -352,6 +352,19 @@ function _M:orderSaveCharball(o)
 	cprofile.pushEvent("e='SaveCharball' ok=true")
 end
 
+function _M:orderGetCharball(o)
+	self:command("CHAR", "GETCHARBALL", o.id_profile, o.uuid, o.module)
+	if self:read("200") then
+		local _, _, size = self.last_line:find("^([0-9]+)")
+		size = tonumber(size)
+		if not size or size < 1 then return end
+		local body = self:receive(size)
+		cprofile.pushEvent(string.format("e='GetCharball' id_profile=%q uuid=%q data=%q", o.id_profile, o.uuid, body))
+	else
+		cprofile.pushEvent(string.format("e='GetCharball' id_profile=%q uuid=%q unknown=true", o.id_profile, o.uuid))
+	end
+end
+
 function _M:orderCurrentCharacter(o)
 	self:command("CHAR", "CUR", table.serialize(o))
 	self.cur_char = o