Whip-Assist Modlet Idea

EmperorFool

Deity
Joined
Mar 2, 2007
Messages
9,637
Location
Mountain View, California
I've been thinking of a small modlet idea for a while now. Basically, it's a whip assistant on the city screen to help you decide when to whip. I'm still unsure of exactly what it should show (only info you can figure out yourself doing math).

Since I'm busy with BUG right now, I'm posting the idea here in case anyone wants to try their hand at a small Python project. When I got started modding, ideas were harder for me to come by than time to code. That's reversed for me right now, but hopefully someone else is still in that boat. :)

I started by asking What is the player's goal?

Goal: Maximize hammer overflow

Next, what questions would the player need answered to achieve their goal?

Question: When is the best time to whip?

Question: How much overflow will I get now versus if I wait?

Does the player care how much overflow they'll get now if waiting 1 or 2 turns will get more? What about if they have to wait 5 turns? Does it matter; is there a cutoff?

Sometimes I'll MM to the extreme and back off :hammers: production in a very production poor city with lots of food to maximize overflow, even if that means having to adjust the citizens while waiting for the best time or delaying a turn. Do others do this, or is it going overboard?

Here are the pieces of information I came up with to answer the questions:

  • Current threshold
  • Current production (already there)
  • Current overflow if you whip now
  • Next whip threshold
  • Production you'll have on that turn (or how close to threshold)
  • Overflow at next threshold
  • How many turns before the next threshold (without passing it)
For example, you have put 63 :hammers: into a 180 :hammers: Courthouse at 10 :hammers:/turn (no bonuses) on epic speed (45 :hammers:/pop). If you whip right now, your overflow will be 18 + X (however many :hammers: you generate this turn working plots)

45 * 3 - (180 - 63) + X
= 135 - 117 + X
= 18 + X

[ Since you lose population, X might not be 10 anymore depending on how the citizens are rearranged. From now on, ignore that value in this example. ]

Clearly, 18 is a suboptimal overflow. 44 is the ideal amount. If you wait 2 turns, you'll get 20 more overflow -- 38. This is usually better than whipping immediately because X will likely go down after whipping. So the modlet should show

  • Current threshold = 45
  • Current production = 63
  • Current overflow = 18
  • Next threshold = 90
  • Production then = 83
  • Overflow then = 38
  • Turns before = 2 (without going over)
Now that I've written all that, it seems what you really want to know is how close you are to hitting the next threshold, or 1 less than it actually. For the above, the key information is

  • 27 :hammers: until next threshold
  • 2 turns
Bonus points for a "Remind me" button that sets a Reminder (with that mod) to notify the player to "Whip <City Name>". The problem is that if :hammers:/turn changes along the way (growth!) they might miss the best time. I'm leary of having the game actually watch it each turn to tell you -- seems like too much.
 
Bonus points for a "Remind me" button that sets a Reminder (with that mod) to notify the player to "Whip <City Name>". The problem is that if :hammers:/turn changes along the way (growth!) they might miss the best time. I'm leary of having the game actually watch it each turn to tell you -- seems like too much.
  • Check if city will grow/shrink before reaching whip time
  • If yes check where governor will place the new pop point/which pop point is lost
  • If it changes production include in calculation.
Only problem then is if the player manually change it or something unexpected happends.
 
I have completed the first version of this. It currently displays a message on the screen giving you the information for the selected city when you hit Shift-W. The next step is to add it to the city screen and as columns in the Customizable Domestic Adviser.

Another way to present the information clearly (the toughest part) might be to use a stacked bar. That's the technical term for all the percentage bars (food, production, population, culture, great people points, research and great general XPs).

Each bar can have three areas I think which correspond with colors. In the production bar, for example, the left part (green) shows the production completed; the middle (dark green) shows what will be produced this turn; and the right part (no color) shows what will be left to produce.

Here's how I would display this whip-bar:

Code:
+---------------------------------------+
|  Overflow  |  H/T  |  Next Threshold  |
+---------------------------------------+

Overflow shows the current overflow if you whip now. H/T is the hammers/turn you are producing. Next Threshold is how many hammers you can produce (including H/T this turn) before you hit the next population threshold. On top of the bar I would overlay three numbers.

Left: Current Overflow
Middle: Turns until next threshold
Right: Hammers until next threshold

It would also be handy to include the hammers per population for what you're currently building since it changes for various build items and cities. That's usually the biggest PITA in manually calculating the whip thresholds -- calculating the prod/pop first.
 
Wow, this is far trickier than I first thought. I believe I have the code algorithm complete. Basically, I ended up having to rewrite some of the C++ DLL code in Python to create a production and whip simulator. While this was tough, I have it working and outputting text as to what's happening. The hard part is going to be turning this data into code to draw the bar!

This will be somewhat undecipherable to you all, but here's the output from the tests I have run. The simulation is run at normal speed (30 :hammers:/:mad: whip).

Code:
==> (1) 7/45 @ 12/6 + 0%
 0: Whip 1 for 30 in 8
 0: 12 >= 8
 1: Can whip
 1: End in 38
 1: Passed 1 thresholds
 1: 18 < 38
 2: 24 < 38
 3: 30 < 38
 4: 36 < 38
 5: Can't advance: 42 >= 38
--- Overflows:
     5 @  15/ 45: Whip 1 pop for 28
--- Thresholds:
     1 @  15/ 45: Pop 1 passed at 19 (1)
     5 @  45/ 45: Pop 0 stopped at 43

==> (2) 7/45 @ 12/6 + 0%
 0: Whip 2 for 60 in -22
 0: Whip 1 for 30 in 8
 0: 12 >= 8
 1: Can whip
 1: End in 38
 1: Passed 1 thresholds
 1: 18 < 38
 2: 24 < 38
 3: 30 < 38
 4: 36 < 38
 5: Can't advance: 42 >= 38
--- Overflows:
     0 @ -15/ 45: Whip 2 pop for 22
     5 @  15/ 45: Whip 1 pop for 28
--- Thresholds:
     0 @ -15/ 45: Pop 2 passed at 7 (1)
     1 @  15/ 45: Pop 1 passed at 19 (1)
     5 @  45/ 45: Pop 0 stopped at 43

==> (4) 10/100 @ 10/10 + 0%
 0: Whip 3 for 90 in 0
 0: Whip 2 for 60 in 30
 0: 10 >= 30
 1: Can whip
 1: Passed 0 thresholds
 1: 20 < 30
 2: Can't advance: 30 >= 30
--- Overflows:
     0 @  10/100: Whip 3 pop for 0
     2 @  10/100: Whip 3 pop for 20
--- Thresholds:
     0 @  10/100: Pop 3 passed at 10 (1)
     2 @  40/100: Pop 2 stopped at 30

==> (4) 20/100 @ 10/10 + 0%
 0: Whip 3 for 90 in -10
 0: Whip 2 for 60 in 20
 0: 10 >= 20
 1: Can whip
 1: Passed 0 thresholds
 1: Can't advance: 20 >= 20
--- Overflows:
     0 @  10/100: Whip 3 pop for 10
     1 @  10/100: Whip 3 pop for 20
--- Thresholds:
     0 @  10/100: Pop 3 passed at 20 (1)
     1 @  40/100: Pop 2 stopped at 30

==> (3) 20/100 @ 10/10 + 0%
 0: Whip 3 for 90 in -10
 0: Whip 2 for 60 in 20
 0: 10 >= 20
 1: Can whip
 1: Passed 0 thresholds
 1: Can't advance: 20 >= 20
--- Overflows:
     0 @  10/100: Whip 3 pop for 10
     1 @  10/100: Whip 3 pop for 20
--- Thresholds:
     0 @  10/100: Pop 3 passed at 20 (1)
     1 @  40/100: Pop 2 stopped at 30

==> (2) 20/100 @ 10/10 + 0%
 0: Whip 2 for 60 in 20
 0: 10 >= 20
 1: 20 >= 20
 2: Can whip
 2: Whip 1 for 30 in 50
 2: Passed 1 thresholds
 2: 30 < 50
 3: 40 < 50
 4: Can't advance: 50 >= 50
--- Overflows:
     4 @  40/100: Whip 2 pop for 20
--- Thresholds:
     2 @  40/100: Pop 2 passed at 40 (1)
     4 @  70/100: Pop 1 stopped at 60

==> (8) 0/100 @ 10/10 + 0%
 0: Whip 7 for 105 in -5
 0: Whip 6 for 90 in 10
 0: 10 >= 10
 1: Whip 4 for 120 in -20
 1: Can whip
 1: Whip 3 for 90 in 10
 1: Whip 2 for 60 in 40
 1: Passed 2 thresholds
 1: 20 < 40
 2: 30 < 40
 3: Can't advance: 40 >= 40
--- Overflows:
     0 @  -5/100: Whip 7 pop for 5
     3 @  10/100: Whip 3 pop for 20
--- Thresholds:
     0 @  -5/100: Pop 7 passed at 0 (1)
     1 @  10/100: Pop 3 passed at 10 (1)
     3 @  40/100: Pop 2 stopped at 30

==> (4) 0/100 @ 10/10 + 0%
 0: Whip 4 for 60 in 40
 0: 10 >= 40
 1: Whip 4 for 120 in -20
 1: Can whip
 1: Whip 3 for 90 in 10
 1: Whip 2 for 60 in 40
 1: Passed 2 thresholds
 1: 20 < 40
 2: 30 < 40
 3: Can't advance: 40 >= 40
--- Overflows:
     3 @  10/100: Whip 3 pop for 20
--- Thresholds:
     1 @  10/100: Pop 3 passed at 10 (1)
     3 @  40/100: Pop 2 stopped at 30

==> (2) 0/100 @ 10/10 + 0%
 0: Whip 2 for 30 in 70
 0: 10 >= 70
 1: Whip 4 for 120 in -20
 1: 20 >= -20
 2: 30 >= -20
 3: 40 >= -20
 4: Can whip
 4: Whip 3 for 90 in 10
 4: Whip 2 for 60 in 40
 4: Whip 1 for 30 in 70
 4: Passed 3 thresholds
 4: 50 < 70
 5: 60 < 70
 6: Can't advance: 70 >= 70
--- Overflows:
     6 @  40/100: Whip 2 pop for 20
--- Thresholds:
     4 @  40/100: Pop 2 passed at 40 (1)
     6 @  70/100: Pop 1 stopped at 60
The "==>" lines show the test case.

Code:
==> (w) p/c @ x/y +z%
  • (w): max whippable population
  • p/c: production so far (paid/cost), p out of c total hammers
  • x/y: hammers per turn, x is first turn, y is every turn thereafter (for cases where you have overflow or chops)
  • z: production bonus (forge, OR, etc)
You can ignore the lines immediately under that up until the "-->" lines. It would take too long to explain. The "-->" lines show you what the simulator has determined. The "Overflows" show you the places where you can whip initially and optimally. The "Thresholds" tell you the whip thresholds (places where the # of pop drops) that you pass and approach.

Here's one test case examined.

Code:
[1] ==> (2) 20/100 @ 10/10 + 0%
[2] --- Overflows:
[3]      4 @  40/100: Whip 2 pop for 20
[4] --- Thresholds:
[5]      2 @  40/100: Pop 2 passed at 40 (1)
[6]      4 @  70/100: Pop 1 stopped at 60
Optimal whipping is accomplished by coming as close to a threshold without going over. The first threshold is at 2 population (60 :hammers:), and we start 20 :hammers: away from it. We cannot whip this turn for 90 :hammers: since we have 2 max pop available for whipping.

In 2 turns we pass the 2 threshold (line [5] above), but if we whip here we get 0 overflow :hammers:. The optimal whipping point is just before the 1 pop threshold at 70 :hammers: (line [6]). If we don't adjust our :hammers:/turn, we'll hit that optimal point at 60 hammers in 4 turns (line [3]) for a whip overflow of 20 :hammers:.

How to draw this graphically?

Code:
10h/turn         [B]2p for 20h[/B]
   |                  |
[#####=====|==========|-----] 4 turns
Thresholds:|                |
          20h              50h
The above is a text representation of a stacked bar (like that used for food or GP). #, = and - would be different colors with the following meanings:
  • # for production this turn (:hammers:/turn)
  • = for future production up to the point where you should whip
  • - for the rest of the distance to the threshold. This is the part that cuts into your overflow; you want to minimize this down to 1:hammers: if possible.
Since you can't whip 3 pop, you don't really care about the 20:hammers: threshold. But if you are 1 or 2 turns away from population growth, you might want to back off your :hammers:/turn so you can whip at 3 optimally. Thus, it would be nice to show it visually somehow.

This is just one case, however. There's also the simplest case where you can whip now. The above example, if you could whip 3 pop max instead of 2, would look like this:

Code:
10h/turn   [B]3p for 20h[/B]
   |       |
[##########|----------] 1 turn
Threshold:            |
                     20h

Here you see that you should ideally drop production by 1:hammers:/turn this or next turn so you can get 29:hammers: overflow.

Given the above, I think a number to show is how far you'll be from the threshold when you whip (10:hammers: in both examples). This tells you that you could reduce production slightly to optimize.

It's hard to tell, but I think I'm getting closer to a solution. :)
 
I haven't had a detailed read of the above, but for me, the benefit of the whip is max hammers produced per head of pop whipped. In the classic axe rush, the whip is applied to generate 2 axes in 2 turns. I typically use it as follows:

- marathon speed
- 1 pop = 90 hammers
- 1 cat is 100 hammers
- put less than 10 hammers into a brand new cat
- whip for 2 population
- finish the 2nd cat with normal production

... 2 cats in 2 turns by whipping 2 pop - wait 30 turns for unhappiness to go away and repeat.

Here, the critical bit of information is the 10 hammers. If I put 10+ hammers into the cat, it only whips for 1 pop. If 9 or less, 2 pop are required.

Thus, I would like to know these critical points ... when the required population reduces by 1. And the number of turns until this event (whip pop required) reduces. Maybe killing off 1 extra pop is not worth 3 turns of normal production. In this way, the optimum (for me) time to whip is found ... ie: when the turns to whip pop required is equal to 1.
 
Yes, this is exactly what I think is the important information and goal. In my previous posts, the point where you pass from X pop needed to X - 1 is called a threshold.

At a minimum, it should show how many :hammers: and turns until the next threshold.
 
You say you weren't able to find a good way to present the information. Obviously, there should be both the info present in v3.5 (what will you get by whipping this turn) and what will you get by whipping the nex turn (that is, will you pass the threshold with the current production). That's too much to fit into one line, for sure. Can it be alternated like the clock? Or on a mouse cursor rollover? Or can the second info be displayed in a tooltip? Without making its own dll?
 
My original plan was to add a third bar below the current production bar. I could move the two bars up a little to make some room and increase the vertical space of the tab background slightly while still leaving enough room for the worked tiles below it.

If you read that thread, what I really want is a bar that would show current result plus the next threshold at least. A stacked bar can have at most 4 different "areas", so I can't show every threshold. And in fact, showing more than the next threshold may be too much, but I'd really like the next two if I can fit them.

The question is, how? What will be clear? Unfortunately, I have not been able to provide a hover for bars or text labels without DLL modifications, so the bar needs to be self-explanatory.

I'm totally open to ideas, though. If you can mock something up I'm happy to give it a shot. If you haven't already, I would like anyone doing this to have skimmed that thread I linked so we are on the same page.

I had wanted to have one for the GP Bar on the main interface showing either the full breakdown or maybe the next X cities in GPP order, but I couldn't intercept a mouseover event for it. Civ4's mouseover events only seem to fire in certain circumstances, and I haven't nailed down exactly what does it. :(
 
what a suggestion ... here is one ...

whipassist0020ce4.jpg


Each yellow line is a 'threshold' and represents the number of hammers generated by killing off 1 population. Easy to understand, easy to add to the screen, easy to see how many turns until each threshold, easy to see when you will pass a threshold.
 
This idea has a couple trouble spots. First, there's no real insight into how the stacked bars are drawn, so it would be difficult to line up the lines so as to ensure clarity. It would take a lot of trial and error to figure it out.

Assuming we could do that, however, the main deficiency I see is that it doesn't convey what you really need to know when planning your whips. I find myself calculating how many turns before I should whip (so I can set a reminder), and how close I am to the threshold so I can maximize my overflow.

For example, if in 3 turns I will cross the next threshold by a few hammers, I will often shift production so as to come as close to the threshold without passing it.

The production bar is already quite crowded, so there's no room for this kind of information. This is why I want to add a new bar. For one thing, the hammers you've already put into the build don't apply to the whipping decision, so this expands the room available if a new bar is used.
 
I don't think we really need multiple thresholds that much. Just a 2 to 1 pop will do fine for me.
 
Just a 2 to 1 pop will do fine for me.

I don't get what you mean by this. Can you please give an example or explain further? Are you saying you only ever whip for 1 or 2 population, so you don't want to see the thresholds for 3, 4, and 5 population if you can whip right now for 6?
 
I don't get what you mean by this. Can you please give an example or explain further? Are you saying you only ever whip for 1 or 2 population, so you don't want to see the thresholds for 3, 4, and 5 population if you can whip right now for 6?
Yes. That is, I do whip for more than 2 pops from time to time - when competing for a wonder with an AI, for example. But in such desperate cases I care far less for overflow than I do in regular 2 pop whipping. After all, the whole idea of whipping calculation is to get a maximum overflow for a minimum pop price, isn't it? Maximum overflow you can get is basically the price of 1 "extra" pop whipped minus 1 hammer, plus all the modifiers, so why murder 5 pops plus 1 "extra" for the same overflow as 1 pop plus 1 "extra" would get you?

But, supposing people rushing for a wonder and whipping half of their megapolis to snatch it before the AI does wish to maximize their overflow. They need to calculate a 5/6 or 8/9 pop threshold, too. But why clutter the interface with multiple thresholds? Isn't the nearest one all we need? If it's, say, 40 hammers to completion, let it show the nearest 1/2 pop threshold so that one can invest 9 hammers and whip for 2 pop and 29 hammer overflow. If it is 200 hammers and one has got 7 spare pops, let it show the nearest - 6/7 pop - threshold so that one can invest 9 hammers, whip 7 pops the next turn and get the maximum 29 hammer overflow.

So it would be some kind of dynamic threshold indication showing the nearest one. If you overinvest your hammers and pass the threshold, it would show the next one (up to 0/1 when yoy've got but 1 hammer to invest to finish the job 'peacefully').
 
In my haste this morning, I phrased my question quite oddly. You seem to have answered it nonetheless. :)

What I meant to ask was this: Say you can whip for 5 pop right now. Do you want to see

  1. the threshold for 4 pop, or
  2. the thresholds for 1 and 2 pop.
What I read is that you want #2. I was confused by your "1/2 pop" where now I see you mean the next closest 1 or 2 thresholds, whatever population they might be. Correct?

If so, I agree that this makes sense. Even if you want to only whip at 1 or 2 population, by the time you've put in enough production to get it down to that level, your production has probably changed and you'll need to adjust it again to maximize overflow. Seeing the thresholds 20 or 30 turns ahead won't be very useful.

Far more effective I think would be the ability to create a dynamic alert for a city like "tell me when I will pass the threshold for X pop the following turn." It would check the city at the end of each turn before you hit the end turn button and alert you if the build is ready to whip. At that point you could whip or reduce production to further maximize overflow.

As for your question about when to whip, whipping for 1 pop is actually inefficient. For one thing, you're likely to grow population before the anger wears off, meaning that new citizen might be unhappy and not work, so it's better to whip for 2 which incurs the same anger (1 pop for x turns) regardless of how many pop you whip.

The reason to whip is not simply to get the overflow but also to make food-heavy cities more productive. Whipping converts food to production, and there is a sweet spot (IIRC size 5-7 cities) since each population point requires a different amount of food to regrow. The article on whipping is a great read for this information. It's probably in the BUG Sevopedia for easy in-game reference. ;) </shameless-plug>
 
What I meant to ask was this: Say you can whip for 5 pop right now. Do you want to see

  1. the threshold for 4 pop, or
  2. the thresholds for 1 and 2 pop.
What I read is that you want #2.
Not exactly. For the public benefit I suggest the former, a dynamic indication of the current closest threshold. When I want to whip but 2 pop, I'll simply wait for the 4 pop and 3 pop thresholds to pass. But being dynamic, it will help maximize overflow at any given time.

As for your question about when to whip, whipping for 1 pop is actually inefficient. For one thing, you're likely to grow population before the anger wears off, meaning that new citizen might be unhappy and not work, so it's better to whip for 2 which incurs the same anger (1 pop for x turns) regardless of how many pop you whip.
That's what I do, really. Whip 2 pops.
 
The reason to whip is not simply to get the overflow but also to make food-heavy cities more productive.

Or to get quick production or to get a benefit from unhappy population, but yeah. Right. So why does whip overflow merit being the focus of the modlet if the goal is

to help you decide when to whip

in general?
 
Because only you can decide if you need to hurry the item being built so it's available sooner. Maybe BUG could help you utilize unhappy citizens by suggesting that you whip them away when possible, but no algorithm jumps out at me. Same for whipping buildings that produce happiness.

However, BUG can easily help you maximize overflow. And if you're going to whip, you may as well get the most out of it as long as it's not an emergency. And quite frankly, the overflow calculation is a PITA to calculate each time.
 
get the most out of it
I don't follow this part. How is maximizing the overflow getting the most out of my whip? I understand why I would want to maximize overflow in a few cases:
* I'm applying the overflow to a wonder
* I want to overflow into gold
* maybe if my next build has a multiplier, and somehow the micromanagement makes it better to whip this build than the next one. Or vice versa, I suppose.
But those cases are not typical. You seem to be saying that I would typically want to maximize overflow.
 
[snip] But those cases are not typical. You seem to be saying that I would typically want to maximize overflow.

When you whip, you lose population. That typically means fewer citizens working tiles (unless you're whipping away angry citizens, which is sub-optimal). Fewer citizens working tiles means fewer hammers produced per turn. The later you whip (ie the more overflow you produce), the greater amount of hammers produced in total because of those 1 or 2 (or 3 or 4 ...) citizens working tiles for longer.
It's a well-known technique of super-micromanagers.
 
I might respond to your post later, but first I'd like to see if EmperorFool will respond to me himself. I just want to be very precise here, and avoid confusing the discussion by trying to have two conversations at once.
 
Back
Top Bottom