Maxing out City State Count

Charsi

Chieftain
Joined
Mar 18, 2015
Messages
45
Hi,

After reading various threads and looking through the lua and ui reference on modiki it seems that I should be able to set the number of city states to maximum in a game with a simple lua line:

Code:
PreGame.SetNumMinorCivs(math.min(41, #GameInfo.MinorCivilizations))

This doesn't seem to be taking effect for some reason, because when I go to kill off the settlers at the start of the game (Events.SequenceGameInitComplete) there are only the default number of city state settlers alive to be killed.

What happened to the rest of the city states, and what am I doing wrong? I'd like them all to be alive so I can reuse them later (in a manner similar to this).
 
You might want to use GameDefines.MAX_MINOR_CIVS instead of 41 in case someone is using a modded DLL.

Previously I've successfully used PreGame.SetNumMinorCivs(GameDefines.MAX_CIV_PLAYERS - GameDefines.MAX_MAJOR_CIVS) for a similar purpose and it worked OK.

EDIT: Oh, I see the issue. Are you assuming they all get a Settler? No, the minor player exists, it just doesn't get a settler unless you've changed the number in the Game Setup. You can give it a settler manually, though.
 
Yes, your assumption is correct - I assumed that SetNumMinorCivs didn't work since they didn't have settlers. I am testing now... guess I should have done that to start.

Edit: on a Duel size map (2 civs, 6 CS)...

If I call Players[25]:Found(x, y) it works (recreating a settler which I have printed to lua console that I killed off on turn 0).

If I call Players[30]:Found(x, y) it crashes to desktop. So it doesn't seem I can create a city state that wasn't part of the default number to start. Why? What am I missing?
 
This is the code isn't working. I'm not sure whether the SetNumMinorCivs should come before the SetTeam or what. I've tried it both ways.

Code:
iMaxCityStates = GameDefines.MAX_CIV_PLAYERS - (GameDefines.MAX_MAJOR_CIVS + 1)

for i = 1, iMaxCityStates, 1 do
	j = i + GameDefines.MAX_MAJOR_CIVS
	print("Forcing player/team [" .. j .. "]")
	PreGame.SetTeam(j, j)
end

PreGame.SetNumMinorCivs(iMaxCityStates)

The game still crashes if I try and use Players[30]:Found(x, y) on duel settings (unless x and y aren't a valid city site).

Note: if I restart the game on turn zero, the increased number of city states appear as settlers, and the Found code works. Everything I read says the additional CS's aren't considered to be "ever alive" according to the game engine, which is why they don't get a settler when the map is generated.
 
Okay, that's kind of what I thought. How do I make it happen at the beginning of the game, if not with a lua file (set as InGameUIAddin)?

I'm not sure if i'm explaining it right but none of that code is inside a function hooked to any game event. It just happens when the mod is loaded, which seems to be AFTER the map is created. Is it the wrong type (in Solution Properties > Content Tab)?

Edit: I tried changing the type.

Custom Type -> custom game; seemed to do something but i'd have a lot of work to do in there since I'd need to import some kind of setup screen
Map Script -> PreGame object is nil, lua errors everywhere.

...?
 
If you add a check that the current player is zero and Game.GetElapsedGameTurns() == 0, then that should ensure it only runs once at the beginning of the game, prior to most everything...
 
I'm familiar with that.

Code:
-- Kill City States on Turn 0
function TurnZeroKillCityStates()
	for i = 0, GameDefines.MAX_CIV_PLAYERS - 1, 1 do
		local pPlayer = Players[i]

		if (pPlayer ~= nil) then
			if pPlayer:IsAlive() then
				if pPlayer:IsMinorCiv() then
					for pUnit in pPlayer:Units() do
						if pUnit ~= nil then
							print("TurnZeroKillCityStates: Killing off [" .. pPlayer:GetName() .. "] unit [" .. pUnit:GetName() .. "]")
							pUnit:Kill()
						end
					end
				end
			end
		end
	end
end

Events.SequenceGameInitComplete.Add( TurnZeroKillCityStates )

It works very well, but only runs AFTER the map has been generated (including number of city states).

I've tried putting code in Events.AfterModsActivate() and it doesn't seem to fire until you load the map and spawn in.
 
Why does it matter that it's after map generation?

EDIT: You might have to make a Game Setup Menu replacement if you really need something to run prior to that.
 
Why does it matter that it's after map generation?

Because all city states past the default 6 (Duel) are invalid. I can't give them a city without the game crashing. Only a restart (turn 0) "fixes" it.

It's like some sort of "valid" flag was tripped for the city states listed in the advanced options (6 on Duel, so id's 23-28 are valid), but if you use SetNumMinorCivs() it may raise the number but they're not valid.

By way of example:

On a Duel sized map (6 CS):

Code:
SetNumMinorCivs(41)
Players[25]:Found(x, y) -- works because civ id's up to 28 were initialized
Players[30]:Found(x, y) -- game crashes because the id was not initialized

I took a look in YNAEMP and they use a custom setup screen.

I might be able to do this by using a second lua file and making that a "mapscript" but then the question becomes what variables etc. do I have available for use. I'll play around with a map script - perhaps I can override the user-chosen number of city states and just max it out. If I uncover something I will update and let everyone know. But just using SetNumMinorCivs() doesn't seem to be enough.

Edit #2:

This might do it. A MapScript containing only one line:

Code:
PreGame.SetNumMinorCivs( 41 );

Ideally i'd make it a variable but if that works just as a starting point to override the number of city states selected by the user BEFORE the map is generated, i'd be delighted.

Edit: well, that didn't work...
 
Sorry, my experience was a long time ago, and I eventually gave up on using the technique because of other issues, so I must have been setting the city states to the max manually in advanced setup to start with. It looks like a custom setup menu may be the only way.

However, note that you'll have the opposite problem if you use Reload, in that your setting may not be remembered, so I think you'll want to leave it in your InGameUIAddin also.
 
Agreed; I may have to just to tell users to max the number of city states.

Google found me Gedemon's Revolutions mod which seemed to set aside city states for use in "revolting" major civ cities, turning the city into a minor civ. But i'm not sure how that even works...
 
Hi there. If MAX_MINOR_CIVS is dependent on map size, or if there is a hardcoded cap in CS numbers dependent on map size, then my suggestion is useless as I only work with a huge map. :C

If it isn't, then: I am running a custom setup screen in my project. A modified OnStart() -function, tied to the start game -button, is used to force the amount of minor civs, keeping it secret to the human player. In my experience the setup screen is the only place where it is sensible to edit the PreGame values.

Code:
function OnStart()
        *stuff*
	PreGame.SetNumMinorCivs(GameDefines.MAX_MINOR_CIVS)

	Events.SerialEventStartGame();
	UIManager:SetUICursor( 1 );
end
Controls.StartButton:RegisterCallback( Mouse.eLClick, OnStart );
 
That's pretty much the conclusion I came to. You need a custom setup screen or the variables don't take (or take in strange ways).

Which means the mod has to push everyone through a custom setup screen. Kinda sucks and increases the potential for mod conflicts enormously.
 
Back
Top Bottom