How could we make the AI more challenging?

Marla_Singer

United in diversity
Joined
Oct 24, 2001
Messages
13,636
Location
Paris, East side.
Why this thread?

Civ4Col's AI is desperately weak. No matter the difficulty level.

This is so true that it's just not fun at all. When I play RAR, the fun is mainly about challenging myself. I don't feel any competition at all with other European settlers, they are about as "environmental" as are the natives.


Improving the AI for which purpose exactly?

Mainly, to make the Human player feel more "threatened" by the AI.

Of course in the best of the worlds we would try to make the AI behaves as a human, but Civ4Col mechanism, especially with RAR, are so different from Civ4 (on which the AI is largely based) that I believe the task wouldn't be worth the time it would take.

That's why the more I think about it, the more I personally believe the AI should simply play a simpler game, but one that would make it more threatening to the Human player.


Let's brainstorm together for solutions!

In this opening post, I'm not proposing solutions on purpose. As this thread is aimed to collective brainstorming.

Of course I have some ideas on solutions, but I'll post them in a next post, as what matters first is to think together before testing ideas.
 
To start the discussion, here are some elements I have observed. Just writing them as food for thoughts.


The AI doesn't properly allocate citizens professions

From what I've seen, the AI assigns jobs according to their direct production value. That "direct value" seems to be calculated according to a formula involving as inputs the amount of goods produced, the current selling price in Europe and the "iAIBaseValue", which is a YieldInfos.xml parameter.

The AI doesn't take into account any "potential value", which would be the value of the production if it would later be transformed. For transforming jobs, it only checks if there is supply and then calculate its direct value the same way as any other job.

That's the reason why, for instance, the AI doesn't produce hammers. In order to produce hammer, you need lumber first. But lumber has both a poor selling price and a poor iAIBaseValue, so the AI pick other jobs, and as there's no lumber, there's no hammer.

A human player will think the other way around. First he tries to optimize his manufactured goods production, and then adapt its raw materials production accordingly. To continue with my hammer example, if we can't produce more than 6 hammers, we will target to produce 6 lumber and not necessarily more.

That's why I'm not sure a simple XML balance could solve the issue. Maybe we could imagine that, besides the "direct value" calculation, there would be a "potential value" calculation that would be determined by the current transforming capacity in the city. This way, the first 6 lumber produced will have a big "potential value" and the extra lumber would have none. I would be glad to have a developper feedback on that one.


The AI has no clue how to get specialists

The more I think about that one, the more I believe it is absolutely impossible to make the AI emulate the Human player behaviour.

That's why I would consider a radical solution: every 20 turns or so, we simply make all AI citizens specialists of their currently assigned jobs.

If you consider that's just too much cheating, please remember the AI has no brain, that gives you a considerable advantage which actually makes you the cheater. :mischief:


The AI doesn't know what buildings to build in a city

Here is a post explaining how the AI pick its buildings to build in Civ4.

The code is located in the CvCityAI.cpp file and the mechanism seems to have been modified both with TAC and with RAR.

The big issue is that the mechanism (or what I've understood from it) cannot properly handle city specialization. The AI will build a rum distiller's house in the tundra even if it's impossible to produce sugar cane around. Then he will build a spice trader's house, he won't even focus in developping his distillery... And if the AI is lucky it can then decides to build a fur trader's house.

Here again, I have an idea which may sound radical, so that's why I would be glad to have your opinion.

The idea is to differenciate universal buildings and specialization buildings. Universal buildings are those that serves a purpose in all colonies : buildings producing bells, hammer, storage capacity, defence, sea food and land food. These buildings could be built by the AI anytime it wants.

All the other buildings would be specialization buildings. And here goes where my idea is becoming radical. I would ban the AI from building the 1st level of them. However, I would give the AI for free the 1st level building as long as the city meets a specific prerequisit. For instance : if the city produces more than 3 tobaccos, it will automatically get a tobacconist's house the next turn.

Then, the AI will be free to upgrade to Tobacconist's shop (2nd level) anytime it wants. This way, I expect to make the AI build things that always serve a purpose to it. And I expect that naturally, the city will specialize as there wouldn't be so many choices of buildings to build anyway.


The AI doesn't know how to handle hammers, tools and stones requirements

That's my last point. Considering that the AI doesnt know how to produce even hammers, I was wondering how does it get its buildings. And the solution is obvious, it simply buys them all.

All the money I spend in Europe to hire immigrants and specialists in the earlier stage of the game, the AI spends it in buying buildings that for many of them, don't even serve a purpose.

The more I think about, the more I believe that, for game balance, it's probably better to keep things this way.
 
Someone needs to reply to this so I will step up. I thank you for your insightful post on the condition of the AI. In my modding I noticed several of these things myself and I have addressed some of the easier issues in the M:C mod, either by improving the AI or giving them a handicap. I haven't really sat down and thought of how to make the AI even better to a great extent however.

One of the biggest AI issues with Col is there is a two step process for military units. You have to acquire the Citizens and then also acquire the Weapons, in Civ4 you just produce the Units. So, if the player can get an early Weapon production start they can easily over take most AI's. Anyway, that is also one of the many issues.

Having looked through some of the AI I realized the what the Devs have given us is mainly a sandbox for modders to play in. They have given us the basics, now it is up to us to flesh out the AI and give them life. I feel like with proper AI planning, the AI can be trained to act more like humans would. Perhaps my next mission will be to improve the AI in the M:C mod at least, at the moment, though, I concentrating on the Economy.
That's why I'm not sure a simple XML balance could solve the issue. Maybe we could imagine that, besides the "direct value" calculation, there would be a "potential value" calculation that would be determined by the current transforming capacity in the city. This way, the first 6 lumber produced will have a big "potential value" and the extra lumber would have none. I would be glad to have a developper feedback on that one.

The "Potential Value" suggestion is a pretty good idea. I have worked with this part of the code some what in order to get Cities to produce Nobles (M:C uses Luxury Food to produce a Noble Class) and I may have had similar thoughts (its been a while but your idea sounds a bit familiar). Anyway, when I visit the AI again I will keep your post in mind, so thanks again for your time and post.
 
Those are good points; I think ideally systems for improving AI economic decisions should make it more adaptable and responsive to supply/demand conditions for any Yield in general, rather than a fixed or hardcoded weighting to a single Yield like Weapons/Spices etc. For instance if local prices are affected by supply and demand for each yield, the local price can appropriately reflect Potential Value, and the AI (and independent traders in M:C) can become more able to seek out supply/demand mismatch for any particular Yield and can move to address this by adjusting production and transport/trade. In Marla Singer's example, constructing manufactory buildings would cause local demand for low-priced Yields such as Lumber that are inputs of that building to increase. The increased local demand would increase local prices of that Yield (with this representing Kailric's and Marla's concept of the current "Potential Value" of that yield being higher there than in Europe). This would cause the AI to appropriately prioritize local production of that Yield, and also to prioritize transport of that Yield where it is currently needed.
 
The AI doesn't properly allocate citizens professions
I posted something on how to deal with that. I think it was in the M:C board, but it applies to all mods.

When the AI tries to figure out the best profession for a unit, before it does so, it will figure out which profession(s) it has bonuses in. It then loops all units to find those already using that profession. If any, it can swap the two units if it provides a production bonus.

Example: (think vanilla)
  • There is a colony, which has just one water plot. There is a free colonist on that plot producing fish.
  • An expert fisherman just arrived from Europe and the AI tries to find the best location.
  • The AI detects that production would be better if the expert fisherman does the fishing
  • The free colonist is set to NO_PROFESSION
  • The fisherman is set to fishing
  • The free colonist then tries to be assigned to a new profession
It can possibly be expanded to make the unit loop all colonies to figure out which one to join for a production bonus. That way the fisherman will not go to an inland colony and try to skip colonies already filled with expert fishermen.

It might not be ideal, but at least the AI will figure out how to use expert units. Right now the AI usage of experts is.... lets just say that it will be pure luck if it manages to place an expert in his expert profession.

DoaNE lists what experts you can use. Clearly it is possible to do that meaning somehow it should be possible to make a professional unit wishlist for the AI. I'm not sure how it should react to the list, but for a start it could send units to be trained at natives.

The AI doesn't know how to handle hammers, tools and stones requirements
I have written code where the threshold increases to minimum requirements of the most expensive building in the construction queue. As a result, using feeder service, import and export with a threshold of 0 will make the colony export this yield if it has any. If it needs 50 for building a building, it stops exporting and imports until it reaches 50 and then it exports any excess. Once the building is finished, the threshold goes back to 0. No human interaction and the human controlled threshold has been 0 all the time.

This code is currently in M:C and in a local copy of RaR. I plan to add it to RaRE once it gets going.

The plan is to set the AI to simply use feeder service for yields it needs for construction and since all AI transports are fully automated, they will understand feeder service without further modifications. All what is needed is modifying CvCityAI.cpp.
 
Why this thread?

Civ4Col's AI is desperately weak. No matter the difficulty level.

This is so true that it's just not fun at all. When I play RAR, the fun is mainly about challenging myself. I don't feel any competition at all with other European settlers, they are about as "environmental" as are the natives.


Improving the AI for which purpose exactly?

Mainly, to make the Human player feel more "threatened" by the AI.

To start the discussion, here are some elements I have observed. Just writing them as food for thoughts.

The AI doesn't properly allocate citizens professions

The AI has no clue how to get specialists

The AI doesn't know what buildings to build in a city

The AI doesn't know how to handle hammers, tools and stones requirements

I have to agree with these statements.
In fact, any TAC/RaR-game is only interesting for the first 100 turns, and that is only since the human player is put at a decisive disadvantage: he lacks military strength and therefore has to be very, very careful in what he's doing.

If he did survive this initial phase, there isn't any challenge anymore - mainly because the Natives aren't imposing any challenge nor an interesting game feature anymore, and because the AI lacks in each area which Marla has correctly identified.

In total it comes down to the fact that the AI is not capable of valuating anything at least halfway correctly.
And, as sad as it may be, this problem seems to have become even more crucial with the last versions of RaR (which I am currently playing). The more units, professions and yields are available in the game, the less the chance for the AI to at least accidentally pick the right thing.

Of course one can try to whitewash this by giving the AI even more bonuses, yet it only leads to the human player and the AI playing completely different games. And scaling these bonuses so that they will work "correctly" at any difficulty level, any mapsize and any gamespeed seems to be next to impossible.

Conclusion: the answer is not to have even more of everything, but more of a meaningful working AI. This might even require to reduce the currently available options for the human player.
 
I think one of the big issues with the AI is that it has access to lots of high value yields, which it intend to produce and sell. It does that fine, but there is a balance issue where lumber has lost its value. This makes the AI clear all forests to make room for cotton plantations and stuff like that.

Increasing the value of lumber and hammers for the AI would counter this effect somewhat and it would be a fairly easy XML change. The only real problem is that it needs a whole lot of playtesting to figure out if a new setting is better or worse than the old one and finding the right numbers could be rather time consuming.

A more advanced solution would be to make a cityAI lumber production planing. The AI would prefer to get a certain fraction of the plots to be lumber producing, hence it will not cut down forests if the limit has been reached. This should be done from the XML and requires a whole lot of checks. A simple approach would be to avoid removing the feature, but then what if the pioneer is set to make a mine and the feature just dies in the process? What if 3 pioneers remove 3 forests at the same time when only one is allowed to be removed? There are plenty of stuff, which can go wrong, which is likely one of the reasons why nobody has tried to fix this issue.
 
This is complicated by the fact that it's not simply Lumber but all Yields that are potentially required for completing Buildings or constructed Units, or especially for equipping Professions, which the AI has no idea of how to plan for. Also, removing some Features can potentially provide Yields from harvesting, and some Features can regrow if an Improvement is not present, so harvesting Features can be a reasonable strategy to create Yields. Something hardcoded specifically for Forest chopping or YIELD_LUMBER could mainly apply to a pure vanilla setup and could likely have lots of unintended consequences. However, using XML to tweak the value the AI puts on individual yields like Lumber/Tools is useful to try with playtesting on a per-mod basis.

For yields required to complete Units/Buildings, the AI's most serious yield planning problems could be helped somewhat by the M:C changes which let it see the construction Yields as actively being consumed in the city (as occurs in vanilla during yield consumption by city Professions).

In general, adding many complicated Yield requirements to the game like in M:C or RaR makes it important to give the AI some form of "safety valve" for when it needs Yields to complete a Unit/Building/Profession but couldn't possibly coordinate the complex series of steps to produce and transport that Yield to a single central location like a human player could by planning many turns in advance.

For the inevitable situation where the AI "gets stuck" on a Yield requirment due to having unavoidably less advanced multistep planning than humans, the biggest benefit could come from allowing the AI to use Plotgroup transport to fulfill some of its Yield requirements at least at more challenging difficulty levels. (That's actually something I would enjoy as a player too, due to finding duties as Wagon Train Scheduler the least interesting part of the game :cowboy:) Taking it further, maybe HurryInfos.xml could be adapted to allow some unlockable options for completing construction with Gold when a Yield requirement is lacking. (Imagine a Black Market perk or economic Tech or Civic allowing the ability to source certain goods rapidly to complete construction when needed, although paying a high price for the privilege when forced to, perhaps as some multiple of the selling price in a certain tradescreen). :king::gold:
 
For yields required to complete Units/Buildings, the AI's most serious yield planning problems could be helped somewhat by the M:C changes which let it see the construction Yields as actively being consumed in the city (as occurs in vanilla during yield consumption by city Professions).
I wrote that for the AI and realized it could be useful for humans as well. However I never finished this and as a result, this AI code is for humans only :crazyeye:

For the inevitable situation where the AI "gets stuck" on a Yield requirment due to having unavoidably less advanced multistep planning than humans, the biggest benefit could come from allowing the AI to use Plotgroup transport to fulfill some of its Yield requirements at least at more challenging difficulty levels.
That's another AI feature I haven't finished yet. Also it should be noted that while vanilla BTS has plotgroups, Colonization does not and to my knowledge, M:C is the only colo mod, which has them. Vanilla as map areas and if I get it right, one island = one area (like civ wonders, which gives bonus to all cities on the continent). However unlike M:C plotgroups, this will not tell if there is an unbroken road between two cities.

Adding plotgroups turned out to be a bit of a hassle because it turns out that plotgroup spread is handled by the BTS exe and the Colo exe can't do that. I had to make do with whatever pathfinding the colo exe has to offer. However writing this right now, I realized it would actually be rather simple to make the spread 100% DLL code. All what is needed is just a function to start on a plot (like the cities), then call all plots next to it and write a check if it spreads there. The exe calls the DLL to perform the checks anyway meaning it would more or less just be the plot loop, which needs to be written.
 
:hmm: Brainstorming some potential algorithms/ideas to help with AI production planning.. :coffee::science::scan:

How to appropriately weight the value of one unit of each Yield:
There should be an adjustable AIWeight for each Yield, so this can be balanced as needed through playtesting for each mod and can avoid hardcoding specific Yields. But ideally, so the AI can respond to changing market prices, the final ValueWeight it puts on each Yield could be the local SellPrice multiplied by the AIWeight multiplier. This could enable modders to optimize and adjust values for specific Yields without needing to rewrite the DLL, and still let it consider market prices. (I clearly don't know much about the vanilla AI innards, but think this may not be too far from the intent for valuing Yields in the core game.)

For manufactured Yields that consume an input, based on the points rased by others above here are two main areas where some progress might be made:

1) The AI should be encouraged to prioritize high value manufactured Yields, while simultaneously making an effort to produce raw materials that are an input for those Yields. This might be done by prioritizing jobs based on their total value produced (assuming all inputs are available), checking whether it's possible to produce enough input yields, and if so assigning the first unit to the manufacturing job and assigning another unit to produce the needed input yields. (If the AI can use PlotGroups to supply input yields, at least at higher difficulty levels, this could avoid many raw material sourcing problems and greatly improve its performance, so could actually turn out to be a better solution).

2) Manufacturing also removes the raw Yields that were consumed in production (which themselves had value and required labor) so this needs to be considered, making the net value of the manufactured Yields somewhat less than you might expect. This could benefit from the economic concept of Value Added, where ValueAdded = Valueofyieldsproduced - Valueofyieldsconsumed
This would also avoid some problems where raw input Yields may be undervalued by the AI because of their low price.


How to improve AI use of specialists? Some ideas, starting from the premise of prioritizing based on which can produce the maximal value:

Once per player per turn, create an array that ranks specialist UnitTypes in order of which can produce the most maximal added value from its specialist bonus. This can be used to prioritize which specialists should be considered first when planning production, and might be done with something like:

foreach unittype, take the highest Yield production bonus it has and multiply that by ValueAdded of that Yield.

When trying to assign unassigned citizens, consider something like the following:
Code:
foreach unassigned citizen (going in the order above):
	foreach potential job (tile or building slot):
		calculate ValueAdded from that job (value of produced Yield minus consumed Yield)
			if the job consumes input Yields, assign another unit to produce the input Yield
			if that's not possible, proceed to the next possible job

How to improve the AI's Building planning? When deciding what Building to build in a city:
foreach available BuildingType, take the highest Yield production bonus it has and multiply that by the maximum of that Yield currently producible in the city (considering available inputs) times the ValueAdded of that Yield. If you want, you could add a slight adjustment for the cost of Yields used to construct the Building. Again, to avoid it getting terminally "stuck" the AI may need to be able to use Plotgroup transport to let it finish Buildings requiring a Yield to construct, or have some HurryInfos.xml option to finish construction at the cost of some gold if or when it gets terminally stuck completing a building.

In fact I'm wondering if some of these worker assignment algorithms may result in infinite loops in some cases, so it may be best to take an alternate approach such as making a multidimensional array based on ValueAdded of each Unit/Profession combination in a city, and then using this to select the optimal set of Unit/Profession combos. I don't know much about the kinds of algorithms actually used in serious optimization problems like that, but perhaps some sort of highly advanced computer science and engineering wizard might be able to figure out genius breakthroughs that escaped the minds of Firaxis.. ahem, Nightingale..? :scan::science::scan:

This is likely still to need a lot more thought and planning to get to ideal algorithms if we ever will; it really may be very hard to impossible to get the AI to simultaneously optimize specialist Unittypes and produced and consumed Yields etc. But at the very least we may succeed in making at least some moderate improvements on the horrible vanilla decision making. :lol::crazyeye:
 
perhaps some sort of highly advanced computer science and engineering wizard might be able to figure out genius breakthroughs that escaped the minds of Firaxis.. ahem, Nightingale..? :scan::science::scan:
Shut up. I'm concentrating hard on spell research and you are breaking my concentration. I'm trying to look into mind control to convert casual players into modders. So far all attempts have failed, but I'm not giving up
wizard.gif



I haven't really investigated the current AI code for city/population management, but I do know it's fairly broken. For starters it shifts all units to new positions each turn, making it impossible to reach the RaR learning by doing goal.

I like your brainstorming regarding the buildings. Somehow I think the best solution would be when the AI has to decide which building to build, it can "sandbox" the building state, allowing it to make each building magically appear, figure out how useful it is, remove it, add the next to analyze and so on. If we then add a score system based on stuff like produced yields and stuff like that, then the system will adapt to future code changes even without AI updates. After all if a production bonus is applied in the code, it is applied to the sandbox, hence a higher production score. It also mean that the AI planning code will not have to consider production bonus from FF, traits and whatever.

However as I wrote somewhere else (in the RaRE thread, I think), the first step to improve the AI is to figure out what it is doing. This mean the first piece of code should be AI "spyware", some sort of code to figure out what it is doing. Once we know that, we can see what it is doing really wrong, fix that and then the AI viewing code can be used to tell if the fix worked or not.

I imagine something like adding an on/off switch for each player. If switched on, all plots viewed by that player is visible to the human, all movements are shown. Clicking on a city allows you to look inside. Possibly more stuff as well. Since this is a serious cheat, not to mention potientially a huge slowdown, it should be coded using an #ifdef setup. This mean it can be disabled entirely at compiletime, which prevents a slowdown for regular gaming.

Stuff, which could be interesting to add is a unit memory of mission and professions for that unit for the last X turns. Possibly a cached value of value for each building a city can produce. We can add all sorts of interesting data, which can then be written onscreen if we hover the mouse over units and stuff.
 
I imagine something like adding an on/off switch for each player. If switched on, all plots viewed by that player is visible to the human, all movements are shown. Clicking on a city allows you to look inside. Possibly more stuff as well. Since this is a serious cheat, not to mention potientially a huge slowdown, it should be coded using an #ifdef setup. This mean it can be disabled entirely at compiletime, which prevents a slowdown for regular gaming.
A first step to this is available by pressing CTRL + Z (might be CTRL + Y for non-german keyboard designs), which triggers some worldbuilder functionality. It reveals map and borders and allows you to look into other civilizations' cities, while still being in the game.

For instance it reveals a problem with the AI's first turns: typically the AI of colonial players will drop the first unit at the first land plot, the ship will move on to explore more of the map (somewhere there is a functionality ordering the AI to explore at least 10 land tiles) and then in most cases the second unit will found the first city. Obviously, in at least some cases this first city will suffer from the first unit still being somewhere else on the map and not in the city. If so, the AI will not start creating buildings, but gathers yields.
This immediately leads to the next problem: as I pointed out somewhere already, the single best thing you can do at the beginning of the game (talking especially about the RaR line) is to build religious buildings. Nothing provides you quicker with more units than this. And more units mean more food, more production, more of everything.

Talking about RaR, knowing this enables the human player to make up for almost any bonus the AI gets in the beginning of the game (except free city defenders).
 
:hmm: Brainstorming some potential algorithms/ideas to help with AI production planning.. :coffee::science::scan:

How to appropriately weight the value of one unit of each Yield:
There should be an adjustable AIWeight for each Yield, so this can be balanced as needed through playtesting for each mod and can avoid hardcoding specific Yields. But ideally, so the AI can respond to changing market prices, the final ValueWeight it puts on each Yield could be the local SellPrice multiplied by the AIWeight multiplier. This could enable modders to optimize and adjust values for specific Yields without needing to rewrite the DLL, and still let it consider market prices. (I clearly don't know much about the vanilla AI innards, but think this may not be too far from the intent for valuing Yields in the core game.)
This seems logical at first glance, but leaves out some important factors.

Currently, all units working in a city consume 2 food per turn. This means, the value of any yield "produced" by these units should be set into relation to the food consumption.

This becomes especially clear when looking at the two most problematic production lines (talking about RaR here):

1) Ore
Ore is needed for producing tools. Tools are needed for constructing buildings, yields like cannons, muskets and blades and for producing units like ships (in combination with other yields).
Unfortunately, 1 ore = 1 tool = 1 cannon/musket/blade; regardless of the "demand" you have at any given point of time and regardless of the price for any of these yields.
(Not to mention the reality factor: it is completely unlogical to have to need as much ore for a blade than for a cannon)
In short, the total ore - tools - weapons line is completely broken, if you ask me.
2) Coloured cloth
Let us assume that each unit/profession combination in this line will produce 3 yields per turn.
For coloured cloth you need to produce cotton (current sales value 5 - any "current sales value" taken from an actual game) and indigo (current sales value 5). From the cotton you produce cloth (current sales value 11) and the coloured cloth is produced from cotton and indigo (current sales value 20).
And finally you need two production buildings, the weaver's house and the dyer's house.
So, to keep the coloured cloth's production on and going, you need 8 food per turn, you have to have the buildings and you will get a final result of 3 * 20 gold = 60 gold.

Do the math and you will see that you will get 7.5 gold per food unit consumed.

Now, the assumed cotton planter will produce 3 units of cotton (15 gold) for 2 food units.
He is as "productive" (in terms of income) as the dyer.

But the yield "Coloured Cloth" will inevitably be valued higher than cotton.

But investigating a bit further, you will see that currently cloth will deliver a value of 8.25/food, yet the sales price still is much lower than for coloured cloth.

Conclusion of 1) and 2):

As far as I see it, the problem has to be adressed in multiple ways:
First, a new setup of the market prices has to be done (rather easy in terms of doing it as we "only" have to change some XML values).
Second, the ratios between ingoing and outgoing yields have to be readjusted (once again, this is rather easy from the technical point of view since this can be done via XML, too - although there might be the need or at least the desire to add some new functionality).
Third, the AI has to enhanced in such way that it can compare the value/food ratio for any yield in the whole production line, as only this can lead to meaningful comparisons.



But we're still not at the end.
Let us assume something like this:
R(10) ---- M1(3) ---- M2(5) ---- P ----- E
where
R = the city which delivers a certain raw yield (R)
M1 = a city consuming 3 R and producing 3 M1
M2 = a city consuming 5 R and producing 5 M2
P = the main port city, storing any surplus R, M1, M2
E = Europe, consuming any surplus R, M1, M2

Now, what is the value of R?
For any "normal" yield, at first glance it seems to be quantity times sales price.

Yet, the picture completely changes when assuming that R is needed for something to be produced in M1/M2 (which would be the case for food, lumber, ore, stone, maybe even silver) as raw materials (there are a lot of other things to be taken into consideration, but I want to keep it short).

Now we have to calculate the value of any missing quantity of R in any of our cities.
And we have to set this in relation to the time needed until completion of the item needing R (think of a building needing 10 turns of "production": at turn 1, R may be missing without causing any problem. At turn 10, R missing leads to a stopped production or to the need of buying R).
Worse it becomes in the case of education (which opens just another can of worms): missing yields to be equipped to your units cannot be bought - you simply cannot assign the respective profession to the unit which may cause the loss of x turns of education time).

The solution I have in mind for solving this is to evaluate any missing yield in a given city by the following formula:
IDV ("internal demand value") = RC ("replacement cost") * Q (quantity) * T ("turns of unsatisfied demand")

Say, we need a quantity of 30 costing 10 each as a replacement in 10 turns from now on. In addition, we will have a delivery of 10 in turn 3 and a delivery of 15 in turn 5.

T1: IDV = 10 (RC) * 30 (Q) * 1 (T) = 300
T2: IDV = 10 (RC) * 30 (Q) * 2 (T) = 600
T3: IDV = 10 (RC) * 20 (Q) * 3 (T) = 600 - delivery of 10
T4: IDV = 10 (RC) * 20 (Q) * 4 (T) = 800
T5: IDV = 10 (RC) * 5 (Q) * 5 (T) = 250 - delivery of 15
T6: IDV = 10 (RC) * 5 (Q) * 6 (T) = 300

As you can see the result (to be stored in a vector for each missing yield/city combination) will change from turn to turn, giving us some kind of approximation of the relative value of that yield in said city.
The closer we get to the turn in which the yield is really needed, the higher the relative value will get (RC * T), giving us a good chance to compare the "demand" (Q) of said yield in all of our cities at any given point of time.

The calculation by itself is rather easy and not very time consuming, neither for IDV nor for the comparison between the limited number of cities we may have at any given point of time.
 
Unfortunately, 1 ore = 1 tool = 1 cannon/musket/blade; regardless of the "demand" you have at any given point of time and regardless of the price for any of these yields.
(Not to mention the reality factor: it is completely unlogical to have to need as much ore for a blade than for a cannon)
I have been thinking of adding a multiplier to required and produced yields. That way it will be possible to make a profession, which takes 2 tools and 2 ore to produce one cannon. This multiplier should then be applied to all input and output yields, making it possible to make plenty of interesting setups in XML. However I started thinking about this around the same time as I started working on CivEffects, and in order to focus on one task at a time, I haven't investigated this setup at all.

The profit/food calculation is interesting, particularly for M:C where units doesn't eat the same amount of food. One thing, which came to mind when reading about prices of manufactured yields is that we could include a restriction saying that the price of a yield can't be lower than the combined value of the input yields + 25% or something like that. One thing you are overlooking is the fact that the king counts the number of yields you sold and use that number for tax changes. This mean if you sell 12 cotton instead of 3 colored cloth, you get the same amount of money, but you are counting towards a tax raise 4 times as fast.

But I agree that prices and the tax system is far from perfect and the tax could do with an upgrade.

I noticed one bug regarding counting sold yields. If you are Dutch, you get a discount for counting the number of sold yields. The implementation is that it counts the number of yields, then multiplies with (100 - discount) and then divide by 100. The problem is that it rounds down. If you have plenty of time, you can unload a single yield at a time and it will round down to 0 in regard to counting traded yields.

One possible solution to this is to multiply the sold amount by 8 before applying the discount. The get function for the traded amount should divide by 8. That way we will get the same, but it will internally store fractions of 8, which will somewhat counter the rounding errors. Other places, which are prone to rounding errors could do the same, such as yields stored in cities (5 yield produced each turn + 10%).

Why 8? Well, division is slow, but if it is a fixed division by 2^n, then it will be a bitshift, which can be done in a single cycle. This mean dividing by 8 or 16 would be the way to go for performance reasons. I would say that those numbers are the ideal balance between "correct rounding" and performance. Even if we use 4 bits (16) for fractions, an int can still store up to 134 million, which should still be enough to prevent overflows.
 
I have been thinking of adding a multiplier to required and produced yields. That way it will be possible to make a profession, which takes 2 tools and 2 ore to produce one cannon. This multiplier should then be applied to all input and output yields, making it possible to make plenty of interesting setups in XML. However I started thinking about this around the same time as I started working on CivEffects, and in order to focus on one task at a time, I haven't investigated this setup at all.
I am not sure if I like the idea of a multiplier.
Instead I would propose to directly define input and output values in the XML as this seems to allow for exactly the ratios you want to have but with less effort.



The profit/food calculation is interesting, particularly for M:C where units doesn't eat the same amount of food.
Well, I am thinking about having different food consumption, too.
This would be especially helpful in case of slaves. A slave is not a very productive person, yet he has an economic value due to the fact that he requires less (food, housing, medical care, you name it). The ratio of input/output is what makes the slave interesting from an economical point of view - even if the absolute value of the output might be less than for another person.


One thing, which came to mind when reading about prices of manufactured yields is that we could include a restriction saying that the price of a yield can't be lower than the combined value of the input yields + 25% or something like that.
That is what Orlanth did mention above - the added value.
But I would propose to make the calculation work differently:
the value of input yields will be determined by the value of the output yield.
After all, you don't plant cotton just to plant cotton. You plant it to make cloth. And the less you get for the cloth, the less the desire (and by that, the price) for cotton will be.

One thing you are overlooking is the fact that the king counts the number of yields you sold and use that number for tax changes. This mean if you sell 12 cotton instead of 3 colored cloth, you get the same amount of money, but you are counting towards a tax raise 4 times as fast.

But I agree that prices and the tax system is far from perfect and the tax could do with an upgrade.
I admit that I wasn't paying attention to this - just for the reason you mentioned: the tax calculation is another point where Col is just horrible.
In real life, the European nations were not interested in getting X tons of yield from their colonies, they were interested in making Y thousands of gold out of what they would get.
The tax system is just stupid as it is and by that, clearly another candidate for improvement.


I noticed one bug regarding counting sold yields. If you are Dutch, you get a discount for counting the number of sold yields. The implementation is that it counts the number of yields, then multiplies with (100 - discount) and then divide by 100. The problem is that it rounds down. If you have plenty of time, you can unload a single yield at a time and it will round down to 0 in regard to counting traded yields.

One possible solution to this is to multiply the sold amount by 8 before applying the discount. The get function for the traded amount should divide by 8. That way we will get the same, but it will internally store fractions of 8, which will somewhat counter the rounding errors. Other places, which are prone to rounding errors could do the same, such as yields stored in cities (5 yield produced each turn + 10%).

Why 8? Well, division is slow, but if it is a fixed division by 2^n, then it will be a bitshift, which can be done in a single cycle. This mean dividing by 8 or 16 would be the way to go for performance reasons. I would say that those numbers are the ideal balance between "correct rounding" and performance. Even if we use 4 bits (16) for fractions, an int can still store up to 134 million, which should still be enough to prevent overflows.

This is an interesting idea, but once again I would propose first to change the way in which price changes, taxes and all related issues are handled.
On a related note, I want to get away from this crazy random price changing. I mean, you're selling coffee in Europe and as result you're confronted with lower prices for coats? Really?
 
I am not sure if I like the idea of a multiplier.
Instead I would propose to directly define input and output values in the XML as this seems to allow for exactly the ratios you want to have but with less effort.
I don't think we should really care for the effort part. After all I coded a changable multiplier in M:C and it appears to work perfectly. The only "issue" is that it assumes all units to be free colonists. This mean setting the multiplier to 10 turns is actually only 5 if you fill the building with masters with +100% production.

On a related note, I want to get away from this crazy random price changing. I mean, you're selling coffee in Europe and as result you're confronted with lower prices for coats? Really?
The worst example I have seen is a game I had recently (using one plot radius). I started next to a gold mine, then I fairly quickly built 7 one man cities to gain the land. 5 of those had silver, most on peaks. A native settlement right next to me trained expert prospectors. The price of silver dropped to 8 :crazyeye:
Not that I was short on money. I won by buying everything I needed as the mountain landscape allowed me to produce little else than silver. However that uncovers another problem, which is the increasing unit price in Europe. Cannon Regiment ended up costing more than the initial price of a brigantine.
 
Back
Top Bottom