New Beta Version - January 26th (1-26)

Status
Not open for further replies.
Isn't warmonger score raising too high? I capture first city with population 9 and get -50-70 diplo penalty.

Depends on the civ - some civs care much more than others. Also pop isn't the key - it's the economic value of the city relative to all other cities in the world. If it was the largest city in the world, for example, that's a bigger deal than capturing some small outlier city.

G
 
Depends on the civ - some civs care much more than others. Also pop isn't the key - it's the economic value of the city relative to all other cities in the world. If it was the largest city in the world, for example, that's a bigger deal than capturing some small outlier city.

This entire approach makes intuitive sense, and is inherently subtle and dynamic, besides. It actually makes you think about what city (and from which civ) to conquer. It's an aspect of the game that will never get stale.
 
Depends on the civ - some civs care much more than others. Also pop isn't the key - it's the economic value of the city relative to all other cities in the world. If it was the largest city in the world, for example, that's a bigger deal than capturing some small outlier city.

G

I think I remember from a discussion long gone that the economic value is largely based on nearby resources?
 
I think I remember from a discussion long gone that the economic value is largely based on nearby resources?

Spoiler :

Code:
    int iYieldValue = 0;

    CvWeightedVector<int, SAFE_ESTIMATE_NUM_BUILDINGS, true> validResources;

    //notes:
    //- economic value is in gold, so use a rough conversion factor for the others
    //- for food and gold only surplus is interesting, rest is converted to other yields already
    //- ignore trade, as the city might the change owner
    iYieldValue += (getYieldRateTimes100(YIELD_FOOD, true) - foodConsumption() * 100) * 3;
    iYieldValue += getYieldRateTimes100(YIELD_PRODUCTION, true) * 4;
    iYieldValue += getYieldRateTimes100(YIELD_SCIENCE, true) * 3;
    iYieldValue += (getYieldRateTimes100(YIELD_GOLD, true) - GetCityBuildings()->GetTotalBaseBuildingMaintenance() * 100) * 1;
    iYieldValue += getJONSCulturePerTurn() * 3;
    iYieldValue += GetFaithPerTurn() * 3;

#if defined(MOD_API_UNIFIED_YIELDS_TOURISM)
    iYieldValue += getYieldRateTimes100(YIELD_TOURISM, true) * 3;
#endif
#if defined(MOD_API_UNIFIED_YIELDS_GOLDEN_AGE)
    iYieldValue += getYieldRateTimes100(YIELD_GOLDEN_AGE_POINTS, true) * 3;
#endif

    //divide by avg conversion factor
    iYieldValue /= 3;

    //now check access to resources
    //todo: call CvDealAI::GetResourceValue() for each resource

    int iWonders = getNumWorldWonders() * 50;
    iYieldValue += iWonders;

    for (int iI = 0; iI < GetNumWorkablePlots(); iI++)
    {
        CvPlot* pLoopPlot = GetCityCitizens()->GetCityPlotFromIndex(iI);
        //for plots owned by this city
        if (NULL != pLoopPlot && GetID() == pLoopPlot->GetCityPurchaseID())
        {
            //todo: add something for currently unworked plots (future potential)
            ResourceTypes eResource = pLoopPlot->getResourceType(getTeam());
            if (eResource == NO_RESOURCE)
                continue;

            const CvResourceInfo* pkResourceInfo = GC.getResourceInfo(eResource);
            if (!pkResourceInfo)
                continue;

            if (GC.getGame().GetGameLeagues()->IsLuxuryHappinessBanned(getOwner(), eResource))
                continue;

            int iResourceQuantity = pLoopPlot->getNumResource();

            validResources.push_back(eResource, iResourceQuantity);
        } //owned plots
    } //all plots

    for (int iPlayerLoop = 0; iPlayerLoop < MAX_CIV_PLAYERS; iPlayerLoop++)
    {
        PlayerTypes ePossibleOwner = (PlayerTypes)iPlayerLoop;
        m_aiEconomicValue.setAt(iPlayerLoop, 0); //everybody gets a new value

        if (ePossibleOwner != NO_PLAYER && GET_PLAYER(ePossibleOwner).isAlive())
        {
            int iResourceValue = 0;
            if (validResources.size() > 0)
            {
                for (int iResourceLoop = 0; iResourceLoop < validResources.size(); iResourceLoop++)
                {
                    //todo: add something for currently unworked plots (future potential)
                    ResourceTypes eResource = (ResourceTypes)validResources.GetElement(iResourceLoop);
                    if (eResource == NO_RESOURCE)
                        continue;

                    if (GET_TEAM(GET_PLAYER(ePossibleOwner).getTeam()).IsResourceObsolete(eResource))
                        continue;

                    const CvResourceInfo* pkResourceInfo = GC.getResourceInfo(eResource);
                    if (!pkResourceInfo)
                        continue;
    
                    int iResourceQuantity = validResources.GetWeight(iResourceLoop);
                    if (iResourceQuantity > 0)
                    {
                        ResourceUsageTypes eUsage = pkResourceInfo->getResourceUsage();
                        if (eUsage == RESOURCEUSAGE_LUXURY)
                        {
                            int iValue = 200;

                            // If the new owner doesn't have it or the old owner would lose it completely, it's worth more
                            if ((GET_PLAYER(ePossibleOwner).getNumResourceAvailable(eResource) == 0) || (GET_PLAYER(getOwner()).getNumResourceAvailable(eResource) == iResourceQuantity))
                                iValue = 600;

                            int iHappinessFromResource = pkResourceInfo->getHappiness();
                            iResourceValue += iResourceQuantity * iHappinessFromResource * iValue;
                        }
                        else if (eUsage == RESOURCEUSAGE_STRATEGIC)
                        {
                            int iValue = 400;

                            // If the new owner doesn't have it or the old owner would lose it completely, it's worth more
                            if ((GET_PLAYER(ePossibleOwner).getNumResourceAvailable(eResource) == 0) || (GET_PLAYER(getOwner()).getNumResourceAvailable(eResource) == iResourceQuantity))
                                iValue = 800;

                            iResourceValue += iResourceQuantity * iValue;
                        }
                    }
                }
            }

            m_aiEconomicValue.setAt(ePossibleOwner, iYieldValue + iResourceValue);
        }
    }
}
 
That notation! <3
 
pls translate important parts to English? :3

Every coding language that I'm aware of has a way of making notes that explain the code. In this case, the thing you're looking for is "//"

Once we know how these notes are added, even without understanding the language, we can find markers of the authors' intent above the language, where we learn tidbits like

//- economic value is in gold, so use a rough conversion factor for the others
//- for food and gold only surplus is interesting, rest is converted to other yields already
//- ignore trade, as the city might the change owner

So value is the cities resources produced, represented in gold, multiplying other resources by a conversation factor so that their values are reported in gold.

//divide by avg conversion factor
iYieldValue /= 3;

//now check access to resources
//todo: call CvDealAI::GetResourceValue() for each resource

int iWonders = getNumWorldWonders() * 50;
iYieldValue += iWonders;

So everything is divided by 3, and the note gives us the reason why the author chose 3. Then it has a placeholder reminding the author to go back and add a bit so the AI adds the value of nearby resources. Then it adds the number of wonders multiplied by 50 to the value of the city.

I'm unsure about the bit nested under this, but it seems like value is added for the plots the city works and compared to all available plots?

Below that, we find another placeholder reminding the author to add code that will have the AI value future workable plots.

There are a few mysteries to me in there (namely: " // If the new owner doesn't have it or the old owner would lose it completely, it's worth more")
because I don't know the language and I don't understand Civ Modding outside of very, very limited abilities to tweek values, but if I needed to learn it for one reason or another, these sorts of notations would be incredibly helpful.

There are undoubtedly bits I've read wrong, too, so don't take this post as any sort of Rosetta stone.
 
The change to warmongering is the best part of this patch.

Early game warfare to counter expansionism is no longer as punishing.
 
Let them eat cake.

Spoiler :
U7Ghu2s.gif
 
Game freeze on barbarian turn. Unfortunately, I did not have logging enabled during this game. :c5unhappy:
 

Attachments

  • Screenshot from 2018-01-28 14-36-36.png
    Screenshot from 2018-01-28 14-36-36.png
    3.9 MB · Views: 162
For the freeze issue:

1. Disable random seed, so new reload doesn't change the result.
2. Enable AI logging.
3. Manually save at the end of each turn, just before pressing next.
4. When the freeze occurs, reload and see if this happens again pressing next.
5. Zip your log files and the last save game and upload them to the github issue.

Those are the conditions ilteroi needs to be able to search anything.
 
I think city happiness must count as a primary parameter on conquer. If city is too much unhappy - all in the world must be happy, that it was conquer.
 
Is it my computer, or does anyone else have the problem where automating units sometimes crashes the game?
 
For the freeze issue:
Those are the conditions ilteroi needs to be able to search anything.

We’re trying to identify if the problem is in VP itself or related to other mods. The working theory is memory issues caused by lots of mods and/or big maps. So, it would be best if this would be a clean VP install, with no other mods enabled (no RAS, FlagPromos, InfoAddict, etc.) running standard game.

The other aspect could be number of turns. The longer you play, the more memory is used. If you restart the game, the memory is cleared and you can play more. As a consequence, problems could be more frequent in late game which is memory heavy by default, then in early game.
 
Status
Not open for further replies.
Back
Top Bottom