Assign custom value to entity in data-updates.lua, then access it later in code

Place to get help with not working mods / modding interface.
FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2768
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Assign custom value to entity in data-updates.lua, then access it later in code

Post by FuryoftheStars »

Hi, I was wondering, if I was to do something to create some variants on an entity, and added a custom value to that entity, is there a way to later in code check for the existence of this value and even pull it?

For example, if I did this:

Code: Select all

local variant = table.deepcopy(data.raw["type"]["name"])
variant.name = "newname"
variant.custom = value
data:extend(variant)
And then later in control.lua I have something like this:

Code: Select all

local function ON_BUILT(event)
local entity = event.created_entity
How can I check if entity had that custom value assigned to it and then actually use it? I've obviously already discovered that entity.custom doesn't work, and data is no longer accessible (so I can't do data.raw["type"][entity.name]).
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles | New Gear Girl & HR Graphics

User avatar
darkfrei
Smart Inserter
Smart Inserter
Posts: 2904
Joined: Thu Nov 20, 2014 11:11 pm
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by darkfrei »

LuaEntity.html#LuaEntity.prototype

But I want to have a possibility to add custom table for access with scripting.

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by eradicator »

FuryoftheStars wrote:Hi, I was wondering, if I was to do something to create some variants on an entity, and added a custom value to that entity, is there a way to later in code check for the existence of this value and even pull it?
Nope. All irrelevant values are trashed after creating the prototype. There is no method to transcend information from data to control. If it's a hardcoded value you'll just have to hardcode it again into control.

User avatar
Optera
Smart Inserter
Smart Inserter
Posts: 2920
Joined: Sat Jun 11, 2016 6:41 am
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by Optera »

Order string used to be exploitable to move arbitrary strings between data and control phase.
I used it to read wagon capacities before we had proper prototype api access. If you dig through the code of early LTN you may be able to find it. Attached code snippet.

Data:

Code: Select all

local inventory = {
    type = "flying-text",
    name = "ltn-inventories["..wagon.name.."]",
    time_to_live = 0,
    speed = 1,
    order = tostring(inventorySize)
  }

data:extend({inventory})
Control:

Code: Select all

local INVSTRING = "ltn-inventories[[name]]"

function getInventorySize(name)
  local reference = game.entity_prototypes[INVSTRING:gsub("%[name%]", tostring(name))]
  if type(reference) == "table" then
    InventoryLookup[name] = tonumber(reference.order)
    return tonumber(reference.order)
   end
   return 0
end

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by eradicator »

With the order string approach there's always the lingering possibility of someone changing the value you originally read, so that the value in the order string you stored is incorrect though. And officially policy on that is "if you need to read currently unavailable prototype data in control stage post a request on the Simple Requests Thread.

User avatar
Optera
Smart Inserter
Smart Inserter
Posts: 2920
Joined: Sat Jun 11, 2016 6:41 am
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by Optera »

Is it possible to pass data between data and control phase with som hack? Yes.
Is it better to request adding a clean api access to the data? Definitely.

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2768
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by FuryoftheStars »

Thanks for the replies. This is too bad. Currently I'm using the prototype/entity name and then using string.find and string.match where appropriate, but it looks messy.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles | New Gear Girl & HR Graphics

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by eradicator »

Just out of curiosity what exactly are you trying to implement? Maybe someone here can come up with a better solution than data hacking.

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2768
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by FuryoftheStars »

Not sure if I can explain it correctly, but I'll try.

I'm essentially modding a mod at the moment. I'm creating a mod (currently for personal use, but that may change) that uses evildogbot100's mod Diesel Locomotive as a base. I'm creating (currently) 3 locomotives that use his system, each with (hopefully) different qualities, pros & cons, etc. This also includes different fuel tank sizes for each one. In order for his system to work of allowing the locomotive to use fluids, he needs to create proxy tanks (pre-establishing their capacity) and then in control.lua has hardcoded "entity.name = " checks to see if the locomotive is one of his, and if so, hardcoded assignment of the proxy tanks to it in the appropriate circumstances.

Because I'm adding additional locomotives, obviously his "entity.name = " checks will fail to identify mine. I've gotten around this by modifying his code with string.find for now.

Then there's the matter of my locomotives having different tank sizes. I created the appropriate proxy tanks in my mod, but need to modify his code to support adding different sized tanks depending on which locomotive is queued up in the code. For now I do this by adding the tank size to the name of my locomotive and the proxy tanks I created, then in his code use string.match to find and pull this number so it can in turn be used to match up the correct proxy tank.

So, for example, I'll do something like this in data-update.lua during the creation process of the locomotives

Code: Select all

newloco1.name = "Diesel-Locomotive-fluid-locomotive-"..NEWLOCO1_TANK_CAPACITY.."-newloco1" -- The additional "newloco1" in the name is meant as a further identifier in case two locomotives have the same tank capacity value
and fluid tanks

Code: Select all

tank.name = "Diesel-Locomotive-proxy-tank-"..NEWLOCO1_TANK_CAPACITY.."-"..i
Then in his control.lua, I have to modify his code so where it checks to see if it's a valid locomotive, instead of

Code: Select all

entity.name == "Diesel-Locomotive-fluid-locomotive"
it's now

Code: Select all

string.find(entity.name, "Diesel%-Locomotive%-fluid%-locomotive") ~= nil
Then, where it checks for and creates/destroys the proxy tanks, I have to modify this

Code: Select all

if not (proxy.tank[i].name == "Diesel-Locomotive-proxy-tank-"..tank_type)
to this

Code: Select all

if not (proxy.tank[i].name == "Diesel-Locomotive-proxy-tank-"..(string.match(loco.name, "Diesel%-Locomotive%-fluid%-locomotive%-(%d+%-)%w+") or "")..tank_type) then
Obviously I feel all of this would just be easier if during creation of the locomotive (at least) I could just do this:

Code: Select all

newloco1.fluid_tank_size = NEWLOCO1_TANK_CAPACITY
And then in control.lua, I could use the presence of that value to tell if it's a locomotive requiring a fluid tank and even directly query it for use in assigning the correct proxy tank.

Ultimately, once I'm done with these edits, I plan on suggesting them to evildogbot100 to make his mod more compatible with anyone else wanting to expand off from it, but also to make it so if he makes an edit to his mod, I won't need find and port this edit into my current alternate version of his mod. :) I want to try and make it as "fool proof" as possible first, though, before calling it good and sending the edits to him. But as is it just seems messy. :/
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles | New Gear Girl & HR Graphics

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by eradicator »

Hm. Sounds like a classical case of wanting a remote.interface. I.e. you want his mod to keep a mapping table {LocoName = TankSize} with a remote.call() function to add your own Locomotives and tanks to it. That also makes detecting the entity trivial with "if mappingtable[entity.name] then" instead of having to string.find() name bits.

As you're not trying to store any dynamic data from the data stage i guess storing the tank size into the locos order string/corpse name/whatever would "work" fine without any obvious complications too, but does have the hacked-with-an-axe feeling to it ^^.

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2768
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by FuryoftheStars »

eradicator wrote:Hm. Sounds like a classical case of wanting a remote.interface.
Hmm... that seems promising. :) I haven't done a whole lot of modding with this game, yet, so I'm still learning the available features, how to do things, terms, etc. Thankfully scripting isn't foreign to me, though my last use of Lua was about 8-10 years ago. lol
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles | New Gear Girl & HR Graphics

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2768
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by FuryoftheStars »

Awesome, the remote.interface appears to have worked! So much cleaner looking. :) Took me a while to find the time.... :P

One trip-up I've hit, I need to start a new game for the remote.interface to be defined (I create it in the on_init event, currently). Is there a better place to define this so it'll work on saves that had this mod loaded in it already, or is that what the migration scripts are for? Gonna have to research those... :/
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles | New Gear Girl & HR Graphics

User avatar
eradicator
Smart Inserter
Smart Inserter
Posts: 5207
Joined: Tue Jul 12, 2016 9:03 am
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by eradicator »

on_init is only called when a mod is first added to a world. After that use on_configuration_changed (you'll have to trigger it by increasing the mod version if you want to test it in your dev environment).

Data-Lifecycle <-Read this once per week. :P
LuaBootstrap.on_configuration_changed

Also i'm not really sure (50% confidence) but i think adding a remote interface is actually allowed outside of events. Calling them is not.

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2768
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by FuryoftheStars »

Excellent, thanks for this! When I have more time I'll implement this. I had put it in the on_init because that was what evildogbot100 was using for everything. I didn't see an on_configuration_changed event.

Reading through the provided links real quick, the Data-Lifecycle page does mention in section 4 that the remote table is available and assuming each section is listed in order of execution, I believe you are correct that it should be able to be setup outside of an event.

You've been a great help, eradicator. Thank you!
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles | New Gear Girl & HR Graphics

FuryoftheStars
Smart Inserter
Smart Inserter
Posts: 2768
Joined: Tue Apr 25, 2017 2:01 pm
Contact:

Re: Assign custom value to entity in data-updates.lua, then access it later in code

Post by FuryoftheStars »

Everything appear to be running smoothly now! And to confirm, yes, you can add interfaces to remote from outside of the functions.
My Mods: Classic Factorio Basic Oil Processing | Sulfur Production from Oils | Wood to Oil Processing | Infinite Resources - Normal Yield | Tree Saplings (Redux) | Alien Biomes Tweaked | Restrictions on Artificial Tiles | New Gear Girl & HR Graphics

Post Reply

Return to “Modding help”