Éa, Dawn of the Mortal Races (phase 1, pre-alpha code development and discussion)

@rocklikeafool, Geometric series is just a special case of power series (where |r| < 1) which applies here.

I think my equation is pretty close to correct but with some +1, -1's still needed on some of the t's (this is a brain twister).

But I'm pretty happy with this goofy exercise because it gives me a nice way to balance stuff like wonders or just normal buildings. Not perfect, but better than my total guesses (as Calavente demonstrates above for my Great Work's costs).

Edit: Not in my mod plans, but this could also be applied to AI city build decision. Not perfect. But at least you wouldn't have a size 1 city building a library just because of "flavor". (Have I said how much I hate the flavor system? I really really hate the flavor system a lot.)
 
@rocklikeafool, Geometric series is just a special case of power series (where |r| < 1) which applies here.
Well, not quite...but anyway, guess I didn't really pay attention to it all, haha.
 
Delayed reaction, I know, but I only run an ego search about once a week. (For those who don't know, it's where you put your own name into a search engine to see what people are saying about you.) Posting in my threads or sending PMs will get these things answered much more quickly.

The last time I played (a very early version) there was no new 3D unit art. Does he have good units now? Can you point me to any existing screen shots? (I don't see any in the first page.) I'll certainly ask Spatz if I can "borrow" some if they look appropriate.

I've got a lot of the Civ4 models I'll need sitting on my hard disk, roughly half the number I'll need in the end, but I haven't done the conversions to Civ5 yet. They're likely to be the last thing I add, after I'm sure all of the mechanical bits work (which they now seem to). The main reason for the delay is that I need to figure out what I'm doing wrong in the conversion process; when I tried converting futuristic models for the Ascension mod, something happened to make them only work for DX9. Until I figure out why that happened, I'm not going to be working on any new models, since I'm using the Ascension units as my testbed. My latest theory involves the DDS compression, but I've had Real Life priorities the last couple weeks that interfered. My units do have custom icons and custom unit flags already, but the 3d models will be a while longer.

Once that gets resolved, and I start converting stuff, you're free to swipe the models for your own fantasy setting; I'll probably just make a big post in the Unit Graphics forum and dump them all there. I'm not sure how much will apply to what you're doing here; while I do have some classical fantasy bits mixed in, they're less D&D-style High Fantasy and more, well, mythology-based. Tiamat isn't some five-headed multicolored dragon in the original Sumerian myths, for instance. There won't be any Elves, Dwarves, Goblins, etc., but there will be Zombies, Skeletons, Elementals and so on, so there will be at least some overlap.
 
g can be zero if I'm on the plot and I have movement. However, t is always > 0 because any action that gives us something "uses" the GP's movement (t=1). That's what I mean when I say "instant." Some of these might really be "instant" payoff versus next turn, but I'm not going to sweat that small difference. If something has completion time = 8, that just means that the unit's movement will be used up 8 times.
okay...
if you are sure of "g can be 0 and t always >= 1":
v = [(i + p / (1 - r)) * r^(t-1) + b/(1 - r) - b/(1 - r) * r^(t-1)+ B ] * r^(g) / (t + g)

(that requires that if I can move to the location this turn AND have some movement left, g=0 ; While being able to move to location this turn with no movement left changes g to 1 and that I cannot cast if no movement left !)
t (casting time) is at least 1.

verfication :
instant gain (instant casting time): t=1 ; g=0
v = [(i + p / (1 - r)) * r^(1-1) + b/(1 - r) - b/(1 - r) * r^(1-1)] * r^(0) / (1+ 0)
v = [(i + p / (1 - r)) * r^(0) + b/(1 - r) - b/(1 - r) * r^(0)] * r^(0) / (1)
v = [(i + p / (1 - r)) * 1 + b/(1 - r) - b/(1 - r) * 1] * 1] / (1+ 0)
check= ok : no division by 0, no deduction due to casting time, no move deduction

gain next turn due to 1 turn of movement needed : t=1 ; g=1
v = [(i + p / (1 - r)) * r^(1-1) + b/(1 - r) - b/(1 - r) * r^(1-1)] * r^(1) / (1 + 1)
v = [(i + p / (1 - r)) * 1 + b/(1 - r) - b/(1 - r) * 1] * r / (2)
check= ok : no division by 0, no deduction due to casting time, but 1) perceived value is reduced due to 1 turn of movement (* r / 2) and the gain is layered of 2 turns of action of the GP.

gain next turn due to 2 casting turns : t=2 ; g=0
v = [(i + p / (1 - r)) * r^(2-1) + b/(1 - r) - b/(1 - r) * r^(2-1)] * r^(0) / (2 + 0)
v = [(i + p / (1 - r)) * r + b/(1 - r) - b/(1 - r) * r] * 1 / (2)
check= ok : no division by 0, deduction due to casting time is perceived only once, both for the cost and the gains, there is no deduction due to movement and the gain is layered of 2 turns of action of the GP (this turn and next turn as casting takes 2 turns).


Only thing I note as "maybe unbalanced" :

dividing by GP turns still means that 500 now is better than 1000 next turn due to counting the GP "effort". (500 in 10 turns is better than 1000 in 20 turns but that is understandable IMO...but 500 now vs 1000 next ???
Spoiler let's count ! :
500 now vs 1000 next turn :
Being able to do both actions :
1000 next turn then 500 the turn after (let say the difference is in casting time) 1000 * 0.986 + 500* 0.986^2 = 972+472 = 1472.1... (layered over 3 turns : 490.69/turn)
500 now then 1000 2 turn after : 1000 * 0.986^2 + 500 = 958+500= 1472.2... (layered over 3 turns : 490.71/turn)
In this case, chosing 500 before chosing 1000 seems indeed a better idea, but only very marginally.

However if doing 1 action eliminates the possibility of the other action (sacrifice of the GP or it involves declaring war with the non-chosen; or the other city will be rased in 4 turns but not in 2: Or casting the 1 turn action forbids to cast the other action...=)
you would have 500 versus = 493.... 500 now will be chosen while in reality 1000 next turn is way better. It's a non-decision for the player
 
I was just looking again at the general mechanics... miam

it seems the Heldeofol are barred a great number of names (they have some compensation advantages).... but it seems the replayability of Heldeofol will be greatly reduced.
( I counted 8 names allowed to Heldeofol on top of "clan of____" ; of those, 6 are in competition with man;.. 5 on "military" techs/achievement that man will heavily try to gain)
Why not have some other names allowed to H ?

or some other "specific H" names :
Wurraw : first to capture an Ogre/Hill giant... : all land units gain +30%str against Hill giant/ogre ; all land units have +30% chance capturing Hill giant/ogre ; Hill giant/ogres are 15% easier to build.
Borddar : first to build 2 Ogre/Hill giant : +30% Strength to hill giant/ogres.
Laklsul : first to capture a city : +20% city attack for land units ; *warrior
Quisnach : first to pillage 3 improvements : +100% in pillage
Thactyer : first to have both : a captured city AND a library AND the tech writing (so a captured library doesn't count): +10 research point per pop captured toward each known tech (30/pop instead of 20/pop); *engineer

...Etc

New "subsequent" trait familly
Elite Army (the xp numbers are not balanced : I don't know the level/mean of xp generated by combat)

lvl 2 : first to get 2 units past 30 xp : free 5xp on unit creation
lvl 2 : first to get a mean of 20 xp/unit : +10%str/rng.
lvl 2 : first to get 100xp in total through combat :+1xp/combat for each unit

lvl 3 : first to get 5 units past 50 xp : free 5xp on unit creation
lvl 3 : first to get a mean of 40xp/unit : +10%str/rng..
lvl 3 : first to get 500xp in total through combat : +1xp/combat for each unit

lvl 4 : first to get 8 units past 80 xp : free 10xp on unit creation
lvl 4 : first to get a mean of 60xp/unit : free +2 str/rng per unit.
lvl 4 : first to get 1500xp in total through combat : +1xp/combat for each unit
 
correct me if i'm wrong: those values are only for trade routes that are available instantly... and not after a delay.
Right. With the delay of y though, you just discount it back by another y periods. So, X per period forever starting y turns from now = [(0.99)^y]*X/[1-0.99]

(no need to set a turn horizon at all)
Well, there is arguably some need. If you're only 50 turns away from the end of the game, then optimally you should be focusing more on building stuff now, not on investing. But I think it is ok to ignore that, and to pretend that the AI doesn't know the game is going to end. The math for infinite series is simpler.

With the notation you have here:
r = discount rate
t = build time
b = per turn gain/loss during build time (a cost is just a negative)
i = instant gain/loss when complete
p = per turn gain/loss when complete
v = marginal value
g = travel time

So for example, with 2 turns of movement, I can take an action that costs 50 gold instantly and 2 gold per turn for 10 turns, that then gives me a trade route that gives 5 gold per turn forever.

Then the value of this is:
[-50r^2] [2(r^2 - r^12)/(1-r) + [5/(1-r)]*r^(10+2)
and the value per turn of action is all this over 12.
So for discount factor of 0.99, this would be:
[-49.005] - [18.743] + [443.19] = 412.93
And the value per turn for this action would be [412.93/12] = 34.41

well, IIRC, Pazyrk plans for "trade routes" (opened by GM) to produce 1%more every 10 turns...showing the increased security.
You can figure this in easily enough, if you assume they last forever, just add an extra compounding term in at 0.1% per year; the trade route doesn't give 5 per turn, it gives 5/0.999 per turn.
 
dividing by GP turns still means that 500 now is better than 1000 next turn due to counting the GP "effort". (500 in 10 turns is better than 1000 in 20 turns but that is understandable IMO...but 500 now vs 1000 next ???
This is fine, because the assumption is (which I thought was true?) that these actions are duplicable (eg as soon as this great person finished building this trade route, it can start building another trade route).
500 instantly today and 500 instantly again tomorrow *is* better than 1000 tomorrow.

If this valuation formula is being used for actions that can't be replicated, then value per turn is the wrong heuristic to be trying to maximize.
 
but then going to a city which is available in 2 turns would give 1000 instantaneously (and would also be recastable).
so you would do : 500, 500, 500, 500, 500 ...Etc
and I would do : 0 (travel farther), 1000, 1000, 1000, 1000 ... in 3 turns I produced more than you in 4 turns and in 4 turns more than you in 6.
however, initiating the initial travel decision : 0, 1000 or getting an instant 500 would weight the AI toward the "get 500 now and recast each turn cycle".

While this discussion is academic (as I suppose that Pazyryk will not enable "recastable instant gain".) IMO it shows that "dividing by GP turn" might be a bit too strong. Maybe divide by X + GP turns ? X being chosen for balance reasons only (maybe map size dependant)
so either the GM dies, or he is sent back to capitol,or the GM loses a promo he needs to get back... or something.
 
Welcome to the maths forum.

My apologies for not going through the posts above yet. I took this offline and worked it out pretty well I think.

Just to rehash:

r = time discount rate
t = turns to complete (t=1 for "instant" effect because all use up GP movement)
g = turns to get to target plot (0 if we are here already with movement)
i = adjusted* instant gain/loss when completed
b = adjusted* per turn gain/loss during action
p = adjusted* per turn gain/loss after action

v = final marginal value (in "yield units / GP turn" but I drop the units below)

All actions take at least one turn (t &#8805; 1) with gains/losses coming in three different ways: an instant payoff/loss at turn t (call this i); a gain/loss that occurs each turn while the action/build is in progress from turn 1 to t (called b); and a gain/loss per turn that starts on turn t and lasts forever (called p). In reality, all "instant" effects use up the GPs movement but some payoff now and some next turn. For simplicity, I treat both situations as one turn actions with payoff on the next turn (t = 1). [Note: these are "practical/operational" definitions based on how my actions work.]

Here's the math:
Spoiler :
The whole thing relies on this equality for geometric series, where |r| < 1:

1 + r + r^2 + r^3 + ... = 1/(1 - r)

Let's assume g = 0, meaning we are on the target plot and have some movement. We also ignore GP effort (turns lost) for the time being. We have:

i --instant gain
i * r^t --value of that instant gain if it comes t turns in the future

p/(1-r) --gain on per turn starting now (t=0) until forever
p/(1-r) * r^t --value of that per turn gain if it starts on turn t

(i + p/(1-r)) * r^t --add time-discounted i and p values together and simplify

Now consider b, which is another per turn but we ultimately want it from turn 1 to t
b/(1 - r) --value of b if it started now (t=0) and lasted forever
b/(1 - r) * r^(t+1) --value of b if it started on turn t+1 and lasted forever
b --value of b if we only got it on t=0
b/(1 - r) - b - b/(1 - r) * r^(t+1) --What we want, which is just the 1st minus the 2nd minus the 3rd line above

So now we can add time-discounted values for i, p and b from above (discount considering action time only):
(i + p/(1-r)) * r^t + b/(1 - r) - b - b/(1 - r) * r^(t+1)

Let's account for g now, which is easy. We just put it all g turns in the future, like this:
[(i + p/(1-r)) * r^t + b/(1 - r) - b - b/(1 - r) * r^(t+1)] * r^g

Now we account for GP "effort", which is time lost on this action, which is t + g. But we need to time discount this too. This is necessary so that a 10 gpt action (say take residence) has the same value of exactly 10 yield units / GP turn whether you do it for 1 turn or 25 or 100 (assuming no travel time). The GP is "spending effort" from now (really turn 1) to turn g + t. I do this as I did for b above, but I replace b with 1 ("1 GP turn unit") and t with t + g:
(1 - r^(t + g + 1)) / (1 - r) - 1

This gives us the final marginal value:

v = [(i + p/(1-r)) * r^t + b/(1 - r) - b - b/(1 - r) * r^(t+1)] * r^g / [1/(1 - r) - 1 - 1/(1 - r) * r^(t + g +1)]

I looks messy but it simplifies down to:

v = [b + r^(t - 1) * (i + p - r * (i + b))] / [r^(-g) - r^t]
The whole thing boils down to this:

v = [b + r^(t - 1) * (i + p - r * (i + b))] / [r^(-g) - r^t]

You can put that in an Excel spreadsheet and try some different things:

Code:
r =	0.98623	which gives us half-value at 50 turns, quarter at 100, etc...		

[U]type						g	t	i	b	p	v	[/U]

trade route (10/t payoff; 100 cost; 8 turns)	0	8	0	-12.5	10	73.9332115
trade route (10/t payoff; 100 cost; 8 turns)	5	8	0	-12.5	10	43.91031667
trade route (10/t payoff; 100 cost; 8 turns)	10	8	0	-12.5	10	30.59455339

wonder (28/t payoff; 200 cost, 25 turns)	0	25	0	-8	28	60.52576026
wonder (28/t payoff; 200 cost, 25 turns)	5	25	0	-8	28	48.61274349
wonder (28/t payoff; 200 cost, 25 turns)	10	25	0	-8	28	40.1441269
wonder (2000 instant, 200 cost, 25 turns)	0	25	2000	-8	0	59.39997991
wonder (2000 instant, 200 cost, 25 turns)	5	25	2000	-8	0	47.70854549
wonder (2000 instant, 200 cost, 25 turns)	10	25	2000	-8	0	39.39744534

residence (10% of 100 each turn; 1 turn)	0	1	0	10	0	10
residence (10% of 100 each turn; 8 turn)	0	8	0	10	0	10
residence (10% of 100 each turn; 25 turn)	0	25	0	10	0	10
residence (10% of 100 each turn; 1 turn)	5	1	0	10	0	1.609431564
residence (10% of 100 each turn; 1 turn)	5	8	0	10	0	5.939186974
residence (10% of 100 each turn; 1 turn)	5	25	0	10	0	8.031744381
I've lowered my wonder costs to 200p, which is spread over the 25 build turn to give you b = -8. Trade route is 100g spread over the 8 turn completion time for b = -12.5. Take Residence could be done for any number of turns, but you can see that the value (in yield units / GP turn) is the same as long as we are already at the tile. But it isn't worth traveling to the city for only 1 turn of residence. For the sake of the AI, I'll just treat it as a 25 turn action so that they will consider it even from a distance.

--------------------------------------------------

OK, what about those adjustments* to i, p and b that I mentioned above?

i = adjusted instant gain/loss when completed
i = i' - i" * malus,
where i' is my instant gain/loss and i" is someone else's instant gain/loss from my action (loss is always negative here).

Malus has to do with how much I don't want to help the other player. This is zero for a city state (I don't care one way or the other) and 1 for a powerful enemy (I don't want to help them but I do want to cause them losses). For a player I am neutral with, it is their proportion of world power. When I build an exclusive wonder, I am harming other players because they can't build it now (so just set i" = -i') but the player is unspecified, so I just use malus = 1 / number full players.

p = adjusted per turn gain/loss after action
p = (p' * m' - p" * m" * malus) * (1 - k),
where p' and p" are my and their per turn gain/loss when completed (for a trade route, p" = p'), m' and m" are my and their city modifiers for this yield type, and k is "risk factor". Per turn yields extending into the future are usually at some risk of loss. For now I'm using a low value k = 0.05 for wonders (they can be pillaged, but then repaired) and a higher value k = 0.2 for trade routes. The trade route logic could get smarter later (e.g., does the city belong to a weak civ next to a strong civ?).

You can see how malus affects trade routes: p for a CS trade route (malus = 0) is just what I get (p' * m'). But p for a trade route with a powerful enemy (malus = 1) is going to be zero or very close to zero (depending on m' and m"). The heightened risk for trade routes is going to lower the values (by about 20%) from what I have in the table above. Per turn value from a Wonder is also reduced but only by about 5%.

b = adjusted per turn gain/loss during action
b = b' * m' - b" * m" * malus
I'm not dealing with risk for the build time.

--------------------------------------------------

I now have additional value added for "clustered opportunity" (i.e., the target area has more good things to do after we complete the first action). Value calculation continues in post #99 below.

--------------------------------------------------

Added in edit:

An interesting concept to ponder is malus > 1. This is "spite," which means that I am willing to cause you loss even if it causes a greater loss to me. I don't have specific plans to use that but it does show how flexible this system is.
 
that's brillant.
maybe a bit time consuming for the PC.
however you have all parameters boiled down to a single value to help decision.

(it seems you also increased the bonus given by wonders : 30/turn in your examples)

last ; in my huge kindness I'm forgiving you for not reading all our math posts.... however you wouldn't be forgiven for not reading my post #85 and Spatz' post #83 as they are not "math post"...

:D

...


Joke...! I'm not that mean. if you didn't read it.. I can post it back latter :D
 
(it seems you also increased the bonus given by wonders : 30/turn in your examples)

My examples are just hypotheticals. Many of the wonder effects can be boiled down to either an instant effect or (more often) and everlasting per turn effect. Even if they aren't simple yield effects, I'll just make up some proxy values that seem more or less right. But the effects will be much more interesting than just +27p per turn.
 
however you wouldn't be forgiven for not reading my post #85 and Spatz' post #83 as they are not "math post"...

:D

...
You really are Richard, aren't you?! :eek:


My examples are just hypotheticals. Many of the wonder effects can be boiled down to either an instant effect or (more often) and everlasting per turn effect. Even if they aren't simple yield effects, I'll just make up some proxy values that seem more or less right. But the effects will be much more interesting than just +27p per turn.
Well, frankly, I'd like to see how this boils down in playtesting. I mean, I'm sure your math is correct; just I want to see what's OP or underpowered or just right, what the AI can handle, etc. :popcorn:
 
but then going to a city which is available in 2 turns would give 1000 instantaneously (and would also be recastable).
so you would do : 500, 500, 500, 500, 500 ...Etc
and I would do : 0 (travel farther), 1000, 1000, 1000, 1000 ... in 3 turns I produced more than you in 4 turns and in 4 turns more than you in 6.
however, initiating the initial travel decision : 0, 1000 or getting an instant 500 would weight the AI toward the "get 500 now and recast each turn cycle".

While this discussion is academic (as I suppose that Pazyryk will not enable "recastable instant gain".) IMO it shows that "dividing by GP turn" might be a bit too strong. Maybe divide by X + GP turns ? X being chosen for balance reasons only (maybe map size dependant)
so either the GM dies, or he is sent back to capitol,or the GM loses a promo he needs to get back... or something.
Well, not *quite*, I assumed that these actions couldn't be repeated in the same city. So for your story to work, what you'd need is that with a bit of movement, you could end up in a region with higher value cities that then gave a higher yield as you moved between them.

I agree with the fact that movement time can cause issues because just looking at the movement time for the current action doesn't include the second order impact - the fact that choosing where I go for my next action then affects the set of possible actions I can take after that.
This could be fixed by forcing a teleport back to capital after an action was taken, but that might be annoying in other ways.

But I think there has to be *some* kind of calculation of benefits per turn that the AI is trying to maximize.

Here's the math:
I haven't checked all the details, but the general approach seems right. It might have some biases - for minimizing movement time for example - but I think that is ok. Any system is going to have some biases, and the discount rate in the end is going to be some what arbitrary.

I think as well this approach is useful because it lets us do some prioritization in design; I think it should be the case such that non-repeatable actions like building a wonder (*if* a wonder is available) should give a higher per-turn payoff than actions that can be easily repeated.
Basically, you should be rewarded for taking actions that have other constraints. Actions that just immediately give you instant gold should have the lowest payoff, because they cannot be disrupted in any way from something not in the model (eg; by losing control of the city that you're building a wonder improvement near). What is important is to get the risk/reward tradeoffs right, and to reward actions that rely on player-initiated strategic choices - eg being first to a tech that allows a particular wonder.
 
It might have some biases - for minimizing movement time for example -
This deters exactly as turns to complete (I tested this in Excel, though you don't see it above). Both are in units of "GP turns", which is basically the denominator (so marginal values are all in units: "yield units per GP turn"). I can't think of any reason why travel time should be counted any higher or lower than completion time.

I think it should be the case such that non-repeatable actions like building a wonder (*if* a wonder is available) should give a higher per-turn payoff than actions that can be easily repeated.
This is in the "malus" calculation near the bottom. It's a little more abstract for unique wonders than trade routes, but you are basically harming other players by preventing them from building the wonder (malus = 1/#full players in this case, which may be a little low; and p" = -p' or b" = -b' or i" = -i", whichever is relevant).

Actions that just immediately give you instant gold should have the lowest payoff, because they cannot be disrupted in any way from something not in the model (eg; by losing control of the city that you're building a wonder improvement near).
Flip this around. Immediate payoff is good because it can't be taken away. Per turn payoffs are risky because they may be interrupted, and so they are discounted by risk (see k above).


One thing not accounted for is that there might be a second action possible (after the 1st) at the target plot you are headed to. This is better than if you have to move on again. Oh well...
 
This deters exactly as turns to complete (I tested this in Excel, though you don't see it above). Both are in units of "GP turns", which is basically the denominator (so marginal values are all in units: "yield units per GP turn"). I can't think of any reason why travel time should be counted any higher or lower than completion time.
The biases I am thinking about are second order effects, and any system is going to contain those kinds of environments.
On reflection, I misstated, I think the algorithm as given is likely to bias very slightly towards long-distance actions.
Here's what I have in mind; suppose that I have a bunch of cities all close to each other (say, they are on the east coast of north america) and then there is a lone distant one further away (say in Europe). And there are actions in each of these cities that I can take.
Suppose that from a from the formula the European city action gives a very slightly higher payoff, so the algorithm picks that - it says it is worth the 10 turns it takes to cross the Atlantic.
What the algorithm doesn't include is the fact that for the *next* action I take, crossing the Atlantic now means I am on the other side of the ocean, and I have a long trip back to get to any of the other American cities. An algorithm that looks only at the next move to make will ignore secondary effects from options that are destroyed (eg the option to have another action in a nearby city).
By analogy, consider a chess AI that only looked at the current move, and couldn't look 2-3-4+ moves ahead.
And this is ok, this kind of second order effect is very difficult to capture, and it is ok to fudge it.

but you are basically harming other players by preventing them from building the wonder
You're also harming yourself in some sense, in that if I build the Wonder now I am eliminating the possibility that I can build it tomorrow.
But you would have to have an insanely complicated algorithm to try to incorporate real option analysis.
[Note that all the stuff you're doing here is basically re-inventing the basics of financial theory.....]

Flip this around. Immediate payoff is good because it can't be taken away. Per turn payoffs are risky because they may be interrupted, and so they are discounted by risk (see k above).
I think we're in basic agreement, but slightly talking past each other.
Here's what I mean. Suppose we have two potential actions, one that gives instant cash that cannot be taken away, one that relies on some risk. If the two had equal value as described by a valuation heuristic that doesn't take account of risk, then we would always choose the instant cash one. It would be a no-brainer.
So in order to make the strategic decision interesting, we should make it so that they don't actually have equal value - we set the payoffs (ie the amount of gold you actually get) such that the risky decision gives more gold.

Similarly, we design a non-repeatable Wonder so that it is more valuable than a repeatable instant gold opportunity.

I'm talking about balance design here, not the AI valuation decision.

One thing not accounted for is that there might be a second action possible (after the 1st) at the target plot you are headed to
Right, this is the kind of second order effect I was trying to talk about before; it need not be on the same plot, but it might be nearby.
 
I'm talking about balance design here, not the AI valuation decision.
Yeah, it is not exactly the same consideration, although they can inform each other.


Right, this is the kind of second order effect I was trying to talk about before; it need not be on the same plot, but it might be nearby.
Yeah, I think I could capture this with a fudge factor on g. Lower g if many opportunities near the target. Raise it if not. At worst, g should be doubled because you have to go there, do one thing, and then come back. At best, there are so many opportunities near the target that g should be near zero. (That should be the maximum benefit for clustering, because if another opportunity with a "true low g" exists and evaluates to a better v, then we should go for the nearby opportunity rather than the distant clustered opportunity, which presumably will still be there later.) [Edit: added this to post #89 above, which I suppose is the "official" documentation for this concept.]

I was just looking again at the general mechanics... miam

it seems the Heldeofol are barred a great number of names (they have some compensation advantages).... but it seems the replayability of Heldeofol will be greatly reduced.
( I counted 8 names allowed to Heldeofol on top of "clan of____" ; of those, 6 are in competition with man;.. 5 on "military" techs/achievement that man will heavily try to gain)
Why not have some other names allowed to H ?

or some other "specific H" names :
Wurraw : first to capture an Ogre/Hill giant... : all land units gain +30%str against Hill giant/ogre ; all land units have +30% chance capturing Hill giant/ogre ; Hill giant/ogres are 15% easier to build.
Borddar : first to build 2 Ogre/Hill giant : +30% Strength to hill giant/ogres.
Laklsul : first to capture a city : +20% city attack for land units ; *warrior
Quisnach : first to pillage 3 improvements : +100% in pillage
Thactyer : first to have both : a captured city AND a library AND the tech writing (so a captured library doesn't count): +10 research point per pop captured toward each known tech (30/pop instead of 20/pop); *engineer
I like these. Some of these are early and others late, but they will work with the special Heldeofol naming mechanic (that is: "Clan of ____" name is going to be special in that it is the only one where you can gain another name later).

New "subsequent" trait familly
Elite Army (the xp numbers are not balanced : I don't know the level/mean of xp generated by combat)

lvl 2 : first to get 2 units past 30 xp : free 5xp on unit creation
lvl 2 : first to get a mean of 20 xp/unit : +10%str/rng.
lvl 2 : first to get 100xp in total through combat :+1xp/combat for each unit

lvl 3 : first to get 5 units past 50 xp : free 5xp on unit creation
lvl 3 : first to get a mean of 40xp/unit : +10%str/rng..
lvl 3 : first to get 500xp in total through combat : +1xp/combat for each unit

lvl 4 : first to get 8 units past 80 xp : free 10xp on unit creation
lvl 4 : first to get a mean of 60xp/unit : free +2 str/rng per unit.
lvl 4 : first to get 1500xp in total through combat : +1xp/combat for each unit
These are good too. I'm probably not going to add and subsequent traits till phase 2 (don't need them for a good game). But I'm pasting all this into my mod documentation for later.
 
Another way to deal with the effect of "clustered opportunity" is to add another travel cost after g and t. The problem with jacking up g is that I'm adding time before the action, which ends up adding extra (unfair) time discount on any value gained. The real cost here is the wasted time lost by the GP getting back from the trip (or going somewhere else), or getting to that 3rd opportunity even if there are 2 near the target plot. Looking on to 4th, 5th opportunities is much less important with the time-discounting. Just about every action takes 8 or 25 turns (and even if it is less, it can be "treated" that way like I did above for Take Residency) so we are really getting far into discounted value past option 3. Accounting for that should be enough penalty for a distant solitary opportunity.

You can make multiple trade routes with a foreign city (one for each of your cities), so, depending on what trade routes you already have (and # of worthwhile-sized cities) there may be a 2nd and 3rd opportunity with no extra travel. My code returns values for list of potential targets so I also know if there are other nearby opportunities. It's not too expensive to calculate a matrix of path distances between cities as long as that is saved and not run too often (Civ4 did this calculation from every city to every other city every more than once per turn, for trade routes, which was a huge sink). So it's not too hard to get travel distance to the 2nd and 3rd reasonably good opportunities (not sure what "reasonably good" is here, maybe >50% of the value of the present target opportunity).

I could call this a for "after action travel turns" and add it to my equation. That'll be another 4 pages of algebra for me.


Please don't worry that I'm delaying the mod on this too much. It's sort of crazy trying to get this perfect but it's a fun diversion for me. My best guess is that the individual GP AIs are going to take me about a month to polish. The specific Wonders and Epics will go in as I get to Engineers and Artists (respectively).
 
just for looking at ART
I stumbled upon the LOTR civs.
From what I understood, All civ have at least some 1-2-3 UU with unique art. As there are 3.5 civs (4 civ-worth of unique art) : Rohan, Gondor, Isengard and Mordor.
I didn't check if there are new models or just reskin or only "icon changes".

Maybe you'll find some things that you can use.

best regards.
 
I think I can account for clustered opportunities in a fairly precise way. I'm utilizing game "areas" which are defined by the game engine and correspond to continents or subcontinental regions (islands are in their own area). I make a simplifying assumption that travel time between opportunities in an area is 4 turns (w = 4) and then look ahead to four (o = 4) additional opportunities in this area adding their time discounted values. There is little extra processing overhead because the values were gotten in the initial target analyses anyway. This system does not account for nearby opportunities that happen to span two areas.

Here's the value calculation from post #89, but now I'm calling it v':

v' = [b + r^(t - 1) * (i + p - r * (i + b))] / [r^(-g) - r^t]

Let's consider this with no travel time (g = 0), which I call v":

v" = [b + r^(t - 1) * (i + p - r * (i + b))] / [1 - r^t]

I'll break this further into numerator and denominator, so that I don't have to recalculate the whole equation for v' and v":

numerator = b + r^(t - 1) * (i + p - r * (i + b))
denominator = 1 - r^t
v' = numerator / (denominator + r^(-g) - 1)
v" = numerator / denominator

Numerator, denominator, v' and v" are going to be calculated for many potential target sites. These calculations can be super-optimized by pre-calculating r powers and holding them in an array (r[0] = 1, r[1] = r, r[2] = r^2, etc; r^(-2) is just 1/r[2]), so the calculations here are really trivial.

We want to add time-discounted value for the 2nd, 3rd, 4th and 5th best opportunities in the same area (o = 4 additional opportunities). Actually we already know which target the GP is going to first if they are going to a particular area. It is the target in the area with the highest v'. Considering subsequent opportunities in that area, we don't want to use v' because g will likely be much less (once we are there). So we use v" and apply an ad hoc travel time (w = 4) between opportunities in the area. (It's too expensive to run additional pathing to get actual travel times between potential targets.) Our 2nd, 3rd, 4th and 5th best opportunities are just the 4 best targets in the area sorted by v" (excluding our initial target with the best v').

w = 4 -->estimated travel turns between opportunities within an area
g2 = g + t + w -->total turns before we get to opportunity #2 (where g and t are for the initial target)
g3 = g2 + t2 + w -->total turns before we get to opportunity #3
g4 = g3 + t3 + w -->total turns before we get to opportunity #4
g5 = g4 + t4 + w -->total turns before we get to opportunity #5

v2', v3', v4' and v5' are time-discounted versions of v2", v3", v4", v5" using g2, g3, g4, g5 (calculated as above). We only need to calculate this once for each area, so we get a time-discounted value for each area:

a = v2' + v3' + v4' + v5'

You can think of a as the marginal value for getting the GP to that area based on what it can do after its first action is done. There is limited value in looking further than v5', since g6 would be at least 5 * (8 + 4) = 60. Then our final marginal value for each potential target is:

v = v' + a

Remember that a is an area boost, so it is going to be the same for all targets in an area. It could push us toward a really good area, but we still go to the best target in the area considering the individual target v' (which considers both v" and travel time to the individual target, g). With the heavy time-discounting on a, it is unlikely to push us off the continent we are currently on if there are any reasonable nearby opportunities. But it will certainly affect choice between two distant areas.

Keep in mind that v" (together with numerator and denominator above) is calculated for many potential targets anyway, so we are not adding much overhead. The major overhead in all of this is running a path out from the GP's current location to each potential target for g. But even that might be sped up by 2x or more using a mild heuristic for A* pathfinding.

Here's the pseudocode for the whole analysis:
Spoiler :
I am a GP with movement and not currently doing anything.

Look for likely good targets (plots where some action is possible and productive) using a special heuristic for each GP type.

For each potential target:
Calculate g using modified Redox's A* algorithm; if unreachable then drop from list
calculate numerator, denominator, v' and v" for all potential actions at target

For each area:
find best v' in area, use this for g and t
sort v" to find 2nd, 3rd, 4th and 5th best targets in area
calculate g2 - g5
calculate v2' - v5'
add to get area (a) value

For each potential target:
caclulate v from v' + a

Pick best v and go do it.
 
I've reorganized the GP section in the initial "game doc" posts (see post #4). There are some changes and additional info, especially for Warriors. I'm also removing the "join worker/slave" system for engineers, so that has been taken out of the doc. It's now nicely organized by GP class rather than the messy way I had it before. None of it is really "balanced" yet, though some changes were motivated by discussion above.

Progress on the Merchant AI was good this weekend. It's mostly working but I introduced some bugs to other systems that I need to track down. As I work though issues with the Merchant, I can already see how I will program most other GP classes (Warrior presents its own specific challenges since it isn't "yield based" like the others).
 
Top Bottom