Skip to content

Show CityStateType civilopedia text on CS Nation pages - #15283

Open
Fanfblrik wants to merge 7 commits into
yairm210:masterfrom
Fanfblrik:feature/cs-type-civilopedia-on-nation
Open

Show CityStateType civilopedia text on CS Nation pages#15283
Fanfblrik wants to merge 7 commits into
yairm210:masterfrom
Fanfblrik:feature/cs-type-civilopedia-on-nation

Conversation

@Fanfblrik

@Fanfblrik Fanfblrik commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #15271 / review note from @SomeTroglodyte: CityStateType is a RulesetObject with civilopediaText / uniques, but has no Civilopedia category.

  • Surface type civilopediaText and type-level uniques on the city-state Nation civilopedia page (NationDescriptions.getCityStateInfo).
  • Start bias […] from the type is not duplicated in the type-unique list — it already appears via Nation.getStartBias, using the same block as major civs (Terrain/… link, chain + terrain icons, civilopedia navigation).
  • CS page layout aligned with major-civ Nation pages: no separator before start bias; friend/ally bonuses stay sub-indented; shared Color.toHexColor() helper (review).

Bangkok (Maritime CS) — Civilopedia Nation page

(Screenshot file is for review only; can drop _pr_screenshots/ before merge.)

Test plan

  • CityStateTypeCivilopediaOnNationTests
  • Civilopedia → Nations → Bangkok (G&K Maritime CS): type line, When Friends/Allies bonuses, Start bias: Coast with Terrain/Coast link (click opens Coast terrain page)
  • Mod CityStateType with civilopediaText / non-StartBias unique — both show on a CS of that type
  • CI green

CityStateType has no Civilopedia category; surface type lore and type-level uniques (except Start bias, already listed via getStartBias) on the nation entry.

Co-authored-by: Cursor <cursoragent@cursor.com>
@SomeTroglodyte

Copy link
Copy Markdown
Collaborator

UI PR's need screenshots

val textList = ArrayList<FormattedLine>()

val cityStateType = ruleset.cityStateTypes[cityStateType]!!
textList += FormattedLine("{Type}: {${cityStateType.name}}", header = 4, color = "#"+cityStateType.getColor().toString())

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yours, but
https://kotlinlang.org/docs/coding-conventions.html#horizontal-whitespace

Also, how often is such a conversion done in the current codebase 🤔 ? The luxury version exists here:

private fun Color.toMarkup(): String {
val mapEntry = inverseColorMap[this]
if (mapEntry != null) return mapEntry
if (a < 1f) return "#" + toString()
return "#" + toString().substring(0,6)
}

And another here:

@Readonly fun getHexColor() = "#" + getColor().toString().substring(0, 6)

Might be worth a common extension.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch on the spacing — fixed.

Also extracted a shared Color.toHexColor() next to colorFromRGB in Scene2dExtensions, and wired Era.getHexColor / ColorMarkupLabel.toMarkup / this call site through it.

return textList
}

@Readonly

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pity the @Cache/@LocalState way is blocked here, right?

See also: #15015, where it's done properly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes — restoring @Readonly fails here because uniquesToCivilopediaTextLines (mutable overload) is not @Readonly. Left a short note pointing at #15015; once the FormattedLineListBuilder lands this is the obvious cleanup.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it lands - I was hoping for some -any- feedback before I un-draft it, because converting existing code would be a lengthy chore. But then that was the trigger - seeing how many structurally different generators we cobbled together over time.

Fanfblrik and others added 5 commits July 27, 2026 11:22
…only

Co-authored-by: Cursor <cursoragent@cursor.com>
…t bias)

Co-authored-by: Cursor <cursoragent@cursor.com>
…ayout)

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
return textList
}

private fun Nation.appendStartBiasLines(textList: MutableList<FormattedLine>, ruleset: Ruleset) {

@yairm210 yairm210 Jul 27, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact as of the latest version this is Readinly-able! This is exactly the scenario for @Mutated, passing mutation rights on to subfunctions!
https://yairm210.github.io/Purity/usage/advanced-usage/#mutating-input-parameters

Requires Purity 1.7.0 for the Mutated annotation (was added after 1.6.0).

Co-authored-by: Cursor <cursoragent@cursor.com>
@Fanfblrik

Copy link
Copy Markdown
Contributor Author

Tried marking getCityStateInfo / uniquesToCivilopediaTextLines @Readonly with @Mutated lists. Purity still rejects it: the sequence overload calls non-Readonly SuspendFunction1.invoke, and the mutable overload calls non-Readonly Sequence.toCollection. Left as-is pending FormattedLineListBuilder (#15015) or Readonly-friendly helpers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants