Forced Specialists

Spatzimaus

Mad Scientist
Joined
Sep 21, 2005
Messages
3,063
Location
Los Angeles, CA
All right, I'm kind of stuck on one little detail in my own mod. Here's the problem.

I've created a new Specialist type, the Priest, used in my religious buildings. A Priest gives you 1 Food, 1 Culture, 1 Happiness, and (3, 6, or 9) Favor, where Favor is my custom yield that unlocks new gods and such. That's a lot of stuff, so they should be very desirable, especially once you unlock the National Wonders that add +1 Production or +1 Gold to them as well.

The problem is that the AI doesn't think so; it doesn't know about the Happiness or Favor part, and since they don't produce Great Person Points, it thinks Priests are less useful than normal specialists. The SpecialistFlavors table doesn't seem to be used at all; while it's in the vanilla game's XML, there's no actual table declared for any vanilla specialist types, and even setting a specialist's flavor to 999 doesn't make the AI more inclined to use them. So it looks like the AI only uses the yields given (and won't include any consideration for the Happiness or Favor I add) when deciding if/when to slot one. The only time the city manager AI will slot one is if a city is set to Great Person Focus (which, again, is stupid as they don't produce GP points).

Now, I NEED the AI to use a certain number of them, both in the city manager AI for the human player and the AI players' controller as well. So I found an override method based on how CityView handles specialist slots:
Code:
UI.ClearSelectedCities();
UI.AddSelectedCity(pCity, pID);
Game.SelectedCitiesGameNetMessage(GameMessageTypes.GAMEMESSAGE_DO_TASK, TaskTypes.TASK_ADD_SPECIALIST, iSpecialist, iBuilding);
UI.ClearSelectedCities();
And I just execute that command block within a loop that uses an equation to decide how many Priests to use based on a bunch of explicit factors. This works... for the human player. It slots a worker in the building, regardless of whether you've set the AI to manual or automatic specialist handling, and they stay there through the end of the turn, so it does exactly what I need. Similarly, TASK_REMOVE_SPECIALIST removes the specialist from a building, which I need to be able to do at the end of my mod's content to prevent things from breaking. This mechanism does what I want, for the human player's city AI, but it does NOT work, at all, for the AI-controlled players.

So is there any way to apply this, or any other method, to an AI player?

The problem seems to be that those UI commands, which require a city to be selected, can't be used for cities other than those of the active player. It just doesn't DO anything when I try it; a check immediately after the command says that there are still no Priests slotted in that city.

What's funny is that in my Alpha Centauri-based mod, the Empath specialist (+2 Food, +1 Happiness, +5 Great Empath points) is definitely used by the AI. So if I can't do this sort of hard override, I COULD just create a new great person type (say, the Great Prophet) for the Priests, and jack up their Great Person Points to a level where the AI still wants them. But I really doubt the AI will use the right number of them in this situation.
 
I have the same exact need. Nice find on the SelectedCitiesGameNetMessage.

Your theory about the UI is probably correct. However, it is also possible that the AI is undoing your change based on when in the turn you run this block. Is it at the beginning of the active player turn, the beginning of the AI turn, or after the AI turn? You can set up a function that runs for each player including AI after their turn by running it at the beginning of the next player's turn (for all but barb). Perhaps that could catch the AI at a time when it can't undo it.

Edit: Also, are you sure that it didn't work before the AI undid the forced specialist? I.e., did you check your GP points or did you check the current city specialists use?
 
Have you tried

Code:
city:DoTask(TaskTypes.TASK_ADD_SPECIALIST, iSpecialist, iBuilding)

at the beginning of the AI turn with GameEvents.PlayerDoTurn ?
 
I have the same exact need. Nice find on the SelectedCitiesGameNetMessage.

It's how CityView.lua handles it when you click on a specialist slot. And I didn't think to look there until someone suggested it in my mod's threads, so I can't even take peripheral credit. I'm trying to get the definitive version of my Mythology mod out on the 13th, and this was really the last bit of mechanics needed to make the game fully playable. Fix this, and add a few final content bits, and it'd basically be done other than the usual 3D unit model work and the occasional balance tweak.

I could have just increased the yields of the Priest until the AI would want to use them, but besides just being really overpowered once the "hidden" bonuses are applied, the AI just has no concept of moderation. If I've got 4 Priest slots in a major city, then I want the AI to only fill a few of them (0-2, 1-3, or 2-4 depending on your particular pantheon), but the existing logic is generally all-or-nothing.

However, it is also possible that the AI is undoing your change based on when in the turn you run this block.

Nope, checked that. IMMEDIATELY after setting the slot to occupied (within the same start-of-turn GameEvent), I checked the City:GetNumSpecialistsInBuilding command for the building I just modified, and it still says zero specialists for an AI player and 1 for the human player, so the problem was purely in the add command. I'm not saying that the recalculation phase won't also break it for the AI, but it's not even making it to that point.

And the usual end-of-turn recalculation is apparently not breaking it for the human player, since I verified the yields and such involved. So in theory, if I could make the AI work with that code, it SHOULD have the desired effects. Thing is, I could probably make it work by just changing which player is the Active player for just long enough to make this change stick. But I'm sure that'd break a dozen other things, especially since I'd be doing this dozens of times per turn for each player.

Gedemon said:
Have you tried ... city:DoTask?

Nice; I hadn't even noticed that command existed. Assuming the arguments work the same as that UI command, and it accepts a change command for an AI player, then it SHOULD work perfectly for this, at least in terms of setting the slotting; I still don't know if it'll work right during the recalculation phase at the end of each turn. I'll try it when I get home tonight. And since it wouldn't require any UI funkiness, a few of my other concerns go away as well.

It's still annoying that there's no equivalent GameEvent to PlayerDoTurn for an end-of-turn check. Sure, you can just check at the start of the following turn, but is it safe to assume that the game always goes through player IDs sequentially?
 
It's still annoying that there's no equivalent GameEvent to PlayerDoTurn for an end-of-turn check. Sure, you can just check at the start of the following turn, but is it safe to assume that the game always goes through player IDs sequentially?

Yes, it's sequential.

just a note, strangely, PlayerDoTurn for player 1 is fired before ActivePlayerTurnEnd (which is for the human player 0 on non-multiplayer game)
 
just a note, strangely, PlayerDoTurn for player 1 is fired before ActivePlayerTurnEnd (which is for the human player 0 on non-multiplayer game)

Yet another reason why I've been trying to migrate my logic away from the serial events. I've also seen times when EndCombatSim for the first combat occurs just AFTER RunCombatSim for the second combat; when the two combats involve the same unit, this can cause some serious issues. I'd be so much happier if they gave us a robust set of GameEvents...
 
just a note, strangely, PlayerDoTurn for player 1 is fired before ActivePlayerTurnEnd (which is for the human player 0 on non-multiplayer game)

That's weird. For what it's worth, I also noticed that PlayerDoTurn for player 0 fires before ActivePlayerTurnStart.

I wish that we had a detailed "time-line" of exactly what happens when with respect to turn events, AI, and effects. For example, PlayerDoTurn for an AI fires before AI units move, but is it before or after any city manager changes for the turn? And then you have techs already awarded but research points not yet deducted (right?). I'm really pretty vague about some of this, which adds a lot of difficulty to my AI modding. (Would other be interested in contributing if I start a thread on this?)

I've also seen times when EndCombatSim for the first combat occurs just AFTER RunCombatSim for the second combat; when the two combats involve the same unit,
The human player often does the next thing before the graphics have run their course on the last thing. I assume that's what's happening here. If so, it makes sense since the serial events are really about graphics. We all want access to game logic, but have to do this lousy hack of pinning it on a graphic functions.
 
Just to follow up: It works. The DoTask command's syntax on the wiki is wrong; the fourth argument requires a number, not a boolean, so I guessed "player ID" and it seemed to work just fine after that. And there was no end-of-turn funny stuff; the slotting made during the start-of-turn GameEvent seemed to persist just fine through the end. I still need to try it out a bit more in practice, but it's definitely handling it pretty well.
 
Related but different question:

Can city: DoTask() be used to force the AI (AI player or human city manager) to work a certain plot? I would need this to override any "out of food panic" from the AI. (For that matter, do we know that the forced specialist above is resistant to food panic?)
 
Can city: DoTask() be used to force the AI (AI player or human city manager) to work a certain plot?

I'd assume so. The CityView already has the line
Code:
Network.SendDoTask(pCity:GetID(), TaskTypes.TASK_CHANGE_WORKING_PLOT, 0, -1, false, bAlt, bShift, bCtrl);
so presumably this can be translated to the city:DoTask in the same way that the specialist one was. As usual, the main issue would be if there's any end-of-turn recalculation that might undo your choice.

For that matter, do we know that the forced specialist above is resistant to food panic?

My own mod (the one I started this thread for) really isn't a good way to test that. My Mythology mod includes an inherent food penalty, but the Priest and Empath specialists add a little food; I was actually counting on that "food panic" mechanism to get the AI to use them, but it didn't seem to happen.

One thing that's been reported in my mod is the AI somehow overriding your choices when you go into manual specialist mode, though. It doesn't appear to be caused by any error in my own code, which means the AI probably IS executing some sort of panic override. You could test this pretty easily, though, by ramping up the food penalty and making the specialists add a lot of food; I just haven't tried that.
 
Back
Top Bottom