Closed hackedpassword closed 1 year ago
Hit next turn, sudden crash. That's all there is to it. :/
Same crash.
It seems some city states or civilization will be destroyed (by another non-player civilization) in next turn, but throws NPE when updating ~trading list~ trade route .
java.lang.NullPointerException
at com.unciv.logic.city.CityStats.getStatsFromTradeRoute(CityStats.kt:103)
at com.unciv.logic.city.CityStats.updateBaseStatList(CityStats.kt:460)
at com.unciv.logic.city.CityStats.update(CityStats.kt:499)
at com.unciv.logic.city.CityStats.update$default(CityStats.kt:491)
at com.unciv.logic.city.CityConstructions.updateUniques(CityConstructions.kt:499)
at com.unciv.logic.city.CityConstructions.updateUniques$default(CityConstructions.kt:495)
at com.unciv.logic.city.CityConstructions.removeBuilding(CityConstructions.kt:492)
at com.unciv.logic.civilization.Civilization.moveCapitalTo(Civilization.kt:813)
at com.unciv.logic.civilization.Civilization.moveCapitalToNextLargest(Civilization.kt:819)
at com.unciv.logic.city.managers.CityConquestFunctions.moveToCiv(CityConquestFunctions.kt:263)
at com.unciv.logic.city.City.moveToCiv(City.kt:498)
at com.unciv.logic.city.managers.CityConquestFunctions.conquerCity(CityConquestFunctions.kt:103)
at com.unciv.logic.city.managers.CityConquestFunctions.puppetCity(CityConquestFunctions.kt:136)
at com.unciv.logic.city.City.puppetCity(City.kt:491)
at com.unciv.logic.automation.civilization.NextTurnAutomation.onConquerCity(NextTurnAutomation.kt:1142)
at com.unciv.logic.battle.Battle.conquerCity(Battle.kt:621)
at com.unciv.logic.battle.Battle.attack(Battle.kt:151)
at com.unciv.logic.battle.Battle.attackOrNuke(Battle.kt:93)
at com.unciv.logic.battle.Battle.moveAndAttack(Battle.kt:48)
at com.unciv.logic.automation.unit.BattleHelper.tryAttackNearbyEnemy(BattleHelper.kt:30)
at com.unciv.logic.automation.unit.BattleHelper.tryAttackNearbyEnemy$default(BattleHelper.kt:16)
at com.unciv.logic.automation.unit.UnitAutomation.tryAttacking(UnitAutomation.kt:358)
at com.unciv.logic.automation.unit.UnitAutomation.automateUnitMoves(UnitAutomation.kt:200)
at com.unciv.logic.automation.civilization.NextTurnAutomation.automateUnits(NextTurnAutomation.kt:1004)
at com.unciv.logic.automation.civilization.NextTurnAutomation.automateCivMoves(NextTurnAutomation.kt:87)
at com.unciv.logic.civilization.managers.TurnManager.automateTurn(TurnManager.kt:321)
at com.unciv.logic.GameInfo.nextTurn(GameInfo.kt:338)
at com.unciv.ui.screens.worldscreen.WorldScreen$nextTurn$1.invokeSuspend(WorldScreen.kt:598)
at com.unciv.ui.screens.worldscreen.WorldScreen$nextTurn$1.invoke(WorldScreen.kt)
at com.unciv.ui.screens.worldscreen.WorldScreen$nextTurn$1.invoke(WorldScreen.kt)
at com.unciv.utils.ConcurrencyKt$launchCrashHandling$1.invokeSuspend(Concurrency.kt:87)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at com.unciv.utils.CrashHandlingDispatcher$dispatch$1.invoke(Concurrency.kt:173)
at com.unciv.utils.CrashHandlingDispatcher$dispatch$1.invoke(Concurrency.kt:173)
at com.unciv.ui.crashhandling.CrashHandlingExtensionsKt$wrapCrashHandling$1.invoke(CrashHandlingExtensions.kt:17)
at com.unciv.ui.crashhandling.CrashHandlingExtensionsKt$wrapCrashHandlingUnit$1.invoke(CrashHandlingExtensions.kt:33)
at com.unciv.ui.crashhandling.CrashHandlingExtensionsKt$wrapCrashHandlingUnit$1.invoke(CrashHandlingExtensions.kt:33)
at com.unciv.utils.CrashHandlingDispatcher.dispatch$lambda$0(Concurrency.kt:173)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
or
at com.unciv.logic.city.CityStats.getStatsFromTradeRoute(CityStats.kt:103)
at com.unciv.logic.city.CityStats.updateBaseStatList(CityStats.kt:460)
at com.unciv.logic.city.CityStats.update(CityStats.kt:499)
at com.unciv.logic.city.CityStats.update$default(CityStats.kt:491)
at com.unciv.logic.civilization.Civilization.updateStatsForNextTurn(Civilization.kt:379)
at com.unciv.logic.civilization.transients.CivInfoTransientCache.updateCivResources(CivInfoTransientCache.kt:328)
at com.unciv.logic.civilization.transients.CivInfoTransientCache.updateOurTiles(CivInfoTransientCache.kt:156)
at com.unciv.logic.city.managers.CityConquestFunctions.moveToCiv(CityConquestFunctions.kt:324)
at com.unciv.logic.city.City.moveToCiv(City.kt:498)
at com.unciv.logic.city.managers.CityConquestFunctions.conquerCity(CityConquestFunctions.kt:103)
at com.unciv.logic.city.managers.CityConquestFunctions.liberateCity(CityConquestFunctions.kt:195)
at com.unciv.logic.city.City.liberateCity(City.kt:495)
at com.unciv.logic.automation.civilization.NextTurnAutomation.onConquerCity(NextTurnAutomation.kt:1137)
at com.unciv.logic.battle.Battle.conquerCity(Battle.kt:621)
at com.unciv.logic.battle.Battle.attack(Battle.kt:151)
at com.unciv.logic.battle.Battle.attackOrNuke(Battle.kt:93)
at com.unciv.logic.battle.Battle.moveAndAttack(Battle.kt:48)
at com.unciv.logic.automation.unit.BattleHelper.tryAttackNearbyEnemy(BattleHelper.kt:30)
at com.unciv.logic.automation.unit.BattleHelper.tryAttackNearbyEnemy$default(BattleHelper.kt:16)
at com.unciv.logic.automation.unit.UnitAutomation.tryAttacking(UnitAutomation.kt:358)
at com.unciv.logic.automation.unit.UnitAutomation.automateUnitMoves(UnitAutomation.kt:200)
at com.unciv.logic.automation.civilization.NextTurnAutomation.automateUnits(NextTurnAutomation.kt:1004)
at com.unciv.logic.automation.civilization.NextTurnAutomation.automateCivMoves(NextTurnAutomation.kt:87)
at com.unciv.logic.civilization.managers.TurnManager.automateTurn(TurnManager.kt:321)
at com.unciv.logic.GameInfo.nextTurn(GameInfo.kt:338)
at com.unciv.ui.screens.worldscreen.WorldScreen$nextTurn$1.invokeSuspend(WorldScreen.kt:598)
at com.unciv.ui.screens.worldscreen.WorldScreen$nextTurn$1.invoke(WorldScreen.kt)
at com.unciv.ui.screens.worldscreen.WorldScreen$nextTurn$1.invoke(WorldScreen.kt)
at com.unciv.utils.ConcurrencyKt$launchCrashHandling$1.invokeSuspend(Concurrency.kt:87)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at com.unciv.utils.CrashHandlingDispatcher$dispatch$1.invoke(Concurrency.kt:173)
at com.unciv.utils.CrashHandlingDispatcher$dispatch$1.invoke(Concurrency.kt:173)
at com.unciv.ui.crashhandling.CrashHandlingExtensionsKt$wrapCrashHandling$1.invoke(CrashHandlingExtensions.kt:17)
at com.unciv.ui.crashhandling.CrashHandlingExtensionsKt$wrapCrashHandlingUnit$1.invoke(CrashHandlingExtensions.kt:33)
at com.unciv.ui.crashhandling.CrashHandlingExtensionsKt$wrapCrashHandlingUnit$1.invoke(CrashHandlingExtensions.kt:33)
at com.unciv.utils.CrashHandlingDispatcher.dispatch$lambda$0(Concurrency.kt:173)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Looks like be similar to #8337.
================================ Update: I am afraid that it was introduced by https://github.com/yairm210/Unciv/commit/6f0a51d6d8440f6584da32e8ca40e34533079709. 🥲
Looks like be similar
Believe it or not, these two crashes as similar, but mostly unrelated. Though 6f0a51d likely accidentally stumbled into the problem
Looks like it crashed when moving the capital, which included removing the old capital, which has faulty code for updating city connections and therefore ran through code it shouldn't
Same crash, different game.
Platform: Android
Version: 4.7.6-patch1 (Build 887)
Rulesets: [Policy mod, RekMOD, Ruins Extended, Upside Down, tGUR grape update, Thin Bubbly Borders, Nextgen Maps, NextgenMaps Labs, Antiyoy maps, Better ruins Lite, Pix5 Tileset, Civ V - Vanilla, No Fog Of War, Resource Recyclers, Civ V Leader portraits, Alpha Frontier, Raze anything, All units can be automated, Civ V - Gods & Kings, The Great Unciv Rework, Closer Cities Distance of 1, DeCiv in Alpha Frontier, 5Hex Tileset, Better Workers, Better ruins, Mapping Tools for Unciv]
Last Screen: com.unciv.ui.screens.worldscreen.WorldScreen
Device Model: SM-G973U1 API Level: 31
Message:
java.lang.NullPointerException
at com.unciv.logic.city.CityStats.getStatsFromTradeRoute(CityStats.kt:103)
at com.unciv.logic.city.CityStats.updateBaseStatList(CityStats.kt:460)
at com.unciv.logic.city.CityStats.update(CityStats.kt:499)
at com.unciv.logic.city.CityStats.update$default(CityStats.kt:491)
at com.unciv.logic.city.CityConstructions.updateUniques(CityConstructions.kt:499)
at com.unciv.logic.city.CityConstructions.updateUniques$default(CityConstructions.kt:495)
at com.unciv.logic.city.CityConstructions.removeBuilding(CityConstructions.kt:492)
at com.unciv.logic.civilization.Civilization.moveCapitalTo(Civilization.kt:813)
at com.unciv.logic.civilization.Civilization.moveCapitalToNextLargest(Civilization.kt:819)
at com.unciv.logic.city.managers.CityConquestFunctions.moveToCiv(CityConquestFunctions.kt:263)
at com.unciv.logic.city.City.moveToCiv(City.kt:498)
at com.unciv.logic.city.managers.CityConquestFunctions.conquerCity(CityConquestFunctions.kt:103)
at com.unciv.logic.city.managers.CityConquestFunctions.puppetCity(CityConquestFunctions.kt:136)
at com.unciv.logic.city.City.puppetCity(City.kt:491)
at com.unciv.logic.automation.civilization.NextTurnAutomation.onConquerCity(NextTurnAutomation.kt:1142)
at com.unciv.logic.battle.Battle.conquerCity(Battle.kt:621)
at com.unciv.logic.battle.Battle.attack(Battle.kt:151)
at com.unciv.logic.battle.Battle.attackOrNuke(Battle.kt:93)
at com.unciv.logic.battle.Battle.moveAndAttack(Battle.kt:48)
at com.unciv.logic.automation.unit.BattleHelper.tryAttackNearbyEnemy(BattleHelper.kt:30)
at com.unciv.logic.automation.unit.BattleHelper.tryAttackNearbyEnemy$default(BattleHelper.kt:16)
at com.unciv.logic.automation.unit.UnitAutomation.tryAttacking(UnitAutomation.kt:358)
at com.unciv.logic.automation.unit.UnitAutomation.automateUnitMoves(UnitAutomation.kt:200)
at com.unciv.logic.automation.civilization.NextTurnAutomation.automateUnits(NextTurnAutomation.kt:1004)
at com.unciv.logic.automation.civilization.NextTurnAutomation.automateCivMoves(NextTurnAutomation.kt:87)
at com.unciv.logic.civilization.managers.TurnManager.automateTurn(TurnManager.kt:321)
at com.unciv.logic.GameInfo.nextTurn(GameInfo.kt:338)
at com.unciv.ui.screens.worldscreen.WorldScreen$nextTurn$1.invokeSuspend(WorldScreen.kt:598)
at com.unciv.ui.screens.worldscreen.WorldScreen$nextTurn$1.invoke(Unknown Source:8)
at com.unciv.ui.screens.worldscreen.WorldScreen$nextTurn$1.invoke(Unknown Source:4)
at com.unciv.utils.ConcurrencyKt$launchCrashHandling$1.invokeSuspend(Concurrency.kt:87)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at com.unciv.utils.CrashHandlingDispatcher$dispatch$1.invoke(Concurrency.kt:173)
at com.unciv.utils.CrashHandlingDispatcher$dispatch$1.invoke(Concurrency.kt:173)
at com.unciv.ui.crashhandling.CrashHandlingExtensionsKt$wrapCrashHandling$1.invoke(CrashHandlingExtensions.kt:17)
at com.unciv.ui.crashhandling.CrashHandlingExtensionsKt$wrapCrashHandlingUnit$1.invoke(CrashHandlingExtensions.kt:33)
at com.unciv.ui.crashhandling.CrashHandlingExtensionsKt$wrapCrashHandlingUnit$1.invoke(CrashHandlingExtensions.kt:33)
at com.unciv.utils.CrashHandlingDispatcher.dispatch$lambda$0(Concurrency.kt:173)
at com.unciv.utils.CrashHandlingDispatcher.$r8$lambda$GFMOlD6QMgmLfgwAvPAW33Ob6HE(Unknown Source:0)
at com.unciv.utils.CrashHandlingDispatcher$$ExternalSyntheticLambda0.run(Unknown Source:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:920)
Save Mods:
[The Great Unciv Rework]
Save Data:
Also, Full-Crashed-Saves.zip
Crash would be happened in 441, 415, 360 turns (And some turns but I forgot to save) if using 4.7.6-patch1
.
Using old version (like 4.7.5-patch1
) to load these saves would not lead to crash, and you would see some civilization or city states destroyed in their next turns.
This makes me wonder how many other scenarios needs fixing via something like #9709. Probably could be fixed in other ways, but that getCapital
check should still be avoided
This is ridiculous What we need then are tests for city transfer
Cases: A. Last city of civ was conquered B. Capital conquered, other cities exist C. Non-capital city liberated from B and given to C D. Capital city liberated from B and given to C
I see what's happening here though. And I don't like it, but I'll fix it
Resolved in patch2, rolling out now Also added tests for many different city moving scenarios so this doesn't happen again
Isn't TGUR that mod trying to make selling your palace legal?
I still see us -one of these days- moving to a no-Palace-allowed architecture. How about one new field - City.isCapital or Civilization.capitalID. Backwards compatiblity determines it as is obvious. Building a Palace sets it. Removing leaves it as is. getCapital checks integrity, and if there's no capital, it fixes by looking for a Palace, and if none, marks the one with most population / oldest. Could be one Sequence.sortedWith(compareBy.thenBy.thenBy).firstOrNull(). getCapital still returns null when cities.size == 0, but never when cities.size > 0. Later simply add a modOption disabling the auto-gifted Palace, and you get Civ4 behaviour IIRC.
Note civs undefeated with 0 cities even in the later game are perfectly possible. Just ask for max CS and max AI's on a larger map, some settler will survive to turn 200 while all the time being too close to an existing city to settle. You can even ally with a CS with no city and gain the stats it has no way to produce, or units it has no way to build.
Patch 2 did fix the problem. This image is the result of pressing Next Turn:
Thank you @yairm210 for your diligence in solving this!
Resolved in patch2, rolling out now
@yairm210 If you merge #9731 (namely `cityConstruction.removeBuilding part of it), I recommend reverting that fix, actually, as it may cause other problems further down the road
Trying to submit the bug... github app keeps crashing. Uploading crash info as a .txt and we'll start there.