This document describes how to convert a Freeciv 2.4 compatible ruleset to a 2.5 compatible one.


Capability string of each ruleset file must be changed:


No more default fallbacks for individual ruleset files[]

In earlier versions it was possible to have ruleset similar enough to default one to actually use default ruleset files just by omitting that file from custom ruleset. That's no longer the case. This affects also ruleset specific script file script.lua, but fallback to default.lua that most rulesets should not implement themselves still works.

Use 'TRUE' and 'FALSE' instead of '0' and '1' for booleans[]

Here the list of affected settings:

  • "cities.ruleset":

  • "effects.ruleset":
reqs = { "negated", "survives" }
  • "game.ruleset":




  • "terrain.ruleset":

  • nation files:

Remove useless cruft[]

  • The old road_superhighway_trade_bonus field is no longer read and should be removed. (It turned out it wasn't doing anything anyway; to control this, use effects.)
  • In nations rulesets, the is_available field is no longer read and should be removed. It didn't do anything.

Move fragments[]

  • Amount of fragments that make up single movement point is no longer hardcoded to 3. To keep old values, add move_fragments = 3 and igter_cost = 1 in terrain.ruleset [parameters] section. If you set number of fragments to value other than 3, note that road movement costs are relative to that value too.


  • Road types sections must be added to terrain.ruleset. See classic terrain.ruleset for documentation and road types similar to old hardcoded ones.
  • "rail_TFS_bonus" fields (for TFS in trade/food/shield) are replaced by "TFS_bonus" fields in road definitions. To make exact conversion from old version, define each "TFS_bonus" zero for all other road types, but use old "rail_TFS_bonus" values for road type "Railroad".
  • "road_trade_incr" field for terrains has been replaced by "TFS_incr" that tells how much of road type specific increase applies on this terrain. To make exact conversion from old version, define all other road type "TFS_incr" fields 0, but make "Road" "trade_incr" 1. Then replace each terrain "road_trade_incr" with "road_trade_incr_pct" and value multiplied by 100, e.g., in 2.4 [terrain_desert] had 1 as road_trade_incr, in 2.5 it is 100 as road_trade_incr_pct.
  • There's only one road build time field for each terrain when previously we had both "road_time" and "rail_time". You may not be able to make exact conversion depending on your previous values. In the common case of earlier "rail_time" being same for all terrain types, you can make build time for road type "Railroad" road specific, not terrain specific by settings its "build_time" to value you used to have in terrain specific "rail_time"s.
  • "river_move_mode" is replaced with road type move mode. Set road type "River" "move_mode" to the equivalent value to what you used to have in "river_move_mode"; 0 -> "NoBonus", 1 -> "Cardinal", 2 -> "Relaxed", 3 -> "FastAlways".
  • Set road type "River" defense bonus to value that used to be "river_defense_bonus".
  • Set road type "River" "trade_incr_const" to value that used to be "river_trade_incr".
  • Set road type "River" helptext to what used to be "river_help_text".
  • Set flags "River", "PreventsOtherRoads", "UnrestrictedInfra", and "Natural" for road type "River" to have it behave just like river special in earlier versions.
  • Requirements on roads should be changed from checking Special Road, Railroad, or River to checking roads
    "Special", "Road", "Local"
    "Road", "Road", "Local"
  • Tech flag "Railroad" has been removed as obsolete. You should have such tech defined as requirement for road type "Railroad" in terrain.ruleset instead.
If you had several Railroad enabling techs, you need to create user tech flag you give all those techs, and have that TechFlag as requirement for road type "Railroad"
  • Unit class flag "RoadNative" has been removed as obsolete. Instead you should give flag "NativeTile" for road type "Road"
  • Unit class flag "RiverNative" has been removed as obsolete. Instead you should give flag "NativeTile" for road type "River"


  • With some limitations it's possible to define terrain specific build time instead of base specific ones, or to disable base building completely on some terrain with new "base_time" field in terrain definitions. To make exact conversion from old version, give each terrain "base_time" field with non-zero value. Base specific build times are still used as they are available, and non-zero terrain specific value just makes sure that base building is not disabled on that terrain.
  • The defense bonuses from rivers and bases are now additive, not multiplicative, as rivers are now a kind of ruleset-defined terrain 'extra' (as are bases) and all defense bonuses from these are added together. For instance if a fortress adds +100% defense (doubles it) and a river adds +50% (1.5x) then in 2.4 they would combine for a 3x bonus, but in 2.5 they only give a lesser 2.5x bonus.
    It is not always possible to exactly preserve existing behavior; while you can add a DefendBonus effect to compensate in most cases (such as the example below), any IgWall units (traditionally Howitzer) will ignore the correction.
type     = "Defend_Bonus"
value    = 20
reqs     =
    { "type", "name", "range"
      "Base", "Fortress", "Tile"
      "Road", "River", "Tile"


  • One may add random disaster sections to game.ruleset, but that's optional. If there's no disasters defined, none simply ever occurs. See default game.ruleset for documentation.

AI traits[]

  • Default traits section should be added to nations.ruleset
  • Optionally you can add also nation specific values for individual nations

Nations compatibility[]

  • In the supplied rulesets which use the standard nations, nations.ruleset is split into two files. The main nations.ruleset defines only global settings such as default traits, and includes a second shared file, default/nationlist.ruleset, which contains the list of individual nations to include. You can either include that same full list from your own nations.ruleset, or have a list of your own, or define nations directly in your ruleset.
  • Nationsets originally introduced in freeciv-2.4 as soft limit (more like preference) have now been reworked to be hard limit. Under no circumstances will a nation from outside the selected set end to the game. Every ruleset must introduce at least one nation set. In the above mentioned three-level setup they are part of default/nationlist.ruleset so ruleset that includes that gets correct settings automatically.
Rulesets not using nationlist.ruleset can make a set containing all their nations like this:
The complete set of playable nations\
  • The nation [compatibility] section has new fields allowed_govs, allowed_terrains, and allowed_city_styles (replacing the boolean warn_city_styles), in which are listed the governments/terrains/city styles that individual nation definitions are allowed to reference. This is mainly for use in our nationlist.ruleset, so that if you include it in a ruleset which doesn't have a particular government (say Fundamentalism), any references to that government (e.g. in ruler titles) are silently ignored rather than causing an error. These fields are optional and not expected to be useful in rulesets which specify their own nations.

Unit conversion[]

  • Converting unit to another is no longer instant operation. You should add "convert_time" field for each unit type that can convert to another. The "convert_time" has to be given as move points, it's rounded up to a multiple of MP per turn.

Effect types[]

Preferred field to give effect type in (such as "Growth_Food") is now type, though old name still works for backward compatibility reasons.

type	= "Growth_Food"
value	= 50
reqs	=
    { "type", "name", "range"
      "Building", "Granary", "City"

Trade routes[]

  • Number of trade routes city may have is controlled by new Max_Trade_Routes-effect. You have to add such an effect to make trade routes possible at all. To recreate old hardcoded behavior of all cities always having 4 trade route slots, you can add this:
type    = "Max_Trade_Routes"
value   = 4
  • The classic ruleset now has a value of 2 in [effect_trade_routes_base] without special requirements, adding 1 in [effect_trade_routes_magnetism], and another 1 in [effect_trade_routes_corporation] for corresponding requirements. The suffix in names of the [effect_trade_routes_*] sections doesn't matter as long as it is unique.

Traderoute settings[]

Some aspects of traderoutes are now defined in ruleset instead of being hardcoded. You have to add [trade] section to game.ruleset with traderoute specific settings. To recreate settings similar to old hardcoded rules, use these values:

settings =
  { "type",       "pct", "cancelling"
    "National",   100,   "Cancel"
    "NationalIC", 200,   "Cancel"
    "IN",         200,   "Cancel"
    "INIC",       400,   "Cancel"

Attack to non-native tiles[]

  • To allow shore bombardment ability to sea units like the hardcoded one they used to have, give any sea moving unit class flag AttackNonNative.
  • Unit type flag No_Land_Attack renamed as Only_Native_Attack and it makes sense for those unit types only for which unit class has AttackNonNative

Attack from non-native tiles[]

  • To allow ships to attack out of harbour cities like they used to with old hardcoded rule, give any sea moving unit class flag AttFromNonNative.

Governmental centers[]

Corruption no longer depends on distance to capital city, but to nearest Governmental center. To make capital act as governmental center as in earlier versions, add "Gov_Center" effects with same requirements as you have "Capital_City" effects.

Nationality conversion[]

Citizens of foreign nationality now slowly convert to city owner's nationality. Add convert_speed to [citizen] section of cities.ruleset. Set it to value 0 to disable conversion the way 2.4 worked.

Partisan appearance[]

Add partisans_pct to [citizen] section of cities.ruleset. Set it to value 0 to make partisan appearance depend on who originally built the city, just like in the earlier versions. If you want to make partisan appearance now to depend on number of citizens of old owner's nationality in city, set the required percentage instead (nationality must be enabled).

If you have replaced the default_make_partisans_callback() in Lua script with one of your own, you may want to change it to use the new (City):inspire_partisans function.


It's now somewhat configurable how many people single point of city size represents. This is purely for values shown in reports. It has no gameplay effect. Add pop_report_zeroes entry to [parameters] section of cities.ruleset. Set it to value 4 to have population in tens of thousands as in earlier versions.

Terrain class[]

Use of terrain flag Oceanic has been replaced by giving class field for all terrain types. Remove Oceanic flag from all terrains that have it, and instead add class = "Oceanic" for them and class = "Land" for all others.

Terrain conversions[]

All of Irrigation, mining, and transform actions are now possible only if relevant effects have positive value. In version 2.4 only basic Irrigation had such a control by Irrig_Possible effect. To make Irrigation and Mining, including terrain changes by them, always available like in earlier versions, define effects Mining_Possible, Irrig_TF_Possible, and Mining_TF_Possible without any requirements and with positive value.

Transform action has never been always possible - it has required unit to have Transform flag. There no longer is such a hardcoded flag, but one can define equivalent flag as user unit type flag. Then one can give that unit flag as requirement for new Transform_Possible effect to have transform work like it did it earlier versions.

The may_road, may_irrigate, may_mine, and may_transform boolean flags have been removed. To disable may_road you can just not define any buildable roads. For the other activities, use the *_Possible effects to control whether these actions are available.

Flooding Lakes[]

Other oceanic terrains now flood to FreshWater terrains when the two get adjacent. To ensure best behavior, you may want to change terrain conversions from land to oceanic terrain to have FreshWater target instead of oceanic one. Then the transformation will result in FreshWater when part of FreshWater lake, and without flooding the lake. If newly created FreshWater tile is part of Ocean, it will be immediately flooded in to part of Ocean instead.

Free tech selection method[]

You need to add setting free_tech_method to [research] section in game.ruleset. Value Goal gives behavior like old hardcoded functionality.

Tech upkeep[]

Tech upkeep method is now defined by descriptive words instead of magic numbers. Replace game.ruleset research.tech_upkeep_style to match

tech_upkeep_style = 0


tech_upkeep_style = "None"

tech_upkeep_style = 1


tech_upkeep_style = "Basic"

There's also new style "Cities" which makes upkeep to be multiplied by the number of player cities.

In 2.4, enabling tech upkeep in the ruleset also enabled loss of techs due to negative bulbs. In 2.5, that's controlled by server settings, independent of whether the ruleset has tech upkeep. To restore the exact previous behavior of such a ruleset, add the following settings to [settings] in game.ruleset:

set =
  { "name", "value"
    "techlossforgiveness", 0
    "techlossrestore", -1

Veteran_Build now cumulative[]

The Veteran_Build effect is now treated as numeric rather than boolean: a unit can be created at a veteran level greater than the first. To preserve existing behaviour, you may have to add nreqs such that at most one of your Veteran_Build effects applies at any time.

Upgrading NoVeteran units doesn't remove veteran levels[]

As of beta2, upgrading to a NoVeteran unit type (that is, one that doesn't gain veteran levels through experience) no longer automatically removes all experience from the unit, as it did in 2.4 and prior.

It's not possible to exactly recreate this behaviour in all circumstances; depending on what you want, giving the new unit type a custom veteran system with a single level, or setting the game settings 'upgrade_veteran_loss' / 'autoupgrade_veteran_loss', may be useful.

Use unit type flags[]

Old single array of user unit type flag names is replaced with table where also helptext to be shown for the units having the flag is present.

flags =
  { "name", "helptxt"
    "Airbase", _("Can build Airbases.") 

Combat bonuses[]

Old special flags Horse, Pikemen, AEGIS, AirUnit, Fighter, and Helicopter removed, and new combat bonuses framework introduced instead. Bonus is always defined for units benefitting from it in the combat. The unit bonus applies against, must have relevant flag, so you may need to define some user unit type flags equivalent of old hardcoded flags.

Horse vs Pikemen[]

To reproduce old Horse vs Pikemen flags behavior, define user unit type flag Horse. Remove old Pikemen flag from units, and define this kind of combat bonus for them instead:

bonuses       =
  { "flag", "type", "value"
    "Horse", "DefenseMultiplier", 1

AEGIS vs AirUnit[]

To reproduce old AEGIS vs AirUnit flags behavior, define user unit type flag AirUnit. Remove old AEGIS flag from units, and define this kind of combat bonus for them instead:

bonuses       =
  { "flag", "type", "value"
    "AirUnit", "DefenseMultiplier", 4

(You may wish to avoid giving non-attack units like AWACS your new AirUnit flag, to avoid confusing help.)

Fighter vs Helicopter[]

To reproduce old Fighter vs Helicopter flags behavior, define user unit type flag Helicopter. Remove old Fighter flag from units, and define these kind of combat bonuses for them instead:

bonuses       =
  { "flag", "type", "value"
    "Helicopter", "DefenseDivider", 1
    "Helicopter", "Firepower1", 1

Max Rates of Cheating AI[]

Cheating AI is no longer hardcoded to ignore Max_Rates limitations for tax/sci/lux settings. If you want Cheating AI still not to be subject to those limitations, you can add this kind of effect:

type    = "Max_Rates"
value   = 100
reqs    =
    { "type", "name", "range"
      "AI", "Cheating", "Player"


Killstack is now server option. Remove it from game.ruleset combat_ruleset section. If you want to force its value with your ruleset, you can add it as locked ruleset setting to settings listing in game.ruleset

set =
  { "name", "value", "lock"
    "killstack", "enabled", TRUE


Unit classes that kill citizens upon succesful attack against city are now defined in units.ruleset by giving them KillCitizen flag. To mimic old default value of killcitizen setting, give that flag to all land moving unit classes.

Minimum native start area[]

Add min_start_native_area value to parameters section of terrain ruleset. Set it to value 0 to accept any size of start area like earlier versions did. You will want set it to some other value only if your ruleset has terrain types non-native to startunits.

Civil war[]

You can disable civil war entirely by including civil_war_enabled = FALSE to game.ruleset civstyle section. To get the previous default behaviour of allowing civil war, add civil_war_enabled = TRUE.

Game loss style[]

A new bitwise option gameloss_style controls what happens to a player's possessions if they lose the game by for instance losing their Leader unit. Set gameloss_style = "" to get the old hardcoded behaviour where all units/cities simply disappear.

Paradrop options[]

It's now possible to allow paratroopers to land on transports. Define this in game.ruleset civstyle section. To get the old hardcoded behaviour where they could only land on cities/bases, use paradrop_to_transport = FALSE.

Embark/Disembark Unreachable units[]

Embarking or Disembarking Unreachable units is no longer possible by default. Just like units able to attack Unreachable units must list Unreachable unit class in targets, units wanting to embark or disembark when Unreachable transport is outside native base and not in a city, must list such transport classes in embarks or disembarks lists. To mimic old behavior that units can always embark or disembark Unreachable units, just list them in lists of all possible cargo units.