Page 1 of 1

[0.13.17] LuaForce as table key not reliable

Posted: Mon Aug 22, 2016 10:54 pm
by mknejp
Consider this simple test setup

Code: Select all

local forces = { }

script.on_load(function()
  forces[game.forces.player] = true
end)

script.on_event(defines.events.on_built_entity, function(event)
  for _, player in pairs(game.players) do
    player.print(type(forces[event.created_entity.force]))
  end
end)
When placing an entity as the player I expect this to print "boolean" but it prints "nil" instead. I know I can use the force's name as table key but this behavior is quite surprising.

Re: [0.13.17] LuaForce as table key not reliable

Posted: Mon Aug 22, 2016 11:47 pm
by Nexela
Game is nil in on_load

viewtopic.php?f=25&t=25463#p160508

Re: [0.13.17] LuaForce as table key not reliable

Posted: Tue Aug 23, 2016 12:03 am
by mknejp
This is for demonstration only. The same happens with this command

Code: Select all

/c local t = {}; t[game.forces.player] = true; game.player.print(type(t[game.player.force]))
prints "nil"

Re: [0.13.17] LuaForce as table key not reliable

Posted: Tue Aug 23, 2016 12:09 am
by DaveMcW
mknejp wrote:/c local t = {}; t[game.forces.player] = true; game.player.print(type(t[game.player.force]))
Try using the same index for both.

Re: [0.13.17] LuaForce as table key not reliable

Posted: Tue Aug 23, 2016 12:11 am
by mknejp
DaveMcW wrote:
mknejp wrote:/c local t = {}; t[game.forces.player] = true; game.player.print(type(t[game.player.force]))
Try using the same index for both.
Doesn't change the result. Besides they both refer to the same force so regardless how you obtain the force handle they should compare as equivalent, which they do using == but not as table key.

Re: [0.13.17] LuaForce as table key not reliable

Posted: Tue Aug 23, 2016 12:30 am
by Rseding91
Don't use the force object as the key. The object is a different new one every time you get the object from the game state.

Use the force name - which can't change.

Re: [0.13.17] LuaForce as table key not reliable

Posted: Tue Aug 23, 2016 12:33 am
by mknejp
Rseding91 wrote:Don't use the force object as the key. The object is a different new one every time you get the object from the game state.

Use the force name - which can't change.
It's good that this advice is now hidden somewhere deep in the bug report forum. Can you throw an error if an attempt is made to use a force as key? Then at least we know if we do something we're not supposed to instead of having a latent bug that one may or may not notice for ages.

Re: [0.13.17] LuaForce as table key not reliable

Posted: Tue Aug 23, 2016 12:39 am
by mknejp
By the way I would still consider this a bug. If the game understands that value1 == value2 then it should follow the equivalence principle and also have the same hash.

Re: [0.13.17] LuaForce as table key not reliable

Posted: Tue Aug 23, 2016 2:24 am
by TruePikachu
mknejp wrote:
Rseding91 wrote:Don't use the force object as the key. The object is a different new one every time you get the object from the game state.

Use the force name - which can't change.
It's good that this advice is now hidden somewhere deep in the bug report forum. Can you throw an error if an attempt is made to use a force as key? Then at least we know if we do something we're not supposed to instead of having a latent bug that one may or may not notice for ages.
The better thing to do is to note it in the API reference, since it could theoretically be useful to use a force object as a key for some applications.

Re: [0.13.17] LuaForce as table key not reliable

Posted: Tue Aug 23, 2016 3:39 am
by Rseding91
TruePikachu wrote:
mknejp wrote:
Rseding91 wrote:Don't use the force object as the key. The object is a different new one every time you get the object from the game state.

Use the force name - which can't change.
It's good that this advice is now hidden somewhere deep in the bug report forum. Can you throw an error if an attempt is made to use a force as key? Then at least we know if we do something we're not supposed to instead of having a latent bug that one may or may not notice for ages.
The better thing to do is to note it in the API reference, since it could theoretically be useful to use a force object as a key for some applications.
It has worked this way since the lua API was a thing and almost no one has issues with it.

It's not specific to LuaForce - every single one of the "objects" returned by the API works the same way. 0.12 introduced the ability to compare them with == and before that there was no way to know if internally 2 references to some objects where the same internally.