City map in city dialog: working tile sometimes not updated
Launch Freeciv 2.6.0-beta2, gui-gtk-3.0 client.
- Open attached savegame, take player pi and start
- Open Gao's city dialog
- In the city map, click on the city, this organizes tiles automatically
- Click on the grassland working tile to free it
=> nothing happens, the grassland still appears working.
- Close the city dialog and reopen it. The grassland working tile has changed. The actions worked as expected but the city map was not redrawn because production didn't change.
#1 Updated by Jacob Nevins over 2 years ago
What seems to be going wrong for me is that the initial click on the city centre to auto-arrange citizens does not cause the city map to be updated. For me, the savegame starts with the right-center tile (due east of city centre) worked; auto-arrange changes this to the tile southeast of the city centre (which I can see on the main map immediately with View / City Production Levels enabled), but the map in the city dialog doesn't reflect this. If I subsequently click on the grassland that appears to be work (east) nothing happens, of course, because it isn't. Clicking on the tile that's really worked (SE) does update the display.
It seems to be client-independent; I can reproduce it with all of freeciv-gtk3, -gtk2, -qt, and -sdl2.
#3 Updated by Jacob Nevins over 2 years ago
Here is a guess at what is going on.
PACKET_TILE_INFOs convey information about changes to which tiles are worked by which cities, which will be a natural consequence of auto-arranging workers.
I went looking for the mechanism by which PACKET_TILE_INFOs could cause an open city dialog to be refreshed, and failed to find such a mechanism. CITY_INFO and CITY_SHORT_INFO do, though. (I think the key function that causes a city dialog refresh is refresh_city_dialog().)
In this case, the tile previously chosen (E) and the tile chosen by auto-arrange (SE), while different, have the exact same terrain so give the exact same bonus to the city. So it's plausible that there is no net change to the city parameters at all, so we never get as far as triggering refresh_city_dialog() from a city packet.
And indeed, if I use the editor to make the SE tile different (add Resources), then this symptom goes away, supporting this theory.
We need to make changes to worked tiles (and in principle other tile changes) able to trigger a city dialog refresh. For protocol-frozen branches the only way is to have handle_tile_info() look at whether it's a tile relevant to a current city dialog or something.
(On later branches, I vaguely wondered about changing the protocol to put a bitmap of worked tiles in the city packet, but in principle the city dialog cares about other tile changes -- if the terrain changed, or another city started working a tile, the city dialog needs a refresh. So that's probably a non-starter.)
#4 Updated by Jacob Nevins over 2 years ago
- File m-30-26-25-refresh-city-dialog-worked-tiles.patch m-30-26-25-refresh-city-dialog-worked-tiles.patch added
- Status changed from New to Resolved
- Assignee set to Jacob Nevins
- Target version set to 2.5.11
have handle_tile_info() look at whether it's a tile relevant to a current city dialog or something
The trick here would be finding out which cities have ptile in their map cheaply. But I can't think of a cheap way to do that; I think we'd have to either iterate over all cities or iterate outward from ptile to the max city radius. Neither sounds like a thing we'd want the client doing on every PACKET_TILE_INFO.
However, in this specific case we already know the IDs of the affected cities (from the 'worked' field), so we can just call refresh_city_dialog() on those. That is pretty cheap; it sets a flag in the city structure, and the GUI's idle callback will eventually iterate over all cities looking for that flag (which was probably going to happen anyway).
The attached patch does this. I've briefly tested that it resolves the original symptom, but not tested it any more thoroughly that than. If it is to go in 2.5.11 it could do with some more exercise than that.
I think that should completely fix the common case of clicking auto-arrange in a city dialog not updating that dialog. It may not update adjacent cities' dialogs though, and there are certainly remaining situations where a tile change ought to be reflected in an open city dialog but isn't.
It might also improve the odds of a city dialog being updated if a hostile unit moves onto a worked city tile. That should trigger a worked-tile change.