Armies

I would worry a lot that non-obsoleting UUs would become very unbalanced, particularly with the Professional Military civic.
Run a gold economy, build Jaguars for a tiny handful of hammers over a few turns, upgrade to rifles for low gold cost.

* * *
On the resource issue, I'd also suggest again removing the buffs for siege units, but removing their iron requirement, and leaving iron as rare.

That way: horses are for mounted line, superior mobility units.
Iron is for melee line, high strength units.
And anyone can take cities, get weak resourceless units and bombardment.
 
I would worry a lot that non-obsoleting UUs would become very unbalanced, particularly with the Professional Military civic.
Run a gold economy, build Jaguars for a tiny handful of hammers over a few turns, upgrade to rifles for low gold cost.

I pointed this out a few posts above and Thal agreed.
Spoiler :
At one point CCMAT made Scouts never obsolete, and when I reached Rifling I was building them in one turn (while Rifles took about 5-7 turns) and taking two turns to upgrade them (only costing about 1/3 of Rifles' rushbuy cost because of Professional Army). Take into consideration that there are two policies (Mercantilism and Pro Army) and two wonders (Big Ben and the Pentagon) that affect this, and you're looking at a very OP mechanic because the AI will not take advantage of it. It depends on how early the UU is; the earlier it is, the more powerful this would become.

A possible compromise would be to push back obsolescence to two units beyond the unit's replacement, allowing a larger window to build them. In other words have Muskets obsolete at Replaceable Parts instead of Rifling, for example. I'd suggest this for the next test version, and if something's OP/UP it can be adjusted.
@Seek
Yeah that's basically what I'm thinking of... change the obsolete tech for UUs to the next tier of unit.

On the resource issue, I'd also suggest again removing the buffs for siege units, but removing their iron requirement, and leaving iron as rare.

That way: horses are for mounted line, superior mobility units.
Iron is for melee line, high strength units.
And anyone can take cities, get weak resourceless units and bombardment.

+1 for eliminating iron requirement for siege. I think it's a good move.
 
Saw the original, missed the reply.
Agree that 1-tier delayed obsolescence is a good compromise.
 
This means if you start with very little fresh-water grassland nearby, for example (the place horses are coded to appear most) you will have few or no horse resources.

I like this, and fear the sameness of the opposite. Grass isn't great, but it gives you horses, and so on, is the sort of balance that the devs achieved pretty well. Bringing the extremes closer to the center makes sense to me, but I would find horses and iron everywhere boring. Variety is more engaging in the long run than moderate imbalance is a turnoff.
 
A problem might arise when you have iron working, but no iron nearby.

Bronze Working revealing Iron probably mitigates this issue, as you can delay tech if you don't have the resource. This obviously doesn't apply to AIs, but an AI can still build Spearmen, which (with the mod) are more cost-effective than warriors per strength point (and counter horses).

If you're curious, here's the specifics of what I did for "minor" horse nodes (majors simply got a 50% increase in tiles-per-node). I just tweaked a few values to shift the probabilities a little more in favor of Iron.

Spoiler Minor Resource Placement :
Code:
-- Combat Mod +
if plotType == PlotTypes.PLOT_HILLS then
  if terrainType == TerrainTypes.TERRAIN_GRASS or terrainType == TerrainTypes.TERRAIN_PLAINS then
    -- ** was 5
    local diceroll = Map.Rand(7, "Resource selection - Place Small Quantities LUA");
    if diceroll < 3 then  -- ** was 2
      selected_ID = self.iron_ID;
      selected_quantity = iron_amt;
    elseif diceroll == 3 then  -- ** was 2
      selected_ID = self.horse_ID;
      selected_quantity = horse_amt;
    else
      selected_ID = self.coal_ID;
      selected_quantity = coal_amt;
    end
  else
    local diceroll = Map.Rand(5, "Resource selection - Place Small Quantities LUA");
    if diceroll < 2 then
      selected_ID = self.iron_ID;
      selected_quantity = iron_amt;
    else
      selected_ID = self.coal_ID;
      selected_quantity = coal_amt;
    end
  end
elseif terrainType == TerrainTypes.TERRAIN_GRASS then
  if res_plot:IsFreshWater() then
    selected_ID = self.horse_ID;
    selected_quantity = horse_amt;
  else
    local diceroll = Map.Rand(5, "Resource selection - Place Small Quantities LUA");
    if diceroll < 4 then  -- ** was 3
      selected_ID = self.iron_ID;
      selected_quantity = iron_amt;
    else
      selected_ID = self.horse_ID;
      selected_quantity = horse_amt;
    end
  end
elseif terrainType == TerrainTypes.TERRAIN_PLAINS then
  local diceroll = Map.Rand(5, "Resource selection - Place Small Quantities LUA");
  if diceroll < 3 then  -- ** was 2
    selected_ID = self.iron_ID;
    selected_quantity = iron_amt;
  else
    selected_ID = self.horse_ID;
    selected_quantity = horse_amt;
  end

In addition, each start location has extra resources added based on its value, I didn't alter the horse vs iron balance for this:

Spoiler Start Location Normalization :
Code:
if terrainType == TerrainTypes.TERRAIN_GRASS or terrainType == TerrainTypes.TERRAIN_PLAINS then -- Could be horses.
  local choice = self.horse_ID;
  local diceroll = Map.Rand(4, "Selection of Strategic Resource type - Start Normalization LUA");
  if diceroll == 2 then
    choice = self.iron_ID;
    --print("Placed Iron.");
  --else
    --print("Placed Horse.");
  end
  plot:SetResourceType(choice, 2);
  self.amounts_of_resources_placed[choice + 1] = self.amounts_of_resources_placed[choice + 1] + 2;
else -- Can't be horses.
  plot:SetResourceType(self.iron_ID, 2);
  self.amounts_of_resources_placed[self.iron_ID + 1] = self.amounts_of_resources_placed[self.iron_ID + 1] + 2;
  --print("Placed Iron.");
end
return true

There's also the "strategic balance" setting option, which is about 100 lines but overall the algorithm seems simple and I should be able to incorporate some of it into basic resource placement, if desired:

Spoiler Strategic Balance :
Code:
function AssignStartingPlots:AddStrategicBalanceResources(region_number)
  -- This function adds the required Strategic Resources to start plots, for
  -- games that have selected to enable Strategic Resource Balance.
  local iW, iH = Map.GetGridSize();
  local start_point_data = self.startingPlots[region_number];
  local x = start_point_data[1];
  local y = start_point_data[2];
  local plot = Map.GetPlot(x, y);
  local plotIndex = y * iW + x + 1;
  local wrapX = Map:IsWrapX();
  local wrapY = Map:IsWrapY();
  local odd = self.firstRingYIsOdd;
  local even = self.firstRingYIsEven;
  local nextX, nextY, plot_adjustments;
  local iron_list, horse_list, oil_list = {}, {}, {};
  local iron_fallback, horse_fallback, oil_fallback = {}, {}, {};
  local radius = 3;
  
  --print("- Adding Strategic Balance Resources for start location in Region#", region_number);
  
  for ripple_radius = 1, radius do
    local ripple_value = radius - ripple_radius + 1;
    local currentX = x - ripple_radius;
    local currentY = y;
    for direction_index = 1, 6 do
      for plot_to_handle = 1, ripple_radius do
         if currentY / 2 > math.floor(currentY / 2) then
          plot_adjustments = odd[direction_index];
        else
          plot_adjustments = even[direction_index];
        end
        nextX = currentX + plot_adjustments[1];
        nextY = currentY + plot_adjustments[2];
        if wrapX == false and (nextX < 0 or nextX >= iW) then
          -- X is out of bounds.
        elseif wrapY == false and (nextY < 0 or nextY >= iH) then
          -- Y is out of bounds.
        else
          local realX = nextX;
          local realY = nextY;
          if wrapX then
            realX = realX % iW;
          end
          if wrapY then
            realY = realY % iH;
          end
          -- We've arrived at the correct x and y for the current plot.
          local plot = Map.GetPlot(realX, realY);
          local plotType = plot:GetPlotType()
          local terrainType = plot:GetTerrainType()
          local featureType = plot:GetFeatureType()
          local plotIndex = realY * iW + realX + 1;
          -- Check this plot for resource placement eligibility.
          if plotType == PlotTypes.PLOT_HILLS then
            if ripple_radius < 3 then
              table.insert(iron_list, plotIndex)
            else
              table.insert(iron_fallback, plotIndex)
            end
            if terrainType ~= TerrainTypes.TERRAIN_SNOW and featureType == FeatureTypes.NO_FEATURE then
              table.insert(horse_fallback, plotIndex)
            end
          elseif plotType == PlotTypes.PLOT_LAND then
            if featureType == FeatureTypes.NO_FEATURE then
              if terrainType == TerrainTypes.TERRAIN_TUNDRA or terrainType == TerrainTypes.TERRAIN_DESERT then
                if ripple_radius < 3 then
                  table.insert(oil_list, plotIndex)
                else
                  table.insert(oil_fallback, plotIndex)
                end
                table.insert(iron_fallback, plotIndex)
                table.insert(horse_fallback, plotIndex)
              elseif terrainType == TerrainTypes.TERRAIN_PLAINS or terrainType == TerrainTypes.TERRAIN_GRASS then
                if ripple_radius < 3 then
                  table.insert(horse_list, plotIndex)
                else
                  table.insert(horse_fallback, plotIndex)
                end
                table.insert(iron_fallback, plotIndex)
                table.insert(oil_fallback, plotIndex)
              elseif terrainType == TerrainTypes.TERRAIN_SNOW then
                if ripple_radius < 3 then
                  table.insert(oil_list, plotIndex)
                else
                  table.insert(oil_fallback, plotIndex)
                end
              end
            elseif featureType == FeatureTypes.FEATURE_MARSH then    
              if ripple_radius < 3 then
                table.insert(oil_list, plotIndex)
              else
                table.insert(oil_fallback, plotIndex)
              end
              table.insert(iron_fallback, plotIndex)
            elseif featureType == FeatureTypes.FEATURE_FLOOD_PLAINS then    
              table.insert(horse_fallback, plotIndex)
              table.insert(oil_fallback, plotIndex)
            elseif featureType == FeatureTypes.FEATURE_JUNGLE or featureType == FeatureTypes.FEATURE_FOREST then    
              table.insert(iron_fallback, plotIndex)
              table.insert(oil_fallback, plotIndex)
            end
          end
          currentX, currentY = nextX, nextY;
        end
      end
    end
  end

  local uran_amt, horse_amt, oil_amt, iron_amt, coal_amt, alum_amt = self:GetMajorStrategicResourceQuantityValues()
  local shuf_list;
  local placed_iron, placed_horse, placed_oil = false, false, false;

  if table.maxn(iron_list) > 0 then
    shuf_list = GetShuffledCopyOfTable(iron_list)
    iNumLeftToPlace = self:PlaceSpecificNumberOfResources(self.iron_ID, iron_amt, 1, 1, -1, 0, 0, shuf_list);
    if iNumLeftToPlace == 0 then
      placed_iron = true;
    end
  end
  if table.maxn(horse_list) > 0 then
    shuf_list = GetShuffledCopyOfTable(horse_list)
    iNumLeftToPlace = self:PlaceSpecificNumberOfResources(self.horse_ID, horse_amt, 1, 1, -1, 0, 0, shuf_list);
    if iNumLeftToPlace == 0 then
      placed_horse = true;
    end
  end
  if table.maxn(oil_list) > 0 then
    shuf_list = GetShuffledCopyOfTable(oil_list)
    iNumLeftToPlace = self:PlaceSpecificNumberOfResources(self.oil_ID, oil_amt, 1, 1, -1, 0, 0, shuf_list);
    if iNumLeftToPlace == 0 then
      placed_oil = true;
    end
  end
  if placed_iron == false and table.maxn(iron_fallback) > 0 then
    shuf_list = GetShuffledCopyOfTable(iron_fallback)
    iNumLeftToPlace = self:PlaceSpecificNumberOfResources(self.iron_ID, iron_amt, 1, 1, -1, 0, 0, shuf_list);
  end
  if placed_horse == false and table.maxn(horse_fallback) > 0 then
    shuf_list = GetShuffledCopyOfTable(horse_fallback)
    iNumLeftToPlace = self:PlaceSpecificNumberOfResources(self.horse_ID, horse_amt, 1, 1, -1, 0, 0, shuf_list);
  end
  if placed_oil == false and table.maxn(oil_fallback) > 0 then
    shuf_list = GetShuffledCopyOfTable(oil_fallback)
    iNumLeftToPlace = self:PlaceSpecificNumberOfResources(self.oil_ID, oil_amt, 1, 1, -1, 0, 0, shuf_list);
  end
end
 
I played Alpaca's PWM mod, and I liked the efforts made on:
- countering Carpet of Doom: by low healing and NO healing promos (but 2x HP)
- "supply": no upgrade, low heal - you have to train units...

What do you think about these ideas, Thal?
In general, what so you think about the way the map is filled with units? Supply?
I have ideas about it (see my sig). What are yours, if any?
What are the general concept direction you're heading to with combat mod?
Does combat need big changes, or just more balance? :)

I am excited by your mods, also by Alpaca's - so I hope my lots of questions are no offense for you...
 
Hi Thalassicus,

A suggestion I would make regarding air units - at the moment stealth bombers are unable to get promotions. Maybe that's intentional, maybe it's a bug, I don't know. But it kind of sucks for a few reasons:
1) it's just No Fun to have units that never promote
2) a bomber with two promotions is almost entirely better than a stealth bomber
3) bombers that upgrade to stealth bombers still keep their promos, which makes the smart move "build obsolete units then upgrade"
4) it's a seriously advanced tech that gives you nothing else, and leads to Giant Death Robots, so it sort of seems like it's not a huge problem if they're a bit scarily powerful
 
@V. Soma
I do like having more units on the map, which is something I've been going for with increased production and more useful non-resource units. I think significant changes to healing mechanics would fall a little out of the scope of balance mods though, it's more of a direct mod.

I'll take a look at the links in your sig, thank you. :)


@Polycrates
I had no idea stealth bombers were unable to get promotions, that's almost certainly a bug in vanilla. To be honest none of my games last that long, so I hadn't played with them. I'll try and figure out if I can fix that.

Air units in general are in poor shape, and have been since release.
 
I took a look at Alpaca's mod and one thing I do particularly like is a shift away from "keep X units around forever" to "need to build new units periodically." I think removing the capability to upgrade entirely is too much for a balance mod, but I could increase the cost of upgrades. That'd also help deal with some buy-and-upgrade issues.

The ideas in your links all look like very interesting concepts for mods, I think they're a little beyond the scope of a balance mod like this, though.
 
I took a look at Alpaca's mod and one thing I do particularly like is a shift away from "keep X units around forever" to "need to build new units periodically." I think removing the capability to upgrade entirely is too much for a balance mod, but I could increase the cost of upgrades. That'd also help deal with some buy-and-upgrade issues.

Wholeheartedly agree with this proposal! It would have the added side-effect of buffing the fairly weak Professional Army and Pentagon as well.

After an adjustment period to get used to it, I found that the hitpoint change in PWM also made for good gameplay as well. Healing is a bit too slow there for many people, including me, but if units had 15 or 20 HPs and healing was unchanged, it might be a good compromise.
 
one thing I do particularly like is a shift away from "keep X units around forever" to "need to build new units periodically." I think removing the capability to upgrade entirely is too much for a balance mod, but I could increase the cost of upgrades.

The removal of upgrades in alpaca's mod is one of the main things that stops me from playing it, that doesn't sound fun to me. But an increase in upgrade costs doesn't seem unreasonable.

I don't really like the hp changes either, I don't think they're "fun" for the general player, though I acknowledge they make the game more difficult.
 
Let me explain why I don't like the "no upgrades" philosophy.

No upgrades means you are *severely* punished for building a military and not using it. You waste vast numbers of hammers.

Its also just not fun. Part of the fun of Civ is carefully guarding your units and keeping them alive and watching as they become more experienced. Removing this feels punitive.

Yes, there are some buy-and-upgrade issues, but these are minor issues that revolve around some human player exploits that many people don't use, so please make very sure that you don't throw the baby out with the bathwater when changing these values.
 
Let me explain why I don't like the "no upgrades" philosophy.

No upgrades means you are *severely* punished for building a military and not using it. You waste vast numbers of hammers.

Its also just not fun. Part of the fun of Civ is carefully guarding your units and keeping them alive and watching as they become more experienced. Removing this feels punitive.

Yes, there are some buy-and-upgrade issues, but these are minor issues that revolve around some human player exploits that many people don't use, so please make very sure that you don't throw the baby out with the bathwater when changing these values.

I agree. No upgrades made sense in earlier versions of Civ because units were cheap to make. With Civ 5's hammer costs the "supply" approach to combat may be theoretically preferable, but would probably be less fun in reality.
 
Let me explain why I don't like the "no upgrades" philosophy.

I agree with Ahriman here.

I'm very open to making upgrading more expensive, though, since you have a lot of benefits from it (and no penalties):

- it's fast (1 turn)
- you keep promotions
- you don't occupy build queues
- upgraded units may get promotions they couldn't otherwise (UUs!)

I would love someone to post the exact formula for upgrading costs, before we discuss this further, though. Is it 10 gold + 2x hammer cost difference?
 
Back
Top Bottom