Workers

Forestry is the new double-move-in-forests promotion.

Speaking of Forestry, isn't it a wasted promotion considering Woodsman II gives double movement in forests, jungles, etc., or is that unintended and Woodsman II needs to be nerfed like Guerrilla II was nerfed?
 
Why is the elephant worker now restricted in number?

I second this question. Why can I only have 5 Elephant workers, but the AI can have unlimited Mule workers? The pedia says the Buffalo workers are unlimited too.
 
I second this question. Why can I only have 5 Elephant workers, but the AI can have unlimited Mule workers? The pedia says the Buffalo workers are unlimited too.
Whoops, that's a relic of my Combat Worker experiment. I'll fix that when I get back.

Speaking of Forestry, isn't it a wasted promotion considering Woodsman II gives double movement in forests, jungles, etc., or is that unintended and Woodsman II needs to be nerfed like Guerrilla II was nerfed?

I already knew that and nerfed Woodsman and Guerilla when I added Forestry and Hillsman.
 
I already knew that and nerfed Woodsman and Guerilla when I added Forestry and Hillsman.

Unless you fixed it since the 10 June svn (not sure about the number) the Woodsman II still grants double movement but the Guerrilla II does not. It makes the Guerrilla line incredibly weak by comparison and makes the Forestry promotion pointless.
 
Unless you fixed it since the 10 June svn (not sure about the number) the Woodsman II still grants double movement but the Guerrilla II does not. It makes the Guerrilla line incredibly weak by comparison and makes the Forestry promotion pointless.

I can't check atm, but I could swear it was working as intended for me last week.:confused: Oh well, I'll check and fix that when I get back.
 
I noticed in my current game that workers can build seed camps on unirrigated territory, and that (once agriculture has been researched) seed camps that are worked will evolve into farms. This allows you to build farms on unirrigated terrain long before you should be able to 'by the back door'. Ideally we'd prevent seed camps evolving into farms unless the terrain requirements for farms are met (however, those are on the build, not the improvement, so currently the code cannot tell this restriction should be present). For now perhaps we should disallow seed camps to be built in places where farms cannot (I.e. Require fresh water for the seed camp build too)?
 
I noticed in my current game that workers can build seed camps on unirrigated territory, and that (once agriculture has been researched) seed camps that are worked will evolve into farms. This allows you to build farms on unirrigated terrain long before you should be able to 'by the back door'. Ideally we'd prevent seed camps evolving into farms unless the terrain requirements for farms are met (however, those are on the build, not the improvement, so currently the code cannot tell this restriction should be present). For now perhaps we should disallow seed camps to be built in places where farms cannot (I.e. Require fresh water for the seed camp build too)?

Done now on the SVN.
 
I noticed in my current game that workers can build seed camps on unirrigated territory, and that (once agriculture has been researched) seed camps that are worked will evolve into farms. This allows you to build farms on unirrigated terrain long before you should be able to 'by the back door'. Ideally we'd prevent seed camps evolving into farms unless the terrain requirements for farms are met (however, those are on the build, not the improvement, so currently the code cannot tell this restriction should be present). For now perhaps we should disallow seed camps to be built in places where farms cannot (I.e. Require fresh water for the seed camp build too)?

This is a hold over from the Stone Age mod where we got it from. I would like to think about it a bit.

Done now on the SVN.

Rats, too late.:p
 
@Koshling:

I was looking at some old files, and I found my old combat workers module archived somewhere. Didn't you say a while back that you would make the AI understand how to use combat workers? Is that still planned? I still would like to try and get them to work properly, and in a balanced manner.

Edit: I've added a branch to the SVN with all of my old Combat Workers stuff for now.
 
@Koshling:

I was looking at some old files, and I found my old combat workers module archived somewhere. Didn't you say a while back that you would make the AI understand how to use combat workers? Is that still planned? I still would like to try and get them to work properly, and in a balanced manner.

Edit: I've added a branch to the SVN with all of my old Combat Workers stuff for now.

No, I said the AI NEEDED to be made to understand them if we wanted them in. As things stand I have lots of AI work I want to do for EXISTING features before we start adding more that need AI work I'm afraid.
 
No, I said the AI NEEDED to be made to understand them if we wanted them in. As things stand I have lots of AI work I want to do for EXISTING features before we start adding more that need AI work I'm afraid.

Well, that's OK, the branch can remain there for a while. I too want some performance and AI improvements this version and next, and Multi-Maps can wait I suppose. Do you have a list somewhere of the AI and performance enhancements that you have planned?
 
Well, that's OK, the branch can remain there for a while. I too want some performance and AI improvements this version and next, and Multi-Maps can wait I suppose. Do you have a list somewhere of the AI and performance enhancements that you have planned?

In my head ;-)

See the SVN thread for the first cut of the first thing I wanted to do (building evaluation for techs)
 
@Koshling:

Where in the code is the AI behavior regarding workers located?

All AI unit behaviour (loosely speaking anyway) is in CvUnitAI.cpp. Workers use th routine AI_workerMove() as I recall (not able to look at source right now)
 
Here's the function in question. (I've been learning some c++, so I can figure out simple stuff).

PHP:
void CvUnitAI::AI_workerMove()
{
	PROFILE_FUNC();
	
	CvCity* pCity;
	bool bCanRoute;
	bool bNextCity;

	bCanRoute = canBuildRoute();
	bNextCity = false;

	// XXX could be trouble...
	if (!getGroup()->canDefend() && plot()->getOwnerINLINE() != getOwnerINLINE())
	{
		if (AI_retreatToCity())
		{
			return;
		}
	}

	if (!isHuman())
	{
		if (plot()->getOwnerINLINE() == getOwnerINLINE())
		{
			if (AI_load(UNITAI_SETTLER_SEA, MISSIONAI_LOAD_SETTLER, UNITAI_SETTLE, 2, -1, -1, 0, MOVE_SAFE_TERRITORY))
			{
				return;
			}
		}
	}

	if (!(getGroup()->canDefend()))
	{
		if (GET_PLAYER(getOwnerINLINE()).AI_isPlotThreatened(plot(), 2))
		{
			if (AI_retreatToCity()) // XXX maybe not do this??? could be working productively somewhere else...
			{
				return;
			}
		}
	}

It seems that the issue is that the function checks if the unit can defend, as opposed to checking other things (such as unitcombat). Hm, maybe it would be possible to add an or condition to the function which checks unitcombat.
 
Here's the function in question. (I've been learning some c++, so I can figure out simple stuff).

PHP:
void CvUnitAI::AI_workerMove()
{
	PROFILE_FUNC();
	
	CvCity* pCity;
	bool bCanRoute;
	bool bNextCity;

	bCanRoute = canBuildRoute();
	bNextCity = false;

	// XXX could be trouble...
	if (!getGroup()->canDefend() && plot()->getOwnerINLINE() != getOwnerINLINE())
	{
		if (AI_retreatToCity())
		{
			return;
		}
	}

	if (!isHuman())
	{
		if (plot()->getOwnerINLINE() == getOwnerINLINE())
		{
			if (AI_load(UNITAI_SETTLER_SEA, MISSIONAI_LOAD_SETTLER, UNITAI_SETTLE, 2, -1, -1, 0, MOVE_SAFE_TERRITORY))
			{
				return;
			}
		}
	}

	if (!(getGroup()->canDefend()))
	{
		if (GET_PLAYER(getOwnerINLINE()).AI_isPlotThreatened(plot(), 2))
		{
			if (AI_retreatToCity()) // XXX maybe not do this??? could be working productively somewhere else...
			{
				return;
			}
		}
	}

It seems that the issue is that the function checks if the unit can defend, as opposed to checking other things (such as unitcombat). Hm, maybe it would be possible to add an or condition to the function which checks unitcombat.

The unitcombat is always the same since this routine is ONLY used for workers. What happens is that when they can defend it just assumes they are good on their own due to those two clauses (the danger check and the retreat to city) not being called at all. That's way too binary - it needs to be made sensitive to how much danger (and what sort possibly) and not just retreat to a city (which is fine for a non-defensive unit, but for a defensive on its usually better to seek good defensive ground locally). If you look at the routines for other AIs (take the explorer one say) you'll see it's MUCH more complex and nuanced in this regard.
 
@Koshling:

Looking around a bit at the code I found the function exposedToDanger, which evaluates how much of a risk a unit faces. Would changing

PHP:
 if (!getGroup()->canDefend() && plot()->getOwnerINLINE() != getOwnerINLINE())

to something like

PHP:
 if (!getGroup()->canDefend() && exposedToDanger(plot(), 80) && plot()->getOwnerINLINE() != getOwnerINLINE())

help at all?
 
@Koshling:

Looking around a bit at the code I found the function exposedToDanger, which evaluates how much of a risk a unit faces. Would changing

PHP:
 if (!getGroup()->canDefend() && plot()->getOwnerINLINE() != getOwnerINLINE())

to something like

PHP:
 if (!getGroup()->canDefend() && exposedToDanger(plot(), 80) && plot()->getOwnerINLINE() != getOwnerINLINE())

help at all?

No. You need it to do what it does now for ones that can't defend, but make more subtle checks, and take more subtle actions for ones that can. The exposedToDanger() routine would be part of the more subtle checks, but retreatToCity() is not the best response for a unit that can defend really. Aslo the code that handles whether they call for an escort needs to be changed to account for differences in defensive capability (right now all workers call for escorts if there is any danger, but having a strength 2 worker call for a strength 2 escort would be a bit pointless). Those checks are all in the subroutines of the main one when it has determined where it wants to move to and evaluates danger at that location - if there is danger it won't go without an escort, which is not the right check for a unit that can defend (but nor is unconditionally not requesting an escort - it ceases to be black and white once they can defend)
 
No. You need it to do what it does now for ones that can't defend, but make more subtle checks, and take more subtle actions for ones that can. The exposedToDanger() routine would be part of the more subtle checks, but retreatToCity() is not the best response for a unit that can defend really. Aslo the code that handles whether they call for an escort needs to be changed to account for differences in defensive capability (right now all workers call for escorts if there is any danger, but having a strength 2 worker call for a strength 2 escort would be a bit pointless). Those checks are all in the subroutines of the main one when it has determined where it wants to move to and evaluates danger at that location - if there is danger it won't go without an escort, which is not the right check for a unit that can defend (but nor is unconditionally not requesting an escort - it ceases to be black and white once they can defend)

For the actual Combat Workers yes, but in this case the normal workers are so weak that they could only really take a unit two or three eras behind them, the only reason they have combat strength is to ward off animals later on (and to get xp, but that comes later). It would be close enough in almost all cases for the Industrial worker (Str 8) to call for an escort against most any contemporary unit.

Combat Workers are another animal entirely, and would need more subtle routines, I agree. However, I'm trying to do something simple here, as I know very little C++ so far.

I'll try a couple things and post them, to see what you think of them.
 
Back
Top Bottom