[2.0.43] inconsistencies between LuaRecord <-> LuaItemStack

Bugs that are actually features.
User avatar
SunBlade
Burner Inserter
Burner Inserter
Posts: 17
Joined: Mon Jan 15, 2018 8:27 am
Contact:

[2.0.43] inconsistencies between LuaRecord <-> LuaItemStack

Post by SunBlade »

Issues
while creating my mod i ran into some inconsistencies.
LuaRecord and LuaItemStack expose mostly the same modding interface, but there are some jarring differences.
  • LuaRecord
    1. 'name' field is missing. Should be prototype name.
    2. 'type' field gives prototype name. Should be prototype type.
    3. 'valid_for_read' field is missing. Should be bool.
  • LuaItemStack
    1. 'valid_for_write' field is missing. Should be bool.
    2. 'contents' field is missing for blueprint books. Should be array[LuaItemStack].
Don't know how much of that falls into the realm of bugfixing. But the most aggravating one is definitely LuaRecord::type.


How to reproduce/test
  1. load the supplied example save with some prepared books and planners. Or create some yourself.
  2. execute the following command.

    Code: Select all

    /c local function dump(v)
    	local t = serpent.serialize(v,{comment=false,sortkeys=false,sparse=true,compact=true,indent="\t"})
    	for _,p in pairs(game.connected_players) do
    		p.print(t,{game_state=false,skip=defines.print_skip.never})
    	end
    	return log(t)
    end
    local function getter(t,k) return t[k] end
    local function get(t,k)
    	local _,r = pcall(getter,t,k)
    	return r==nil and "nil" or r
    end
    script.on_event(defines.events.on_player_cursor_stack_changed,function(ev)
    	local p = game.get_player(ev.player_index)
    	local i = p.cursor_record or p.cursor_ghost or (p.cursor_stack.valid_for_read and p.cursor_stack)
    	if not i then return end
    	return dump{
    		hand = i,
    		item = {
    			name = get(i,"name"),
    			type = get(i,"type"),
    			valid_for_read = get(i,"valid_for_read"),
    			valid_for_write = get(i,"valid_for_write"),
    			contents = get(i,"contents"),
    		},
    	}
    end)
  3. picking up planners and books gives output like this in con, log and chat.

    Code: Select all

    hand="[LuaItemStack: 1x {deconstruction-planner, normal}]",
    item={
    	name="deconstruction-planner",
    	type="deconstruction-item",
    	valid_for_read=true,
    	valid_for_write="LuaItemStack doesn't contain key valid_for_write.",
    	contents="LuaItemStack doesn't contain key contents."
    }
    
    hand="[LuaRecord: deconstruction planner ID=2 in game shelf]",
    item={
    	name="LuaRecord doesn't contain key name.",
    	type="deconstruction-planner",
    	valid_for_read="LuaRecord doesn't contain key valid_for_read.",
    	valid_for_write=true,
    	contents="Record is not a BlueprintBookRecord."
    }
    
    
    hand="[LuaItemStack: 1x {blueprint-book, normal}]",
    item={
    	name="blueprint-book",
    	type="blueprint-book",
    	valid_for_read=true,
    	valid_for_write="LuaItemStack doesn't contain key valid_for_write.",
    	contents="LuaItemStack doesn't contain key contents."
    }
    
    
    hand="[LuaRecord: book ID=22 inside of a book ID=18 inside of a book ID=8 in game shelf]",
    item={
    	name="LuaRecord doesn't contain key name.",
    	type="blueprint-book",
    	valid_for_read="LuaRecord doesn't contain key valid_for_read.",
    	valid_for_write=true,
    	contents={
    		"[LuaRecord: blueprint ID=23 inside of a book ID=22 inside of a book ID=18 inside of a book ID=8 in game shelf]",
    		"[LuaRecord: deconstruction planner ID=24 inside of a book ID=22 inside of a book ID=18 inside of a book ID=8 in game shelf]",
    		"[LuaRecord: upgrade planner ID=25 inside of a book ID=22 inside of a book ID=18 inside of a book ID=8 in game shelf]",
    		"[LuaRecord: book ID=26 inside of a book ID=22 inside of a book ID=18 inside of a book ID=8 in game shelf]"
    	}
    }
Attachments
factorio-current.log
(13.14 KiB) Downloaded 8 times
[item=blueprint-book] example.zip
(392.14 KiB) Downloaded 8 times
Live your life, you got only one.
User avatar
raiguard
Factorio Staff
Factorio Staff
Posts: 719
Joined: Wed Dec 13, 2017 8:29 pm
Contact:

Re: [2.0.43] inconsistencies between LuaRecord <-> LuaItemStack

Post by raiguard »

This is not a bug - these objects are very different internally and therefore their Lua APIs are also different.

It is a bit of a pain, but you will need to write your own wrappers if you want a consistent API between the two.

You can differentiate between the two with the object_name field, which will give you LuaItemStack or LuaRecord so you can figure out which API to use.
Don't forget, you're here forever.
User avatar
SunBlade
Burner Inserter
Burner Inserter
Posts: 17
Joined: Mon Jan 15, 2018 8:27 am
Contact:

Re: [2.0.43] inconsistencies between LuaRecord <-> LuaItemStack

Post by SunBlade »

raiguard wrote: Fri Apr 04, 2025 9:51 pm... very different internally ...
So, if i understand this correctly you have two entirely separate systems, which do essentially the same? If your endpoints have at least some commonality between both systems, wouldn't it make more sense to spent a few more resources into merging both systems, than to maintain both?
And since it looks like you can seamlessly convert between the two (no hitches when moving books with over a thousand blueprints between inventory and shelf), that raises even more questions. Why don't you convert them when a script needs them? Why don't you make shelves be normal LuaInventory, one attached to the game and one for each player and maybe even one for each force?
What's the benefit of separating LuaRecord and LuaItemStack?
please do not take this as a rant, i am genuinely interested to understand why the systems are that way.


raiguard wrote: Fri Apr 04, 2025 9:51 pm... You can differentiate between the two with the object_name field ...
yea, that's what i am currently doing. but i expected something mundane as getting the prototype name to be consistent.
Live your life, you got only one.
Rseding91
Factorio Staff
Factorio Staff
Posts: 15329
Joined: Wed Jun 11, 2014 5:23 am
Contact:

Re: [2.0.43] inconsistencies between LuaRecord <-> LuaItemStack

Post by Rseding91 »

In the simplest terms: they’re different because they’re different. They each have their uses and features and work as designed. They aren’t the same thing because they aren’t the same things. In the same way that a semi truck and a pickup truck are *similar* but are not the same thing.
If you want to get ahold of me I'm almost always on Discord.
User avatar
SunBlade
Burner Inserter
Burner Inserter
Posts: 17
Joined: Mon Jan 15, 2018 8:27 am
Contact:

Re: [2.0.43] inconsistencies between LuaRecord <-> LuaItemStack

Post by SunBlade »

Rseding91 wrote: Sat Apr 05, 2025 1:02 am... they’re different ...
yes, i assumed as much, putting two different lua wrapper over the same class would not make much sense. i also assume that internally LuaRecord and LuaItemStack have no subclasses. from my perspective LuaItemStack looks like a class only referencing other objects and LuaRecord looks more like a data heavy struct.


Rseding91 wrote: Sat Apr 05, 2025 1:02 am... a semi truck and a pickup truck ...
since i have zero interest in cars, my knowledge there is very limited. still here are some uses and features from the top of my head: a semi truck is normally used in commercial scenarios, a pickup truck is more for private uses. while semi trucks usually have a higher carrying capacity, pickup trucks are often faster and more manoeuvrable. while there is no clear cut metric or feature that sets those two apart, most people use size and carrying capacity to differentiate between the two.


Rseding91 wrote: Sat Apr 05, 2025 1:02 am... each have their uses and features ...
now i am even more curious. is LuaRecord a variable length struct without pointers so it (de)serialises as fast as read and write speeds allow? does LuaItemStack loose pointer integrity when put outside the game world? is one of them immune to circular references or pointer loss?
what are those uses and features? as you can see my imagination is already running wild.


Rseding91 wrote: Sat Apr 05, 2025 1:02 am... In the simplest terms ...
sorry, it seems like i failed to convey my intentions. i am digging for complex knowledge from people with more experience than me.



i am fascinated by lua as a scripting language and factorio is one of the best games i play. i am a compelled optimiser, so ... while writing my mod i always feel like something is off about the blueprint library. my optimiser sense is tingling the whole time. shelves feel like inventories, but aren't. book records feel like items with inventories, but aren't. blueprint and planner records feel like items, but aren't. this goes very deep into the uncanny valley for me. am i to crept out by this, to the point where my intuition fails me? i would like to make sure, but don't know how. that is why i have all those questions floating in my head.



also: i am socially inept. if i am a nuisance please tell me. i promise you can't hurt my feelings with words. others have tried and failed miserably.
Live your life, you got only one.
Post Reply

Return to “Not a bug”