Send only recipe notification changes on inventory download

Lua includes its current cleared recipe list in the download request. The instance plugin diffs it against the stored list and sends back the names to add and remove instead of the full list. Lua rebuilds the full list from the snapshot kept in the download record and runs the existing deserializer, so the end state is unchanged.

Also stop the serializer from appending to the stored failed recipe list in place, which grew the list on every upload without a download in between.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bbassieandClaude Fable 5.1 committed 2026-09-09 21:52:32 +00:00
1 parent 7987a5d925
commit 0d6beeba47
6 files changed
+210 -10

No files matched your search

+49 -5
View File
@@ -533,17 +533,61 @@ function serialize.serialize_crafting_notifications(player, failed)
recipes[recipe.name] = nil
end
-- Convert to a list of names
local recipe_names = failed or {} -- Includes previous recipes if any
local index = #recipe_names + 1
-- Convert to a list of names, including previously failed recipes if any
local recipe_names = {}
for _, name in ipairs(failed or {}) do
recipe_names[#recipe_names + 1] = name
end
for name in pairs(recipes) do
recipe_names[index] = name
index = index + 1
recipe_names[#recipe_names + 1] = name
end
return helpers.encode_string(helpers.table_to_json(recipe_names))
end
--- Current notification state, sent with download requests so the instance plugin only returns the difference
--- @param player LuaPlayer
--- @param failed FailedDeserializationPlayerData?
--- @return string?
function serialize.crafting_notification_snapshot(player, failed)
if not recipe_notifications_api then
return nil
end
return serialize.serialize_crafting_notifications(player, failed and failed.recipe_notifications)
end
--- @class CraftingNotificationDelta
--- @field add string[]? Recipe names to add to the cleared list
--- @field remove string[]? Recipe names to remove from the cleared list
--- Rebuild the full serialized form from the snapshot the delta was computed against
--- @param snapshot string
--- @param serialized_delta string
--- @return string?
function serialize.apply_crafting_notification_delta(snapshot, serialized_delta)
local recipe_names = helpers.json_to_table(assert(helpers.decode_string(snapshot)))
assert(type(recipe_names) == "table", "wrong type decoded from json_to_table")
--- @type CraftingNotificationDelta
local delta = helpers.json_to_table(assert(helpers.decode_string(serialized_delta)))
assert(type(delta) == "table", "wrong type decoded from json_to_table")
local cleared = {}
for _, name in pairs(recipe_names) do
cleared[name] = true
end
for _, name in pairs(delta.remove or {}) do
cleared[name] = nil
end
for _, name in pairs(delta.add or {}) do
cleared[name] = true
end
local merged = {}
for name in pairs(cleared) do
merged[#merged + 1] = name
end
return helpers.encode_string(helpers.table_to_json(merged))
end
--- @param player LuaPlayer
--- @param serialized string
--- @return string[]? failed Recipe names that do not exist