Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions C7/Lua/game_modes/base-ruleset.json
Original file line number Diff line number Diff line change
Expand Up @@ -5534,6 +5534,7 @@
"primaryColorIndex": 0,
"secondaryColorIndex": 0,
"leaderGender": "male",
"cultureGroupKey": "None",
"cityNames": [
"Chanca",
"Lupaca",
Expand Down Expand Up @@ -5622,6 +5623,7 @@
"primaryColorIndex": 1,
"secondaryColorIndex": 1,
"leaderGender": "male",
"cultureGroupKey": "Mediterranean",
"leaderArtFile": "art\\advisors\\CE_all.pcx",
"cityNames": [
"Rome",
Expand Down Expand Up @@ -5687,6 +5689,7 @@
"primaryColorIndex": 3,
"secondaryColorIndex": 3,
"leaderGender": "female",
"cultureGroupKey": "Mediterranean",
"leaderArtFile": "art\\advisors\\CL_all.pcx",
"cityNames": [
"Thebes",
Expand Down Expand Up @@ -5737,6 +5740,7 @@
"primaryColorIndex": 10,
"secondaryColorIndex": 10,
"leaderGender": "male",
"cultureGroupKey": "Mediterranean",
"leaderArtFile": "art\\advisors\\AL_all.pcx",
"cityNames": [
"Athens",
Expand Down Expand Up @@ -5787,6 +5791,7 @@
"primaryColorIndex": 1,
"secondaryColorIndex": 13,
"leaderGender": "male",
"cultureGroupKey": "Mid East",
"leaderArtFile": "art\\advisors\\HA_all.pcx",
"cityNames": [
"Babylon",
Expand Down Expand Up @@ -5835,6 +5840,7 @@
"primaryColorIndex": 6,
"secondaryColorIndex": 6,
"leaderGender": "male",
"cultureGroupKey": "European",
"leaderArtFile": "art\\advisors\\BS_all.pcx",
"cityNames": [
"Berlin",
Expand Down Expand Up @@ -5872,6 +5878,7 @@
"primaryColorIndex": 9,
"secondaryColorIndex": 9,
"leaderGender": "female",
"cultureGroupKey": "European",
"leaderArtFile": "art\\advisors\\CA_all.pcx",
"cityNames": [
"Moscow",
Expand Down Expand Up @@ -5932,6 +5939,7 @@
"primaryColorIndex": 5,
"secondaryColorIndex": 15,
"leaderGender": "male",
"cultureGroupKey": "Asian",
"leaderArtFile": "art\\advisors\\MO_all.pcx",
"cityNames": [
"Beijing",
Expand Down Expand Up @@ -5971,6 +5979,7 @@
"primaryColorIndex": 5,
"secondaryColorIndex": 5,
"leaderGender": "male",
"cultureGroupKey": "American",
"leaderArtFile": "art\\advisors\\AB_all.pcx",
"cityNames": [
"Washington",
Expand Down Expand Up @@ -6032,6 +6041,7 @@
"primaryColorIndex": 4,
"secondaryColorIndex": 11,
"leaderGender": "male",
"cultureGroupKey": "Asian",
"leaderArtFile": "art\\advisors\\TO_all.pcx",
"cityNames": [
"Kyoto",
Expand Down Expand Up @@ -6079,6 +6089,7 @@
"primaryColorIndex": 7,
"secondaryColorIndex": 7,
"leaderGender": "female",
"cultureGroupKey": "European",
"leaderArtFile": "art\\advisors\\JO_all.pcx",
"cityNames": [
"Paris",
Expand Down Expand Up @@ -6121,6 +6132,7 @@
"primaryColorIndex": 8,
"secondaryColorIndex": 12,
"leaderGender": "male",
"cultureGroupKey": "Asian",
"leaderArtFile": "art\\advisors\\GH_all.pcx",
"cityNames": [
"Delhi",
Expand Down Expand Up @@ -6159,6 +6171,7 @@
"primaryColorIndex": 10,
"secondaryColorIndex": 14,
"leaderGender": "male",
"cultureGroupKey": "Mid East",
"leaderArtFile": "art\\advisors\\XE_all.pcx",
"cityNames": [
"Persepolis",
Expand Down Expand Up @@ -6209,6 +6222,7 @@
"primaryColorIndex": 4,
"secondaryColorIndex": 4,
"leaderGender": "male",
"cultureGroupKey": "American",
"leaderArtFile": "art\\advisors\\MN_all.pcx",
"cityNames": [
"Tenochtitlan",
Expand Down Expand Up @@ -6266,6 +6280,7 @@
"primaryColorIndex": 3,
"secondaryColorIndex": 16,
"leaderGender": "male",
"cultureGroupKey": "Mid East",
"leaderArtFile": "art\\advisors\\ZU_all.pcx",
"cityNames": [
"Zimbabwe",
Expand Down Expand Up @@ -6303,6 +6318,7 @@
"primaryColorIndex": 8,
"secondaryColorIndex": 8,
"leaderGender": "male",
"cultureGroupKey": "American",
"leaderArtFile": "art\\advisors\\HI_all.pcx",
"cityNames": [
"Salamanca",
Expand Down Expand Up @@ -6353,6 +6369,7 @@
"primaryColorIndex": 2,
"secondaryColorIndex": 2,
"leaderGender": "female",
"cultureGroupKey": "European",
"leaderArtFile": "art\\advisors\\LZ_all.pcx",
"cityNames": [
"London",
Expand Down Expand Up @@ -6403,6 +6420,7 @@
"primaryColorIndex": 3,
"secondaryColorIndex": 26,
"leaderGender": "male",
"cultureGroupKey": "Asian",
"leaderArtFile": "art\\advisors\\x_temujin advisor.pcx",
"cityNames": [
"Karakorum",
Expand Down Expand Up @@ -6454,6 +6472,7 @@
"primaryColorIndex": 5,
"secondaryColorIndex": 20,
"leaderGender": "female",
"cultureGroupKey": "European",
"leaderArtFile": "art\\advisors\\x_isabell advisor.pcx",
"cityNames": [
"Madrid",
Expand Down Expand Up @@ -6506,6 +6525,7 @@
"primaryColorIndex": 8,
"secondaryColorIndex": 31,
"leaderGender": "male",
"cultureGroupKey": "European",
"leaderArtFile": "art\\advisors\\x_ragnar advisor.pcx",
"cityNames": [
"Trondheim",
Expand Down Expand Up @@ -6560,6 +6580,7 @@
"primaryColorIndex": 2,
"secondaryColorIndex": 18,
"leaderGender": "male",
"cultureGroupKey": "Mid East",
"leaderArtFile": "art\\advisors\\x_osman advisor.pcx",
"cityNames": [
"Istanbul",
Expand Down Expand Up @@ -6610,6 +6631,7 @@
"primaryColorIndex": 4,
"secondaryColorIndex": 25,
"leaderGender": "male",
"cultureGroupKey": "European",
"leaderArtFile": "art\\advisors\\x_brennus advisor.pcx",
"cityNames": [
"Entremont",
Expand Down Expand Up @@ -6661,6 +6683,7 @@
"primaryColorIndex": 7,
"secondaryColorIndex": 30,
"leaderGender": "male",
"cultureGroupKey": "Mid East",
"leaderArtFile": "art\\advisors\\x_abu bakr advisor.pcx",
"cityNames": [
"Mecca",
Expand Down Expand Up @@ -6710,6 +6733,7 @@
"primaryColorIndex": 9,
"secondaryColorIndex": 11,
"leaderGender": "male",
"cultureGroupKey": "Mediterranean",
"leaderArtFile": "art\\advisors\\x_Hannibal advisor.pcx",
"cityNames": [
"Carthage",
Expand Down Expand Up @@ -6761,6 +6785,7 @@
"primaryColorIndex": 6,
"secondaryColorIndex": 19,
"leaderGender": "male",
"cultureGroupKey": "Asian",
"leaderArtFile": "art\\advisors\\x_Wang Kon advisor.pcx",
"cityNames": [
"Seoul",
Expand Down Expand Up @@ -6812,6 +6837,7 @@
"primaryColorIndex": 5,
"secondaryColorIndex": 20,
"leaderGender": "male",
"cultureGroupKey": "Mid East",
"leaderArtFile": "art\\advisors\\x2_Gilgamesh advisor.pcx",
"cityNames": [
"Ur",
Expand Down Expand Up @@ -6858,6 +6884,7 @@
"primaryColorIndex": 14,
"secondaryColorIndex": 27,
"leaderGender": "male",
"cultureGroupKey": "Mid East",
"leaderArtFile": "art\\advisors\\x2_Mursilis advisor.pcx",
"cityNames": [
"Hattusas",
Expand Down Expand Up @@ -6904,6 +6931,7 @@
"primaryColorIndex": 2,
"secondaryColorIndex": 18,
"leaderGender": "male",
"cultureGroupKey": "European",
"leaderArtFile": "art\\advisors\\x2_William advisor.pcx",
"cityNames": [
"Amsterdam",
Expand Down Expand Up @@ -6950,6 +6978,7 @@
"primaryColorIndex": 8,
"secondaryColorIndex": 17,
"leaderGender": "male",
"cultureGroupKey": "European",
"leaderArtFile": "art\\advisors\\x2_Henry advisor.pcx",
"cityNames": [
"Lisbon",
Expand Down Expand Up @@ -7007,6 +7036,7 @@
"primaryColorIndex": 11,
"secondaryColorIndex": 1,
"leaderGender": "female",
"cultureGroupKey": "Mediterranean",
"leaderArtFile": "art\\advisors\\x2_Theodora advisor.pcx",
"cityNames": [
"Constantinople",
Expand Down Expand Up @@ -7053,6 +7083,7 @@
"primaryColorIndex": 7,
"secondaryColorIndex": 8,
"leaderGender": "male",
"cultureGroupKey": "American",
"leaderArtFile": "art\\advisors\\x2_Pachacuti advisor.pcx",
"cityNames": [
"Cuzco",
Expand Down Expand Up @@ -7099,6 +7130,7 @@
"primaryColorIndex": 6,
"secondaryColorIndex": 5,
"leaderGender": "male",
"cultureGroupKey": "American",
"leaderArtFile": "art\\advisors\\x2_Smoke-Jaguar_advisor.pcx",
"cityNames": [
"Chich\u00E9n Itza",
Expand Down Expand Up @@ -7139,6 +7171,32 @@
"isBarbarian": false
}
],
"cultureGroups": [
{
"index": -1,
"name": "None"
},
{
"index": 0,
"name": "American"
},
{
"index": 1,
"name": "European"
},
{
"index": 2,
"name": "Mediterranean"
},
{
"index": 3,
"name": "Mid East"
},
{
"index": 4,
"name": "Asian"
}
],
"strengthBonuses": [
{
"description": "Fortified",
Expand Down
21 changes: 21 additions & 0 deletions C7Engine/C7GameData/Civilization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ public enum Gender {
Female,
}

public class CultureGroup() {
public int index { get; init; }
public string name { get; init; }
}

public class Civilization {
public enum Trait {
Militaristic,
Expand Down Expand Up @@ -39,6 +44,22 @@ public Civilization(string name) {
public int secondaryColorIndex;
public Gender leaderGender;

[JsonIgnore]
public CultureGroup cultureGroup { get; private set; }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What uses are there for the culture group? Is it just potential trade/reputation schemes and culturally linked start?

Just wondering if the extra de/serialization machinery is worth it vs just using cultureGroupKey in game logic, together with the game knowing what culture groups there are.

Copy link
Copy Markdown
Contributor Author

@stavrosfa stavrosfa Mar 14, 2026

Choose a reason for hiding this comment

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

The short answer is textures. Check the PediaIcons.txt, there are building textures that are generic (mostly Great Wonders), but also culture and era specific.

The cultureGroupKey is used because we might want to add more fields/info in the CultureGroup iteself, and we wouldn't want to be copy pasting the same information across many civs. It simply a reference, we do the same with experienceLevel on the (EDIT) MapUnit or uniqueUnit currently in Civilization.

I hope that covers your question


// This is null during gameplay to discourage usage, and instead use the cultureGroup
// It's only used for saving/loading
public string cultureGroupKey;

public void SetCultureGroup(int index, string cultureGroupName) {
cultureGroupKey = null;
var cg = new CultureGroup {
index = index,
name = cultureGroupName
};
cultureGroup = cg;
}

// Like `art\advisors\LZ_all.pcx` for the English.
public string leaderArtFile;

Expand Down
1 change: 1 addition & 0 deletions C7Engine/C7GameData/GameData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class GameData {
public List<City> cities = new List<City>();

internal List<Civilization> civilizations = new List<Civilization>();
internal HashSet<CultureGroup> cultureGroups = new HashSet<CultureGroup>();

public List<ExperienceLevel> experienceLevels = new List<ExperienceLevel>();
public List<Tech> techs = new();
Expand Down
30 changes: 30 additions & 0 deletions C7Engine/C7GameData/ImportCiv3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ private void ImportSharedBiqData() {
save.TerrainImprovements = SaveTerrainImprovement.Civ3Improvements().ToList();

ImportRaces();
ImportCultureGroups();
ImportTechs();
ImportCiv3Resources();
ImportTerraforms();
Expand Down Expand Up @@ -355,6 +356,23 @@ private void ImportCiv3Resources() {
}
}

private void ImportCultureGroups() {
BiqData theBiq = biq.Race is null ? defaultBiq : biq;
HashSet<CultureGroup> cultureGroups = new HashSet<CultureGroup>();
HashSet<int> cultureGroupsIndexes = new HashSet<int>();
int i = 0;
foreach (RACE race in theBiq.Race) {
if (cultureGroupsIndexes.Add(race.CultureGroup)) {
var cg = new CultureGroup() {
index = race.CultureGroup,
name = GetCultureGroupIdentifier(race.CultureGroup),
};
cultureGroups.Add(cg);
}
}
save.CultureGroups = cultureGroups.OrderBy(c => c.index).ToHashSet();
}

private void ImportRaces() {
BiqData theBiq = biq.Race is null ? defaultBiq : biq;
int i = 0;
Expand All @@ -373,6 +391,7 @@ private void ImportRaces() {
civ.cityNames.Add(city.Name);
}
civ.traits = LoadCivTraits(race).ToHashSet();
civ.cultureGroupKey = GetCultureGroupIdentifier(race.CultureGroup);

// Look up the image for non-barbarian civs.
string artName = pediaIcons.GetLeaderArtName(race.CivilopediaEntry);
Expand All @@ -385,6 +404,17 @@ private void ImportRaces() {
}
}

private static string GetCultureGroupIdentifier(int cultureGroupIndex) {
if (cultureGroupIndex == -1) return "None"; // Barbarians
if (cultureGroupIndex == 0) return "American";
if (cultureGroupIndex == 1) return "European";
if (cultureGroupIndex == 2) return "Mediterranean";
if (cultureGroupIndex == 3) return "Mid East";
if (cultureGroupIndex == 4) return "Asian";
log.Error($"The culture group index {cultureGroupIndex} is invalid. Defaulting to `American`.");
return "American";
}

private static IEnumerable<Civilization.Trait> LoadCivTraits(RACE race) {
return new[] {
(race.Militaristic, Civilization.Trait.Militaristic),
Expand Down
2 changes: 1 addition & 1 deletion C7Engine/C7GameData/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ public int CalculateGoldPerTurn() {
}

public bool WouldAcceptDealFrom(GameData gameData, Player other, TradeOffer theirOffer, TradeOffer ourOffer) {
// TODO: consider any factors like trade reputations here
// TODO: consider any factors like trade reputations here and culture groups
// TODO: figure out when peace is acceptable
int theirGoldValue = theirOffer.GoldEquivalentFor(gameData, this);
int ourGoldValue = ourOffer.GoldEquivalentFor(gameData, this);
Expand Down
Loading
Loading