Correct the rulesets civ1 and civ2

Do you want to help out with Freeciv development? Then check out this forum.
nef
Elite
Posts: 324
Joined: Mon Jun 25, 2018 5:01 pm

Re: Correct the rulesets civ1 and civ2

Post by nef »

As I recall free shield upkeep should be MIN (city size, 3) under despotism (and anarchy?).

If so then replace sections [effect_upkeep_free_units_anarchy] and
[effect_upkeep_free_units_despotism] with the following:

Code: Select all

[effect_upkeep_free_units_1]
type    = "Unit_Upkeep_Free_Per_City"
value   = 1
reqs    =
    { "type",       "name",      "range", "present"
      "MinSize",      1,         "city",   TRUE
      "Gov",        "Monarchy",  "Player", FALSE
      "Gov",        "Republic",  "Player", FALSE
      "Gov",        "Democracy", "Player", FALSE
      "Gov",        "Communism", "Player", FALSE
      "OutputType", "Shield",    "Local",  TRUE
    }

[effect_upkeep_free_units_2]
type    = "Unit_Upkeep_Free_Per_City"
value   = 1
reqs    =
    { "type",       "name",      "range", "present"
      "MinSize",      2,         "city",   TRUE
      "Gov",        "Monarchy",  "Player", FALSE
      "Gov",        "Republic",  "Player", FALSE
      "Gov",        "Democracy", "Player", FALSE
      "Gov",        "Communism", "Player", FALSE
      "OutputType", "Shield",    "Local",  TRUE
    }

[effect_upkeep_free_units_3]
type    = "Unit_Upkeep_Free_Per_City"
value   = 1
reqs    =
    { "type",       "name",      "range", "present"
      "MinSize",      3,         "city",   TRUE
      "Gov",        "Monarchy",  "Player", FALSE
      "Gov",        "Republic",  "Player", FALSE
      "Gov",        "Democracy", "Player", FALSE
      "Gov",        "Communism", "Player", FALSE
      "OutputType", "Shield",    "Local",  TRUE
    }
Can someone confirm/deny?
User avatar
meynaf
Hardened
Posts: 155
Joined: Sun Jan 21, 2018 10:27 am
Location: Lyon / France
Contact:

Re: Correct the rulesets civ1 and civ2

Post by meynaf »

nef wrote: In Civ I a fairly simple test to check (b) is to use republic or democracy, for (c) celebration under monarchy or communism. The criterion in both cases is: does a normal railroad tile produce 2 or 3 trade? (Normal = grassland|plains|desert.)
From an old save game i can see it's 2 trade under democracy.

nef wrote:As I recall free shield upkeep should be MIN (city size, 3) under despotism (and anarchy?).
Civilopedia says "Home city units numbering less than or equal to city size do not require maintenance" for despotism and something similar for anarchy. In addition, a simple test has shown that number of free units for despotism is always city size, nothing to do with 3 (city of size 1 has only 1 free unit, not 3 ; city of size 4 has 4 free units, not 3).

Note : this is for Civ 1 version 855.04.
cazfi
Elite
Posts: 3069
Joined: Tue Jan 29, 2013 6:54 pm

Re: Correct the rulesets civ1 and civ2

Post by cazfi »

Preventing Railroads on city centers -> Feature #803249
nef
Elite
Posts: 324
Joined: Mon Jun 25, 2018 5:01 pm

Re: Correct the rulesets civ1 and civ2

Post by nef »

meynaf wrote: Civilopedia says "Home city units numbering less than or equal to city size do not require maintenance" for despotism and something similar for anarchy. In addition, a simple test has shown that number of free units for despotism is always city size, nothing to do with 3 (city of size 1 has only 1 free unit, not 3 ; city of size 4 has 4 free units, not 3).
I didn't want to hear this. Civ2civ3 deals with this (for food upkeep) but it is ugly. I think it is time for a new idea in reqs predicates but that's outside the scope of this topic. In the meantime the effects from civ2civ3 could be adapted (and adopted).
nef
Elite
Posts: 324
Joined: Mon Jun 25, 2018 5:01 pm

Re: Correct the rulesets civ1 and civ2

Post by nef »

From an old save game i can see it's 2 trade under democracy.
Means that fc was, and still is, correct in using the [road_*] fields for calculating the railroad multiplier (rather than the Output_Per_Tile effect).
nef
Elite
Posts: 324
Joined: Mon Jun 25, 2018 5:01 pm

Re: Correct the rulesets civ1 and civ2

Post by nef »

My recollection of Civ I was that when you get mercenaries from hut_enter the home city is not determined by the unit entering the hut but by proximity to the player's nearby city. I had thought it was just a matter of distance, but I have read that it actually depends on whose city is nearest. That is, if the nearest city belongs to the player, then it becomes the home city. If another player's city is closest (or there are no cities) then the merc. is a freebie.

I have implemented this in Lua. The first part is a modification to default.lua. I have used my own version first posted here.
The reasons being:
  • That is the one I use.
    Profiles are easy to change making tests much easier.
The change comprises turning the two references to "unit:get_homecity()" to a call to a new function _deflua_unit_get_home (unit). This function is defined in default.lua as:

Code: Select all

if type(_deflua_unit_get_home) ~= "function"
then _deflua_unit_get_home = function (unit)
     return unit:get_homecity()
     end
end
The conditional is there to guarantee that it can be overridden by a replacement. It may, or may not, be necessary but I have been too lazy to find out.
EDIT: I finally got around to testing this. The (default) default.lua script is processed after the ('ruleset') script.lua so it was, in fact, necessary.

Here is my new version:
default.txt
(10.91 KiB) Downloaded 463 times

I should point out that there is nothing essential in my version; the same changes to the distro version are straightforward (as described above).

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

The other part is Lua text in the ruleset (e.g.civ1) script.lua that defines the alternative version of "_deflua_unit_get_home()":

Code: Select all

--   nef 20190214

_deflua_unit_get_home = function (unit)
     local old_distance, old_city
     local tile  = unit.tile

-- find closest city     
     for   player
     in    players_iterate ()
     do
           for new_city
           in  player:cities_iterate ()
           do
               local  new_distance = tile:sq_distance (new_city.tile)
               if not old_distance
               or     new_distance < old_distance
               then   old_distance, old_city  = new_distance, new_city
               end
           end
     end
     
-- if ours then use as unit home city, if not then its a freebie     
     if    old_city
     and   old_city.owner  == unit.owner
     then  return old_city
--   else  return nil    
     end
end

Both parts are necessary to activate the new feature. Absence of either (or both!) will result in the exact same behaviour as that in the distro. I have included settlers as well. They don't happen in civ1 - but you can get them in other rulesets.

The script.lua segment is inserted as a script function - i.e. not part of any other function, loop or call back etc, as has been the case of previous changes. If you want it for ALL your rulesets then it could be inserted directly into default.lua instead (either my new version or the MODIFIED form of the distro default.lua). I have no idea which (or what) paradigm is used in Civ II & III - I will leave that to someone who knows.
Last edited by nef on Mon Sep 02, 2019 4:06 pm, edited 1 time in total.
nef
Elite
Posts: 324
Joined: Mon Jun 25, 2018 5:01 pm

Re: Correct the rulesets civ1 and civ2

Post by nef »

Color conflicts:

Civ I had a limited set of colors for nations (players), in fact in all cases (except barbs) there were two nations (players) per color. Both could not be present at the same time. The plan was that as various players got elimated, the mate would be eligible to take its place spontaneously (which is not a current facility in fc), or be added to the list of available nations for civil war purposes (as an alternative to the original???).

While I was playing civ1, I noticed that often there were pairs of nations that had colors so similar that I sometimes made a mistake in identifying them. I classified them so:

Code: Select all

Aztec      - yellow
Egyptian   - yellow
Babylonian - green
Zulu       - green
Roman      - white
Russian    - white
French     - blue
German     - blue
Mongol     - purple     (grey)
Indian     - purple     (grey)
Greek      - orange     (pink)
English    - orange     (pink)
Chinese    - light blue
American   - light blue
barbs x2   - red
It seemed to me that there had been a plan to implement the color exclusion of Civ I/II, but that something had gone wrong at the last hurdle.


Using the list above add to the sections [nation_*] in the civ1 nations.ruleset:

conflicts_with="<mate_to_*>", where of course, <mate_to_*> is the color twin to the nation being defined in the current [nation_*] section.

Some notes:
  • Only one of each pair would be needed but I personally changed all.
    Since this exclusion is color related I placed the field immediately after the three color fields e.g.

    Code: Select all

    [nation_zulu]
    ......
    name=_("Zulu")
    ......
    color.r = 90
    color.g = 230
    color.b = 42
    conflicts_with="Babylonian"   ;nef
    ......
    

The colors in parentheses are the colors listed in the wikis. It is certainly my recollection that the Indian nation was grey (dark grey in fact). Perhaps a slight shift in colors for authenticity might be useful. The colors used in Civ I&II are a prominent feature in the wikis.

Civ2 is similiar but there is one more in each conflict group:

Code: Select all

Spanish      - yellow
Japanese     - green
Celtic       - white
Viking       - blue
Sioux        - purple     (grey)
Carthaginian - orange     (pink)
Persian      - light blue
Note that the value for the "conflicts_with = " field is a CSV list - add the additional conflict to each list.

A suggestion I have here to make maintenance/preparation easier is to allow the same [nation_*] nation to appear in its own conflict list. Obviously, it would be ignored but this would allow the exact same text to be used in all members of any one conflict group. If it had been allowed then it would have been easy for me to include the fixes in this post. A possible 'deprecation' route may be to have an alternative field name "conflict_group = <CSV>".

The exact same suggestion for [extra_*] conflicts (in terrain.ruleset).

Bug: exclusion fails with civil war
nef
Elite
Posts: 324
Joined: Mon Jun 25, 2018 5:01 pm

Re: Correct the rulesets civ1 and civ2

Post by nef »

As I recall in Civ I ALL units (except your own) will displace tile workers under all circumstances.


In units.ruleset sections [unitclass_air] and [unitclass_missile] have the flag "DoesntOccupyTile". I believe these are wrong and should be removed. I.e. [unitclass_air]

Code: Select all

; flags         = "Unreachable", "DoesntOccupyTile"
flags         = "Unreachable"   ;nef
[unitclass_missile]

Code: Select all

; flags         = "Missile", "Unreachable", "DoesntOccupyTile"
flags         = "Missile", "Unreachable"   ;nef
The unit class flag is small beer. The elephant in the room is:

Code: Select all

; "NonMil"	= a non-military unit: no attacks; no martial law; can enter
;                 peaceful borders; DoesntOccupyTile

This flag is still egregiously overloaded and needs to be split up into individual components. If there is to be only one splinter then my top pick would be "OccupiesTile" as a direct contradiction to the unit class flag "DoesntOccupyTile". ["no attacks" is already implicit in the field "attack = 0" - so that can be removed right now - if it's not already.] The flag should be absolute - i.e. it should apply equally to war AND PEACE (but, of course, not alliance - but that's a problem in its own right). Someone with detailed knowledge of Civ II may need to review this for civ2 purposes - so maybe "Martial_Law" may be the way to go instead.

I could not find a current way to separate 'occupies tile' from 'martial law'. Still open to someone who knows better.

It is not obvious to me that fc3.0 action enablers will help with this one so for civ1 purposes this is a bug in the c code and needs to be fixed - separate the three features:
  • No attacks - already covered by attack = 0
    Martial law
    Occupies tile - defeated only by Civ II/fc style common occupancy of 'Alliance'.
nef
Elite
Posts: 324
Joined: Mon Jun 25, 2018 5:01 pm

Re: Correct the rulesets civ1 and civ2

Post by nef »

A related civ1 anomaly:
  • [unit_settlers]
    [unit_diplomat]
    [unit_caravan]
    [unit_barbarian_leader]
The civ1 ruleset allows the first three of these units to be built as veterans if there are any barracks in the city. The first three result in incorrect gameplay (IMO). Typically the veteran build is defeated in (other) current rulesets by using "NonMil" and "NoVeteran" nreqs predicates . Since [unit_settlers] and [unit_diplomat] already have the "NoVeteran" flag it makes sense to just add this same flag to [unit_caravan]

Code: Select all

; flags         = "TradeRoute", "HelpWonder", "IgZOC", "NonMil"
flags         = "TradeRoute", "HelpWonder", "IgZOC", "NonMil", "NoVeteran"  ;nef
and [unit_barbarian_leader]

Code: Select all

; flags         = "IgZOC", "NonMil", "NoBuild"
flags         = "IgZOC", "NonMil", "NoBuild", "NoVeteran"   ;nef
although this latter case is moot.

I believe [unit_caravan] should have already had the flag for regular unit activities (in addition to build with barracks).

The three sections [effect_barracks], [effect_barracks_ii], and [effect_barracks_iii] should have the "NoVeteran" (nreqs) predicate and therefore read:

Code: Select all

[effect_barracks]
type    = "Veteran_Build"
value	= 1
reqs	=
    { "type",     "name",         "range", "present"
      "Building", "Barracks",     "City",   TRUE
      "Building", "Barracks II",  "City",   FALSE
      "Building", "Barracks III", "City",   FALSE
      "UnitFlag", "NoVeteran",    "Local",  FALSE   ;nef
    }

[effect_barracks_ii]
type    = "Veteran_Build"
value	= 1
reqs	=
    { "type",     "name",         "range", "present"
      "Building", "Barracks II",  "City",   TRUE
      "Building", "Barracks III", "City",   FALSE
      "UnitFlag", "NoVeteran",    "Local",  FALSE   ;nef
    }

[effect_barracks_iii]
type    = "Veteran_Build"
value	= 1
reqs	=
    { "type",     "name",         "range", "present"
      "Building", "Barracks III", "City",   TRUE
      "UnitFlag", "NoVeteran",    "Local",  FALSE   ;nef
    }

Add a "NonMil" predicate as well if you insist, but I think for civ1 the "NoVeteran" flag will do just fine (if you fix the caravan).
nef
Elite
Posts: 324
Joined: Mon Jun 25, 2018 5:01 pm

Re: Correct the rulesets civ1 and civ2

Post by nef »

"Cannot conquer from non native tile" (not as I remember it) - units that can occupy the city ("CanOccupyCity") from land should also be able to occupy from sea (in civ1). There were no marines in Civ I - or - to put it another way - there were no non marines.

I tried using the unit class flag "AttFromNonNative" but it became obvious that this flag is overloaded - that is there does need to be a distinction between occupying and attacking for army units as a direct complement to (the absence of) "CanOccupyCity" as applied to air and sea units. As corbeau pointed out, an IRL direct amphibious assault by army is perilous, but as I pointed out invading an undefended city is not. Civ I seems to have got this right (IMO). As for Civ II I don't know.

When I tried "AttFromNonNative" the civ1 AI took advantage and used artillery on ships to attack anything and everything on land within or without cities!

To provide a Civ I like environment I resorted to selectively applying the marine flag to units that are primarily defensive. So to the sections [unit_militia], [unit_phalanx], [unit_musketeers], [unit_riflemen], [unit_mech_inf] change the (otherwise empty) flags field to

Code: Select all

flags         = "Marines"     ;nef
I presume action enablers in fc3.0 could be used to make the distinction (occupy vs attack) explicit.
Post Reply