Need a little help caching tag names

Hello, I’ve been writing a few scripts to improve my Blender->Aseprite workflow and I’ve run into a weird issue where I just can’t cache any tag property.

If I create a local table storing the original tag objects in the sprite and then I modify those tags in some way, like adding a new frame or changing the name of some tag via code, the cached tags are overwritten for some reason. I’ve tried setting a local scope and encapsulating the cached copy inside a function that simply returns its own copy, but none of this seems to work. I even tried creating separate tables copying the values of each parameter (name, fromFrame.frameNumber, toFrame.frameNumber), thinking “it’s just strings and integers, how are they going to be overwritten”, with no luck, which is what threw me entirely off.

And this doesn’t happen with other cache tables that store “dynamic” information that can be modified via a script, like a layer’s visibility. Caching that visibility in a table, enabling all layers’ visibility then restoring the visibility from that table works perfectly fine.

I thought maybe Lua had some peculiarities so I ran some tests, and this script works exactly as it should. The list is modified and restored from a backup.

Could someone point me in the right direction? I had zero experience with Lua and the Aseprite API until a few days ago so it’s possible I’m missing something extremely basic.

You can find the scripts at this URL with a sample file. The one that’s just not working properly is debugTags: https://github.com/IgnacioLuxP/Aseprite-ScriptTest

(I wasn’t sure if copypasting a bunch of buggy code was proper forum discipline)

Well, after a lot of reading, googling and frustrating trial and error it seems I managed to get it to work. Each tag is stored in a table containing 3 values (name, first and last frames), which in turn is saved in a larger table holding all these “objects” (I don’t know what to call them).

It still feels like I’m missing something important, like where a do/end should go but it should suffice for now. This seems slightly convoluted way by C# standards (only other language I know a little of) but it works…

The key points are these (the whole file with a little test can be found in the GIT link in the OP):

--little cached tags metaclass
local CachedTag = {
	name = "",
	from = 0,
	to = 0,
}

--constructor for creating instances of cached tag object
function CachedTag:new (name, from, to)
	local o = {}
	setmetatable(o, CachedTag)
	o.name = name
	o.from = from
	o.to = to
	return o
end

--function to cache all tags in the original sprite
function saveBaseTags(tags)
	local cachedTags = {}
	for i in ipairs(tags) do
		cachedTags[i] = CachedTag:new(tags[i].name, tags[i].fromFrame.frameNumber, tags[i].toFrame.frameNumber)
	end
	return cachedTags
end

I hope someone will clarify what I was doing wrong originally (I swear I tried local tempTags = sprite.tags multiple times without success) and I’ll be able to share a cleaner version of the actual script I was working on (which was for transposing a sprite with some layers (“columns”) into “rows”, with appropriate tags and frame spacing).