I used Claude to see what had changed. This was the response.
To summarise what the actual Factorio 2.0 breaking change was: tile ghosts were simply dropped from event.entities in selection events. The fix was just one extra find_entities_filtered{type = "tile-ghost"} call to fetch them separately and merge them in.
in events.lua
Change
function on_player_selected_area(event, ignore_tiles)
if event.item ~= NAME.tool.ghost_counter then return end
local ghosts, requests = get_selection_counts(event.entities, ignore_tiles)
to
function on_player_selected_area(event, ignore_tiles)
if event.item ~= NAME.tool.ghost_counter then return end
local entities = event.entities
if not ignore_tiles then
local tile_ghosts = event.surface.find_entities_filtered{
type = "tile-ghost",
area = event.area
}
for _, e in pairs(tile_ghosts) do
table.insert(entities, e)
end
end
local ghosts, requests = get_selection_counts(entities, ignore_tiles)