Coder Social home page Coder Social logo

AI plays always on Chieftan difficulty about unciv HOT 6 OPEN

tuvus avatar tuvus commented on May 18, 2024
AI plays always on Chieftan difficulty

from unciv.

Comments (6)

SeventhM avatar SeventhM commented on May 18, 2024

This is a direct copy of how it works in Civ 5. If there's actually a want to fix it, in theory it likely should be allowing a mod to specify what difficulty the AI play on by default. But it playing on chieftain is in fact, intentional

Edit: at least Firaxis realized for Brave New World that the AI was way too happy and made the AI difficulty a bit less easy for the AI

from unciv.

yairm210 avatar yairm210 commented on May 18, 2024

Sounds like a modoption to me, but unlike most modoptions this is actually one that should be applied to our base rulesets.
Something like "AI always plays at [difficulty] difficulty"
And once that's settled in, we can change default behavior to "AI plays on game difficulty" and have it overridable.
That way we retain Civ V compatibility and allow for differences.

Unrelatedly, a difficulty-type conditional sounds interesting, to customize object behaviour... 🤔

from unciv.

tuvus avatar tuvus commented on May 18, 2024

Okay, it's a little weird, though, how the players can't copy or learn from the AI at the beginning since they are not equal. I know that making a good AI is very hard and will never be as good as a good player. Can we at least state this clearly in the Civilopedia somewhere?

from unciv.

yairm210 avatar yairm210 commented on May 18, 2024

Sure, I don't think it's that interesting to the player what logic the AI is using to play with, though. I only know this because I needed to know in order to program it, it never affected me as a player.

from unciv.

yairm210 avatar yairm210 commented on May 18, 2024

In general if your strategy is 'learn from the AI' then it really doesn't matter what difficulty it's on, since it doesn't really change its behavior between difficulties. But that's for another time...

from unciv.

SomeTroglodyte avatar SomeTroglodyte commented on May 18, 2024

I would likely do the marking right in the difficulties json... And make it a Difficulty : RulesetObject on the way - the missing space is enough motivation, and I think sooner or later we will want difficulty-dependent triggerables? (btw, Speed being marked IsPartOfGameInfoSerialization is wrong - it's loaded from json, not saved, right?)

state this clearly

Comes as side effect - almost free.

Index: android/assets/jsons/Civ V - Gods & Kings/Difficulties.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/android/assets/jsons/Civ V - Gods & Kings/Difficulties.json b/android/assets/jsons/Civ V - Gods & Kings/Difficulties.json
--- a/android/assets/jsons/Civ V - Gods & Kings/Difficulties.json	(revision 6e843770900cb7e9c6b9041e5b8a7e4592b9cde5)
+++ b/android/assets/jsons/Civ V - Gods & Kings/Difficulties.json	(date 1704242979756)
@@ -55,7 +55,8 @@
 		"aiUnhappinessModifier": 1,
 		"aisExchangeTechs": false,
 		"turnBarbariansCanEnterPlayerTiles": 60,
-		"clearBarbarianCampReward": 40
+		"clearBarbarianCampReward": 40,
+        "uniques": ["AI plays at this difficulty"]
 	},
 	{
 		"name": "Warlord",
Index: core/src/com/unciv/models/ruleset/unique/UniqueTarget.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueTarget.kt b/core/src/com/unciv/models/ruleset/unique/UniqueTarget.kt
--- a/core/src/com/unciv/models/ruleset/unique/UniqueTarget.kt	(revision 6e843770900cb7e9c6b9041e5b8a7e4592b9cde5)
+++ b/core/src/com/unciv/models/ruleset/unique/UniqueTarget.kt	(date 1704242724663)
@@ -54,6 +54,7 @@
 
     // Other
     Speed,
+    Difficulty,
     Tutorial,
     CityState(inheritsFrom = Global),
     ModOptions,
@@ -82,7 +83,7 @@
         // As Array so it can used in a vararg parameter list.
         val Displayable = arrayOf(
             Building, Unit, UnitType, Improvement, Tech,
-            Terrain, Resource, Policy, Promotion, Nation, Ruins, Speed
+            Terrain, Resource, Policy, Promotion, Nation, Ruins, Speed, Difficulty
         )
     }
 }
Index: core/src/com/unciv/models/ruleset/nation/Difficulty.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/src/com/unciv/models/ruleset/nation/Difficulty.kt b/core/src/com/unciv/models/ruleset/nation/Difficulty.kt
--- a/core/src/com/unciv/models/ruleset/nation/Difficulty.kt	(revision 6e843770900cb7e9c6b9041e5b8a7e4592b9cde5)
+++ b/core/src/com/unciv/models/ruleset/nation/Difficulty.kt	(date 1704242724671)
@@ -1,34 +1,34 @@
 package com.unciv.models.ruleset.nation
 
 import com.unciv.models.ruleset.Ruleset
+import com.unciv.models.ruleset.RulesetObject
 import com.unciv.models.ruleset.unique.Unique
-import com.unciv.models.stats.INamed
+import com.unciv.models.ruleset.unique.UniqueTarget
 import com.unciv.ui.components.fonts.Fonts
 import com.unciv.ui.screens.civilopediascreen.FormattedLine
-import com.unciv.ui.screens.civilopediascreen.ICivilopediaText
 
-class Difficulty: INamed, ICivilopediaText {
+class Difficulty : RulesetObject() {
     override lateinit var name: String
-    var baseHappiness: Int = 0
-    var extraHappinessPerLuxury: Float = 0f
-    var researchCostModifier:Float = 1f
-    var unitCostModifier:Float = 1f
-    var unitSupplyBase: Int = 5
-    var unitSupplyPerCity: Int = 2
-    var buildingCostModifier:Float = 1f
-    var policyCostModifier:Float = 1f
-    var unhappinessModifier:Float = 1f
-    var barbarianBonus:Float = 0f
+    var baseHappiness = 0
+    var extraHappinessPerLuxury = 0f
+    var researchCostModifier = 1f
+    var unitCostModifier = 1f
+    var unitSupplyBase = 5
+    var unitSupplyPerCity = 2
+    var buildingCostModifier = 1f
+    var policyCostModifier = 1f
+    var unhappinessModifier = 1f
+    var barbarianBonus = 0f
     var barbarianSpawnDelay: Int = 0
     var playerBonusStartingUnits = ArrayList<String>()
 
-    var aiCityGrowthModifier:Float = 1f
-    var aiUnitCostModifier:Float = 1f
-    var aiBuildingCostModifier:Float = 1f
-    var aiWonderCostModifier:Float = 1f
-    var aiBuildingMaintenanceModifier:Float = 1f
+    var aiCityGrowthModifier = 1f
+    var aiUnitCostModifier = 1f
+    var aiBuildingCostModifier = 1f
+    var aiWonderCostModifier = 1f
+    var aiBuildingMaintenanceModifier = 1f
     var aiUnitMaintenanceModifier = 1f
-    var aiUnitSupplyModifier: Float = 0f
+    var aiUnitSupplyModifier = 0f
     var aiFreeTechs = ArrayList<String>()
     var aiMajorCivBonusStartingUnits = ArrayList<String>()
     var aiCityStateBonusStartingUnits = ArrayList<String>()
@@ -39,9 +39,7 @@
     // property defined in json but so far unused:
     // var aisExchangeTechs = false
 
-    override var civilopediaText = listOf<FormattedLine>()
-
-
+    override fun getUniqueTarget() = UniqueTarget.Difficulty
     override fun makeLink() = "Difficulty/$name"
 
     private fun Float.toPercent() = (this * 100).toInt()
@@ -108,6 +106,11 @@
         lines += FormattedLine()
         lines += FormattedLine("{Turns until barbarians enter player tiles}: $turnBarbariansCanEnterPlayerTiles ${Fonts.turn}")
         lines += FormattedLine("{Gold reward for clearing barbarian camps}: $clearBarbarianCampReward ${Fonts.gold}")
+
+        if (uniques.isEmpty()) return lines
+        lines += FormattedLine()
+        for (unique in uniques)
+            lines += FormattedLine(unique)
         return lines
     }
 
Index: core/src/com/unciv/models/ruleset/unique/UniqueType.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt
--- a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt	(revision 6e843770900cb7e9c6b9041e5b8a7e4592b9cde5)
+++ b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt	(date 1704242979740)
@@ -780,6 +780,11 @@
 
     //endregion
 
+    ///////////////////////////////////////////// region 11 GAME RULES /////////////////////////////////////////////
+    AIDifficulty("AI plays at this difficulty", UniqueTarget.Difficulty),
+
+    //endregion
+
     ///////////////////////////////////////////// region 90 META /////////////////////////////////////////////
     HiddenWithoutReligion("Hidden when religion is disabled",
         UniqueTarget.Unit, UniqueTarget.Building, UniqueTarget.Ruins, UniqueTarget.Tutorial,
Index: android/assets/jsons/Civ V - Vanilla/Difficulties.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/android/assets/jsons/Civ V - Vanilla/Difficulties.json b/android/assets/jsons/Civ V - Vanilla/Difficulties.json
--- a/android/assets/jsons/Civ V - Vanilla/Difficulties.json	(revision 6e843770900cb7e9c6b9041e5b8a7e4592b9cde5)
+++ b/android/assets/jsons/Civ V - Vanilla/Difficulties.json	(date 1704243006201)
@@ -55,7 +55,8 @@
 		"aiUnhappinessModifier": 1,
 		"aisExchangeTechs": false,
 		"turnBarbariansCanEnterPlayerTiles": 60,
-		"clearBarbarianCampReward": 40
+		"clearBarbarianCampReward": 40,
+        "uniques": ["AI plays at this difficulty"]
 	},
 	{
 		"name": "Warlord",
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 6e843770900cb7e9c6b9041e5b8a7e4592b9cde5)
+++ b/core/src/com/unciv/logic/civilization/Civilization.kt	(date 1704243210745)
@@ -302,10 +302,11 @@
     //region pure functions
     fun getDifficulty(): Difficulty {
         if (isHuman()) return gameInfo.getDifficulty()
-        // TODO We should be able to mark a difficulty as 'default AI difficulty' somehow
-        val chieftainDifficulty = gameInfo.ruleset.difficulties["Chieftain"]
-        if (chieftainDifficulty != null) return chieftainDifficulty
-        return gameInfo.ruleset.difficulties.values.first()
+        return gameInfo.ruleset.difficulties.values.run {
+            firstOrNull { it.hasUnique(UniqueType.AIDifficulty) }
+                ?: firstOrNull { it.name == "Chieftain " }  // backwards mod compatibility
+                ?: first()
+        }
     }
 
     fun getDiplomacyManager(civInfo: Civilization) = getDiplomacyManager(civInfo.civName)

... anyone care to test? Then add a <when Player uses difficulty [x] or harder> Conditional?

from unciv.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.