on_selected_entity_changed not raised on controller change
on_selected_entity_changed not raised on controller change
When a player is teleported from one surface to another, the entity under the cursor changes. The rendering in the info box in the right sidebar is updated, but the on_selected_entity_changed event is not raised.
Edit: changed subject due to clarification on the actual scenario as explored below
Edit: changed subject due to clarification on the actual scenario as explored below
Last edited by Therax on Sun Nov 04, 2018 7:59 pm, edited 2 times in total.
Miniloader β UPS-friendly 1x1 loaders
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Re: on_selected_entity_changed not raised on surface change
Thanks for the report however I can't reproduce what you describe. When I test it works correctly and the event is fired.
If you want to get ahold of me I'm almost always on Discord.
Re: on_selected_entity_changed not raised on surface change
A little further testing indicates it seems to be related to setting LuaPlayer.character on the same tick.
For context:
In Pipelayer and Beltlayer, I attach the player to a god controller (player.character = nil), and then teleport them to another surface.
Here I'm simulating that with the console, and using Creative Mode to log events. It shows an on_player_changed_surface, but no on_selected_entity_changed.
For context:
In Pipelayer and Beltlayer, I attach the player to a god controller (player.character = nil), and then teleport them to another surface.
Here I'm simulating that with the console, and using Creative Mode to log events. It shows an on_player_changed_surface, but no on_selected_entity_changed.
Miniloader β UPS-friendly 1x1 loaders
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Re: on_selected_entity_changed not raised on surface change
If I don't change the character, I get some very odd behavior. After the teleport, player.selected returns a valid entity with an empty name. The on_selected_entity_changed event is fired, but not until the next tick.
Miniloader β UPS-friendly 1x1 loaders
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Re: on_selected_entity_changed not raised on surface change
Changing character not firing the event is expected and working correctly. The event is associated with the character entity - not the player.
The other things you describe sound like the spam protection absorbing messages you're trying to print.
The other things you describe sound like the spam protection absorbing messages you're trying to print.
If you want to get ahold of me I'm almost always on Discord.
Re: on_selected_entity_changed not raised on surface change
This is not consistent with the documentation:
on_selected_entity_changed
Called after the selected entity changes for a given player.
Contains
player_index :: uint: The player whose selected entity changed.
last_entity :: LuaEntity (optional): The last selected entity if it still exists and there was one.
It's also not consistent with observed behavior when a player has no character. To remove the spam protection as a factor, here are my experiments with writing to the log, not to the console.
When the player starts out without a character (god controller), on_selected_entity_changed is fired on the following tick:
Code: Select all
901.875 Script @__creative-mode-fix__/scripts/events.lua:1041: T36663 on_player_changed_surface (ID 51)
T36663 (ID 51) "player_index" :: uint: 1
T36663 (ID 51) "surface_index" :: uint: 1
901.876 Script character=game.player.character~=nil before=game.player.selected.name game.player.character=nil game.player.teleport(game.player.position,'beltlayer') after=game.player.selected==nil log(serpent.block{before=before,after=after,character=character}):1: {
after = false,
before = "stone-furnace",
character = false
}
901.876 Script @__creative-mode-fix__/scripts/events.lua:1041: T36663 on_console_command (ID 72)
T36663 (ID 72) "player_index" :: uint: 1
T36663 (ID 72) "command" :: string: "c"
T36663 (ID 72) "parameters" :: string: "character=game.player.character~=nil before=game.player.selected.name game.player.character=nil game.player.teleport(game.player.position,'beltlayer') after=game.player.selected==nil log(serpent.block{before=before,after=after,character=character})"
901.890 Script @__creative-mode-fix__/scripts/events.lua:1041: T36664 on_selected_entity_changed (ID 52)
T36664 (ID 52) "player_index" :: uint: 1
T36664 (ID 52) "last_entity" :: LuaEntity: {type = "furnace", name = "stone-furnace", unit_number = 2, position = {-3, -1}}
Code: Select all
799.692 Script @__creative-mode-fix__/scripts/events.lua:1041: T34965 on_player_changed_surface (ID 51)
T34965 (ID 51) "player_index" :: uint: 1
T34965 (ID 51) "surface_index" :: uint: 1
799.692 Script character=game.player.character before=game.player.selected.name game.player.character=nil game.player.teleport(game.player.position,'beltlayer') after=game.player.selected==nil log(serpent.block{before=before,after=after,character={character}}):1: {
after = true,
before = "stone-furnace",
character = {
{
__self = "userdata: 0x00000298846e79f0"
}
}
}
799.692 Script @__creative-mode-fix__/scripts/events.lua:1041: T34965 on_console_command (ID 72)
T34965 (ID 72) "player_index" :: uint: 1
T34965 (ID 72) "command" :: string: "c"
T34965 (ID 72) "parameters" :: string: "character=game.player.character before=game.player.selected.name game.player.character=nil game.player.teleport(game.player.position,'beltlayer') after=game.player.selected==nil log(serpent.block{before=before,after=after,character={character}})"
Miniloader β UPS-friendly 1x1 loaders
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Re: on_selected_entity_changed not raised on surface change
Then the documentation is incorrect. The event is fired when the thing that owns the entity selector changes what it has selected when it has an associated player.
For character entities that's the character. For the god controller that's the god controller. If a character has no player associated then it won't fire the event. If you change who owns a character the selected entity for that character hasn't changed but the owning player has.
That's just how this event works.
For character entities that's the character. For the god controller that's the god controller. If a character has no player associated then it won't fire the event. If you change who owns a character the selected entity for that character hasn't changed but the owning player has.
That's just how this event works.
If you want to get ahold of me I'm almost always on Discord.
Re: on_selected_entity_changed not raised on surface change
I've still not seen anything that would be classified as a bug.
If you want to get ahold of me I'm almost always on Discord.
Re: on_selected_entity_changed not raised on surface change
Okay, let me see if I understand correctly:Rseding91 wrote: βSun Nov 04, 2018 4:35 pmThen the documentation is incorrect. The event is fired when the thing that owns the entity selector changes what it has selected when it has an associated player.
For character entities that's the character. For the god controller that's the god controller. If a character has no player associated then it won't fire the event. If you change who owns a character the selected entity for that character hasn't changed but the owning player has.
That's just how this event works.
1. An "entity selector" is owned by a controller (character or god controller), not by a player.
2. on_selected_entity_changed is generated when a controller's selection on tick N is different from its selection on tick N-1, and only if the controller has an associated player on both ticks N and N-1.
3. In my use case, on tick N there is a god controller G associated with player P, and on tick N-1 there was a character controller C associated with player P. Since neither G nor C had an associated player on both ticks N and N-1, no event is generated.
4. The surface change is completely unrelated. If the cursor position changes such that a different entity is selected, and this happens on the same tick that a player's controller changes (from character to god controller, or vice versa, or from character to another character), then this is also a scenario where on_selected_entity_changed would not be fired.
Do I have that all correct? This is all pretty counter-intuitive, since from a player's perspective selection is a UI concept tied to the mouse cursor, and is logically assumed to be owned by a connected Player (a disconnected player doesn't have a mouse cursor and can't select anything).
So let's test. Without any change of controller, let's clear the selection. As expected, the selection is restored on the next tick by the UI, and we get two on_selected_entity_changed events:
Code: Select all
799.301 Script script.on_event(defines.events.on_selected_entity_changed, function(e) last_entity_name=e.last_entity and e.last_entity.name or "(none)" s=game.players[e.player_index].selected e.current_selection=s and s.name or "(none)" e.last_entity_name=last_entity_name log(serpent.block(e)) end ):1: {
current_selection = "(none)",
last_entity = {
__self = "userdata: 0x0000019ae7baa460"
},
last_entity_name = "stone-furnace",
name = 52,
player_index = 1,
tick = 39698
}
799.301 Script @__creative-mode-fix__/scripts/events.lua:1041: T39698 on_console_command (ID 72)
T39698 (ID 72) "player_index" :: uint: 1
T39698 (ID 72) "command" :: string: "c"
T39698 (ID 72) "parameters" :: string: "game.player.clear_selected_entity()"
799.317 Script script.on_event(defines.events.on_selected_entity_changed, function(e) last_entity_name=e.last_entity and e.last_entity.name or "(none)" s=game.players[e.player_index].selected e.current_selection=s and s.name or "(none)" e.last_entity_name=last_entity_name log(serpent.block(e)) end ):1: {
current_selection = "stone-furnace",
last_entity_name = "(none)",
name = 52,
player_index = 1,
tick = 39699
}
Code: Select all
1024.850 Script @__creative-mode-fix__/scripts/events.lua:1041: T53231 on_console_command (ID 72)
T53231 (ID 72) "player_index" :: uint: 1
T53231 (ID 72) "command" :: string: "c"
T53231 (ID 72) "parameters" :: string: "game.player.character=nil"
1024.867 Script script.on_event(defines.events.on_selected_entity_changed, function(e) last_entity_name=e.last_entity and e.last_entity.name or "(none)" s=game.players[e.player_index].selected e.current_selection=s and s.name or "(none)" e.last_entity_name=last_entity_name log(serpent.block(e)) end ):1: {
current_selection = "stone-furnace",
last_entity_name = "(none)",
name = 52,
player_index = 1,
tick = 53232
}
If I then move the mouse cursor such that no entity is selected, I get on_selected_entity_changed again, which is expected. However, if I then reassociate with the old character entity (/c game.player.character=old_character), that character's entity selector is still recording that the stone-furnace is selected, and on the next tick I get another on_selected_entity_changed event, with last_entity set to the stone-furnace, even though from the perspective of the player's UI, that stone-furnace hasn't been selected for a long time!
Miniloader β UPS-friendly 1x1 loaders
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Re: on_selected_entity_changed not raised on surface change
One more scenario, where I destroy the selected entity via script. Here, on_selected_entity_changed is fired, but since the entity no longer exists, last_entity is nil, as is the player's current selection:
And again, but where the controller changes in the same tick:
All in all, I guess I can see the logic of how this behavior arises from the idea that the "currently selected entity" is a concept of a character or god controller, not of the UI, a connected player's session, or the long-lived Player which persists while a player is disconnected. But it is all very unintuitive from a player experience perspective, and contradictory to the documentation.
From a mod making perspective, could we get an event that's fired when the controller associated with a player is changed? This would allow mod makers to detect the scenario where a controller changes and the selected entity in the UI changes in the same tick.
Code: Select all
1702.368 Script @__creative-mode-fix__/scripts/events.lua:1041: T93760 on_console_command (ID 72)
T93760 (ID 72) "player_index" :: uint: 1
T93760 (ID 72) "command" :: string: "c"
T93760 (ID 72) "parameters" :: string: "game.player.selected.destroy()"
1702.368 Script script.on_event(defines.events.on_selected_entity_changed, function(e) last_entity_name=e.last_entity and e.last_entity.name or "(none)" s=game.players[e.player_index].selected e.current_selection=s and s.name or "(none)" e.last_entity_name=last_entity_name log(serpent.block(e)) end ):1: {
current_selection = "(none)",
last_entity_name = "(none)",
name = 52,
player_index = 1,
tick = 93760
}
Code: Select all
1770.252 Script @__creative-mode-fix__/scripts/events.lua:1041: T97833 on_console_command (ID 72)
T97833 (ID 72) "player_index" :: uint: 1
T97833 (ID 72) "command" :: string: "c"
T97833 (ID 72) "parameters" :: string: "entity=game.player.selected game.player.character=nil entity.destroy()"
From a mod making perspective, could we get an event that's fired when the controller associated with a player is changed? This would allow mod makers to detect the scenario where a controller changes and the selected entity in the UI changes in the same tick.
Miniloader β UPS-friendly 1x1 loaders
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Re: on_selected_entity_changed not raised on controller change
You're correct on all but 2 things:
* The selected entity is not cleared when the player is disconnected from the character entity
* "The same tick" doesn't matter. The event fires when the entity selector detects a new entity is selected regardless of what tick it happened in.
I'll 'fix' the documentation to mention how it actually works but how it actually works isn't going to change.
I'm unsure on the event when a controller is changed because it changes for many different reasons that the game is not build in a state where it expects mods to be able to break the game and any event fired needs a load of protection built around it to handle everything mods can break when an event is fired.
* The selected entity is not cleared when the player is disconnected from the character entity
* "The same tick" doesn't matter. The event fires when the entity selector detects a new entity is selected regardless of what tick it happened in.
I'll 'fix' the documentation to mention how it actually works but how it actually works isn't going to change.
I'm unsure on the event when a controller is changed because it changes for many different reasons that the game is not build in a state where it expects mods to be able to break the game and any event fired needs a load of protection built around it to handle everything mods can break when an event is fired.
If you want to get ahold of me I'm almost always on Discord.
Re: on_selected_entity_changed not raised on controller change
Ticks I guess matter only in the sense that (I presume) the UI updates the entity selector of the active controller once per tick, so the only way an event can be βmissedβ is if the selection changes on the same tick as a controller change. As far as I can tell, in all other cases there may be an βextraβ event fired, and the last_entity might not be quite what is expected, I.e. when reattaching to a character where that character has a lingering selection.
Okay, I guess itβll just be one of those cases where a mod needs to raise a custom event from a safe point in Lua when it performs an intentional controller change. Thanks for your patience!Rseding91 wrote: βSun Nov 04, 2018 9:34 pmI'll 'fix' the documentation to mention how it actually works but how it actually works isn't going to change.
I'm unsure on the event when a controller is changed because it changes for many different reasons that the game is not build in a state where it expects mods to be able to break the game and any event fired needs a load of protection built around it to handle everything mods can break when an event is fired.
Miniloader β UPS-friendly 1x1 loaders
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground
Bulk Rail Loaders β Rapid train loading and unloading
Beltlayer & Pipelayer β Route items and fluids freely underground