diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index 0c739457ad..54ef8fbc43 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -56,6 +56,13 @@ import java.util.UUID * When you change the structure of any class with this interface in a way which makes it impossible * to load the new saves from an older game version, increment [CURRENT_COMPATIBILITY_NUMBER]! And don't forget * to add backwards compatibility for the previous format. + * + * Reminder: In all subclasse, do use only actual Collection types, not abstractions like + * `= mutableSetOf()`. That would make the reflection type of the field an interface, which + * hides the actual implementation from Gdx Json, so it will not try to call a no-args constructor but + * will instead deserialize a List in the jsonData.isArray() -> isAssignableFrom(Collection) branch of readValue: + * https://github.com/libgdx/libgdx/blob/75612dae1eeddc9611ed62366858ff1d0ac7898b/gdx/src/com/badlogic/gdx/utils/Json.java#L1111 + * .. which will crash later (when readFields actually assigns it) unless empty. */ interface IsPartOfGameInfoSerialization diff --git a/core/src/com/unciv/logic/civilization/managers/EspionageManager.kt b/core/src/com/unciv/logic/civilization/managers/EspionageManager.kt index 9c5946e7b8..996f26df73 100644 --- a/core/src/com/unciv/logic/civilization/managers/EspionageManager.kt +++ b/core/src/com/unciv/logic/civilization/managers/EspionageManager.kt @@ -8,15 +8,15 @@ import com.unciv.models.Spy class EspionageManager : IsPartOfGameInfoSerialization { - var spyList = mutableListOf() - val erasSpyEarnedFor = mutableSetOf() + var spyList = ArrayList() + val erasSpyEarnedFor = LinkedHashSet() @Transient lateinit var civInfo: Civilization fun clone(): EspionageManager { val toReturn = EspionageManager() - toReturn.spyList.addAll(spyList.map { it.clone() }) + spyList.mapTo(toReturn.spyList) { it.clone() } toReturn.erasSpyEarnedFor.addAll(erasSpyEarnedFor) return toReturn }