Yeah, already got the history event bit in there since I wanted to make sure they were recorded right in legends mode.
I still can't figure out why the first one you make in a world ends up turning into a slab-duplicate that crashes unless removed.
If the code on your github repo is up-to-date, it's probably because of the way you try to find and initialise the artifact record. You go through
df.global.world.artifacts.all looking for an id of 0, which will be the first artifact created during world generation, which is probably a slab containing the secrets of life and death. Then, for some reason, you change its
item pointer to point to a newly-heap-allocated item (which I think you make as a copy of the item you already made earlier? I'm not totally sure how the Lua API does that table-initialisation thing) that isn't in the items list. You never get around to inserting it into the items list, so you've got an artifact record pointing to an object that's out in the void, that the game otherwise doesn't know about. Since it isn't in the items list, it won't get serialised out when you save the game. The original artifact with id 0
will get serialised out to the save file, though, except its
general_ref_is_artifactst will be pointing to an artifact record that doesn't point to it, and instead points to a non-existant item.
EDIT: Also, I totally forgot the part that causes it to only happen once: you set the id of
artifacts.all[0] to
global.artifact_next_id, so when you next try to create a new item it'll skip over it. But, from what I can tell, it should just go through the whole loop and do nothing, because it shouldn't ever find an artifact with an ID of 0 (unless
{new=df.artifact_record} initialises the id to 0, instead of -1 like
df.artifact_record:new() does).
You should ditch that whole loop. If you insert a new artifact record with
'#' as the index, you don't need to find it, it'll always be at the end of the vector (so,
df.global.world.artifacts.all[#df.global.world.artifacts.all - 1] or
df.global.world.artifacts.all[df.global.artifact_next_id]). No need to find it with a loop looking for an unintialised ID (which would be -1, not 0, as you're doing there; not expected, I know, but it's how dfhack initialises objects). And, set the artifact record's item field to
base, which is the item you already created with
createItem(), then set it up from there, don't try to create another new object.
Also, you weirdly call new() on the artifact record and history events records, which shouldn't even work in a sane language, but in Lua probably means that a pair of vectors get heap allocated and then immediately discarded. That probably wouldn't cause a crash on its own, just a tiny memory leak, but you should remove the "
df.global.world.artifacts.all:new()" and "
df.global.world.history.events:new()" lines just to be a good citizen, anyway.