How to update a ruleset from 3.1 to 3.2

This document describes how to convert freeciv 3.1 compatible ruleset to development version (one that will become freeciv 3.2) compatible ones. Currently this goes up to compatibility with freeciv main commit ce01159593.
==ruleup==
The ruleup -utility can be used to do the update (mostly) automatically. Also ruledit does the same update process if one loads 3.1 ruleset to it, and saves it back as 3.2 ruleset.
This process does not keep any custom comments, or formatting of the ruleset. It just saves the rules and some standard comments. For ruleset readability, and for not having as mindless rule conversions as ruledit does, you may still want to do the manual update. Rest of this document describes those changes that you need to do.
Freeciv-ruleup
==Capability==
Capability string and format_version of each ruleset file must be updated. For 3.2 rulesets the format version is 30.
[datafile]
options = "+Freeciv-ruleset-3.2-Devel-2022.Feb.02"
format_version = 30
==.modpack -files==
There's a new modpack metadata file <modpack>.modpack. You should add one for your ruleset. See ones for supplied rulesets for simple examples.
==actions.ruleset==
New actions.ruleset needs to be created, with the standard [datafile] header, and actions related content from game.ruleset moved there. The content to move are [auto_attack], [actions], and all [actionenabler_*] sections.
==Tile range==
From requirement range Local a new range Tile has been split. Replace Local range by Tile in all requirements in all requirements list where requirement is about tile. Local now always refers to ruleset item (as defined by requirement type and value) itself.
==Topology and Wrap split==
Map wrapping information has been split away from Topology information. This affects "Topology" requirements. If you have had "Topology" requirements with value "WrapX" or "WrapY", turn those to "Wrap" requirements with similar value.
==Latitude settings==
There are new MinLatitude and MaxLatitude requirement types. Old ServerSetting based requirements for alltemperate and singlepole should be converted to use those.
AllTemperate can be recreated by MinLatitude 750 and reverted presence field compared to old ServerSetting requirement.
SinglePole can be recreated by MaxLatitude -500 and reverted presence field compared to old ServerSetting requirement.
==Building genus Convert==
Change genus of any building with Gold flag to Convert.
==Prevent city destruction by attack actions==
Old rule that attack actions cannot take last population point from the city has been unhardcoded. To keep the old behavior, add an Unit_No_Lose_Pop effect like
[effect_attack_bombard_no_city_destruction]
type = "Unit_No_Lose_Pop"
value = 1
reqs =
 { "type", "name", "range", "present"
 "MinSize", "2", "City", FALSE
 }
==NoAggressive extra flag unhardcoding==
Remove old NoAggressive flag from extras, and instead setno_aggr_near_city = 3
to those extras that had it.
==Polar Huts==
Hardcoded rule that Huts cannot appear on Frozen terrains removed. To prevent Huts from appearing on polar regions, add following requirements for Hut extras:
"MaxLatitude", "980", "Tile"
"MinLatitude", "-980", "Tile"
==Revealing trade partner==
Old hardcoded rule that trade partner city is always revealed has been unhardcoded, and the new default is that they are not revealed. To keep old rule of revealing the trade partners, set game.ruleset trade -section entry reveal_trade_partner to TRUE.
==Generalized unit requirements==
Units now have general requirement vectors. Replace old tech_req, impr_req, and gov_req -fields with equivalent requirements. Tech and Government requirements should be in Player range. Small Wonder Building requirements should also be in Player range, but other Building requirements in City range.
tech_req = "Alphabet"
gov_req = "Monarchy"
->
reqs =
 { "type", "name", "range"
 "Tech", "Alphabet", "Player"
 "Gov", "Monarchy", "Player"
 }
==Homeless unit gold upkeep==
Ruleset can now make even homeless units to pay for upkeep. To keep the old rule that homeless units are always excluded from paying upkeep, set game.ruleset civstyle -section entry homeless_gold_upkeep = FALSE
==Merged Clean actions==
Former separate Clean Pollution and Clean Fallout actions have been merged to one Clean action.
===Action ui_names===
Remove ui_name_clean_pollution and ui_name_clean_fallout entries. Provide new ui_name_clean entry if you want non-default value for it.
===Action enablers===
If you used to have identical action enablers for them, rename one to Clean and remove the other.
If you used to have different action enablers for them, you should add user extra flag for Fallout extras. Add not-present target requirement ExtraFlag Fallout to former Clean Pollution enablers and present = TRUE ExtraFlag Fallout target requirement to former Clean Fallout enablers. Rename both enabler types to Clean.
===Extra rmcause===
Change extras with rmcause Clean Pollution or Clean Fallout to have rmcause Clean instead.
===Clean time===
Terrains used to have pollution_time and fallout_time -fields, applied depending on the action type. These have been replaced by more generic extra -specific removal times in extra_settings array. Set removal time of the pollution extras to the former pollution_time value, and fallout extras to the former fallout_time value.
pollution_time = 3
fallout_time = 2
->
extra_settings =
 { "extra", "removal_time"
 "Pollution", 3
 "Fallout", 2
 }
In the unlikely case that you had the same extra with both causes Pollution and Fallout, and with different removal time depending on whether Clean Pollution or Clean Fallout was being enabled/used, you need to build the exact removal time by using Activity_Time -effects. 
==pop_cost unit nationality==
The way nationality of a unit with population cost gets determined is now configurable. To keep old hardcoded rule that the nationality is that of citizens, set cities.ruleset citizen -section setting ubuilder_nationality to FALSE.
==Growth_Food split==
Growth_Food effect has been split to two. Growth_Food now affects situation only when the city grows. New Shrink_Food is used when city shrinks. To keep the old rule that the effects are always the same, add similar (both the value and requirements) Shrink_Food effect for each Growth_Food effect you have.
==Transport Deboard==
Transport Alight action has been renamed as Transport Deboard. Change all the occurrences of the action name in action enablers and requirement lists. Change ui_name_transport_alight to ui_name_transport_deboard:
ui_name_transport_alight = _("%sDeboard%s")
->
ui_name_transport_deboard = _("%sDeboard%s")
==Collect Ransom action==
Collect Ransom is now action enablers controlled action.
===Action enablers===
To always allow Collect Ransom, like old hardcoded rule was, add action enablers like following:
[actionenabler_ransom_from_native]
action = "Collect Ransom"
actor_reqs =
 { "type", "name", "range", "present"
 "UnitFlag", "NonMil", "Local", FALSE
 "UnitClassFlag", "Missile", "Local", FALSE
 "MinMoveFrags", "1", "Local", TRUE
 "UnitState", "OnNativeTile", "Local", TRUE
 "DiplRel", "War", "Local", TRUE
 }
[actionenabler_ransom_marines]
action = "Collect Ransom"
actor_reqs =
 { "type", "name", "range", "present"
 "UnitFlag", "NonMil", "Local", FALSE
 "UnitClassFlag", "Missile", "Local", FALSE
 "MinMoveFrags", "1", "Local", TRUE
 "UnitFlag", "Marines", "Local", TRUE
 "DiplRel", "War", "Local", TRUE
 }
[actionenabler_ransom_att_from_non_native]
action = "Collect Ransom"
actor_reqs =
 { "type", "name", "range", "present"
 "UnitFlag", "NonMil", "Local", FALSE
 "UnitClassFlag", "Missile", "Local", FALSE
 "MinMoveFrags", "1", "Local", TRUE
 "UnitClassFlag", "AttFromNonNative", "Local", TRUE
 "DiplRel", "War", "Local", TRUE
 }
===Movement Cost effect===
To make Collect Ransom to take movement like old hardcoded rule, add effects like following. Exact cost depends on move fragment count in terrain.ruleset:
[effect_action_success_ransom_one_attack]
type = "Action_Success_Actor_Move_Cost"
value = 65535
reqs =
 { "type", "name", "range", "quiet"
 "Action", "Collect Ransom", "Local", TRUE
 "UnitFlag", "OneAttack", "Local", TRUE
 }
[effect_action_success_ransom]
type = "Action_Success_Actor_Move_Cost"
value = 3
reqs =
 { "type", "name", "range", "present"
 "Action", "Collect Ransom", "Local", TRUE
 "UnitFlag", "OneAttack", "Local", FALSE
 }
===Collect Ransom blocking other movement actions===
Old hardcoded rule was that user can't select between movement actions, but if Collect Ransom is possible, it's always executed instead of any other movement actions. To replicate that rule, add Collect Ransom to the beginning of the attack_blocked_by and suicide_attack_blocked_by arrays.
===Occupychance movement after Collect Ransom===
Old hardcoded rule was that certain movement actions are exectuted after Collect Ransom if occupychance server setting dictates that unit should try to move to the tile where enemies were. To replicate that rule, add following entry:
collect_ransom_post_success_forced_actions =
 "Conquer City", "Conquer City 2",
 "Transport Disembark",
 "Transport Disembark 2",
 "Conquer Extras", "Conquer Extras 2",
 "Enter Hut", "Enter Hut 2",
 "Unit Move"
===Collect Ransom autoattack===
Old hardcoded rule was that autoattack try to Collect Ransom before actual attacks if unit capture and bombard are impossible. To achieve similar rule, add Collect Ransom to the attack_actions after possible Capture Units and/or Bombard.
==min_tech_cost==
Minimum tech cost is no longer hardcoded to be same as the base tech cost. Add the min_tech_cost entry to game.ruleset, and to preserve old behavior, make it's value same as that of base_tech_cost
==Mandatory Max_Rates base effect==
It's now mandatory to have at least one Max_Rates effect in the ruleset. Your ruleset is unlikely to require any changes because of this, as the ruleset would have never worked properly without the effect. Now it just gives clear error when loading the ruleset, instead of behaving badly in game.
==Mandatory CanRoad requirement for Build Road==
Build Road action enablers are now required to have target requirement TerrainAlter CanRoad
Add the requirement to all Build Road action enablers
target_reqs =
 { "type", "name", "range"
 "TerrainAlter", "CanRoad", "Tile"
 }
==Mandatory CanBase requirement for Build Base==
Build Base action enablers are now required to have target requirement TerrainAlter CanBase
Add the requirement to all Build Base action enablers
target_reqs =
 { "type", "name", "range"
 "TerrainAlter", "CanBase", "Tile"
 }
==ui_name_build_road==
Build Road activity's name entry ui_name_road has been renamed as ui_name_build_road. Replace the entry.
ui_name_road = _("Build %sRoad%s")
->
ui_name_build_road = _("Build %sRoad%s")
==Spaceship travel time setting==
Server setting has been renamed from spaceship_travel_time to spaceship_travel_pct. Update entry in game.ruleset settings -section, if you have one.
==Bzip2 compresstype deprecation==
Deprecation of bzip2 compresstype has progressed to the point where it's no longer supported at all on saving the game. Loading old bzip2 compressed savegames still work.
If your game.ruleset settings -section has a compresstype entry, and it set compresstype to bz2, change that to one of the supported compresstypes. Current default is zstd
==See also==
Category:Editing rulesets