Extending usefulness of linked inventory (and script inventory)

Place to ask discuss and request the modding support of Factorio. Don't request mods here.
Honktown
Smart Inserter
Smart Inserter
Posts: 1045
Joined: Thu Oct 03, 2019 7:10 am
Contact:

Extending usefulness of linked inventory (and script inventory)

Post by Honktown »

Goal: Have a persistent LuaInventory held in code that is also compatible with an entity (at least writable to)
Two methods, which currently don't work:

Method 1) Create linked chest, use link_id as identification, and get_inventory(defines.inventory.chest) as LuaInventory. Destroy chest.
Problem: LuaInventory is invalid as soon as chest is destroyed, even though linked inventory persists.
Example Command
Method 2) Create a script_inventory, and use inventory.link_id (a newly implemented value) as the index. This allows writing this inventory to a linked container, as well as if it were implemented for linked-container inventories.

Looking over the wiki page for a linked container: https://wiki.factorio.com/Prototype/LinkedContainer, there is this:
"The link IDs are per prototype and force, so only containers with the same ID, same prototype name and same force will share inventories."
Good: details on how inventories can be stored (which makes the initial simple method, unreasonable)
Bad: a script inventory has none of these properties, and can be of any size

This implies a potentially quick implementation:
Part 1)
local inventory, link_index = game.create_linked_inventory(force, EntityPrototypeIdentification)
Part 2)
linked inventory allowed to be valid outside of the entity.

Optional helper 3)
link_id available on the inventory
Optional helper 4)
game.get_linked_inventory(force, prototype, link_id) -> inventory?

If a LuaInventory from a linked container also persisted as a valid inventory, then Method 1 would be "the worse way" of using Method 2 to create an inventory that is:
persistent (valid object over repeated use, usable by mods)
can be created via code or taken from a compatible entity
can be pushed back onto an entity from code
And with optional helper 4)
can be gotten easily if relevant data is stored or available from remote calls, events, a referenced linked container (with force, name, and link_id, or inventory and inventory.link_id), etc

The behavior from the example code for Method 1 implies a linked inventory is only "exposed" when it's linked to an inventory.entity_owner. Breaking this requirement changes existing behavior, but does allow for the above benefits. Exposing a linked inventory *only* via game.get_linked_inventory() which doesn't have an entity_owner or mod_owner doesn't have this problem (though the object was created by a mod, so most of what is desired could be implemented via extending a script inventory, including mod_owner).

One consideration for bugs or behavior changes:
If the LuaInventory object is persistently valid, then LuaInventory.entity_owner becomes less predictable for a linked inventory. If the inventory is taken from a chest, should it have an entity owner, or just a link_id (if implemented)? If it had an entity owner, then it could become nil if the entity is destroyed or disconnected, but what happens if the inventory link is used again? Still nil, or would the object acquire the last-assigned entity, or hell, a table of all entities using it somewhere?
I have mods! I guess!
Link
User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 3321
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: Extending usefulness of linked inventory (and script inventory)

Post by boskid »

I am mostly skipping through the content

Inventories are not targetable, LuaInventory has to be binding to some concept that is targetable and has inventories.

If you obtain inventory by querying LuaEntity, the LuaInventory will be binding to an entity and it becomes invalid when entity is destroyed. If you want to obtain a slightly more persistent LuaInventory to that linked inventory, you may use LuaForce::get_linked_inventory, this will be binding to {ForceID, EntityID, linkID}. LuaInventory obtained from linked container is binding to entity and as such if the linkID in the entity would change, the inventory targeted by LuaInventory will also change.
Post Reply

Return to “Modding interface requests”