yairm210 / Unciv

Open-source Android/Desktop remake of Civ V
Mozilla Public License 2.0
8.54k stars 1.58k forks source link

Wrong city-state shown in notification log after being destroyed #11486

Closed fincentxyz closed 6 months ago

fincentxyz commented 7 months ago

Is there an existing issue for this?

Game Version

4.11.4

Describe the bug

In one of my games Babylon attacked and destroyed the city-state of Belgrade. When Belgrade was destoryed, a notification appears saying the city-state of Kathmandu has been destroyed. Clicking on this notification points towards Belgrade.

The city-state of Kathmandu was already destroyed and puppeted earlier in the game by Babylon.

Steps to Reproduce

  1. Load the save file
  2. Go to Belgrade in the top left corner of the map
  3. Click next turn
  4. Belgrade is destroyed, but the notification says Kathmandu is destroyed

Screenshots

No response

Link to save file

https://hastebin.com/share/mafawewapu.bash

Operating System

Android

Additional Information

Had to use a paste website because the save file is longer than 65536 characters.

yairm210 commented 7 months ago

Wow! Can you please provide the autosave of the turn before, so we can debug how this happened?

fincentxyz commented 7 months ago

Wow! Can you please provide the autosave of the turn before, so we can debug how this happened?

Ah crap, I do not have access to those autosaves anymore... I already started a new game, I guess they have been overwritten... I did not know providing a save more turns prior to a bug occuring is useful for debugging. I will remember this for the next time I submit a bug report!

I hope this save and bug report is still somewhat useful for now.

SomeTroglodyte commented 7 months ago

The notification is correct.

Load your save, go to diplomacy though the "Belgrade" city's menu -> Belgrade the City belongs to Kathmandu the Nation. How you managed to do that is another matter... Look at the replay: Border changes colour from turn 212 to turn 213 - Kathmandu the Nation conquered Belgrade then lost Kathmandu the City to Babylon on turn 253.

In other words: Not city destroyed but city-state destroyed - key wording. Should we rename City-States that happen to survive losing their Capital to maybe "Ex-Kathmandu"?[^1]

[^1]: Or patterned after "The ~Jo... pardon, -~ Artist Formerly Unknown As X"?

fincentxyz commented 7 months ago

The notification is correct.

Load your save, go to diplomacy though the "Belgrade" city's menu -> Belgrade the City belongs to Kathmandu the Nation. How you managed to do that is another matter... Look at the replay: Border changes colour from turn 212 to turn 213 - Kathmandu the Nation conquered Belgrade then lost Kathmandu the City to Babylon on turn 253.

In other words: Not city destroyed but city-state destroyed - key wording. Should we rename City-States that happen to survive losing their Capital to maybe "Ex-Kathmandu"?1

Wow, great find! I did not know city-states could do that, haha.

SomeTroglodyte commented 7 months ago

did not know city-states could do that

They can, though it needs several unlikely happenstances. You seen them conquering another city from time to time, but they always raze and go back to their one-loneliness. In this case, they couldn't - either because it's forbidden to raze an original capital, or because they lost their own before they could raze, or both.

I'll leave this open - somebody decide a) Rare and fine as is b) Implement hint in such a case - change notification text to express they lost their last city but it wasn't their own original capital - if and only if that is the case. Either only for CS or for all Nations?

yairm210 commented 7 months ago

I'm definitely fine with it as-is, but having the city-state AI change the name to "new X" would be a cool Easter egg for this edge case

SomeTroglodyte commented 7 months ago

Easter egg

Playing to Temptation, eh? Well, changing Nation.name or civName is out of the question. Regrettably - if we had that open feature where a Nation could be played by more than one Civilization, possibly with different Leaders - then we'd probably already have the flexibility...

So, a displayName... With civName having 498 'value-read' or 'receiver' places in our code... Could be a chore to find all UI-going places.

Uh, and civName should definitely have a Kdoc - and be private set.

Like this: ```patch Subject: [PATCH] civName linting --- Index: tests/src/com/unciv/logic/map/TileImprovementConstructionTests.kt IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/tests/src/com/unciv/logic/map/TileImprovementConstructionTests.kt b/tests/src/com/unciv/logic/map/TileImprovementConstructionTests.kt --- a/tests/src/com/unciv/logic/map/TileImprovementConstructionTests.kt (revision 008fbea81788b1b39caffeda5b35e5762e662704) +++ b/tests/src/com/unciv/logic/map/TileImprovementConstructionTests.kt (date 1713709184698) @@ -56,7 +56,7 @@ tile.setTransients() if (improvement.uniqueTo != null) { - civInfo.civName = improvement.uniqueTo!! + civInfo.setNameForUnitTests(improvement.uniqueTo!!) } val canBeBuilt = tile.improvementFunctions.canBuildImprovement(improvement, civInfo) @@ -92,7 +92,7 @@ for (improvement in testGame.ruleset.tileImprovements.values) { if (!improvement.uniques.contains("Can only be built on [Coastal] tiles")) continue - civInfo.civName = improvement.uniqueTo ?: "OtherCiv" + civInfo.setNameForUnitTests(improvement.uniqueTo ?: "OtherCiv") val canBeBuilt = coastalTile.improvementFunctions.canBuildImprovement(improvement, civInfo) Assert.assertTrue(improvement.name, canBeBuilt) } @@ -104,7 +104,7 @@ for (improvement in testGame.ruleset.tileImprovements.values) { if (!improvement.uniques.contains("Can only be built on [Coastal] tiles")) continue - civInfo.civName = improvement.uniqueTo ?: "OtherCiv" + civInfo.setNameForUnitTests(improvement.uniqueTo ?: "OtherCiv") val canBeBuilt = tile.improvementFunctions.canBuildImprovement(improvement, civInfo) Assert.assertFalse(improvement.name, canBeBuilt) } @@ -114,7 +114,7 @@ fun uniqueToOtherImprovementsCanNOTBeBuilt() { for (improvement in testGame.ruleset.tileImprovements.values) { if (improvement.uniqueTo == null) continue - civInfo.civName = "OtherCiv" + civInfo.setNameForUnitTests("OtherCiv") val tile = tileMap[1,1] val canBeBuilt = tile.improvementFunctions.canBuildImprovement(improvement, civInfo) Assert.assertFalse(improvement.name, canBeBuilt) @@ -165,7 +165,7 @@ tile.resource = "Sheep" tile.setTransients() tile.addTerrainFeature("Hill") - civInfo.civName = "Inca" + civInfo.setNameForUnitTests("Inca") for (improvement in testGame.ruleset.tileImprovements.values) { if (!improvement.uniques.contains("Cannot be built on [Bonus resource] tiles")) continue Index: tests/src/com/unciv/testing/TestGame.kt IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/tests/src/com/unciv/testing/TestGame.kt b/tests/src/com/unciv/testing/TestGame.kt --- a/tests/src/com/unciv/testing/TestGame.kt (revision 008fbea81788b1b39caffeda5b35e5762e662704) +++ b/tests/src/com/unciv/testing/TestGame.kt (date 1713709184746) @@ -133,7 +133,7 @@ val civInfo = Civilization() civInfo.nation = nation civInfo.gameInfo = gameInfo - civInfo.civName = nation.name + civInfo.setNameForUnitTests(nation.name) if (isPlayer) civInfo.playerType = PlayerType.Human civInfo.setTransients() Index: core/src/com/unciv/logic/civilization/Civilization.kt IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/core/src/com/unciv/logic/civilization/Civilization.kt b/core/src/com/unciv/logic/civilization/Civilization.kt --- a/core/src/com/unciv/logic/civilization/Civilization.kt (revision 008fbea81788b1b39caffeda5b35e5762e662704) +++ b/core/src/com/unciv/logic/civilization/Civilization.kt (date 1713709504227) @@ -58,6 +58,7 @@ import com.unciv.models.translations.tr import com.unciv.ui.components.extensions.toPercent import com.unciv.ui.screens.victoryscreen.RankingType +import org.jetbrains.annotations.VisibleForTesting import kotlin.math.max import kotlin.math.min import kotlin.math.roundToInt @@ -141,7 +142,16 @@ /** The Civ's gold reserves. Public get, private set - please use [addGold] method to modify. */ var gold = 0 private set + + /** The Civ's name + * + * - must always be equal to Nation.name (except in the unit test code, where only local consistency is needed) + * - used as uniquely identifying key, so no two players can used the same Nation + * - Displayed and translated as-is + */ var civName = "" + private set + var tech = TechManager() var policies = PolicyManager() var civConstructions = CivConstructions() @@ -701,6 +711,11 @@ //region state-changing functions + @VisibleForTesting + fun setNameForUnitTests(name: String) { + civName = name + } + /** This is separate because the REGULAR setTransients updates the viewable ties, * and updateVisibleTiles tries to meet civs... * And if the civs don't yet know who they are then they don't know if they're barbarians =\ Index: tests/src/com/unciv/logic/map/UnitMovementTests.kt IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/tests/src/com/unciv/logic/map/UnitMovementTests.kt b/tests/src/com/unciv/logic/map/UnitMovementTests.kt --- a/tests/src/com/unciv/logic/map/UnitMovementTests.kt (revision 008fbea81788b1b39caffeda5b35e5762e662704) +++ b/tests/src/com/unciv/logic/map/UnitMovementTests.kt (date 1713709184754) @@ -176,7 +176,7 @@ fun canNOTPassThroughTileWithEnemyUnits() { val barbCiv = Civilization() barbCiv.gameInfo = testGame.gameInfo - barbCiv.civName = Constants.barbarians // they are always enemies + barbCiv.setNameForUnitTests(Constants.barbarians) // they are always enemies barbCiv.nation = Nation().apply { name = Constants.barbarians } testGame.gameInfo.civilizations.add(barbCiv) ```

...?

yairm210 commented 7 months ago

Nonono change the city name!! That's already built in and supported

SomeTroglodyte commented 7 months ago

you mean in this case, rename the City "Belgrade" which was formerly owned and founded by Belgrade the Nation, and is now the last bastion of the Nation Kathmandu - to - "New Kathmandu (formerly known as Belgrade)" (...or... to "Belgrade (last bastion of Kathmandu, the wussies that managed to lose their name-giving capital)" ... :thinking: )...

Won't change the observation of this issue - the notification doesn't display any city name, it just has a city-pointing LocationAction. Becomes clearer only after clicking it.

Also, I don't think CityButton is able to wrap...?

Seems to me some more effort is involved anyway.

SomeTroglodyte commented 7 months ago

... and translatability of that easter-egg name, and the "city names exhausted" feature and its non-translatability, ...

screenshot ![image](https://github.com/yairm210/Unciv/assets/63000004/d73e15ec-fde3-4e6f-b5eb-7af017b1de31)
save ``` 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 ```

(Thank Yair for that console, for without, it would have been a nightmare to stage such a save)

SomeTroglodyte commented 7 months ago

Force-wrapping that (\n in the name) isn't too pretty but bearable?: image