Casting entities to specific classes

Place to get help with not working mods / modding interface.
Post Reply
VampireSilence
Inserter
Inserter
Posts: 26
Joined: Wed Feb 03, 2021 7:54 am
Contact:

Casting entities to specific classes

Post by VampireSilence »

Hello everyone,
i just started modding and i wondered, if i get an entity, i.e. like this:

Code: Select all

local function onPlaceEntity(entity)
    local ent1 = entity
end

script.on_event(defines.events.on_built_entity, function(event) onPlaceEntity(event.created_entity) end, filters)
How do i cast it to a specific derived class of Prototype/Entity?

I need it, because obviously it wont let me change "ent1.energy_source", since Prototype/Entity doesn't include that property. But if i know it being a Prototype/Lamp and i'd like to alter this property, how do i make LUA treat it like that derived class?

TLDR;

How do i make this work?

Code: Select all

local function onPlaceEntity(entity)
    local ent1 = entity
    ent1.energy_source = {anything}
end

script.on_event(defines.events.on_built_entity, function(event) onPlaceEntity(event.created_entity) end, filters)

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2250
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: Casting entities to specific classes

Post by boskid »

This is quite huge misunderstanding of the lua api. You are being confused by the data stage prototypes with the control stage objects. In control stage all the entities have all their fields thrown into catch-all bucket called LuaEntity but some of those fields will complain when used on entity of incorrect type than the fields was implemented for.

VampireSilence
Inserter
Inserter
Posts: 26
Joined: Wed Feb 03, 2021 7:54 am
Contact:

Re: Casting entities to specific classes

Post by VampireSilence »

Ok, so properties like "energy_source" doesn't exist anymore in control stage? How do i change those then?

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2250
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: Casting entities to specific classes

Post by boskid »

You can not. Prototypes can only be specified during data stage. When data stage is done and game is running you cannot change anything prototype related. This is fundamental limitation and its never going to change. When mods are trying to emulate changes in prototype, they have multiple entities defined with different set prototype values and with some magic (scripted entity swap by destroying entity and creating new one) it can be somehow emulated.

VampireSilence
Inserter
Inserter
Posts: 26
Joined: Wed Feb 03, 2021 7:54 am
Contact:

Re: Casting entities to specific classes

Post by VampireSilence »

Do i understand this right that if i got like 200 different "energy_source"s, i need to define 200 different Prototypes and there is no chance of changing this for one specific instance (entity) of that Prototype?

So if i try to change different Properties with i.e. 200, 50 and 100 different options i got to create 200 * 50 * 100 = 1.000.000 different Prototypes to cover all possible combinations?

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2250
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: Casting entities to specific classes

Post by boskid »

Core idea behind prototypes is that they are describing how entities of given type should work, and the prototype itself is shared state between every entity that uses that prototype. It is literally not possible to change prototype in control stage because doing so would 1/ change behavior of every entity of that type on the whole map, 2/ would not be save-load stable because prototypes are not stored inside of the game state. When entity is implemented all the data that can be changed run time are kept inside of the Entity itself, and those that are considered to "never changing" are kept inside of EntityPrototype. Trying to change value that is designed to be not possible to change is literally out of scope. Entity consists of 2 parts: Entity itself (which contains all the data that can be changed and are save-loaded) and EntityPrototype (which constains all the data that cannot be changed and are not saved).

If your solution would need 200 different entity types then you should consider if there are maybe other easier solutions to your issue. 1000000 is obviously not possible because of the limitation of 65k entity types total. Some mods (i guess it was Merging Chests) are sometimes defining 1000+ entity types but they have no other option to work.

VampireSilence
Inserter
Inserter
Posts: 26
Joined: Wed Feb 03, 2021 7:54 am
Contact:

Re: Casting entities to specific classes

Post by VampireSilence »

Yeah i see, so Prototypes and LuaEntities are similar to classes and instances (in like C# or similar).

The workaround i could imagine would be defining "custom"-properties, which are then forced to be added to those changable properties inside the created Entities itself. If thats possible, i could then recode/emulate the behaviour of changing energy_sources within an onTick-Event. But to do so, i need to derive the base classes another time, since their properties-table is protected, am i right?

User avatar
boskid
Factorio Staff
Factorio Staff
Posts: 2250
Joined: Thu Dec 14, 2017 6:56 pm
Contact:

Re: Casting entities to specific classes

Post by boskid »

Swapping entities every tick sounds like really bad idea and you should avoid it at all costs. There are some runtime values of some prototypes (like electric energy interface) that help emulate some dynamic properties of energy sources. For example you can have entity to be of "electric-energy-interface" prototype with "gui_mode" set to "none" in the prototype. This entity can then be placed on the map and its values like buffer size, energy production and consumption can be changed run-time using for example LuaEntity::power_production, LuaEntity::power_usage. If you do not want entity to be of that prototype but still want to use it, you may create a composite entity (which is basically having multiple entities on top and if main entity is deleted you detect this by script and remove the other pieces as well).

User avatar
ptx0
Smart Inserter
Smart Inserter
Posts: 1507
Joined: Wed Jan 01, 2020 7:16 pm
Contact:

Re: Casting entities to specific classes

Post by ptx0 »

boskid wrote:
Sun Mar 14, 2021 9:16 am
Swapping entities every tick sounds like really bad idea and you should avoid it at all costs. There are some runtime values of some prototype types (like electric energy interface) that help emulate some dynamic properties of energy sources. For example you can have entity to be of "electric-energy-interface" prototype type with "gui_mode" set to "none" in the prototype. This entity can then be placed on the map and its values like buffer size, energy production and consumption can be changed run-time using for example LuaEntity::power_production, LuaEntity::power_usage. If you do not want entity to be of that prototype type but still want to use it, you may create a composite entity (which is basically having multiple entities on top and if main entity is deleted you detect this by script and remove the other pieces as well).
the electric energy interface is pretty heavy on update cost when used in excess; see also the Electric Trains mod that has EEIs placed along the rail as overhead wires for transferring energy. it was due to the ElectricNetwork::update routine and chunk updates from having them spread all over the map, if I remember correctly, dragging it down to 36 UPS until I removed all the EEIs.

of course, that's definitely more performant than replacing entities.

VampireSilence
Inserter
Inserter
Posts: 26
Joined: Wed Feb 03, 2021 7:54 am
Contact:

Re: Casting entities to specific classes

Post by VampireSilence »

No no, haha. The user will be able to choose between energy_sources, i doubt someone is able to do so in 60 FPS. Besides that, i only check for changes per tick and update/replace when needed, not every tick. But i think it's easier for me to split buildings in parts and every part has its own Prototype-range, so i can combine buildings instead of properties in control stage.

Post Reply

Return to “Modding help”