Eunomiac's Strategy Layer

I don't know which would be harder: a new screen or coding up the logic to select which order to handle next.

An easy, naive approach when a worker completes a task is to work on the closest task. This would lead to small inefficiencies, e.g. when a closer worker will complete their current task before the worker looking for work could get to the tile, but I doubt many humans take that into consideration now.

I micromanage my workers quite heavily. I team them up and prioritize the work queue based on a mixture of closeness and usability (can the new mine be worked now or in a few turns?). I build railroads on mines and lumbermills first, sending a group of workers to my main production cities so they arrive as I complete research on Railroad.

I suspect that I would not use this feature in any incarnation, only because I like that part of the micromanagement. Yes, I'm weird. :D

So I'd definitely like more input from people that would use a smarter worker automation feature like this. The reason I liked marking plots with what to build is that it would fit in with this strategy layer code quite well.
 
I don't think we should play with the worker priorities, mainly because it is probably too hard. However, we could open up the worker strategy layer when a worker comes up for breath ... thus presenting the human with the information so that he/she can make the decision.

My little worker MM trick is to send a worker onto a hill, have him road as the first thing he does. Next turn (or 2) I like to press Ctrl-A (units complete orders - worker actions, moves, etc) at the start of my turn so that the worker roading the hill finishes it - and then I can send my other 4 workers up the hill and build the mine while only losing 1 'move onto hill' worker cycle.
 
I don't think we should play with the worker priorities, mainly because it is probably too hard.

It would only affect workers that you have specifically set to this new type of automation. I suppose opening the work queue layer would be another option.

My little worker MM trick is to send a worker onto a hill, have him road as the first thing he does. . . .

I do the same thing. I had a great example that demonstrated the lost turns due to entering a forest/hill/jungle (I love India!): I had 12 forests around a city that I had saved for preserving. 8 workers could do them all in 24 turns, 1 turn to enter tile, 1 turn to preserve, 1 turn to enter next tile, ... Or 8 could do 8 tiles in 9 turns each individually (1 worker per tile) and then 4 could do the remaining 4 tiles in 9 turns. That's 6 * 8 + 9 * 4 = 48 + 36 = 84 worker turns!
 
The rest of us saner-types recognize that, by the time you get railroad, one extra turn of production from a teeny mine in a single city isn't quite worth all that, you know, math and stuff ;) No, instead I'll forget to Lumbermill four forests in my primary production city until I'm researching Fusion. So... yeah, we all make our little mistakes *cough, cough*

I don't think this feature has to be good enough for use in the early game, when you have to squeeze every single turn you can out of your Workers. Instead, I think this is a feature for the late game, when you can sacrifice a bit of Worker efficiency without compromising your position (and when the sheer number of Workers makes a robust and semi-automatic queuing system more attractive). Cottage-spamming new cities, or remembering to build Lumbermills by planning them in advance, etc. In such situations, I won't mind too much if the Workers are a little inefficient — especially if that's seen as a major hurdle in getting this idea off the ground. We can always improve this bit as time goes on, too.

Actually, I just found myself wondering ... wouldn't programming in efficient Worker optimization go against the BUG mission statement? I think that would go beyond giving the player information that's already available, as it basically automates a portion of the strategic challenge of the game. Players should have to choose the order Workers do things in; that's part of the learning curve.

Perhaps the Worker screen could be a glorified queuing system, in which the player not only assigns the actions themselves, but also the order in which the Worker performs them. Taking the city screen model, these could appear down the left side in place of buildings, in the order they're selected by the player. This list can include things the Worker is unable to do yet (i.e. planning in advance where to build Lumbermills), which would appear greyed-out in the action queue.

The Worker completes actions in order; when it finishes one, it moves to the next "live" action in its queue. If there are no actions left, the Worker activates for the player to control. If the only actions left are greyed-out "future" actions, then the Worker simply returns to the nearest city and sleeps until one of its actions goes live.

We would also have to figure out what we're going to do with the Alt-Click on Cancel Orders. It would be a nightmare if doing that wiped all the action queues from all your Workers!

Let me know if I'm making unfounded assumptions about what's easy to program vs. what's more difficult, so I can improve the likelihood that my suggestions are helpful :)
 
If the only actions left are greyed-out "future" actions, then the Worker simply returns to the nearest city and sleeps until one of its actions goes live.

This is the only thing with which I can quibble. I'd rather the game not idle my workers hidden in a city without notifying me first. Other than this trivial matter, I agree with everything.

Regarding alt-cancel, the queues will be stored in our own data structures, so they won't be affected.

I wonder how it would work to have orders tied to cities and allow you to assign control of them to cities at will. This way if you want to build up a city faster, you can assign it more workers. I'm wary of assigning tasks to workers -- what if they get captured? Your queue is lost. :(

I suppose we could have a queue for each city and one single outside city borders queue. Or perhaps assign each order to the nearest city, though we would then need to visually note the borders of each city's territory.
 
All of these are valid concerns. I suppose I was describing the "bare essentials" just to get the thing off of the ground. I agree with everything you said, with one exception: I don't know if you'd need a separate "outside city borders" queue.

If we're going to use the city screen as a model of sorts, then adapting that for use in the world at large would likely be much more difficult than containing it within a city's BFC (though I leave this call to you!). Worker actions outside of city walls are typically restricted to building roads, forts and the odd chop. Since these things are either already handled well in the game (i.e. the "Route-to" command), or not commonly used enough to warrant separate functionality, I don't know if it would be worth the work involved in queuing those sorts of things separately.

But hey, if you can pull it off, then go team! :)
 
According to the game, you can already queue orders for workers - there is a hint about it. However, I have never actually managed to do it in-game. Maybe we can piggie back on this and just create a way where the player can actually queue these orders.

from hint said:
You can give a unit consecutive orders by pressing the SHIFT key. For example, you could tell a worker to build a road and then a mine by clicking on both buttons while holding down SHIFT...
 
@Eunomiac - I think a hybrid city screen view is probably a good way to go, though I also like the idea of a more open view so you can see more area. You just need a single queue visible at a time. The easiest way to do this is to use the built-in city-selection ability. Plus this gives you keypad navigation for free. :)

But let's also not forget about the other strategy layer ideas you threw at us: marking present/future plots of interest for rallying, blockading, attacking, cities (the most important I think), etc. This view would definitely not use the city screen view. In fact, I'm thinking it should begin by hiding the interface save for a panel of our own controls (sort of a tool bar), much like the WB.

According to the game, you can already queue orders for workers - there is a hint about it.

Sure, I do this all the time. You can do it for any unit. Hold down shift as you click actions and right-click locations to move on the map. Works like a charm.

However, the queue is tied to a single unit and is easily deleted (accidentally or not). The idea we're working towards I think is to set up a queue for a city and then be able to give that city 3 workers with which to complete those tasks, issuing work orders to each worker as they complete their tasks.

Even better, you would see the future improvements on the map when viewing this layer. Super bonus points if we can get Raw Yields to take these into consideration with a new button. That would be tough though because some won't have the tech available yet, and some are affected by future techs, so how would you tell it, say, whether or not to assume railroads over all mines, quarries, and lumbermills?
 
Speaking of this, the 4th button is still missing... ;)

You make a great slave-driver! :eek::whipped:

Have you thought of pursuing a career in despotism? :p
 
Bumping this guy because I just thought of another (and simple) use of the area border overlay: lines of latitude so that, for example, you could easily see the allowed range for the space elevator.

I don't know how actually useful that would be or the details of implementing it (i.e. how you'd turn it on or off) but it popped into my head so I figured I'd post it before it popped back out. ;)
 
Bumping this guy because I just thought of another (and simple) use of the area border overlay: lines of latitude so that, for example, you could easily see the allowed range for the space elevator.

I don't know how actually useful that would be or the details of implementing it (i.e. how you'd turn it on or off) but it popped into my head so I figured I'd post it before it popped back out. ;)
This issue came up on polycast #52 and I am going to see if I can knock together a silly little mod to help with this. Something really crude to start with - just a vertical row of flags showing the latitude of each tile running through the capital. Naturally, it will only show on revealed tiles and only if you have managed to center the map (Stonehenge or calendar IIRC).
 
I just found a 3-year-old post that describes how to get Civ4 to generate the barebones documentation on the non-SDK Python functions that Locutus must have used in his API docs. It still works in BTS. :D

Full results are attached, but the reason I posted in this topic is to include the "official" definitions of the CyEngine() functions supplied by that method. The good news is that our guesses for the AreaBorderPlot stuff were spot on; the bad news is that I didn't see any hidden treasures in the list.

Spoiler :
Code:
    class CyEngine(Boost.Python.instance)
     |  Method resolution order:
     |      CyEngine
     |      Boost.Python.instance
     |      __builtin__.object
     |  
     |  Methods defined here:
     |  
     |  __init__(...)
     |  
     |  addColoredPlot(...)
     |      void (int plotX, int plotY, NiColorA color, int iLayer)
     |  
     |  addColoredPlotAlt(...)
     |      void (int plotX, int plotY, int iPlotStyle, int iLayer, string szColor, float fAlpha)
     |  
     |  addLandmark(...)
     |      void (CyPlot* pPlot, const TCHAR* caption)
     |  
     |  addLandmarkPopup(...)
     |      void (CyPlot* pPlot)
     |  
     |  addSign(...)
     |      void (CyPlot *plot, int /* PlayerTypes */ playerType, const TCHAR* caption)
     |  
     |  clearAreaBorderPlots(...)
     |      void (int iLayer)
     |  
     |  clearColoredPlots(...)
     |      void (int iLayer)
     |  
     |  fillAreaBorderPlot(...)
     |      void (int plotX, int plotY, NiColorA color, int iLayer)
     |  
     |  fillAreaBorderPlotAlt(...)
     |      void (int plotX, int plotY, int iLayer, string szColor, float fAlpha)
     |  
     |  getCityBillboardVisibility(...)
     |      bool ()
     |  
     |  getCultureVisibility(...)
     |      bool ()
     |  
     |  getNumSigns(...)
     |      int getNumSigns()
     |  
     |  getSelectionCursorVisibility(...)
     |      bool ()
     |  
     |  getSignByIndex(...)
     |      CySign* (int index)
     |  
     |  getUnitFlagVisibility(...)
     |      bool ()
     |  
     |  getUpdateRate(...)
     |      float ()
     |  
     |  isDirty(...)
     |      bool (EngineDirtyBits eBit)
     |  
     |  isGlobeviewUp(...)
     |      bool ()
     |  
     |  isNone(...)
     |      bool () - is the engine instance valid?
     |  
     |  reloadEffectInfos(...)
     |      void ()
     |  
     |  removeLandmark(...)
     |      void (CyPlot* pPlot)
     |  
     |  removeSign(...)
     |      void (CyPlot* pPlot, int /* PlayerTypes */ playerType)
     |  
     |  setCityBillboardVisibility(...)
     |      void (bool bState)
     |  
     |  setCultureVisibility(...)
     |      void (bool bState)
     |  
     |  setDirty(...)
     |      void (EngineDirtyBits eBit, bool bNewValue)
     |  
     |  setFogOfWar(...)
     |      void (bool bState)
     |  
     |  setSelectionCursorVisibility(...)
     |      void (bool bState)
     |  
     |  setUnitFlagVisibility(...)
     |      void (bool bState)
     |  
     |  setUpdateRate(...)
     |      void (float fUpdateRate)
     |  
     |  toggleGlobeview(...)
     |      void ()
     |  
     |  triggerEffect(...)
     |      void (iEffect, plotPoint)
 

Attachments

  • CvPythonExtensions.hlp.rar
    46.5 KB · Views: 96
I updated the script recently for BTS, but it's not generating the values for the Type Lists. I haven't had a chance to look into it, but it's been very useful for the other stuff, and the type lists haven't changed much since vanilla. Plus they're readily available in the SDK.

Civ4 Python API Project
 
Yeah I've been using your BTS version for primary reference and the apolyton one for the type lists. Didn't realize that you had gotten the non-SDK BTS updates though. I guess I need to update. :)
 
Didn't realize that you had gotten the non-SDK BTS updates though. I guess I need to update. :)

I think I got most of them but stopped mid-way through (boring copy-n-paste work), but I may have finished before committing. Hopefully I left a TODO comment if I stopped. :mischief:

Unfortunately I didn't notice the missing type list values until I was using it a couple weeks after committing, and I just haven't had a chance to look into the script. The script itself is, um, interesting. :D

Let me know if you want to make some changes and I'll add you to that GoogleCode project. Just PM me your Google account if so.
 
I didn't see a TODO in the file anywhere and there's definitely some stuff missing such as the various CyGInterfaceScreen.spaceShip* functions.

After poking around a bit, it looks like part of the type lists problems might be related to the fact that in a couple places it uses '\' as a directory separator instead of '/'.
Code:
Line 1621: 	if strFile[:16] != strSdkDirName + '\Cy' or strFile[-4:] != '.cpp':
Line 1872:		fFile = open(strSdkDirName + '\CyEnumsInterface.cpp', 'rt')
Line 1992: 		fFile = open(strSdkDirName + '\CvEnums.h', 'rt')
Changing those all to '/' seems to have fixed the type list issue for me, although my environment is highly weird because I'm a masochist and I try using the script under cygwin and those might be fine under a pure windows Python. And basically none of the SDK stuff actually shows up when I run the script so I really don't know what's going on. Given that and the fact that the script kinda scares me, I don't envision needing write access anytime soon. :p
 
That had no effect for me, but I did find the problem. The script aborts type list processing if any XML file it expects is missing. I committed the fix.
 
I knocked together a silly little mod that shows the map / tile latitudes. You have to have at least 1 city and the map has to be centered (Stonehenge or Calendar IIRC). Then hit Ctrl-Alt-L, click Ok and you get a series of signs (Thx Dresden) with the tile latitudes.

You have to remove the tiles manually (Alt-S).



I just hacked something together in the standard eventmanager - it is very crude but it works. I cannot wait to start on the BUG Strategy Layer thingo.
 

Attachments

  • CustomAssets.zip
    37.6 KB · Views: 85
Top Bottom