entity.id, a unique, persistent ID
entity.id, a unique, persistent ID
Add a unique and persistent identifier for entities.
Re: entity.id, a unique, persistent ID
This may not be necessary if entity references in the implementation do not change from load to load — in which case, entity.id already exists: this_entity.id == this_entity. Otherwise, it would be a great addition.
Re: entity.id, a unique, persistent ID
As long as you don't use it as a key , entity == entity 2 works.
Still, I'd like it at least for LuaPlayer, since player_index and player.name might change in MP games.
Still, I'd like it at least for LuaPlayer, since player_index and player.name might change in MP games.
Re: entity.id, a unique, persistent ID
You can do player == player2 to check if they're the same player.Choumiko wrote:As long as you don't use it as a key , entity == entity 2 works.
Still, I'd like it at least for LuaPlayer, since player_index and player.name might change in MP games.
You can do anything == anything - inventory references, entity references, GUI references - they all work with the == operator.
If you want to get ahold of me I'm almost always on Discord.
Re: entity.id, a unique, persistent ID
Across play sessions?Rseding91 wrote:You can do player == player2 to check if they're the same player.
You can do anything == anything - inventory references, entity references, GUI references - they all work with the == operator.
Also, having entities be usable as keys is very, very handy. That way, I don't have to search through the table of paired values, seeking a particular entity. I can just say some_table[entity_as_key] and be done with it.
Re: entity.id, a unique, persistent ID
Yes across play sessions. When you compare 2 Factorio LuaObjects using == it calls an internal compare (__eq meta method if you know Lua).Wyrm wrote:Across play sessions?Rseding91 wrote:You can do player == player2 to check if they're the same player.
You can do anything == anything - inventory references, entity references, GUI references - they all work with the == operator.
Also, having entities be usable as keys is very, very handy. That way, I don't have to search through the table of paired values, seeking a particular entity. I can just say some_table[entity_as_key] and be done with it.
I do however agree a unique ID per entity would be useful. Entities with an owner (entities with a force) already have such an ID and it would be simple to expose it. It wouldn't work for *everything* - trees wouldn't have it, items on the ground wouldn't have it but most entities that you'd want to store would have it.
If you want to get ahold of me I'm almost always on Discord.
- ArderBlackard
- Long Handed Inserter
- Posts: 74
- Joined: Thu May 05, 2016 12:41 pm
- Contact:
Re: entity.id, a unique, persistent ID
Sorry for resurrecting the topic, but this request seems to be still quite relevant.
While the equality comparison between entity references works fine, it's very difficult to use entities as table keys. Two entities which are equal are not necessary the same and thus are considered different as table keys.
It also seems that the API functions always return different wrapper tables so even the code like this (assuming we point mouse at some entity):
will print "nil" instead of "dummy"
while, of course, this:
will print "true"
As a result the only workaround I see so far is to store entities in arrays and find them using equality comparison, while using keys should be a more performant approach I guess.
While the equality comparison between entity references works fine, it's very difficult to use entities as table keys. Two entities which are equal are not necessary the same and thus are considered different as table keys.
It also seems that the API functions always return different wrapper tables so even the code like this (assuming we point mouse at some entity):
Code: Select all
/c map = {};
map[game.player.selected] = "dummy";
game.player.print( tostring( map[game.player.selected] ) )
while, of course, this:
Code: Select all
/c game.player.print( tostring( game.player.selected == game.player.selected ) )
As a result the only workaround I see so far is to store entities in arrays and find them using equality comparison, while using keys should be a more performant approach I guess.
Gib dich hin bis du Glück bist
Re: entity.id, a unique, persistent ID
As I've already said: there's no property or ID to expose that would solve this. Most entities in a given map don't have any unique identifier about them other than the memory address they have.
If an ID was added to every single entity we'd definitely need to make it an 8 byte unsigned int due to the amount of entities created and destroyed over the course of a game.
The map I have going has roughly 5.5 million entities on it. At 8 bytes per entity that would add 8 * 5,500,000 bytes of space to store the ID in RAM and in the save file. That would convert to roughly 42 megabytes of space required in the save file just to save IDs if each entity had one.
If an ID was added to every single entity we'd definitely need to make it an 8 byte unsigned int due to the amount of entities created and destroyed over the course of a game.
The map I have going has roughly 5.5 million entities on it. At 8 bytes per entity that would add 8 * 5,500,000 bytes of space to store the ID in RAM and in the save file. That would convert to roughly 42 megabytes of space required in the save file just to save IDs if each entity had one.
If you want to get ahold of me I'm almost always on Discord.
Re: entity.id, a unique, persistent ID
If id was writable but defaulted to nil, how much space would that take on an unmodded save?
I'm thinking something like:
It would only assign an id when a modder specifically asked for it.
I'm thinking something like:
Code: Select all
function entity.getId()
if not this.id then
this.id = get_unique_id()
end
return this.id
end
- ArderBlackard
- Long Handed Inserter
- Posts: 74
- Joined: Thu May 05, 2016 12:41 pm
- Contact:
Re: entity.id, a unique, persistent ID
Rseding91, thanks for the answer! Hardly ever we will need an ID of every entity in the game including all the doodads
But you have said earlier that
And aside from the idea above just another crazy one:
But as I've stated already, it's just a crazy idea
But you have said earlier that
If implemented, this would be quite enough, as tracking "large" long-living objects is the most common usage I can imagine for these IDs.Rseding91 wrote:Entities with an owner (entities with a force) already have such an ID and it would be simple to expose it.
And aside from the idea above just another crazy one:
Still there is some way to detect whether two entities are equal or not. I mean the __eq metamethod is implemented somehow and it compares something (presumably the related c++ structures pointers/addresses?) Then these addresses seem to be good candidates for entity IDs (if they are not being moved in memory over time of course), dont' they? They may even be obfuscated in some way to prevent from exposing raw addresses (like xor-ing them with some value). Of course they would not be preserved across game sessions, but it's still something. And as DaveMcW suggested, the actual entity ID value can be lazy-computed and stored only per-request.Rseding91 wrote:As I've already said: there's no property or ID to expose that would solve this. Most entities in a given map don't have any unique identifier about them other than the memory address they have.
But as I've stated already, it's just a crazy idea
Gib dich hin bis du Glück bist
Re: entity.id, a unique, persistent ID
Memory addresses aren't save load or MP stable so they won't work for key values. They work fine for equality comparison because that's done as a one-off thing and not something you can "save" - you can only save the result of which will be identical every time it's run on any system.
If you want to get ahold of me I'm almost always on Discord.
- ArderBlackard
- Long Handed Inserter
- Posts: 74
- Joined: Thu May 05, 2016 12:41 pm
- Contact:
Re: entity.id, a unique, persistent ID
Thanks for the explanation. Quite reasonable, I see
Anyway it would be nice to have access to the IDs of the object that actualy have them. Hope we will get this functionality sooner or later.
Anyway it would be nice to have access to the IDs of the object that actualy have them. Hope we will get this functionality sooner or later.
Gib dich hin bis du Glück bist
Re: entity.id, a unique, persistent ID
I have a compromise proposal. Have a field in the data prototypes which turns on persistent entity ids for an entity (like persistent_id = true or something). By default, no entities have it. Then, if a modder wants a particular entity type to have persistent ids, they can set the data prototype field and enable it for individual entities, otherwise, regular users don't experience overhead.
- ArderBlackard
- Long Handed Inserter
- Posts: 74
- Joined: Thu May 05, 2016 12:41 pm
- Contact:
Re: entity.id, a unique, persistent ID
From what I have read on the forum I guess that entities in C++ code have a rigid format without ability to change their number of fields. Not like in Lua, where you can add and remove fields in runtime. Even having a field for "per-request-computed" ID will still require memory for at least pointer-size variable in C++ entity representation.
So each entity either have or have not an ID and it's only a matter of exposing to Lua those IDs that exist.
Of course, it's just a speculation, I don't know the internal structures for sure.
So each entity either have or have not an ID and it's only a matter of exposing to Lua those IDs that exist.
Of course, it's just a speculation, I don't know the internal structures for sure.
Gib dich hin bis du Glück bist
Re: entity.id, a unique, persistent ID
Alternatively there could be some hashing method that generates a hash depending on all it's unique properties (i.e position, name, etc).
Re: entity.id, a unique, persistent ID
That's the hack modders use now. But it doesn't work for anything that moves.ljdp wrote:Alternatively there could be some hashing method that generates a hash depending on all it's unique properties (i.e position, name, etc).
Re: entity.id, a unique, persistent ID
Well position isnt something that should be used in hashes anyways. No non static data should be used in an id hash. In a different game i've modded that uses lua I just had my get_id(entity) function check for the presence of my id variable. If it was nil I would simply assign an unused id. I dont know if Factorio will serialize random mod added variables on default classes.DaveMcW wrote:That's the hack modders use now. But it doesn't work for anything that moves.ljdp wrote:Alternatively there could be some hashing method that generates a hash depending on all it's unique properties (i.e position, name, etc).
- ArderBlackard
- Long Handed Inserter
- Posts: 74
- Joined: Thu May 05, 2016 12:41 pm
- Contact:
Re: entity.id, a unique, persistent ID
Factorio prevents setting any unknown fields to default entities, not to mention serialization.
Gib dich hin bis du Glück bist
Re: entity.id, a unique, persistent ID
All properties available in the Factorio Lua API are backed by some C++ class that holds and maintains the data so runtime properties are not supported. The only way to add new properties in is to change the source code and recompile the program on our end.seronis wrote:Well position isnt something that should be used in hashes anyways. No non static data should be used in an id hash. In a different game i've modded that uses lua I just had my get_id(entity) function check for the presence of my id variable. If it was nil I would simply assign an unused id. I dont know if Factorio will serialize random mod added variables on default classes.DaveMcW wrote:That's the hack modders use now. But it doesn't work for anything that moves.ljdp wrote:Alternatively there could be some hashing method that generates a hash depending on all it's unique properties (i.e position, name, etc).
If you want to get ahold of me I'm almost always on Discord.
Re: entity.id, a unique, persistent ID
It doesn't need to have a unique id for everything. For example, there's no reason why iron plates on a belt should have one.Rseding91 wrote:As I've already said: there's no property or ID to expose that would solve this. Most entities in a given map don't have any unique identifier about them other than the memory address they have.
If an ID was added to every single entity we'd definitely need to make it an 8 byte unsigned int due to the amount of entities created and destroyed over the course of a game.
The map I have going has roughly 5.5 million entities on it. At 8 bytes per entity that would add 8 * 5,500,000 bytes of space to store the ID in RAM and in the save file. That would convert to roughly 42 megabytes of space required in the save file just to save IDs if each entity had one.
Surely you can add a unique id to specific classes like trains?