Robots, entities and mining. But mostly robots.

Place to get help with not working mods / modding interface.
Post Reply
User avatar
Reinard-kun
Inserter
Inserter
Posts: 21
Joined: Wed Jan 14, 2015 7:35 pm
Contact:

Robots, entities and mining. But mostly robots.

Post by Reinard-kun »

Greetings, fellow factorians!

I've searched through the webs and was surprised by how little information there is about Factorio's LuaEvents. Yes, most of them are pretty obvious, like on_tick :Р But there is one specific event that I just can't get the grasp of. I'm talking about on_robot_mined.
So, what does the official lua-api/factorio have to say about it? It's called when a robot mines an entity, contains event.robot -> LuaEntity and event.item_stack -> LuaItemStack. While it is actually called when it should be, it returns something weird. This event.item_stack thing does not behave like LuaItemStack. It cannot be set, cannot be cleared e.c.t. In other words, it looks like it is read-only, and that is really weird.

OK, but why exactly do I need this stack? Why can't I just use event.robot.get_inventory(1)[1]? Well, because it doesn't bloody work. It seems that when on_robot_mined is happening, there is nothing in the inventory of a robot. So, problem is that I can't access this item (that represents an entity just mined) in any way.

Now, let me show you some tests:
test 1
test 2
As you can see, there is definitely something weird with all of this. And it stops me from doing my thing, which is to make a handler that replaces item X with Y, when it is mined by a bot. I hope you people can help me (and many others, who will one day search for the same question).
Rational thinking is awesome, except if you're dealing with women.


User avatar
Adil
Filter Inserter
Filter Inserter
Posts: 945
Joined: Fri Aug 15, 2014 8:36 pm
Contact:

Re: Robots, entities and mining. But mostly robots.

Post by Adil »

Well, itemstacks are weird, they don't exist outside the containing entity or inventory, so the 'mined' events give you purely informational data. (It is not actual itemstack but an ordinary lua table with a couple fields copied from the stack object that does not exist)

The robot inventory is not in defines, so it is probably not meant to be fiddled with.
So if you want to do it so that robots mined specific item from entity, set the mining_result of the entity to it (in prototypes).

As for userdata, lua has a bunch of own datatypes (table, number, string, function) it knows all the stuff about what and how to do with them. And lua has userdata, to lua it is just a bile of bytes it doesn't know what to do with, so it can only store its reference somewhere. However when you're creating that data in external code (C++), you can define its metatable, so that when lua tries to read or call some field, it can call functions from that metatable. And functions in that metatable are usually written with knowledge of what is going on with this chunck of data and how to deal with underlying C++ program, which actually owns the data in question.

As I've said, item_stacks don't exist on their own, and since robot inventory isn't meant to be tampered with, someone has apparently forgot to slap metatable atop of the items in it.

Might be a valid interface request.
I do mods. Modding wiki is friend, it teaches how to mod. Api docs is friend too...
I also update mods, some of them even work.
Recently I did a mod tutorial.

User avatar
Reinard-kun
Inserter
Inserter
Posts: 21
Joined: Wed Jan 14, 2015 7:35 pm
Contact:

Re: Robots, entities and mining. But mostly robots.

Post by Reinard-kun »

Supercheese wrote:Use on_robot_pre_mined instead.
Sadly, it won't work. You can check this out to get a clear picture of what I'm trying to do.
EDIT: I might just cancel deconstruction for now and allow only mining by hand. That might work for now.
Adil wrote:The robot inventory is not in defines, so it is probably not meant to be fiddled with.
So if you want to do it so that robots mined specific item from entity, set the mining_result of the entity to it (in prototypes).
This is sad. I want it to return different items depending on certain conitions...
Adil wrote:Might be a valid interface request.
And a proper Class:new and Class:copy for every single Factorio class.

Also, the more I think of it - the more I feel like devs just got stuck in legacy code and some things can't be fixed without rewriting the game completely. And the fact that everything is defined in C, yet it is being called in Lua (without proper meta) is aking me sad. And yes I know that it might be the proper way to make a new library, but it feels like at first there was no modding support intended and now it causes all sorts of problems.
Rational thinking is awesome, except if you're dealing with women.

User avatar
aubergine18
Smart Inserter
Smart Inserter
Posts: 1264
Joined: Fri Jul 22, 2016 8:51 pm
Contact:

Re: Robots, entities and mining. But mostly robots.

Post by aubergine18 »

The more I've worked with the Lua interface provided by the game, the more I've come to trust the devs' decision making and coding skills.

Lua itself doesn't have any proper way of defining OOP-style classes, or ECMA-style prototype chains, despite appearances when first starting to play with it. There's always alternatives to using classes, etc., and they are usually much faster than their OOP counterparts.
Better forum search for modders: Enclose your search term in quotes, eg. "font_color" or "custom-input" - it prevents the forum search from splitting on hypens and underscores, resulting in much more accurate results.

User avatar
Adil
Filter Inserter
Filter Inserter
Posts: 945
Joined: Fri Aug 15, 2014 8:36 pm
Contact:

Re: Robots, entities and mining. But mostly robots.

Post by Adil »

Reinard-kun wrote:Also, the more I think of it - the more I feel like devs just got stuck in legacy code and some things can't be fixed without rewriting the game completely. And the fact that everything is defined in C, yet it is being called in Lua (without proper meta) is aking me sad. And yes I know that it might be the proper way to make a new library, but it feels like at first there was no modding support intended and now it causes all sorts of problems.
Now this would more fit for a direct letter to devs.
But I personally feel that you're just trying to force patterns of one framework onto another, without learning the workings of the latter.
The modding support with lua was in since the early versions of the game and people did find it sufficient to do stuff. Not to the same extent as if having access to the sources, but still.
I do mods. Modding wiki is friend, it teaches how to mod. Api docs is friend too...
I also update mods, some of them even work.
Recently I did a mod tutorial.

Supercheese
Filter Inserter
Filter Inserter
Posts: 841
Joined: Mon Sep 14, 2015 7:40 am
Contact:

Re: Robots, entities and mining. But mostly robots.

Post by Supercheese »

Ok, just brainstorming here:

Maybe you use on_robot_pre_mined, check the entity information & store needed data, then destroy the entity before the robot is able to pick it up, immediately drop an "item-on-ground" entity right in the place of the old entity that contains the relevant information (i.e. health), and immediately mark that item-on-ground for deconstruction.

That might sufficiently simulate a robot deconstructing an entity.

Pseudo-code:

Code: Select all

on_robot_pre_mined

local stack = {name = ..., count = 1, health = calculateHealth(entity.fluidbox.blah, ...) }
local position = entity.position
local surface = entity.surface

entity.destroy()

local item = entity.surface.create_entity{position = position, name = "item-on-ground" (or maybe it's "item-entity", not sure),  item-entity = stack }

item.mark_for_deconstruction()

end

User avatar
Reinard-kun
Inserter
Inserter
Posts: 21
Joined: Wed Jan 14, 2015 7:35 pm
Contact:

Re: Robots, entities and mining. But mostly robots.

Post by Reinard-kun »

Supercheese wrote:Maybe you use on_robot_pre_mined, check the entity information & store needed data, then destroy the entity before the robot is able to pick it up, immediately drop an "item-on-ground" entity right in the place of the old entity that contains the relevant information (i.e. health), and immediately mark that item-on-ground for deconstruction.

That might sufficiently simulate a robot deconstructing an entity.
That doesn't sound so bad, actually. But I think instead of destroying an entity it's better to robot.clear_items_inside(), because if you destroy an entity it seems that it's data is lost. Anyway, your code seems legit, I'll go try to do something with it. The only thing I'm really concerned about is what happens when multiple bots mine on the same tick, if it's even possible.
EDIT: I tested it, sadly robot.clear_items_inside() doesn't work and surface.create_entity can only make SimpleItemStack AND it's read-only, so I can't modify it before it's picked up.
Rational thinking is awesome, except if you're dealing with women.

Post Reply

Return to “Modding help”