Freeciv
Register
Advertisement

This document describes how to convert freeciv 2.6 compatible ruleset to freeciv 3.0 compatible one.

For updating a tileset, see: How to update a tileset from 2.6 to 3.0

Ruleup[]

The new utility called freeciv-ruleup can also help with updating a ruleset. See

Freeciv-ruleup

Capability[]

Capability string of each ruleset file must be changed. Also a new format_version field needs to be added. For 3.0 rulesets the format version is 10.

[datafile]
options="+Freeciv-3.0-ruleset"
format_version=10

Ruleset capabilities[]

New capability string for matching ruleset compatibility with a scenario file has been added. You may add just an empty value for not supporting any scenarios that have compatibility requirements.

[about]
capabilities = ""

Effect name no longer accepted[]

For backward compatibity reasons, loading of effects from a ruleset has supported giving effect type as name instead in previous versions. This is no longer possible, but only type is being supported. Change all remaining names to type

[effect_granary]
name	= "Growth_Food"
value	= 50
reqs	=
    { "type", "name", "range"
      "Building", "Granary", "City"
    }

->

[effect_granary]
type	= "Growth_Food"
value	= 50
reqs	=
    { "type", "name", "range"
      "Building", "Granary", "City"
    }

Resource Extra[]

Resources are now a kind of Extra. Parts of a resource now lives in its extra section. The rest of it still lives in its resource section. The resource is tied to its extra via its extra field. The fields name, graphic and graphic_alt has moved from the resource section to the extra section. The category of an extra is "Resource". The causes of an extra is "Resource".

Upgrade a resource[]

Say you have the following 2.6 resource:

[resource_gold]
name        = _("Gold")
graphic     = "ts.gold"
graphic_alt = "-"
identifier  = "$"
trade       = 6
# glacier, hills, mountains.

Add an extra section for it. Move the fields name, graphic and graphic_alt from the resource section to the extra section. Add the field extra to the resource section. Set it to the corresponding extra. Set the extra category field to "Resource" and the extra causes field to "Resource". Add the fields activity_gfx and rmact_gfx with the value "None" to the extra section. You may also add graphics alt tag fields (set to "-") and a commented out rmcauses.

[resource_gold]
extra       = "Gold"
identifier  = "$"
trade       = 6
# glacier, hills, mountains.
[extra_gold]
name           = _("Gold")
category       = "Resource"
causes         = "Resource"
;rmcauses       = ""
graphic        = "ts.gold"
graphic_alt    = "-"
activity_gfx   = "None"
act_gfx_alt    = "-"
rmact_gfx      = "None"
rmact_gfx_alt  = "-"

Upgrade requirements[]

Go through all your requirement vectors. Change all requirements with the Resource type to the Extra type.

Retired base flags[]

The base flags ParadropFrom, DiplomatDefense and NoStackDeath have been retired. Feel free to skip this section if you didn't use any of them. NoStackDeath is now a hard coded extra flag. ParadropFrom and DiplomatDefense have been removed. You can add them back as user extra flags.

Move the flag[]

Do this when a base flag now is a hard coded Extra flag or when you plan to add it back as a user Extra flag.

Go over you bases. Move the flag from the base_ section to the extra_ section.

Go over your requirement vectors. Change each BaseFlag requirement that requires a retired base flag to an ExtraFlag requirement.

reqs   =
    { "type",      "name",            "range"
      "BaseFlag", "DiplomatDefense", "Local"
    }

becomes

reqs   =
    { "type",      "name",            "range"
      "ExtraFlag", "DiplomatDefense", "Local"
    }

.

Reintroducing the flag[]

Do this when a base flag has been removed and you wish to reintroduce it as an Extra user flag.

Add the user Extra flag[]

Add the flag to terrain.ruleset's control section's extra_flags. To reintroduce both ParadropFrom and DiplomatDefense:

extra_flags =
  { "name", "helptxt"
    _("ParadropFrom"), _("Units can paradrop from this tile.")
    _("DiplomatDefense"), _("Diplomatic units get a 25% defense bonus in diplomatic fights.")
  }

Give the user Extra flag meaning[]

Use the Paradrop Unit action enabler to give the ParadropFrom extra flag meaning. The details are found in the Paradrop Unit action enabler's upgrade instructions.

Use the Spy_Resistant effect to give the DiplomatDefense flag meaning. It should give 25 spy resistance.

[effect_diplomat_defense_extra]
type    = "Spy_Resistant"
value	= 25
reqs	=
    { "type",      "name",            "range"
      "ExtraFlag", "DiplomatDefense", "Local"
    }

Renamed unit type flags[]

The Trireme flag is now called Coast. The Undisbandable flag is now called EvacuateFirst. All references to a renamed unit type flag must be changed. Check each unit type's flags and combat bonuses fields. Do the same for your requirement vectors.

Caravan one time bonus[]

The one time bonus when a unit performs the actions "Enter Marketplace" and "Establish Trade Route" is less hard coded.

The one time bonus for entering the marketplace is no longer a third of the one time bonus for establishing a new trade route. If you want to keep the old rule add it back using the Trade_Revenue_Bonus effect like:

[effect_enter_marketplace_bonus_reduction]
type	= "Trade_Revenue_Bonus"
value	= -1585
reqs	=
    { "type", "name", "range"
      "Action", "Enter Marketplace", "Local"
    }

One time bonuses aren't tripled to resemble Civ 2 any more. If you want to keep the old rule add it back using the Trade_Revenue_Bonus effect like:

; Fudge factor to more closely approximate Civ2 behavior. (Civ2 is
; really very different -- this just fakes it a little better)
[effect_bonus_fudge_factor]
type	= "Trade_Revenue_Bonus"
value	= 1585

Have_Embassies split[]

Have_Embassies effect has been split to two separate effects. Now Have_Embassies itself provides embassies only with those players one has had contact with. New Have_Contacts effect provides contact with all the players. To keep old behavior of getting contact and embassy with all the players, just add Have_Contacts effects with exactly same requirements for each Have_Embassies. Those Have_Contacts effects will provide contacts for Have_Embassies to get embassy with everyone.

Spy_Resistant split[]

The Spy_Resistant effect has been split in two separate effects. Spy_Resistant itself increases the odds of the defender in diplomatic combat. The new Building_Saboteur_Resistant effect protects against building sabotage. To keep old behavior of getting both, just add a new Building_Saboteur_Resistant effects with exactly same requirements for each Spy_Resistant.

Output_Waste_By_Distance granularity[]

Granularity of the Output_Waste_By_Distance effect has been increased. To convert old values to equivalent new values, multiply value of each Output_Waste_By_Distance effect by 100.

Split Diplomat Action Enablers[]

Some diplomat actions are split to two separate action enablers where hardcoded check for presence of the Spy flag previously dictated how the action enabler behaved.

The instructions below assumes that both Spy and non Spy units uses the same action enabler. There is no need for two action enablers if this isn't the case. All that has to be done for it is to make sure that the action enabler enables the appropriate action. Just set its action to the correct version based on the below instructions' requirement of the presence or absence of the Spy unit type flag.

Investigate City split[]

Investigate City action no longer lets units with Spy flag to escape. New action Investigate City Escape lets unit to escape. To create rules matching old hardcoded behavior, create Investigate City Escape action enablers similar to any Investigate City action enablers you have, and add requirement "UnitFlag", "Spy", "Local", FALSE for Investigate City enablers and "UnitFlag", "Spy", "Local" for Investigate City Escape enablers.

Establish Embassy split[]

Establish Embassy action no longer consumers units without Spy flag. New action Establish Embassy Stay consumes unit. To create rules matching old hardcoded behavior, create Establish Embassy Stay action enablers similar to any Establish Embassy action enablers you have, and add requirement "UnitFlag", "Spy", "Local", FALSE for Establish Embassy Stay enablers and "UnitFlag", "Spy", "Local" for Establish Embassy enablers.

Incite City split[]

Incite City action no longer lets units with Spy flag to escape. New action Incite City Escape lets unit to escape. To create rules matching old hardcoded behavior, create Incite City Escape action enablers similar to any Incite City action enablers you have, and add requirement "UnitFlag", "Spy", "Local", FALSE for Incite City enablers and "UnitFlag", "Spy", "Local" for Incite City Escape enablers.

Poison City split[]

Poison City action no longer lets units with Spy flag to escape. New action Poison City Escape lets unit to escape. To create rules matching old hardcoded behavior, create Poison City Escape action enablers similar to any Poison City action enablers you have, and add requirement "UnitFlag", "Spy", "Local", FALSE for Poison City enablers and "UnitFlag", "Spy", "Local" for Poison City Escape enablers.

Steal Tech split[]

Steal Tech action no longer lets units with Spy flag escape or steal multiple times from the same city. New action Steal Tech Escape Expected lets unit escape. To create rules matching old hardcoded behavior, create Steal Tech Escape Expected action enablers similar to any Steal Tech action enablers you have, and add requirement "UnitFlag", "Spy", "Local", FALSE for Steal Tech enablers and "UnitFlag", "Spy", "Local" for Steal Tech Escape Expected enablers.

Targeted Steal Tech split[]

Targeted Steal Tech action no longer lets units with Spy flag escape or steal multiple times from the same city. New action Targeted Steal Tech Escape Expected lets unit escape. To create rules matching old hardcoded behavior, create Targeted Steal Tech Escape Expected action enablers similar to any Targeted Steal Tech action enablers you have, and add requirement "UnitFlag", "Spy", "Local", FALSE for Targeted Steal Tech enablers and "UnitFlag", "Spy", "Local" for Targeted Steal Tech Escape Expected enablers.

Steal Gold split[]

Steal Gold action no longer lets units with Spy flag escape. New action Steal Gold Escape lets unit escape. To create rules matching old hardcoded behavior, create Steal Gold Escape action enablers similar to any Steal Gold action enablers you have, and add requirement "UnitFlag", "Spy", "Local", FALSE for Steal Gold enablers and "UnitFlag", "Spy", "Local" for Steal Gold Escape enablers.

Sabotage City split[]

Sabotage City action no longer lets units with Spy flag escape. New action Sabotage City Escape lets the unit escape. To create rules matching old hardcoded behavior, create Sabotage City Escape action enablers similar to any Sabotage City action enablers you have, and add requirement "UnitFlag", "Spy", "Local", FALSE for Sabotage City enablers and "UnitFlag", "Spy", "Local" for Sabotage City Escape enablers.

Targeted Sabotage City split[]

Targeted Sabotage City action no longer lets units with Spy flag escape. New action Targeted Sabotage City Escape lets the unit escape. To create rules matching old hardcoded behavior, create Targeted Sabotage City Escape action enablers similar to any Targeted Sabotage City action enablers you have, and add requirement "UnitFlag", "Spy", "Local", FALSE for Targeted Sabotage City enablers and "UnitFlag", "Spy", "Local" for Targeted Sabotage City Escape enablers.

Sabotage Unit split[]

Sabotage Unit action no longer lets units with Spy flag escape. New action Sabotage Unit Escape lets the unit escape. To create rules matching old hardcoded behavior, create Sabotage Unit Escape action enablers similar to any Sabotage Unit action enablers you have, and add requirement "UnitFlag", "Spy", "Local", FALSE for Sabotage Unit enablers and "UnitFlag", "Spy", "Local" for Sabotage Unit Escape enablers.

New Action Enablers[]

All action enablers now have an associated ui name, which are also contained in the game.ruleset file along with the action enablers. The file data/sandbox/game.ruleset contains a complete list of them.

Found City[]

Old hardcoded unit type flag Cities has been retired and city founding is now controlled with Found City action enabler. To preserve old behavior reintroduce Cities as user unit type flag and make that an requirement for Found City action enablers.

[actionenabler_build_city_pioneer]
action = "Found City"
actor_reqs    =
    { "type",   "name", "range"
      "UnitFlag", "Cities", "Local"
      "UnitState", "OnLivableTile", "Local"
      "MinMoveFrags", "1", "Local"
    }
target_reqs    =
    { "type",   "name", "range", "present"
      "CityTile", "Claimed", "Local", FALSE
    }

[actionenabler_build_city_domestic]
action = "Found City"
actor_reqs    =
    { "type",   "name", "range", "present"
      "UnitFlag", "Cities", "Local", TRUE
      "UnitState", "OnLivableTile", "Local", TRUE
      "MinMoveFrags", "1", "Local", TRUE
      "DiplRel", "Is foreign", "Local", FALSE
    }

Add ui name for the action:

ui_name_found_city = _("%sBuild City%s")

Also, to avoid illegal action movement penalty getting paid for failed city founding attempt, make sure that no Illegal_Action_Move_Cost effect applies to Found City action.

[effect_illegal_action_move_cost_base]
type    = "Illegal_Action_Move_Cost"
value   = 1
reqs    =
    { "type", "name", "range", "present"
      "Action", "Found City", "Local", FALSE
      "Action", "Join City", "Local", FALSE
    }

Join City[]

Old hardcoded unit type flag AddToCity has been retired and growing a city is now controlled with Join City action enabler. To preserve old behavior reintroduce AddToCity as user unit type flag and make that an requirement for Join City action enabler.

 [actionenabler_join_city]
action = "Join City"
actor_reqs    =
    { "type",   "name", "range", "present"
      "Unitflag", "AddToCity", "Local", TRUE
      "DiplRel", "Is foreign", "Local", FALSE
      "MinMoveFrags", "1", "Local", TRUE
    }

Add ui name for the action:

ui_name_join_city = _("%sAdd to City%s")

Also, to avoid illegal action movement penalty getting paid for failed city founding attempt, make sure that no Illegal_Action_Move_Cost effect applies to Join City action. See Found City above.

Capture Units[]

Old hardcoded unit type flags Capturer and Capturable have been retired and capture is now controlled with Capture Units action enabler. To preserve old behavior reintroduce Capturer and Capturable as user unit type flags and make former an requirement for Capture Units action enabler actor, and latter for target.

 [actionenabler_capture]
action = "Capture Units"
actor_reqs    =
    { "type",   "name", "range"
      "Unitflag", "Capturer", "Local"
    }
target_reqs   =
    { "type",   "name", "range"
      "UnitFlag", "Capturable", "Local"
    }

Add ui name for the action:

ui_name_capture_units = _("%sCapture Units%s")

By default "Bombard", "Explode Nuclear" and regular attacks are available even when there would be possible to capture the units at a tile in stead. To force the old behavior of making those impossible when "Capture Units" is possible:

force_capture_units = TRUE

Bombard[]

Old hardcoded unit type flag Bombarder has been retired and bombardment is now controlled with the Bombard action enabler. To preserve old behavior reintroduce Bombarder as user unit type flag and make it a requirement for the actor in a Bombard action enabler.

[actionenabler_bombard]
action = "Bombard"
actor_reqs    =
    { "type",         "name",        "range", "present"
      "UnitFlag",     "Bombarder",   "Local", TRUE
      "UnitState",    "Transported", "Local", FALSE
      "MinMoveFrags", "1",           "Local", TRUE
      "DiplRel",      "War",         "Local", TRUE
    }
target_reqs    =
    { "type",   "name", "range", "present"
      "TerrainClass", "Oceanic", "Local", FALSE
    }

Add ui name for the action:

ui_name_bombard = _("%sBombard%s")

By default "Explode Nuclear" and regular attacks are available even when there would be possible to bombard a tile in stead. To force the old behavior of making those impossible when "Bombard" is possible:

force_bombard = TRUE

Explode Nuclear[]

Old hardcoded unit type flag Nuclear has been retired and detonating nukes is now controlled with the Explode Nuclear action enabler. To preserve old behavior reintroduce Nuclear as user unit type flag and make it a requirement for the actor in an Explode Nuclear action enabler.

 [actionenabler_nuke]
action = "Explode Nuclear"
actor_reqs    =
    { "type",   "name", "range", "present"
      "UnitFlag", "Nuclear", "Local", TRUE
    }

Add ui name for the action:

ui_name_explode_nuclear = _("Explode %sNuclear%s")

By default regular attacks are available even when there would be possible to detonate a nuke at a tile in stead. Force the old behavior of making it impossible when "Explode Nuclear" is possible:

force_explode_nuclear = TRUE

Attack[]

The regular attack is now controlled with the Attack action enabler. The old hard coded unit type flag Marines and unit class flag AttFromNonNative have been retired. To preserve the old behavior reintroduce Marines as a unit type user flag, AttFromNonNative as a unit class user flag and their attack rules as the following action enablers:

[actionenabler_attack_native]
action = "Attack"
actor_reqs    =
    { "type",         "name",         "range", "present"
      "UnitFlag",     "NonMil",       "Local", FALSE
      "MinMoveFrags", "1",            "Local", TRUE
      "UnitState",    "OnNativeTile", "Local", TRUE
      "DiplRel",      "War",          "Local", TRUE
    }

[actionenabler_attack_marines]
action = "Attack"
actor_reqs    =
    { "type",         "name",    "range", "present"
      "UnitFlag",     "NonMil",  "Local", FALSE
      "MinMoveFrags", "1",       "Local", TRUE
      "UnitFlag",     "Marines", "Local", TRUE
      "DiplRel",      "War",     "Local", TRUE
    }

[actionenabler_attack_att_from_non_native]
action = "Attack"
actor_reqs    =
    { "type",          "name",             "range", "present"
      "UnitFlag",      "NonMil",           "Local", FALSE
      "MinMoveFrags",  "1",                "Local", TRUE
      "UnitClassFlag", "AttFromNonNative", "Local", TRUE
      "DiplRel",      "War",               "Local", TRUE
    }

Add ui name for the action:

ui_name_attack = _("%sAttack%s")

Conquer City[]

Regular city conquest is now controlled with the Conquer City action enabler. The old hard coded unit type flag Marines and unit class flag AttFromNonNative have been retired. To preserve the old behavior reintroduce Marines as a unit type user flag, AttFromNonNative as a unit class user flag and their attack rules as the following action enablers:

[actionenabler_conquer_city_native]
action = "Conquer City"
actor_reqs    =
    { "type",           "name",          "range", "present"
      "UnitClassFlag",  "CanOccupyCity", "Local", TRUE
      "UnitFlag",       "NonMil",        "Local", FALSE
      "DiplRel",        "War",           "Local", TRUE
      "MinMoveFrags",   "1",             "Local", TRUE
      "UnitState",      "OnLivableTile", "Local", TRUE
    }
target_reqs    =
    { "type",           "name",          "range", "present"
      "MaxUnitsOnTile", "0",             "Local", TRUE
    }

[actionenabler_conquer_city_marines]
action = "Conquer City"
actor_reqs    =
    { "type",           "name",          "range", "present"
      "UnitClassFlag",  "CanOccupyCity", "Local", TRUE
      "UnitFlag",       "NonMil",        "Local", FALSE
      "DiplRel",        "War",           "Local", TRUE
      "MinMoveFrags",   "1",             "Local", TRUE
      "UnitFlag",       "Marines",       "Local", TRUE
    }
target_reqs    =
    { "type",           "name",          "range", "present"
      "MaxUnitsOnTile", "0",             "Local", TRUE
    }

[actionenabler_conquer_city_att_from_non_native]
action = "Conquer City"
actor_reqs    =
    { "type",           "name",             "range", "present"
      "UnitClassFlag",  "CanOccupyCity",    "Local", TRUE
      "UnitFlag",       "NonMil",           "Local", FALSE
      "DiplRel",        "War",              "Local", TRUE
      "MinMoveFrags",   "1",                "Local", TRUE
      "UnitClassFlag",  "AttFromNonNative", "Local", TRUE
    }
target_reqs    =
    { "type",           "name",          "range", "present"
      "MaxUnitsOnTile", "0",             "Local", TRUE
    }

Add ui name for the action:

ui_name_conquer_city = _("%Conquer City%s")

Disbanding a Unit[]

Letting the player disband a unit is now controlled by action enablers. The Recycle Unit action enabler controls disbanding a unit in a city to have 50% of its shield cost added to the city's current production. The Disband Unit action enabler controls disbanding it without getting anything in return. (Disbanding a unit in a city to have 100% of its shield cost added to the city's current production has been controlled by the Help Wonder action enabler since 2.6)

To preserve old behavior add the following action enablers:

[actionenabler_disband_unit]
action = "Disband Unit"
actor_reqs    =
    { "type",   "name", "range", "present"
      "UnitFlag", "EvacuateFirst", "Local", FALSE
    }

[actionenabler_recycle_unit]
action = "Recycle Unit"
actor_reqs    =
    { "type",   "name", "range", "present"
      "UnitFlag", "EvacuateFirst", "Local", FALSE
      "DiplRel",  "War",        "Local", FALSE
      "DiplRel",  "Cease-fire", "Local", FALSE
      "DiplRel",  "Armistice",  "Local", FALSE
      "DiplRel",  "Peace",      "Local", FALSE
    }

Add ui name for the actions:

ui_name_disband_unit = _("%sYou're Fired%s")
ui_name_recycle_unit = _("Rec%sycle Unit%s")

Home City[]

Changing a unit's home city is now controlled with the Home City action enabler. The rule that the player can't give away a unit by moving it to an allied city and change its home city is no longer hard coded. The same is true for the rule that a homeless unit can't do Home City. To preserve old behavior add the following action enabler:

[actionenabler_change_home_city]
action = "Home City"
actor_reqs    =
    { "type",      "name",        "range", "present"
      "UnitFlag",  "NoHome",      "Local", FALSE
      "UnitState", "HasHomeCity", "Local", TRUE
      "DiplRel",   "Is foreign",  "Local", FALSE
    }

Add ui name for the action:

ui_name_home_city = _("Set %sHome City%s")

Upgrade Unit[]

Commanding a unit to upgrade is now controlled with the Upgrade Unit action enabler. To preserve old behavior add the following action enabler:

[actionenabler_upgrade_unit]
action = "Upgrade Unit"
actor_reqs    =
    { "type",    "name",       "range", "present"
      "DiplRel", "Is foreign", "Local", FALSE
    }

Add ui name for the action:

ui_name_upgrade_unit = _("%sUpgrade Unit%s")

Paradrop Unit[]

Old hardcoded unit type flag Paratroopers has been retired. Old hard coded base type flag ParadropFrom has been retired. Paradropping is now controlled with the Paradrop Unit action enabler. To preserve old behavior reintroduce Paratroopers as a user unit type flag and ParadropFrom as a user extra flag. Then add the following action enablers.

[actionenabler_paradrop_base]
action = "Paradrop Unit"
actor_reqs    =
    { "type",      "name",         "range", "present"
      "UnitFlag",  "Paratroopers", "Local", TRUE
      "UnitState", "Transporting", "Local", FALSE
      "ExtraFlag", "ParadropFrom", "Local", TRUE
    }

[actionenabler_paradrop_city]
action = "Paradrop Unit"
actor_reqs    =
    { "type",      "name",         "range", "present"
      "UnitFlag",  "Paratroopers", "Local", TRUE
      "UnitState", "Transporting", "Local", FALSE
      "CityTile",  "Center",       "Local", TRUE
    }

Add ui name for the action:

ui_name_paradrop_unit = _("Drop %sParatrooper%s")

Airlift Unit[]

Old hard coded unit class flag Airliftable has been retired. Airlifting is now controlled with the Airlift Unit action enabler. To preserve old behavior reintroduce Airliftable as user unit class flag and make it a requirement for the actor in the following Airlift Unit action enabler.

[actionenabler_airlift_unit]
action = "Airlift Unit"
actor_reqs    =
    { "type",          "name",         "range", "present"
      "UnitClassFlag", "Airliftable",  "Local", TRUE
      "UnitState",     "Transporting", "Local", FALSE
      "MinMoveFrags",  "1",            "Local", TRUE
    }

Add ui name for the action:

ui_name_airlift_unit = _("Airlift %sto City%s")

New in 3.0[]

Some brand new actions that didn't exist in 2.6 have been added. They are completely optional. To keep 2.6 behavior you shouldn't enable them at all.

  • "Steal Maps" - steal parts of the owner of the target city's map
  • "Suitcase Nuke" - cause a nuclear explosion in the target city
  • "Destroy City" - destroys the target city
  • "Expel Unit" - expels the target unit to its owner's capital.
  • "Heal Unit" - restores (some of) the target unit's hit points.

Action enabler changes[]

Help Wonder target[]

A city can produce ("build") a unit or a building. The "Help Wonder" caravan action helps a city's production by adding 100% of the unit's shield cost to it. Disbanding a unit only adds 50% of the unit's shield cost to the city production.

The old, hard coded, rule was that wonders, great or small, could benefit from "Help Wonder". This rule has been replaced with an ability to specify what items can receive help in "Help Wonder" action enablers.

The old rules requires two action enablers for each 2.6 "Help Wonder" action enabler. Copy each "Help Wonder" action enabler in your ruleset. Remember to rename the copy. Add a local BuildingGenus requirement to the target requirement vector of both the original and the copy. Make one allow helping small wonders and the other allow helping great wonders.

So this 2.6 action enabler

[actionenabler_help_build_wonder]
action = "Help Wonder"
actor_reqs    =
    { "type",   "name", "range", "present"
      "UnitFlag", "HelpWonder", "Local", TRUE
      "DiplRel", "Is foreign", "Local", FALSE
    }

becomes

[actionenabler_help_build_great_wonder]
action = "Help Wonder"
actor_reqs    =
    { "type",   "name", "range", "present"
      "UnitFlag", "HelpWonder", "Local", TRUE
      "DiplRel", "Is foreign", "Local", FALSE
    }
target_reqs    =
    { "type",   "name", "range"
      "BuildingGenus", "GreatWonder", "Local"
    }

[actionenabler_help_build_small_wonder]
action = "Help Wonder"
actor_reqs    =
    { "type",   "name", "range", "present"
      "UnitFlag", "HelpWonder", "Local", TRUE
      "DiplRel", "Is foreign", "Local", FALSE
    }
target_reqs    =
    { "type",   "name", "range"
      "BuildingGenus", "SmallWonder", "Local"
    }

in 3.0.

Hard requirements in action enablers[]

Freeciv can only allow a player to perform an action when the action's hard requirements are fulfilled. Some, but not all, hard requirements can be expressed in an action enabler. Freeciv 2.6 didn't care if an action's hard requirements appeared in its action enablers. Freeciv 3.0 demands that some hard requirements appear in its action's enablers. This makes it easier to see what the rules actually are. It also makes the parts of Freeciv that understands action enablers able to reason about the hard coded rules. The section "Actions and their hard requirements" of README.actions marks hard requirements that must appear in an action's enablers.

Foreign only actions[]

Some actions don't make sense with a domestic target. They are Establish Embassy, Investigate City, Steal Gold, Steal Gold Escape, Steal Tech, Targeted Steal Tech, Incite City and Bribe Unit. Require a foreign target in their actor_reqs requirement vector like this:

"DiplRel", "Is foreign", "Local"

Incidents caused by actions[]

An action may cause a diplomatic incident. The incident provides a valid casus belli against the actor player. A casus beli can be taken to the senate when declaring war.

The new effects Casus_Belli_Success and Casus_Belli_Caught controls action incident causing. The first is checked when an action is performed. The second is checked when an action was prevented. 0 causes no incident. 1 causes an incident with the victim. 1000 causes an incident to every other player.

Here are effects matching the old hardcoded rules.

[effect_incident_caught_steal_tech]
type	= "Casus_Belli_Caught"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Steal Tech", "Local", TRUE
      "DiplRel", "War", "Local", FALSE
    }

[effect_incident_success_steal_tech]
type	= "Casus_Belli_Success"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Steal Tech", "Local", TRUE
      "DiplRel", "War", "Local", FALSE
    }

[effect_incident_caught_tgt_steal_tech]
type	= "Casus_Belli_Caught"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Targeted Steal Tech", "Local", TRUE
      "DiplRel", "War", "Local", FALSE
    }

[effect_incident_success_tgt_steal_tech]
type	= "Casus_Belli_Success"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Targeted Steal Tech", "Local", TRUE
      "DiplRel", "War", "Local", FALSE
    }

[effect_incident_success_bribe_unit]
type	= "Casus_Belli_Success"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Bribe Unit", "Local", TRUE
      "DiplRel", "War", "Local", FALSE
    }

[effect_incident_success_sabotage_unit]
type	= "Casus_Belli_Success"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Sabotage Unit", "Local", TRUE
      "DiplRel", "War", "Local", FALSE
    }

[effect_incident_success_incite]
type	= "Casus_Belli_Success"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Incite City", "Local", TRUE
      "DiplRel", "War", "Local", FALSE
    }

[effect_incident_success_incite_esc]
type	= "Casus_Belli_Success"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Incite City Escape", "Local", TRUE
      "DiplRel", "War", "Local", FALSE
    }

[effect_incident_success_poison]
type	= "Casus_Belli_Success"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Poison City", "Local", TRUE
      "DiplRel", "War", "Local", FALSE
    }

[effect_incident_success_sabotage_city]
type	= "Casus_Belli_Success"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Sabotage City", "Local", TRUE
      "DiplRel", "War", "Local", FALSE
    }

[effect_incident_success_sabotage_city_esc]
type	= "Casus_Belli_Success"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Sabotage City Escape", "Local", TRUE
      "DiplRel", "War", "Local", FALSE
    }

[effect_incident_success_tgt_sabotage_city]
type	= "Casus_Belli_Success"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Targeted Sabotage City", "Local", TRUE
      "DiplRel", "War", "Local", FALSE
    }

[effect_incident_success_tgt_sabotage_city_esc]
type	= "Casus_Belli_Success"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Targeted Sabotage City Escape", "Local", TRUE
      "DiplRel", "War", "Local", FALSE
    }

[effect_incident_success_explode_nuke]
type	= "Casus_Belli_Success"
value	= 1
reqs	=
    { "type", "name", "range", "present"
      "Action", "Explode Nuclear", "Local", TRUE
    }

Action risk[]

The new effect Action_Odds_Pct manipulates some actions' chance of success.

Targeted Sabotage City[]

The rule that the action Targeted Sabotage City is twice as difficult as Sabotage City isn't hard coded any more. If you want to keep the old rule add it back using the Action_Odds_Pct effect like:

[effect_tgt_sabotage_city_half_chance]
type	= "Action_Odds_Pct"
value	= -50
reqs	=
    { "type", "name", "range", "present"
      "Action", "Targeted Sabotage City", "Local", TRUE
    }

[effect_tgt_sabotage_city_half_chance_esc]
type	= "Action_Odds_Pct"
value	= -50
reqs	=
    { "type", "name", "range", "present"
      "Action", "Targeted Sabotage City Escape", "Local", TRUE
    }

Missing unit upkeep consequences[]

When a player fails to pay the food, gold or shield upkeep of a unit it has consequences. The consequences for the unit is now configurable in the missing_unit_upkeep section of cities.ruleset. The following settings keep the old rules:

[missing_unit_upkeep]
food_protected    = "EvacuateFirst"
; food_unit_act   =
food_wipe         = TRUE

; gold_protected  =
; gold_unit_act   =
gold_wipe         = TRUE

shield_protected  = "EvacuateFirst"
shield_unit_act   = "Help Wonder", "Recycle Unit", "Disband Unit"
shield_wipe       = FALSE

Auto attack[]

Enabling the autoattack server setting makes a unit attack other units that moves to an adjacent tile if certain conditions are met.

Unit types that won't autoattack[]

In Freeciv 2.6 a hard coded rule prevented units with the "Nuclear" unit type flag from auto attacking. What utype flag(s) should block a unit from auto attacking is now configured via game.ruleset's new auto_attack.will_never setting. The following settings keep the old rules:

[auto_attack]
; An auto attack may be triggered when another unit moves to an adjacent
; tile and the autoattack server setting is enabled. The following details
; are ruleset controlled.
;   will_never - units with this unit type flag will never auto attack.

; Not a good idea to nuke our own area.
will_never = "Nuclear"

Auto attack provoking unit types[]

A unit considering if it should autoattack a unit that just moved next to it will normally decide not to attack if it has better odds when defending against it than when attacking it. Units with the Provoking utype flag will be attacked even if the odds of defense are better. 2.6 made the same exception for transports and spies. To keep the old rules you should add the Provoking unit type flag to all unit types capable of performing hostile diplomatic actions and to all transporters.

Combat rules[]

New only_killing_makes_veteran setting should be set in game.ruleset combat_rules section. Set it to FALSE for the behavior similar to old hardcoded one.

Goods[]

Trade Goods are a new concept in 3.0. At least one goods type must be defined in game.ruleset

[goods_good]
name = _("Goods")

For examples of more that can be done with goods, see the file data/sandbox/game.ruleset.

Tech stealing when conquering a city[]

Old hardcoded behavior that conqueror always gets one tech from old owner when city changes hands has been made optional. To keep the old behavior, add base Conquest_Tech_Pct effect with value 100.

[effect_conquer_techs_base]
type    = "Conquest_Tech_Pct"
value   = 100

Great Wonder buy cost[]

It's no longer hardcoded that Great Wonders, and no other building, gets their buy costs doubled. To have the old behavior of doubling buy cost of Great Wonders, add Building_Buy_Cost_Pct effect with value 100 and requirement BuildingGenus GreatWonder.

[effect_great_wonder_buy_cost]
type    = "Building_Buy_Cost_Pct"
value   = 100
reqs    =
    { "type", "name", "range"
      "BuildingGenus", "GreatWonder", "Local"
    }

Specialist graphic tags[]

graphic should be defined for all specialists. Formerly these graphics tags were derived from rule_name of the specialist, so to construct value similar to what was earlier in fact used, set it to "specialist.*rule_name*"

rule_name       = "scientist"
short_name      = _("?Scientist:S")

->

rule_name       = "scientist"
short_name      = _("?Scientist:S")
graphic         = "specialist.scientist"

Entertainer tag[]

Supplied tilesets now provide tag specialist.entertainer as an alternative to specialist.elvis, and it's the preferred tag for rulesets to use.

rule_name       = "elvis"
short_name     = _("?Elvis:E")

->

rule_name       = "elvis"
short_name     = _("?Elvis:E")
graphic        = "specialist.entertainer"

Conquest Convert Pct[]

conquest_convert_pct should be defined in cities.ruleset citizen section. Give it value 0 to match old hardcoded behavior.

See also[]

Editing Rulesets
Editing BuildingsEditing CitiesEditing EffectsEditing GameEditing Governments
Editing NationsEditing StylesEditing TechsEditing TerrainEditing Units
Update from 2.2 to 2.32.3 to 2.42.4 to 2.52.5 to 2.62.6 to 3.03.0 to 3.13.1 to 3.23.2 to 3.3
Advertisement