From ae3f8a34161e61a147612dde9092736461ad1e86 Mon Sep 17 00:00:00 2001 From: Juan Bernardo Tamez Pena Date: Sun, 25 Sep 2022 16:31:53 -0700 Subject: [PATCH] Mod scripting guide update (#356) * added bool to number function expression * added group attribute to cell entities * added neighbors attribute to group entities * updated modding guide a bit more * more modding guide updates * Update entities_guide.md * more guide updates * more guide updates * more modding guide updates * final modding guide update --- .../Modding/Entities/CellEntity.cs | 20 + .../Modding/Entities/GroupEntity.cs | 20 + .../Modding/Expressions/ExpressionBuilder.cs | 2 + .../NumberFunctionExpression.cs | 19 + .../NumberFunctionExpression.cs.meta | 11 + Modding Guide/Guides/action_modding_guide.md | 19 +- .../Guides/adjective_modding_guide.md | 2 +- Modding Guide/Guides/attribute_flags.txt | 8 - Modding Guide/Guides/conditions_guide.txt | 121 ------ .../cultural_preferences_modding_guide.md | 4 +- ...ng_guide.txt => decision_modding_guide.md} | 39 +- ...uide.txt => descriptions_modding_guide.md} | 10 +- .../Guides/discovery_modding_guide.md | 37 ++ .../Guides/discovery_modding_guide.txt | 33 -- Modding Guide/Guides/effects_guide.txt | 79 ---- ...ing_guide.txt => effects_modding_guide.md} | 14 +- ...ing_guide.txt => element_modding_guide.md} | 31 +- Modding Guide/Guides/entities_guide.md | 352 ++++++++++++++---- ...dding_guide.txt => event_modding_guide.md} | 20 +- .../Guides/expression_operators_guide.md | 148 ++++++++ .../Guides/expression_operators_guide.txt | 127 ------- Modding Guide/Guides/expressions_guide.md | 81 ++++ Modding Guide/Guides/expressions_guide.txt | 77 ---- Modding Guide/Guides/factors_guide.txt | 74 ---- .../language_structures_modding_guide.md | 50 +++ .../language_structures_modding_guide.txt | 55 --- ...dding_guide.txt => layer_modding_guide.md} | 16 +- ...ing_guide.txt => options_modding_guide.md} | 12 +- .../Guides/phrase_association_guide.md | 32 ++ .../Guides/phrase_association_guide.txt | 33 -- Modding Guide/Guides/properties_guide.md | 4 +- ....txt => region_attribute_modding_guide.md} | 31 +- ..._guide.txt => region_constraints_guide.md} | 84 ++--- Modding Guide/Guides/string_values_guide.md | 32 ++ Modding Guide/Guides/string_values_guide.txt | 33 -- Modding Guide/modding_guide.md | 18 +- 36 files changed, 905 insertions(+), 843 deletions(-) create mode 100644 Assets/Scripts/WorldEngine/Modding/Expressions/NumericExpressions/NumberFunctionExpression.cs create mode 100644 Assets/Scripts/WorldEngine/Modding/Expressions/NumericExpressions/NumberFunctionExpression.cs.meta delete mode 100644 Modding Guide/Guides/attribute_flags.txt delete mode 100644 Modding Guide/Guides/conditions_guide.txt rename Modding Guide/Guides/{decision_modding_guide.txt => decision_modding_guide.md} (69%) rename Modding Guide/Guides/{descriptions_modding_guide.txt => descriptions_modding_guide.md} (95%) create mode 100644 Modding Guide/Guides/discovery_modding_guide.md delete mode 100644 Modding Guide/Guides/discovery_modding_guide.txt delete mode 100644 Modding Guide/Guides/effects_guide.txt rename Modding Guide/Guides/{effects_modding_guide.txt => effects_modding_guide.md} (88%) rename Modding Guide/Guides/{element_modding_guide.txt => element_modding_guide.md} (50%) rename Modding Guide/Guides/{event_modding_guide.txt => event_modding_guide.md} (92%) create mode 100644 Modding Guide/Guides/expression_operators_guide.md delete mode 100644 Modding Guide/Guides/expression_operators_guide.txt create mode 100644 Modding Guide/Guides/expressions_guide.md delete mode 100644 Modding Guide/Guides/expressions_guide.txt delete mode 100644 Modding Guide/Guides/factors_guide.txt create mode 100644 Modding Guide/Guides/language_structures_modding_guide.md delete mode 100644 Modding Guide/Guides/language_structures_modding_guide.txt rename Modding Guide/Guides/{layer_modding_guide.txt => layer_modding_guide.md} (70%) rename Modding Guide/Guides/{options_modding_guide.txt => options_modding_guide.md} (96%) create mode 100644 Modding Guide/Guides/phrase_association_guide.md delete mode 100644 Modding Guide/Guides/phrase_association_guide.txt rename Modding Guide/Guides/{region_attribute_modding_guide.txt => region_attribute_modding_guide.md} (58%) rename Modding Guide/Guides/{region_constraints_guide.txt => region_constraints_guide.md} (60%) create mode 100644 Modding Guide/Guides/string_values_guide.md delete mode 100644 Modding Guide/Guides/string_values_guide.txt diff --git a/Assets/Scripts/WorldEngine/Modding/Entities/CellEntity.cs b/Assets/Scripts/WorldEngine/Modding/Entities/CellEntity.cs index ce64ebc2..25ef4250 100644 --- a/Assets/Scripts/WorldEngine/Modding/Entities/CellEntity.cs +++ b/Assets/Scripts/WorldEngine/Modding/Entities/CellEntity.cs @@ -8,6 +8,7 @@ public class CellEntity : DelayedSetEntity public const string BiomeTraitPresenceAttributeId = "biome_trait_presence"; public const string BiomeTypePresenceAttributeId = "biome_type_presence"; public const string NeighborsAttributeId = "neighbors"; + public const string GroupAttributeId = "group"; public const string ArabilityAttributeId = "arability"; public const string AccessibilityAttributeId = "accessibility"; public const string HillinessAttributeId = "hilliness"; @@ -26,6 +27,7 @@ public virtual TerrainCell Cell private ValueGetterEntityAttribute _hillinessAttribute; private ValueGetterEntityAttribute _flowingWaterAttribute; + private GroupEntity _groupEntity = null; private CellCollectionEntity _neighborsEntity = null; private class BiomeTraitPresenceAttribute : ValueEntityAttribute @@ -115,10 +117,25 @@ public EntityAttribute GetNeighborsAttribute() return _neighborsEntity.GetThisEntityAttribute(); } + public EntityAttribute GetGroupAttribute() + { + _groupEntity = + _groupEntity ?? new GroupEntity( + GetGroup, + Context, + BuildAttributeId(GroupAttributeId), + this); + + return _groupEntity.GetThisEntityAttribute(); + } + public override EntityAttribute GetAttribute(string attributeId, IExpression[] arguments = null) { switch (attributeId) { + case GroupAttributeId: + return GetGroupAttribute(); + case BiomeTraitPresenceAttributeId: return new BiomeTraitPresenceAttribute(this, arguments); @@ -180,6 +197,9 @@ protected override void ResetInternal() if (_isReset) return; + _groupEntity?.Reset(); _neighborsEntity?.Reset(); } + + private CellGroup GetGroup() => Cell.Group; } diff --git a/Assets/Scripts/WorldEngine/Modding/Entities/GroupEntity.cs b/Assets/Scripts/WorldEngine/Modding/Entities/GroupEntity.cs index d8d2ec70..36833832 100644 --- a/Assets/Scripts/WorldEngine/Modding/Entities/GroupEntity.cs +++ b/Assets/Scripts/WorldEngine/Modding/Entities/GroupEntity.cs @@ -16,6 +16,7 @@ public class GroupEntity : CulturalEntity public const string AccessibilityModifierAttributeId = "accessibility_modifier"; public const string PropertiesAttributeId = "properties"; public const string PopulationAttributeId = "population"; + public const string NeighborsAttributeId = "neighbors"; public virtual CellGroup Group { @@ -33,6 +34,7 @@ public virtual CellGroup Group private PolityCollectionEntity _presentPolitiesEntity = null; private FactionCollectionEntity _closestFactionsEntity = null; private ModifiableGroupPropertyContainerEntity _propertiesEntity = null; + private GroupCollectionEntity _neighborsEntity = null; protected override object _reference => Group; @@ -162,10 +164,27 @@ private void UpdateAccessibilityModifier(float value) Group.SetToUpdate(warnIfUnexpected: false); } + public ICollection GetNeighbors() => Group.Neighbors.Values; + + public EntityAttribute GetNeighborsAttribute() + { + _neighborsEntity = + _neighborsEntity ?? new GroupCollectionEntity( + GetNeighbors, + Context, + BuildAttributeId(NeighborsAttributeId), + this); + + return _neighborsEntity.GetThisEntityAttribute(); + } + public override EntityAttribute GetAttribute(string attributeId, IExpression[] arguments = null) { switch (attributeId) { + case NeighborsAttributeId: + return GetNeighborsAttribute(); + case CellAttributeId: return GetCellAttribute(); @@ -242,6 +261,7 @@ protected override void ResetInternal() _presentPolitiesEntity?.Reset(); _closestFactionsEntity?.Reset(); _propertiesEntity?.Reset(); + _neighborsEntity?.Reset(); base.ResetInternal(); } diff --git a/Assets/Scripts/WorldEngine/Modding/Expressions/ExpressionBuilder.cs b/Assets/Scripts/WorldEngine/Modding/Expressions/ExpressionBuilder.cs index e2fb5ac1..ce1a2a2f 100644 --- a/Assets/Scripts/WorldEngine/Modding/Expressions/ExpressionBuilder.cs +++ b/Assets/Scripts/WorldEngine/Modding/Expressions/ExpressionBuilder.cs @@ -321,6 +321,8 @@ private static IExpression BuildIdentifierExpression( return new ClampFunctionExpression(context, argExpressions); case GetProbabilityAdjectiveFunctionExpression.FunctionId: return new GetProbabilityAdjectiveFunctionExpression(context, argExpressions); + case NumberFunctionExpression.FunctionId: + return new NumberFunctionExpression(context, argExpressions); } if (string.IsNullOrWhiteSpace(arguments)) diff --git a/Assets/Scripts/WorldEngine/Modding/Expressions/NumericExpressions/NumberFunctionExpression.cs b/Assets/Scripts/WorldEngine/Modding/Expressions/NumericExpressions/NumberFunctionExpression.cs new file mode 100644 index 00000000..3d06b405 --- /dev/null +++ b/Assets/Scripts/WorldEngine/Modding/Expressions/NumericExpressions/NumberFunctionExpression.cs @@ -0,0 +1,19 @@ +using UnityEngine; +using System.Collections; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +public class NumberFunctionExpression : FunctionExpressionWithOutput +{ + public const string FunctionId = "number"; + + private readonly IValueExpression _arg; + + public NumberFunctionExpression(Context c, IExpression[] arguments) : + base(c, FunctionId, 1, arguments) + { + _arg = ValueExpressionBuilder.ValidateValueExpression(arguments[0]); + } + + public override float Value => _arg.Value ? 1 : 0; +} diff --git a/Assets/Scripts/WorldEngine/Modding/Expressions/NumericExpressions/NumberFunctionExpression.cs.meta b/Assets/Scripts/WorldEngine/Modding/Expressions/NumericExpressions/NumberFunctionExpression.cs.meta new file mode 100644 index 00000000..bbb52c9c --- /dev/null +++ b/Assets/Scripts/WorldEngine/Modding/Expressions/NumericExpressions/NumberFunctionExpression.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a42fb1d5ee3e0b3479578f10939db0a7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Modding Guide/Guides/action_modding_guide.md b/Modding Guide/Guides/action_modding_guide.md index 40353fae..946368b0 100644 --- a/Modding Guide/Guides/action_modding_guide.md +++ b/Modding Guide/Guides/action_modding_guide.md @@ -1,9 +1,10 @@ # Action Modding Guide -**Action** mod files are located within the *Actions* folder. +**Action** scripting mod files are located within the *Actions* folder. To be valid, mod files must have the .json extension and have the following file structure: #### File Structure +Note: *.json* files do not support comments. Remove texts enclosed within double dashes `--` ``` { @@ -30,7 +31,7 @@ To be valid, mod files must have the .json extension and have the following file to decide if action will be present on the list a available actions within the assigned category. If any of the expressions evaluate to 'false', then the action will not be present within the category - menu. Please read expressions_guide.txt for more + menu. Please read expressions_guide.md for more details on how to define valid boolean expressions. @@ -46,9 +47,17 @@ To be valid, mod files must have the .json extension and have the following file "effects": -- (required) List of EFFECT EXPRESSIONS to evaluate after an action has been executed. These can introduce changes to the target or any - related entity. Please read expressions_guide.txt + related entity. Please read expressions_guide.md for more details on how to define valid effect expressions. + + "enableDebugLog": -- (optional) Can only have 'true' or 'false' + as value (default: 'false'). This an option + to assist in mod development. If this is + 'true', and 'Debug Mode' is enabled within + the game, then debug information specific + to this action will be logged during the + game execution. }, ... -- additional actions -- ] @@ -66,12 +75,12 @@ if an action is available for execution, They also define the tooltips to be dis { "condition": -- (required) BOOLEAN EXPRESSION to be evaluated to decide if action can be executed at a particular - time. Please read expressions_guide.txt for more + time. Please read expressions_guide.md for more details on how to define valid boolean expressions. "info": -- (required) Text to generate when a tooltip needs - to be displayed. See string_values_guide.txt + to be displayed. See string_values_guide.md to find more about how to define valid dynamic text values. } diff --git a/Modding Guide/Guides/adjective_modding_guide.md b/Modding Guide/Guides/adjective_modding_guide.md index 21583b59..aa3b6977 100644 --- a/Modding Guide/Guides/adjective_modding_guide.md +++ b/Modding Guide/Guides/adjective_modding_guide.md @@ -23,4 +23,4 @@ ## Notes 1. Remove any trailing commas or the file won't be parsed. -2. These are used to decide whether or not to associate the element with a particular **region**. If any of the constraints fails then the adjective won't be used when generating names of phrases within the region. Refer to *region_constraints_guide.txt* for more details on how to define and use region constraints. +2. These are used to decide whether or not to associate the element with a particular **region**. If any of the constraints fails then the adjective won't be used when generating names of phrases within the region. Refer to *region_constraints_guide.md* for more details on how to define and use region constraints. diff --git a/Modding Guide/Guides/attribute_flags.txt b/Modding Guide/Guides/attribute_flags.txt deleted file mode 100644 index edb3dde2..00000000 --- a/Modding Guide/Guides/attribute_flags.txt +++ /dev/null @@ -1,8 +0,0 @@ ----- Attribute Flags ---- - -Here's an exhaustive list of all flags hardcoded within the simulation and their effects. NOTE: Flags are case sensitive. - -- CAN_FORM_POLITY: When gaining this attribute, the target group will try to form a new polity of the type specified in immediately if no other polity is present in the cell. If the group already had this flag but no polity is present (e.g. all polities where removed while having this flag), then a polity formation event will be scheduled to occur for that group at some point in the future. -Valid Polity Types: tribe - --- diff --git a/Modding Guide/Guides/conditions_guide.txt b/Modding Guide/Guides/conditions_guide.txt deleted file mode 100644 index d53afa59..00000000 --- a/Modding Guide/Guides/conditions_guide.txt +++ /dev/null @@ -1,121 +0,0 @@ ----- Conditions Guide ---- - -Conditions are rules that can be evaluated against different types of entities (cells, groups, factions, etc). These return a boolean value of "true" when the condition is meet. Otherwise return false. When chained together on a requirement list of comma separated conditions (e.g. "",""), all of them must be true for the requirement to pass. By default, conditions are evaluated against the base target unless a special operator is specified. For example, group conditions are evaluated by default against the target group unless an operator like [ANY_NEIGHBOR] is prefixed. In which case the condition will be evaluated against the neighbor groups of the target group. - -- General condition operators - - -[NOT] : A condition can be negated by prefixing [NOT] before the condition. A negated condition must be false to pass. Both the prefix and the condition must be enclosed together in quotes like this: "[NOT]" - -[AND] : Two or more conditions can be evaluated together using the [AND] infix. In which case, all of the conditions within the conjunction must be true for the statement to pass. All of the conditions and infixes in the statement must be enclosed together in quotes like this: "[AND]([AND])" - -[OR] : Two or more conditions can be evaluated together using the [OR] infix. In which case, if any of the conditions within the disjunction is true then the whole statement passes. All of the conditions and infixes in the statement must be enclosed together in quotes like this: "[OR]([OR])" - -- Group condition operators - - -[ANY_N_GROUP] : The target condition must be true for at least one neighbor cell group. The condition to be evaluated with this operator must be applicable to cell groups. Both the prefix and the condition must be enclosed together in quotes like this: "[ANY_N_GROUP]" - -[ALL_N_GROUPS] : The target condition must be true for all neighbor cell groups. The condition to be evaluated with this operator must be applicable to cell groups. Both the prefix and the condition must be enclosed together in quotes like this: "[ALL_N_GROUPS]" - -[AT_LEAST_N_GROUPS:] : The target condition must be true for at least cell groups. The condition to be evaluated with this operator must be applicable to cell groups. Both the prefix and the condition must be enclosed together in quotes like this: "[ALL_N_GROUPS]" - -- Cell condition operators - - -[ANY_N_CELL] : The target condition must be true for at least one neighbor terrain cell. The condition to be evaluated with this operator must be applicable to terrain cells. Both the prefix and the condition must be enclosed together in quotes like this: "[ANY_N_CELL]" - -[ALL_N_CELLS] : The target condition must be true for all neighbor terrain cells. The condition to be evaluated with this operator must be applicable to terrain cells. Both the prefix and the condition must be enclosed together in quotes like this: "[ALL_N_CELLS]" - -[AT_LEAST_N_CELLS:] : The target condition must be true for at least terrain cells. The condition to be evaluated with this operator must be applicable to terrain cells. Both the prefix and the condition must be enclosed together in quotes like this: "[ALL_N_GROUPS]" - - -Operators can be uses together using parenthesis to set modifier priority (values between parenthesis evaluate first). -Example: "[NOT]([OR]([ANY_N_GROUP])[OR])" - ---- - -Here's a list of the current types of conditions (more to be added in future versions) and how they work: - -- "group_has_knowledge" - Tests if a group currently possesses a particular knowledge identified by id, and the knowledge level is equal or greater than the specified value (optional integer value between 0 and 10000). The format of the constraint is as follows: "group_has_knowledge:(,)" - - Examples: "group_has_knowledge:agriculture_knowledge", "group_has_knowledge:shipbuilding_knowledge,3" - -- "group_population" - Tests if a group currently possesses at least certain amount of population. The value can be any quantity between 1 and 2,147,483,647. The format of the constraint is as follows: "group_population:" - - Examples: "group_population:10000" - -- "cell_altitude" - Tests if a cell has an altitude (in meters) equal or greater than the specified value (value between -15000 and 15000). The format of the constraint is as follows: "cell_altitude:" - - Examples: "cell_altitude:-1000", "cell_altitude:4000" - -- "cell_rainfall" - Tests if a cell has a yearly rainfall (in mm) equal or greater than the specified value (value between 0 and 13000). The format of the constraint is as follows: "cell_rainfall:" - - Examples: "cell_rainfall:100", "cell_rainfall:5000" - -- "cell_temperature" - Tests if a cell has a yearly average temperature (in centigrades) equal or greater than the specified value (value between -63.7 and 43.7). The format of the constraint is as follows: "cell_temperature:" - - Examples: "cell_temperature:-15", "cell_temperature:10" - -- "cell_accessibility" - Tests if a cell has an accessibility value (i.e. how accessible the terrain is) equal or greater than 0.01 or than the specified value (optional value between 0 and 1). The format of the constraint is as follows: "cell_accessibility(:)" - - Examples: "cell_accessibility", "cell_accessibility:0.2" - -- "cell_arability" - Tests if a cell has an arability value (i.e. how arable the land is) equal or greater than 0.01 or than the specified value (optional value between 0 and 1). The format of the constraint is as follows: "cell_arability(:)" - - Examples: "cell_arability", "cell_arability:0.6" - -- "cell_foraging_capacity" - Tests if a cell has an foraging capacity value (i.e. how many resources can be extracted through foraging) equal or greater than 0.01 or than the specified value (optional value between 0 and 1). The format of the constraint is as follows: "cell_foraging_capacity(:)" - - Examples: "cell_foraging_capacity", "cell_foraging_capacity:0.5" - -- "cell_survivability" - Tests if a cell has an survivability value (i.e. how easy is for humans to survive on that cell) equal or greater than 0.01 or than the specified value (optional value between 0 and 1). The format of the constraint is as follows: "cell_survivability(:)" - - Examples: "cell_survivability", "cell_survivability:0.6" - -- "cell_layer_value" - Tests if a cell has a layer value equal or greater than the specified value (value between 0 and the layer`s max possible value). The format of the constraint is as follows: "cell_layer_value:," - - Examples: "cell_layer_value:mycosystem,20", "cell_layer_value:necrosilica,50" - -- "cell_hilliness" - Tests if a cell has an hilliness value (i.e. how hilly the terrain is) equal or greater than 0.01 or than the specified value (optional value between 0 and 1). The format of the constraint is as follows: "cell_hilliness(:)" - - Examples: "cell_hilliness", "cell_hilliness:0.4" - -- "cell_flowing_water" - Tests if a cell has an amount of flowing water (in mm) equal or greater than the specified value (value between 1 and 1000000). The format of the constraint is as follows: "cell_flowing_water:" - - Examples: "cell_flowing_water:100", "cell_flowing_water:2000" - -- "cell_biome_presence" - Tests if a cell has an biome relative presence value (i.e. percentage of area in cell covered by such biome) equal or greater than 0.01 or than the specified value (optional value between 0 and 1). The format of the constraint is as follows: "cell_biome_presence:(,)" - - Examples: "cell_biome_presence:forest", "cell_biome_presence:desert,0.3" - -- "cell_biome_most_present" - Tests if a biome is the most present in a cell (i.e. greatest occupied area). The format of the constraint is as follows: "cell_biome_most_present:" - - Examples: "cell_biome_most_present:grassland", "cell_biome_most_present:tundra" - -- "cell_biome_type_presence" - Tests if a cell has a total presence of biomes of the specified type equal or greater than 0.01 or than the specified value (optional value between 0 and 1. See note 1). The format of the constraint is as follows: "cell_biome_type_presence:(,)" - - Examples: "cell_biome_type_presence:land", "cell_biome_type_presence:water,0.5" - -- "cell_biome_trait_presence" - Tests if a cell has a biome trait presence (ie. 'wood', 'sea') equal or greater than 0.01 or than the specified value (optional value between 0 and 1). The format of the constraint is as follows: "cell_biome_trait:(,)" - - Examples: "cell_biome_trait_presence:sea", "cell_biome_trait_presence:wood,0.4" - - -NOTES: -1. The parameter has a precision limit of two decimal places (eg. 0.01 is the smallest value possible above 0, and 0.99 the largest possible below 1) - --- diff --git a/Modding Guide/Guides/cultural_preferences_modding_guide.md b/Modding Guide/Guides/cultural_preferences_modding_guide.md index 2cb5c1f5..57493137 100644 --- a/Modding Guide/Guides/cultural_preferences_modding_guide.md +++ b/Modding Guide/Guides/cultural_preferences_modding_guide.md @@ -1,9 +1,9 @@ # Cultural Preferences Modding Guide -Cultural Preferences modding files are located within the **Preferences** folder. To be valid, mod files must have the **.json** extension and have the following file structure: +Cultural Preferences scripting mod files are located within the **Preferences** folder. To be valid, mod files must have the **.json** extension and have the following file structure: #### File Structure -Note: .json files do not support comments. Remove texts enclosed within double dashes '--' +Note: *.json* files do not support comments. Remove texts enclosed within double dashes `--` ``` { diff --git a/Modding Guide/Guides/decision_modding_guide.txt b/Modding Guide/Guides/decision_modding_guide.md similarity index 69% rename from Modding Guide/Guides/decision_modding_guide.txt rename to Modding Guide/Guides/decision_modding_guide.md index 68a053ee..431da7e6 100644 --- a/Modding Guide/Guides/decision_modding_guide.txt +++ b/Modding Guide/Guides/decision_modding_guide.md @@ -1,10 +1,11 @@ ----- Decision Modding Guide ---- +# Decision Modding Guide -Decision modding files are located within the 'Decisions' folder. To be valid, mod -files must have the .json extension and have the following file structure: +Decision mod files are located within the **Decisions** folder. To be valid, mod +files must have the **.json** extension and have the following file structure: --- File Structure -- +### File Structure +``` { "decisions": [ -- list of decisions -- { @@ -45,7 +46,7 @@ files must have the .json extension and have the following file structure: loaded to generate the body text within the dialog. The texts extracted will be presented in the same order as they appear on this list. - Please read descriptions_modding_guide.txt for + Please read descriptions_modding_guide.md for more details on how to define decision description objects. @@ -54,16 +55,34 @@ files must have the .json extension and have the following file structure: to generate the list of options to present to the player. The options will appear in the order they are defined on this list. Please - read options_modding_guide.txt for more details + read options_modding_guide.md for more details on how to define decision option objects. + + "enableDebugLog": -- (optional) Can only have 'true' or 'false' + as value (default: 'false'). This an option + to assist in mod development. If this is + 'true', and 'Debug Mode' is enabled within + the game, then debug information specific + to this decision will be logged during the + game execution. + + "debugPlayerGuidance": -- (optional) Can only have 'true' or 'false' + as value (default: 'false'). This an option + to assist in mod development. If this is 'true', + the game will pause whenever this decision is + invoked and will request the player to choose + an option instead of letting the simulation do + it. + }, ... -- additional decisions -- ] } +``` --- Notes -- -1. List of values must be enclosed within square brackets and separated by commas. +## Notes +1. Remove any trailing commas or the file won't be parsed +2. List of values must be enclosed within square brackets and separated by commas. Remove any trailing commas on any list enclosed by square brackets, or you'll get a JSON parsing error. -2. Do not duplicate decision ids unless you want to specifically replace another decision - already loaded. +3. Do not duplicate decision *id* values unless you want to specifically replace another decision diff --git a/Modding Guide/Guides/descriptions_modding_guide.txt b/Modding Guide/Guides/descriptions_modding_guide.md similarity index 95% rename from Modding Guide/Guides/descriptions_modding_guide.txt rename to Modding Guide/Guides/descriptions_modding_guide.md index 7be6fde8..953014ff 100644 --- a/Modding Guide/Guides/descriptions_modding_guide.txt +++ b/Modding Guide/Guides/descriptions_modding_guide.md @@ -1,10 +1,11 @@ ----- Descriptions Modding Guide ---- +# Descriptions Modding Guide Descriptions are JSON sub-objects that are added to decisions or other mod objects that can generate texts to display within the game. They have the following structure: --- Object Structure -- +### Object Structure +``` { "id": -- (required) Unique description identifier. Each description must have a unique id within @@ -19,7 +20,7 @@ that can generate texts to display within the game. They have the following stru on how to define valid properties. "text": -- (required) Text to generate when this description - object is evaluated. See string_values_guide.txt + object is evaluated. See string_values_guide.md to find more about how to define valid dynamic text values. @@ -30,8 +31,9 @@ that can generate texts to display within the game. They have the following stru not generated. If no conditions are given, then the the text will always be presented. } +``` --- Notes -- +## Notes 1. List of values must be enclosed within square brackets and separated by commas. Remove any trailing commas on any list enclosed by square brackets, or you'll get a JSON parsing error. diff --git a/Modding Guide/Guides/discovery_modding_guide.md b/Modding Guide/Guides/discovery_modding_guide.md new file mode 100644 index 00000000..28b1e053 --- /dev/null +++ b/Modding Guide/Guides/discovery_modding_guide.md @@ -0,0 +1,37 @@ +# Discovery Modding Guide + +Discovery mod files are located within the *Discoveries* folder. To be valid, mod files must have the **.json** extension and have the following file structure: + +### File Structure + +``` +{ + "discoveries": [ -- list of discoveries -- + { + "id": -- (required) Unique discovery identifier, if more + than one definition share ids, only the last one + loaded will be used + + "name": -- (required) Name of discovery + + "gainEffects": -- (optional) List of EFFECT EXPRESSIONS to + evaluate after the target group 'gains' the discovery. + These can introduce changes to the target entity. + Please read expressions_guide.md for more details on + how to define valid effect expressions. + + "lossEffects": -- (optional) List of EFFECT EXPRESSIONS to + evaluate after the target group 'losses' the discovery. + These can introduce changes to the target entity. + Please read expressions_guide.md for more details on + how to define valid effect expressions. + }, + ... -- additional discoveries -- + ] +} +``` + +## Notes +1. Remove any trailing commas or the file won't be parsed +2. A discovery **target** is always the cell group entity that gains or loses the discovery +3. Discoveries are normally gained or lost as the result of events, actions, or decisions that perform the **add** or **remove** effects on the **discoveries** attribute of a cell group entity diff --git a/Modding Guide/Guides/discovery_modding_guide.txt b/Modding Guide/Guides/discovery_modding_guide.txt deleted file mode 100644 index add824c1..00000000 --- a/Modding Guide/Guides/discovery_modding_guide.txt +++ /dev/null @@ -1,33 +0,0 @@ ----- Discovery Modding Guide ---- - -Discovery modding files are located within the 'Discoveries' folder. To be valid, mod files must have the .json extension and have the following file structure: - --- File Structure -- - -{ - "discoveries": [ -- list of discoveries -- - { - "id": -- (required) Unique discovery identifier, if more than one definition share ids, only the last one loaded will be used - "name": -- (required) Name of discovery - - "gainConditions": -- (optional) List of all conditions a cell group must meet to gain this discovery, separated by commas (see note #2) - "holdConditions": -- (optional) List of all conditions a cell group must meet to hold onto this discovery, separated by commas (see note #2 and note #4) - - "gainEffects": -- (optional) List of all effects triggered on cell group upon gaining this discovery (see note #3) - "lossEffects": -- (optional) List of all effects triggered on cell group upon losing this discovery (see note #3) - - "eventTimeToTrigger": -- (required) The base maximum amount of time that can pass before the related discovery event happens (value between 1 and 9,223,372,036,854,775,807 days). - "eventTimeToTriggerFactors": -- (optional) List of factors that influence how long it will take for this discovery's event to trigger (see note #5) - }, - ... -- additional discoveries -- - ] -} - --- Notes -- -1. Remove any trailing commas or the file won't be parsed -2. Refer to conditions_guide.txt for more details on how to define and use conditions -3. Refer to effects_guide.txt for more details on how to define and use effects -4. If a discovery no longer meets its hold conditions then it will be removed from the cell group. In which case, the gain conditions might get reevaluated and a subsequent discovery event reassigned to the group if possible -5. Factors, once calculated, will be multiplied against the time-to-trigger base value of a discovery to calculate that maximum amount of time that can pass between the inception of an event and when it finally triggers. If a factor is zero, the time-to-trigger will be set to a minimum value (e.g. 1 day). Refer to factors_guide.txt for more details on how to define and use factors. - --- diff --git a/Modding Guide/Guides/effects_guide.txt b/Modding Guide/Guides/effects_guide.txt deleted file mode 100644 index ddc66896..00000000 --- a/Modding Guide/Guides/effects_guide.txt +++ /dev/null @@ -1,79 +0,0 @@ ----- Effects Guide ---- - -Effects are occurrences that can happen to different types of entities (cells, groups, factions, etc) when an event occurs within the simulation. These can affect the entity in multiple ways depending on the type of effect. - -Here's a list of the current types of effects (more to be added in future versions) and how they work: - -- 'add_group_knowledge' - Assigns the specified knowledge to the specified group, and sets the knowledge's level limit to the specified value (integer value between 1 and 10000). the format of the effect is as follows: 'add_group_knowledge:,' - These are valid target group types: - - 'this': the cell group this effect targets - - Examples: 'add_group_knowledge:agriculture_knowledge,10', 'add_group_knowledge:shipbuilding_knowledge,30' - -- 'remove_group_knowledge' - Removes the specified knowledge from the specified group. the format of the effect is as follows: 'remove_group_knowledge:' - NOTE: Try make sure that no more than one 'effector' can remove a particular knowledge at any given time. - - Examples: 'remove_group_knowledge:agriculture_knowledge', 'remove_group_knowledge:shipbuilding_knowledge' - -- 'modify_group_knowledge_limit' - Assigns the specified knowledge to the specified group, and modify the knowledge's current level limit by adding the specified value (integer value between -10000 and 10000). the format of the effect is as follows: 'modify_group_knowledge_limit:,' - NOTE: This effect cannot decrease a knowledge level limit below 1 nor it can increase a specific limit above 10000. - - Examples: 'modify_group_knowledge_limit:shipbuilding_knowledge,20', 'modify_group_knowledge_limit:shipbuilding_knowledge,-20' - -- 'apply_cell_arability_modifier' - Applies the specified arability modifier (value between -1 and 1) to the group, increasing or decreasing the arability on the target cell. the format of the effect is as follows: 'apply_cell_arability_modifier:' - NOTE: This effect cannot decrease the arability below 0 or increase it above 1. - - Examples: 'apply_cell_arability_modifier:0.5', 'apply_cell_arability_modifier:-0.5' - -- 'apply_cell_accessibility_modifier' - Applies the specified accessibility modifier (value between -1 and 1) to the group, increasing or decreasing the accessibility on the target cell. the format of the effect is as follows: 'apply_cell_accessibility_modifier:' - NOTE: This effect cannot decrease the accessibility below 0 or increase it above 1. - - Examples: 'apply_cell_accessibility_modifier:0.5', 'apply_cell_accessibility_modifier:-0.5' - -- 'apply_group_navigation_range_modifier' - Applies the specified navigation range modifier (value between -1 and 1) to the group, giving longer routes a greater chance of success. the format of the effect is as follows: 'apply_group_navigation_range_modifier:' - NOTE: This effect cannot decrease the group navigation range modifier below 0. - - Examples: 'apply_group_navigation_range_modifier:0.5', 'apply_group_navigation_range_modifier:-0.5' - -- 'add_group_activity' - Assigns the specified activity to the specified group. the format of the effect is as follows: 'add_group_activity:' - - Examples: 'add_group_activity:farming' - -- 'remove_group_activity' - Removes the specified activity from the specified group. the format of the effect is as follows: 'remove_group_activity:' - NOTE: Try make sure that no more than one 'effector' can remove a particular activity at any given time. - - Examples: 'remove_group_activity:farming' - -- 'add_group_skill' - Assigns the specified skill to the specified group. the format of the effect is as follows: 'add_group_skill:' - These are valid target group types: - - 'this': the cell group this effect targets - - Examples: 'add_group_skill:seafaring' - -- 'remove_group_skill' - Removes the specified skill from the specified group. the format of the effect is as follows: 'remove_group_skill:' - NOTE: Try make sure that no more than one 'effector' can remove a particular activity at any given time. - - Examples: 'remove_group_skill:seafaring' - -- 'add_group_property' - Assigns the specified property to the specified group. the format of the effect is as follows: 'add_group_property:' - - Examples: 'add_group_property:CAN_FORM_POLITY:tribe' - -- 'remove_group_property' - Removes the specified property from the specified group. the format of the effect is as follows: 'remove_group_property:' - NOTE: Try make sure that no more than one 'effector' can remove a particular property at any given time. - - Examples: 'remove_group_property:CAN_FORM_POLITY:tribe' - --- diff --git a/Modding Guide/Guides/effects_modding_guide.txt b/Modding Guide/Guides/effects_modding_guide.md similarity index 88% rename from Modding Guide/Guides/effects_modding_guide.txt rename to Modding Guide/Guides/effects_modding_guide.md index a773016d..8ba3730f 100644 --- a/Modding Guide/Guides/effects_modding_guide.txt +++ b/Modding Guide/Guides/effects_modding_guide.md @@ -1,11 +1,12 @@ ----- Effects Modding Guide ---- +# Effects Modding Guide -Effects are JSON sub-objects that are added to decisions or other mod objects that +Effects are JSON sub-objects that are added to decision options or other mod objects that define a set of effects to occur within the simulation when triggered. They have the following structure: --- Object Structure -- +### Object Structure +``` { "id": -- (required) Unique effect identifier. Each effect must have a unique id within the list of effects @@ -22,17 +23,18 @@ following structure: object is evaluated. This text will be displayed when needed by the object this effect is associated with (for example, as an option tooltip) See - string_values_guide.txt to find more about how + string_values_guide.md to find more about how to define valid dynamic text values. "result": -- (required) EFFECT EXPRESSION to evaluate after this effect has been triggered. This can introduce changes to the target or any related entity. - Please read expressions_guide.txt for more + Please read expressions_guide.md for more details on how to define valid effect expressions. } +``` --- Notes -- +## Notes 1. List of values must be enclosed within square brackets and separated by commas. Remove any trailing commas on any list enclosed by square brackets, or you'll get a JSON parsing error. diff --git a/Modding Guide/Guides/element_modding_guide.txt b/Modding Guide/Guides/element_modding_guide.md similarity index 50% rename from Modding Guide/Guides/element_modding_guide.txt rename to Modding Guide/Guides/element_modding_guide.md index f4fab831..3b79f25f 100644 --- a/Modding Guide/Guides/element_modding_guide.txt +++ b/Modding Guide/Guides/element_modding_guide.md @@ -1,28 +1,33 @@ ----- Element Modding Guide ---- +# Element Modding Guide -Element modding files are located within the 'Elements' folder. To be valid, mod files must have the .json extension and have the following file structure: +Element modding files are located within the **Elements** folder. To be valid, mod files must have the **.json** extension and have the following file structure: --- File Structure -- +### File Structure +``` { - "elements": [ -- list of elements -- + "elements": [ -- list of elements -- { - "id": -- (required) Unique element identifier, if more than one definition share ids, only the last one loaded will be used + "id": -- (required) Unique element identifier, if more than one definition + share ids, only the last one loaded will be used + "name": -- (required) Name of element (in plural form, see note #2) - "adjectives": -- (optional) List of applicable adjective words or ids, separated by commas. If the if the word/id is present on a adjective mod file then the element will use the adjective word described in the mod entry (if applicable). + "adjectives": -- (optional) List of applicable adjective words or ids, separated by commas. + If the if the word/id is present on a adjective mod file then the element + will use the adjective word described in the mod entry (if applicable). + "regionConstraints": -- (optional) List of region constraints, separated by commas (see note #3) "phraseAssociations": -- (required) List of phrase association strings, separated by commas (see note #4) }, - ... -- additional elements -- + ... -- additional elements -- ] } +``` --- Notes -- +## Notes 1. Remove any trailing commas or the file won't be parsed -2. The name string should be written in translatable plural form. Examples: "stone:s", "grass:es". Refer to language_modding_guide.txt for more details on how to define translatable nouns. -3. Each region constraint is used to decide whether or not to associate the element with a particular region. If any of the constraints fails then the element won't be associated with the region. Refer to region_constraints_guide.txt for more details on how to define and use region constraints -4. Each phrase association is used to form nouns or noun phrases for procedurally generated proper names and other types of texts. Refer to phrase_association_guide.txt for more details on how to define phrase associations - --- +2. The name string should be written in translatable plural form. Examples: "stone:s", "grass:es". Refer to language_modding_guide.md for more details on how to define translatable nouns. +3. Each region constraint is used to decide whether or not to associate the element with a particular region. If any of the constraints fails then the element won't be associated with the region. Refer to region_constraints_guide.md for more details on how to define and use region constraints +4. Each phrase association is used to form nouns or noun phrases for procedurally generated proper names and other types of texts. Refer to phrase_association_guide.md for more details on how to define phrase associations diff --git a/Modding Guide/Guides/entities_guide.md b/Modding Guide/Guides/entities_guide.md index 304ac0a8..b0bf7e8b 100644 --- a/Modding Guide/Guides/entities_guide.md +++ b/Modding Guide/Guides/entities_guide.md @@ -7,72 +7,130 @@ An access operation is handled as an expression and as such, can either ver reso ## Currently Supported Entities: + ### CELL This type of entity encapsulates a fixed area on the world map and has general information about that area's characteristics: longitude, latitude, altitude, temperature, rainfall, present biomes, etc. - ***Properties:*** + ***Attributes:*** - **biome_trait_presence** Attribute function that returns the presence of a specific biome trait within a cell as a **numeric** value between 0 and 1. - *Examples:* `"cell.biome_trait_presence(wood)"`, `"target.cell.biome_trait_presence(sea)"` + *Examples:* `"cell.biome_trait_presence(wood) < 0.3"`, `"target.cell.biome_trait_presence(sea)"` + + - **biome_type_presence** + Attribute function that returns the presence of a specific biome type within a cell as a **numeric** value between 0 and 1. There are only three possible biome types: land, water, and ice. + *Examples:* `"cell.biome_type_presence(water)" > 0.5`, `"target.biome_type_presence(land)"` + + - **neighbors** + Attribute that returns a **collection** entity containing the cell entities that are adjacent to the cell (including those in the NW, NE, SW, and SE corners of it). + *Examples:* `"cell.neighbors"`, `"target.cell.neighbors.sum[cell](cell.biome_type_presence(water))"` + + - **group** + Attribute that returns the **group** entity that inhabits that cell (if any). PMake sure to perform an **is_null** check on the **group** attribute before using it. + *Examples:* `"cell.group"`, `"target.cell.group.is_null"` + + - **arability** + Attribute that returns the arability quality value of a cell as a **numeric** value between 0 and 1. + *Examples:* `"cell.arability"`, `"target.cell.arability > 0.8"` + + - **accessibility** + Attribute that returns the accessibility value of a cell as a **numeric** value between 0 and 1. + *Examples:* `"cell.accessibility"`, `"target.cell.accessibility <= 0.2"` + + - **hilliness** + Attribute that returns the hilliness value of a cell as a **numeric** value between 0 and 1. Where 0 represents mostly flat terrain, and 1 represent extremely high verticality in terrain features. + *Examples:* `"cell.hilliness"`, `"target.cell.hilliness > 0.3"` + + - **flowing_water** + Attribute that returns the amount of flowing water (in *mm/year*) in a cell as a **numeric** value between 0 and 100000. + *Examples:* `"cell.flowing_water"`, `"target.cell.flowing_water > 100"` + ### GROUP This type of entity encapsulates a population group occupying a cell on the surface of the map and contains information about characteristics like: population, cultural attributes, influences, etc. - ***Properties:*** + ***Attributes:*** - **cell** Attribute that returns the **cell entity** where this group is located. *Examples:* `"group.cell"`, `"target.cell"` - - **prominence(*polity*)** - Attribute function that returns the prominence that a particular polity has on the group as a **numeric** value. - *Examples:* `"group.prominence(target.polity)"`, `"target.prominence(polity)"` + - **prominence_value(*polity*)** + Attribute function that returns the prominence value that a particular polity has on the group as a **numeric** value between 0 and 1. + *Examples:* `"group.prominence_value(target.polity)"`, `"target.prominence_value(polity)"` - - **faction_cores_count** - Attribute that returns the amount of faction cores located in the group as a **numeric** value. - *Examples:* `"group.faction_cores_count"`, `"target.faction_cores_count"` + - **get_core_distance(*faction*)** + Attribute function that returns the distance (in *km*) that a particular faction's core has on the group as a **numeric** value. + *Examples:* `"group.get_core_distance(target)"`, `"target.get_core_distance(selected_faction)"` - - **faction_core_distance(*polity*)** - Attribute function that returns the distance between this group's cell and the closest faction core cell in the given polity as a **numeric** value. - *Examples:* `"group.faction_core_distance(target.polity)"`, `"target.faction_core_distance(polity)"` + - **most_prominent_polity** + Attribute that returns the **polity** entity that has the highest prominence value within this group. + *Examples:* `"group.most_prominent_polity"`, `"target.most_prominent_polity"` + + - **present_polities** + Attribute that returns a **collection** entity containing the polity entities that have a prominence value greater than 0 in this particular cell group. + *Examples:* `"group.present_polities"`, `"target.present_polities.sum[polity](target.prominence_value(polity))"` + + - **closest_factions** + Attribute that returns a **collection** entity containing the factions entities, whose polities have a presence in this group and whose core groups are closest to this particular group + *Examples:* `"group.closest_factions"`, `"target.closest_factions.sum[faction](target.prominence_value(faction.polity))"` + + - **navigation_range** + Read/write attribute which contains the current navigation range (as a **numeric** value) of boats/ships that can be built by this group. + *Examples:* `"group.navigation_range"`, `"target.navigation_range += 10"` + + - **arability_modifier** + Read/write attribute which contains the current arability modifier (as a **numeric** value) applied to the arability value (as a multiplier to the difference between the cell's base arability and 1) of the cell the group inhabits. NOTE: the starting arability modifier for all groups is 0. + *Examples:* `"group.arability_modifier"`, `"target.arability_modifier -= 0.3"` + + - **accessibility_modifier** + Read/write attribute which contains the current accessibility modifier (as a **numeric** value) applied to the accessibility value (as a multiplier to the difference between the cell's base accessibility and 1) of the cell the group inhabits. NOTE: the starting accessibility modifier for all groups is 0. + *Examples:* `"group.accessibility_modifier"`, `"target.accessibility_modifier += 0.2"` + + - **properties** + Attribute that returns a modifiable **container** entity of all the group's properties, which are just string keywords. This container entity has three attributes, **add**, **remove**, and **contains**. + *Example:* `"target.properties.add(can_form_tribe)"`, `"target.properties.remove(can_form_tribe)"`, `"target.properties.contains(can_form_tribe)"` + + - **population** + Read-only attribute that returns the current population of a cell group. + *Example:* `"target.population"`, `"group.population <= 1000"` + + - **neighbors** + Attribute that returns a **collection** entity containing the group's entities that inhabit cells adjacent to this group's cell (including those in the NW, NE, SW, and SE corners of it). + *Examples:* `"group.neighbors"`, `"target.neighbors.sum[group](group.preferences.authority) / target.neighbors.count"` - **preferences** - Attribute that returns an entity containing all the groups's cultural preferences, whose **numeric** values can later be read from or written to. + Attribute that returns a non-modifiable **container** entity of all the group's cultural preferences, whose **numeric** values can later be read from or written to. *Example:* `"target.preferences.authority <= 0.5"` + - **skills** + Attribute that returns a modifiable **container** entity of all the group's cultural skills, whose **numeric** values can later be read from. + *Example:* `"target.skills.seafaring <= 0.5"`, `"target.skills.add(seafaring)"` + + - **activities** + Attribute that returns a modifiable **container** entity of all the group's cultural activities, whose **numeric** values can later be read from. + *Example:* `"target.activities.foraging <= 0.4"`, `"target.activities.remove(farming)"` + - **knowledges** - Attribute that returns an entity containing all the groups's cultural knowledges, whose **numeric** values can later be read from. - *Example:* `"target.knowledges.social_organization <= 0.6"` + Attribute that returns a modifiable **container** entity of all the group's cultural knowledges, whose **numeric** values can later be read from. + *Example:* `"target.knowledges.social_organization <= 0.6"`, `"target.knowledges.add(shipbuilding)"` - - **polity_with_highest_prominence** - Attribute that returns the **polity entity** that has the highest prominence value within this group. - *Examples:* `"group.polity_with_highest_prominence"`, `"target.polity_with_highest_prominence"` + - **discoveries** + Attribute that returns a modifiable **container** entity of all the group's cultural discoveries. + *Example:* `"target.discoveries.contains(sailing)"`, `"target.discoveries.add(keels)"` ### POLITY This type of entity encapsulates a polity in the planet and information about it's culture, territory, factions, etc. - ***Properties:*** - - - **type** - Attribute that returns the type of polity. Current available type: **tribe** - *Example:* `"polity.type == tribe"` + ***Attributes:*** - - **get_random_group()** - Attribute that selects and returns a random **group entity** that falls within the polity's prominence sphere. - *Example:* `"polity.get_random_group()"` - - - **get_random_contact()** - Attribute that selects and returns a random **contact entity** encapsulating another polity that is currently in contact with this polity. - *Example:* `"polity.get_random_contact()"` - - - **get_contact(*polity*)** - Attribute that returns the **contact entity** available for *polity*, if any. - *Example:* `"polity.get_contact(polity)"` + - **contacts** + Attribute that returns a **collection** entity containing all **contact** entities that are associated with this polity. + *Examples:* `"polity.contacts.count > 0"`, `"tribe_a.contacts.select[contact](contact.polity == tribe_b)"` - **dominant_faction** Attribute that returns the polity's current *dominant* **faction entity**. @@ -82,6 +140,14 @@ An access operation is handled as an expression and as such, can either ver reso Attribute function that transfers a percentage of influence, *influence_to_transfer*, from *source_faction* towards *target_faction*. *Example:* `"polity.transfer_influence(source_faction, target_faction, 0.2)"` + - **type** + Attribute that returns the type of polity. At the moment, the only available type is **tribe**. + *Example:* `"polity.type == tribe"` + + - **leader** + Attribute that returns the leader of the polity's current dominant faction as an **agent entity**. + *Examples:* `"polity.leader.wisdom"` + - **split(*polity_type*,*splitting_faction*)** Attribute function that splits the polity by creating a new polity of type *polity_type*, with *splitting_faction* as the source of the split. NOTE: supported polity types: *tribe* @@ -91,50 +157,48 @@ An access operation is handled as an expression and as such, can either ver reso Attribute function that merges *polity_to_merge* into the calling polity entity. *Example:* `"polity.merge(other_polity)"` - - **leader** - Attribute that returns the leader of the polity's current dominant faction as an **agent entity**. - *Examples:* `"polity.leader.wisdom"` - - -### CONTACT - - This type of entity encapsulates relationship information between two polities. + - **neighbor_regions** + Attribute that returns a **collection** entity containing all **region** entities which intersect or border the polity's territory and are not already part of its set of core regions. + *Examples:* `"tribe.neighbor_regions.count > 0"`, `"target.polity.neighbor_regions.select_random()"` - ***Properties:*** - - - **polity** - Attribute that returns the **polity entity** that this contact encapsulates relationship information for. - *Examples:* `"contact.polity"`, `"polity.get_random_contact().polity"` + - **add_core_region(*region_to_add*)** + Attribute function that adds the *region_to_add* entity to the polity's set of core regions. + *Example:* `"polity.add_core_region(region)"` - - **strength** - Attribute that returns the contact strength between the polity that contained this contact entity and the polity contained in the contact. Contact strength will be greater than `0` if both polities share a border with each other. - *Examples:* `"contact.strength"`, `"target_polity.get_contact(polity).strength"` + - **core_region_saturation** + Attribute that returns a **numeric** value representing the percentage of area from the polity's core regions which is already covered by the polity's territory. + *Example:* `"polity.core_region_saturation > 0.5"` + - **factions** + Attribute that returns a **collection** entity containing all **faction** entities that are members of this polity. + *Examples:* `"polity.factions.count > 1"`, `"contact.polity.factions.select_subset[faction](faction.has_contact_with(target.polity))"` -### AGENT + - **preferences** + Attribute that returns a non-modifiable **container** entity of all the polity's cultural preferences, whose **numeric** values can later be read from. + *Example:* `"target.preferences.authority <= 0.5"` - This type of entity encapsulates any individual that is or was present within the simulation. That includes faction leaders. + - **skills** + Attribute that returns a non-modifiable **container** entity of all the polity's cultural skills, whose **numeric** values can later be read from. + *Example:* `"target.skills.seafaring <= 0.5"` - ***Properties:*** + - **activities** + Attribute that returns a non-modifiable **container** entity of all the polity's cultural activities, whose **numeric** values can later be read from. + *Example:* `"target.activities.foraging <= 0.4"` - - **charisma** - Attribute that returns an agent's *charisma* level as a value between 0 and 1. - *Example:* `"leader.charisma < 0.5"` + - **knowledges** + Attribute that returns a non-modifiable **container** entity of all the polity's cultural knowledges, whose **numeric** values can later be read from. + *Example:* `"target.knowledges.social_organization <= 0.6"` - - **wisdom** - Attribute that returns an agent's *wisdom* level as a value between 0 and 1. - *Example:* `"0.3 >= current_leader.wisdom"` + - **discoveries** + Attribute that returns a non-modifiable **container** entity of all the polity's cultural discoveries. + *Example:* `"target.discoveries.contains(sailing)"` ### FACTION - This type of entity encapsulates any faction that can be part of a polity. most decisions have a faction as target entity. - - ***Properties:*** + This type of entity encapsulates any faction that can be part of a polity. Most decisions have a faction as target entity. - - **type** - Attribute that returns the type of faction. Current available type: **clan** - *Example:* `"target.type == clan"` + ***Attributes:*** - **administrative_load** Attribute that returns the faction's current administrative load as a **numeric** value. @@ -144,10 +208,6 @@ An access operation is handled as an expression and as such, can either ver reso Attribute that returns the faction's influence on its containing polity as a **numeric** value. *Example:* `"faction.influence <= 0.6"` - - **preferences** - Attribute that returns an entity containing all the groups's cultural preferences, whose **numeric** values can later be read from or written to. - *Example:* `"target.preferences.authority <= 0.5"` - - **leader** Attribute that returns the leader of the polity's current dominant faction as an **agent entity**. *Example:* `"polity.leader.charisma"` @@ -164,6 +224,26 @@ An access operation is handled as an expression and as such, can either ver reso Attribute function that will trigger a faction to split a new faction from itself. The function expects two parameters: a group to become the new faction's core, *core_group*, and a percentage of influence, *influence_to_transfer*, (as a value between 0 and 1) to transfer from the parent faction. *Example:* `"target.split(new_core_group, 0.5)"` + - **remove()** + Attribute function that will make this faction dissapear completely. NOTE: If this faction is the only member faction of a polity, then the polity will also be removed. + *Example:* `"faction.remove()"` + + - **migrate_core_to_group(*group*)** + Attribute function that will make a faction replace its core group with a different one. + *Example:* `"target.migrate_core_to_group(new_core_group)"` + + - **core_group** + Attribute that returns the core of this faction as a **group** entity. + *Example:* `"target.core_group != new_core_group"` + + - **type** + Attribute that returns the type of faction. Currently the only option is **clan**. + *Example:* `"target.type == clan"` + + - **guide** + Attribute that returns who is currently guiding the faction. The possible values are *simulation* (as in the computer running the game simulation) or *player* (as in the person playing the game). + *Example:* `"faction.guide == player"` + - **get_relationship(*faction*)** Attribute function that will return a **numeric** value corresponding to the current relationship value between this faction and the faction given as parameter, *faction*. *Example:* `"target.get_relationship(dominant_faction)"` @@ -172,6 +252,134 @@ An access operation is handled as an expression and as such, can either ver reso Attribute function that will update the relationship value between this faction and the faction given as the first parameter *faction*, using the **numeric** value given in the second parameter, *value*. *Example:* `"dominant_faction.set_relationship(target, input_value / 2)"` - - **core_group** - Attribute that returns the core of this faction as a **group entity**. - *Example:* `"target.core_group != new_core_group"` + - **groups** + Attribute that returns a **collection** entity containing all **group** entities that are under the direct control of this faction. + *Examples:* `"faction.groups.count > 1"`, `"target.groups.select_subset[group](group.get_core_distance(target) < 5000)"` + + - **has_contact_with(*polity*)** + Attribute function that returns *true* if any of the faction's groups overlaps with the territory of the *polity* entity, or is neighbor with any group that overlaps that same territory. Otherwise returns *false*. + *Example:* `"dominant_faction.has_contact_with(other_polity)"` + + - **change_polity(*polity*)** + Attribute function that changes the polity this faction belongs to. + *Example:* `"faction.change_polity(other_polity)"` + + - **preferences** + Attribute that returns a non-modifiable **container** entity of all the faction's cultural preferences, whose **numeric** values can later be read from or written to. + *Example:* `"target.preferences.authority <= 0.5"`, `"target.preferences.agression = 0.3"` + + - **skills** + Attribute that returns a non-modifiable **container** entity of all the faction's cultural skills, whose **numeric** values can later be read from. + *Example:* `"target.skills.seafaring <= 0.5"` + + - **activities** + Attribute that returns a non-modifiable **container** entity of all the faction's cultural activities, whose **numeric** values can later be read from. + *Example:* `"target.activities.foraging <= 0.4"` + + - **knowledges** + Attribute that returns a non-modifiable **container** entity of all the faction's cultural knowledges, whose **numeric** values can later be read from. + *Example:* `"target.knowledges.social_organization <= 0.6"` + + - **discoveries** + Attribute that returns a non-modifiable **container** entity of all the faction's cultural discoveries. + *Example:* `"target.discoveries.contains(sailing)"` + + +### REGION + + This type of entity encapsulates a world region. Currently it has no public attributes. + + +### CONTACT + + This type of entity encapsulates relationship information between two polities. + + ***Attributes:*** + + - **polity** + Attribute that returns the **polity entity** that this contact encapsulates relationship information for. + *Examples:* `"contact.polity"`, `"polity.get_random_contact().polity"` + + - **strength** + Attribute that returns the contact strength between the polity that contained this contact entity and the polity contained in the contact. Contact strength will be greater than `0` if both polities share a border with each other. + *Examples:* `"contact.strength"`, `"target_polity.get_contact(polity).strength"` + + +### AGENT + + This type of entity encapsulates any individual that is or was present within the simulation. That includes faction leaders. + + ***Attributes:*** + + - **wisdom** + Attribute that returns an agent's *wisdom* level as a value between 0 and 1. + *Example:* `"0.3 >= current_leader.wisdom"` + + - **charisma** + Attribute that returns an agent's *charisma* level as a value between 0 and 1. + *Example:* `"leader.charisma < 0.5"` + + +### KNOWLEDGE + + This type of entity encapsulates a cultural knowledge. + + ***Attributes:*** + + - **limit** + Attribute that gets or sets a knowledge limit level. The limit defines the maximum level a knowledge can reach. NOTE: Limits can only be set for knowledges at the **group** entity's level. + *Example:* `"group.knowledges.shipbuilding.limit += 5"` + + +### COLLECTION + + This type of entity encapsulates a collection of items, which could be other entities. + + ***Attributes:*** + + - **count** + Attribute that returns the number of items currently within the collection. + *Example:* `"polity.contacts.count > 0"` + + - **request_selection(*description*)** + Attribute function that will ask the player to select an item within the collection. The *description* parameter should be a *text* string that will be presented to the player to instruct them on the action they must perform. NOTE: Some collections might not support this attribute. + *Example:* `"neighbor_regions.request_selection(''Select the region the <> tribe should expand to...'')"` + + - **select_random()** + Attribute function that will return a randomly picked item within the collection. + *Example:* `"near_factions.select_random()"` + + - **select\[ *item* \](*selection_expression*)** + Attribute function that will return the first item in the collection that satisfies the **boolean** expression defined in *selection_expression*. The expression might use the string value given in *item* as a placeholder keyword for each one of the items in the collection. The function will replace the *item* keyword with an actual item each time the expression is evaluated. + *Example:* `"target.polity.contacts.select[contact](contact.polity == attempting_polity).strength"` + + - **select_subset\[ *item* \](*selection_expression*)** + Attribute function that will return a **collection** entity with all the items within the original collection that satisfy the **boolean** expression defined in *selection_expression*. The expression might use the string value given in *item* as a placeholder keyword for each one of the items in the collection. The function will replace the *item* keyword with an actual item each time the expression is evaluated. + *Example:* `"target.present_polities.select_subset[polity](polity.type == tribe)"` + + - **select_best\[ *item_a*, *item_b* \](*comparison_expression*)** + Attribute function that will return the best item in the collection according to the criteria defined by the **boolean** expression defined in *comparison_expression*. The expression might use the string values given in *item_a* and *item_b* as a placeholder keywords for pairs of items in the collection. The function will replace the *item_\** keywords with actual items each time the expression is evaluated. The expression must return *true* if *item_a* is better than *item_b*, or return *false* otherwise. + *Example:* `"polity.contacts.select_best[contact_a,contact_b](contact_a.strength >= contact_b.strength)"` + + - **sum\[ *item* \](*numeric_expression*)** + Attribute function that will return a **numeric** value that is the sum of the results given by *numeric_expression* as evaluated for each item in the collection. The expression might use the string value given in *item* as a placeholder keyword for each one of the items in the collection. The function will replace the *item* keyword with an actual item each time the expression is evaluated. + *Example:* `"target.cell.neighbors.sum[cell](cell.biome_type_presence(water))"` + + +### CONTAINER + + This type of entity encapsulates a simple container of items. Some containers can be modified (add or remove items) while others are stricly read-only. NOTE: Although similar in concept, a **container** entity is functionaly very different from a **collection** entity and shouldn't be confused with it. + + ***Attributes:*** + + - **contains(*item_identifier*)** + Attribute function that returns *true* if the container contains the item idenfied by *item_identifier*, otherwise returns *false*. + *Example:* `"target.discoveries.contains(boat_making)"` + + - **add(*item_identifier*,*...*)** + Attribute function that adds the item idenfied by *item_identifier* to the container entity. The function can receive additional parameters in *...* to set the initial value for the given item. NOTE: This function is only available in modifiable container entities. + *Example:* `"target.knowledges.add(shipbuilding, 1)"` + + - **remove(*item_identifier*)** + Attribute function that removes the item idenfied by *item_identifier* from the container entity. NOTE: This function is only available in modifiable container entities. + *Example:* `"target.knowledges.remove(shipbuilding)"` diff --git a/Modding Guide/Guides/event_modding_guide.txt b/Modding Guide/Guides/event_modding_guide.md similarity index 92% rename from Modding Guide/Guides/event_modding_guide.txt rename to Modding Guide/Guides/event_modding_guide.md index 40ba40d1..7b5d449a 100644 --- a/Modding Guide/Guides/event_modding_guide.txt +++ b/Modding Guide/Guides/event_modding_guide.md @@ -1,10 +1,11 @@ ----- Event Modding Guide ---- +# Event Modding Guide -Event modding files are located within the 'Events' folder. To be valid, mod files -must have the .json extension and have the following file structure: +Event mod files are located within the **Events** folder. To be valid, mod files +must have the **.json** extension and have the following file structure: --- File Structure -- +### File Structure +``` { "events": [ -- list of events -- { @@ -31,7 +32,7 @@ must have the .json extension and have the following file structure: evaluate before assigning the event to the target. If any of the expressions evaluate to 'false', then the event is not assigned. - Please read expressions_guide.txt for more + Please read expressions_guide.md for more details on how to define valid boolean expressions. NOTE: assignment conditions are also evaluated before triggering an event. @@ -40,7 +41,7 @@ must have the .json extension and have the following file structure: evaluate before triggering the event already assigned to the target. If any of the expressions evaluate to 'false', then the event is not - triggered. Please read expressions_guide.txt + triggered. Please read expressions_guide.md for more details on how to define valid boolean expressions. @@ -53,7 +54,7 @@ must have the .json extension and have the following file structure: evaluate after an event has successfully triggered. These can introduce changes to the target or any related entity. Please - read expressions_guide.txt for more details + read expressions_guide.md for more details on how to define valid effect expressions. "repeatable": -- (optional) Can only have 'true' or 'false' @@ -62,7 +63,7 @@ must have the .json extension and have the following file structure: to the same target after every successful or unsuccessful trigger attempt. - "debug": -- (optional) Can only have 'true' or 'false' + "enableDebugLog": -- (optional) Can only have 'true' or 'false' as value (default: 'false'). This an option to assist in mod development. If this is 'true', and 'Debug Mode' is enabled within @@ -73,8 +74,9 @@ must have the .json extension and have the following file structure: ... -- additional events -- ] } +``` --- Notes -- +## Notes 1. List of values must be enclosed within square brackets and separated by commas. Remove any trailing commas on any list enclosed by square brackets, or you'll get a JSON parsing error. diff --git a/Modding Guide/Guides/expression_operators_guide.md b/Modding Guide/Guides/expression_operators_guide.md new file mode 100644 index 00000000..9d3a3a29 --- /dev/null +++ b/Modding Guide/Guides/expression_operators_guide.md @@ -0,0 +1,148 @@ +# Expression Operators Guide + +Expression operators are a set of reserved symbols that can be used to perform logical +or mathematical operations over one or more expressions (see *expressions_guide.md* +for general details on expressions) + +There are two types of operators, **unary**, and **binary**. Unary operators are prefixed +to a single expression, While binary operators are infixed between two expressions +and operate over both. + +Multiple expressions can be chained together using binary operators. Any set of +expressions to the right of a binary operator are considered to be a single sub-expression +and sub-expressions are evaluated in right to left order. So, for example, the expression +`"5 * 1 + 1"` will be interpreted as `"5 * (1 + 1)"`, where the sub-expression `"1 + 1"` +is evaluated first, and the whole expression evaluates to `10`. Parenthesis can be +inserted to change the order in which sub-expressions are evaluated. For example in +`"(5 * 1) + 1"`, `"(5 * 1)"` is evaluated first, so the whole expression now evaluates +to `6`. + +Following is a list of current supported operators enclosed in single quotes. + +### UNARY OPERATORS + +- Negation (mathematical): `-` + This operator will negate the value of a **numeric** expression. For example, `"-(3 + 4)"` + will return `-7`, `"-(-5)"` will return `5`, etc. + Examples: `"-3"`, `"-(3 + 4)"`, `"-target.administrative_load"` + +- Negation (logical): `!` + This operator will negate the value of a **boolean** expression. For example, `"!true"` will + return `false`, `"!(3 > 7)"` will return `true`. + Examples: `"!false"`. `"!(target.preferences.cohesion > 0.7)"` + in single quotes. + +### BINARY OPERATORS + +- Addition: `+` + This operator will add the value of two **numeric** expressions and return the result. + For example, `"4 + 5"` will return `9`, `"2 + 1.5 + 3"` will return `6.5`, etc. + Examples: `"1 + 3.1"`, `"(3 + 4) + 3"`, `"target.administrative_load + 10.5"` + +- Subtraction: `-` + This operator will subtract the value of the right-side **numeric** value from the + left-side **numeric** value and return the result. For example, `"4 - 5"` will return + `-1`, `"8 - 1.4 - 3"` will return `3.6`, etc. + Examples: `"4 - 3.1"`, `"(5 - 4) - 3"`, `"target.administrative_load - 30.7"` + +- Multiplication: `*` + This operator will multiply the value of two **numeric** expressions and return the + result. For example, `"4 * 5"` will return `20`, `"1.5 * 2 * 2"` will return `6`, etc. + Examples: `"4 * 3.1"`, `"(5 * 4) * 3"`, `"2 * target.administrative_load"` + +- Division: `/` + This operator will divide the value of the left-side **numeric** value by the + right-side **numeric** value and return the result. For example, `"8 / 2"` will return + `4`, `"8 / 4 / 2"` will return 4, etc. + NOTE: Avoid performing divisions by zero. The results are undefined. + Examples: `"4 / 2"`, `"(5 / 5) * 2"`, `"target.administrative_load / 10"` + +- Assignment: `=` + This is a special operator that takes the result of the right-side value expression + and assigns it to the *assignable* value expression on the left-side. For example, + `"target.preferences.authority = (1 - 0.3)"` will assign the result of `"1 - 0.3"` + and assign it to the authority preference of the `target` entity. + NOTE A: An assignment expression is an **effect** expression. Not a value expression. + NOTE B: Only certain entity attributes, like faction preferences, are considered + assignable. Specific entity assignable attributes are described in *entities_guide.md* + +- Increment: `+=` + This is a special operator that takes the result of the right-side **numeric** value + expression, adds to it the current *assignable* **numeric** value expression on the + left-side and assigns the result to value expression on the left-side. For example, + `"target.knowledges.shipbuilding.limit += 10 + 3"` will add the result of `"10 + 3"` + to the value stored in `target.knowledges.shipbuilding.limit` and assign the resulting + value back to `target.knowledges.shipbuilding.limit`. + NOTE A: An increment expression is an **effect** expression. Not a value expression. + NOTE B: Only certain entity attributes, like faction preferences, are considered + assignable. Specific entity assignable attributes are described in *entities_guide.md* + +- Decrement: `+=` + This is a special operator that takes the result of the right-side **numeric** value + expression, substracts it from the current *assignable* **numeric** value expression on + the left-side and assigns the result to value expression on the left-side. For example, + `"target.knowledges.shipbuilding.limit -= 10 + 3"` will substract the result of `"10 + 3"` + from the value stored in `target.knowledges.shipbuilding.limit` and assign the resulting + value back to `target.knowledges.shipbuilding.limit`. + NOTE A: An decrement expression is an **effect** expression. Not a value expression. + NOTE B: Only certain entity attributes, like faction preferences, are considered + assignable. Specific entity assignable attributes are described in *entities_guide.md* + +- Equality: `==` + This operator will compare the result of the left-side value expression and compare + it against the result of the right-side value expression. The return value will + be `true` if both expressions are equal. `false` otherwise. For example `"2 == (1 + 1)"` + will return `true`. `"true == false"` will return `false`. + NOTE: Both side expressions must return the same value type for the comparison + to be valid. Thus, a **numeric** expression can only be compared agains another **numeric** + expression. A string can only be compared against another string. And so on... + +- Inequality: `!=` + This operator will compare the result of the left-side value expression and compare + it against the result of the right-side value expression. The return value will + be `false` if both expressions are equal. `true` otherwise. For example `"4 != 4"` + will return `false`. `"true != false"` will return `true`. + NOTE: Both side expressions must return the same value type for the comparison + to be valid. Thus, a **numeric** expression can only be compared agains another **numeric** + expression. A string can only be compared against another string. And so on... + +- More than: `>` + This operator will compare the result of the left-side **numeric** expression and compare + it against the result of the right-side **numeric** expression. The return value will + be `true` if the left-side value is greater than the right side value. `false` + otherwise. For example `"4 > 3"` will return `true`. `"2.5 > 3"` will return `false`. + +- Less than: `<` + This operator will compare the result of the left-side **numeric** expression and compare + it against the result of the right-side **numeric** expression. The return value will + be `true` if the left-side value is lesser than the right side value. `false` + otherwise. For example `"4 < 3"` will return `false`. `"2.5 < 3"` will return `true`. + +- More Than or Equal: `>=` + This operator will compare the result of the left-side **numeric** expression and compare + it against the result of the right-side **numeric** expression. The return value will + be `true` if the left-side value is equal or greater than the right side value. + `false` otherwise. For example `"4 >= 3"` will return `true`. `"3 >= 3"` will also + return `true`. `"2.5 >= 3"` will return `false`. + +- Less Than or Equal: `<=` + This operator will compare the result of the left-side **numeric** expression and compare + it against the result of the right-side **numeric** expression. The return value will + be `true` if the left-side value is equal or lesser than the right side value. + `false` otherwise. For example `"4 <= 3"` will return `false`. `"2 <= 3"` will return + `true`, `"3 <= 3"` will also return `true`. + +- Logical *and*: `&&` + This operator will return `true` if both the left-side **boolean** expression and the + right-side **boolean** expression return `true`. The operation returns `false` otherwise. + For example: `"(2 == 2) && (3 > 1)"` will return `true`. `"(4 > 3) && (2 == 1)"` will + return `false` because `"2 == 1"` evaluates to `false` even though `"4 > 3"` evaluates + to `true`. + +- Logical *or*: `||` + This operator will return `true` if either the left-side **boolean** expression or the + right-side **boolean** expression return `true`. The operation returns `false` only + if both side expressions return `false`. + For example: `"(2 == 2) && (3 > 1)"` will return `true`. `"(4 > 3) && (2 == 1)"` will + also return `true` because `"4 > 3"` evaluates to `true` even though `"2 == 1"` evaluates + to `false`. diff --git a/Modding Guide/Guides/expression_operators_guide.txt b/Modding Guide/Guides/expression_operators_guide.txt deleted file mode 100644 index 4bf8e6c1..00000000 --- a/Modding Guide/Guides/expression_operators_guide.txt +++ /dev/null @@ -1,127 +0,0 @@ ----- Expression Operators Guide ---- - -Expression operators are a set of reserved symbols that can be used to perform logical -or mathematical operations over one or more expressions (see expressions_guide.txt -for general details on expressions) - -There are two types of operators, unary, and binary. Unary operators are prefixed -to a single expression, While Binary operators are infixed between two expressions -and operate over both. - -Multiple expressions can be chained together using binary operators. Any set of -expressions to the right of a binary operator are considered to be a single sub-expression -and sub-expressions are evaluated in right to left order. So, for example, the expression -"5 * 1 + 1" will be interpreted as "5 * (1 + 1)", where the sub-expression "1 + 1" -is evaluated first, and the whole expression evaluates to "10". Parenthesis can be -inserted to change the order in which sub-expressions are evaluated. For example in -"(5 * 1) + 1", "(5 * 1)" is evaluated first, so the whole expression now evaluates -to "6". - -Following is a list of current supported operators enclosed -in single quotes. - --- UNARY OPERATORS -- - -- Negation (mathematical): '-' - This operator will negate the value of a NUMERICAL expression. For example, "-(3 + 4)" - will return -7, "-(-5)" will return 5, etc. - Examples: "-3", "-(3 + 4)", "-target.administrative_load" - -- Negation (logical): '!' - This operator will negate the value of a BOOLEAN expression. For example, "!True" will - return False, "!(3 > 7)" will return True. - Examples: "!False". "!(target.preferences.cohesion > 0.7)" - in single quotes. - --- BINARY OPERATORS -- - -- Addition: '+' - This operator will add the value of two NUMERICAL expressions and return the result. - For example, "4 + 5" will return 9, "2 + 1.5 + 3" will return 6.5, etc. - Examples: "1 + 3.1", "(3 + 4) + 3", "target.administrative_load + 10.5" - -- Subtraction: '-' - This operator will subtract the value of the right-side NUMERICAL value from the - left-side numerical value and return the result. For example, "4 - 5" will return - -1, "8 - 1.4 - 3" will return 3.6, etc. - Examples: "4 - 3.1", "(5 - 4) - 3", "target.administrative_load - 30.7" - -- Multiplication: '*' - This operator will multiply the value of two NUMERICAL expressions and return the - result. For example, "4 * 5" will return 20, "1.5 * 2 * 2" will return 6, etc. - Examples: "4 * 3.1", "(5 * 4) * 3", "2 * target.administrative_load" - -- Division: '/' - This operator will divide the value of the left-side NUMERICAL value by the - right-side numerical value and return the result. For example, "8 / 2" will return - 4, "8 / 4 / 2" will return 4, etc. - NOTE: Avoid performing divisions by zero. The results are undefined. - Examples: "4 / 2", "(5 / 5) * 2", "target.administrative_load / 10" - -- Assignment: '=' - This is a special operator that takes the result of the right-side VALUE expression - and assigns it to the 'assignable' value expression on the left-side. For example, - "target.preferences.authority = (1 - 0.3)" will assign the result of "1 - 0.3" - and assign it to the authority preference of the 'target' entity. - NOTE A: An assignment expression is an EFFECT expression. Not a VALUE expression. - NOTE B: Only certain entity attributes, like faction preferences, are considered - assignable. Specific entity assignable attributes are described in entities_guide.md - -- Equality: '==' - This operator will compare the result of the left-side VALUE expression and compare - it against the result of the right-side value expression. The return value will - be 'True' if both expressions are equal. 'False' otherwise. For example "2 == (1 + 1)" - will return 'True'. "True == False" will return 'False'. - NOTE: Both side expressions must return the same value type for the comparison - to be valid. Thus, a numeric expression can only be compared agains another numerical - expression. A string can only be compared against another string. And so on... - -- Inequality: '!=' - This operator will compare the result of the left-side VALUE expression and compare - it against the result of the right-side value expression. The return value will - be 'False' if both expressions are equal. 'True' otherwise. For example "4 != 4" - will return 'False'. "True != False" will return 'True'. - NOTE: Both side expressions must return the same value type for the comparison - to be valid. Thus, a numeric expression can only be compared agains another numerical - expression. A string can only be compared against another string. And so on... - -- More Than: '>' - This operator will compare the result of the left-side NUMERIC expression and compare - it against the result of the right-side numeric expression. The return value will - be 'True' if the left-side value is greater than the right side value. 'False' - otherwise. For example "4 > 3" will return 'True'. "2.5 > 3" will return 'False'. - -- Less Than: '<' - This operator will compare the result of the left-side NUMERIC expression and compare - it against the result of the right-side numeric expression. The return value will - be 'True' if the left-side value is lesser than the right side value. 'False' - otherwise. For example "4 < 3" will return 'False'. "2.5 < 3" will return 'True'. - -- More Than or Equal: '>=' - This operator will compare the result of the left-side NUMERIC expression and compare - it against the result of the right-side numeric expression. The return value will - be 'True' if the left-side value is equal or greater than the right side value. - 'False' otherwise. For example "4 >= 3" will return 'True'. "3 >= 3" will also - return 'True'. "2.5 >= 3" will return 'False'. - -- Less Than or Equal: '<=' - This operator will compare the result of the left-side NUMERIC expression and compare - it against the result of the right-side numeric expression. The return value will - be 'True' if the left-side value is equal or lesser than the right side value. - 'False' otherwise. For example "4 <= 3" will return 'False'. "2 <= 3" will return - 'True', "3 <= 3" will also return 'True'. - -- Logical 'AND': '&&' - This operator will return 'True' if both the left-side BOOLEAN expression and the - right-side boolean expression return 'True'. The operation returns 'False' otherwise. - For example: "(2 == 2) && (3 > 1)" will return 'True'. "(4 > 3) && (2 == 1)" will - return 'False' because "2 == 1" evaluates to 'False' even though "4 > 3" evaluates - to 'True'. - -- Logical 'OR': '||' - This operator will return 'True' if either the left-side BOOLEAN expression or the - right-side boolean expression return 'True'. The operation returns 'False' only - if both side expressions return 'False'. - For example: "(2 == 2) && (3 > 1)" will return 'True'. "(4 > 3) && (2 == 1)" will - also return 'True' because "4 > 3" evaluates to 'True' even though "2 == 1" evaluates - to 'False'. diff --git a/Modding Guide/Guides/expressions_guide.md b/Modding Guide/Guides/expressions_guide.md new file mode 100644 index 00000000..116b29df --- /dev/null +++ b/Modding Guide/Guides/expressions_guide.md @@ -0,0 +1,81 @@ +# Expressions Guide + +Expressions are scripting elements within a mod that are evaluated during the game +execution. They can be used to evaluate conditions, set parameters, and modify a +game entity behavior through effects. + +An expression takes the form of a logical or mathematical statement enclosed in quotes +like the following: + +`"[unary-operator]element-A [binary-operator element-B]"` + +The square bracket enclosed elements are optional, and an expression `element` +can be any of the following: + +- a base 10 numeric value (`1`, `3`, `5.3442`, `0.2332`, etc...) +- a boolean value (`true`, `false`) +- a single word string value (`hello`) +- a string phrase enclosed in double single quotes (`''hello world!''`) +- an entity value (polities, factions, agents, cells, groups, properties, etc...) +- an entity attribute value (example: `faction.leader`, `faction.core_group`, + `polity.get_random_group()`) +- a function (`min()`, `max()`, `normalize()`, etc...) +- a sub-expression (`1 + 1`, `3 * (2 + 1)`, etc...) + +NOTE: numeric values are always base 10, and use decimal points instead of commas + +There are two main types of expressions, *value* expressions, and *effect* expressions. +*Value* expressions are expressions that upon being evaluated, return a value of a +specific type such as a number, a boolean, a string, or an entity. *Effect* expressions, +when evaluated, do not return anything. Instead, they have an effect within the game, +such as modifying an entity's attribute value, creating a new entity, or destroying +it. More info below. + +*Function* expressions are a special type of expression that are composed of a function +identifier and a list of 0 or more parameters enclosed within parentheses. For example, +`"max(2,3)"` is a function expression that returns the greater value within the list +of inputs (`3` in this case). There's only a limited set of valid function expressions. +A list of all currently available functions can be found in *function_expressions_guide.md* + +### VALUE TYPES + +Each value expression is expected to return a value of a specific type. Here's a +list of each value type and its properties. + +- **Numeric Values:** + Numeric value expressions are expressions that return a number as a result. This + number can be an integer or a decimal value, and the range of values can go from + **-3.40282347E+38** to **3.40282347E+38**. Though the expression system does not support + fixed number representations larger than 10 digits. See *expression_operators_guide.md* + for a list of operators to work with and/or return numeric values. + +- **Boolean Values:** + Boolean value expressions are expressions that return a boolean value as a result. + The result of the expression has to resolve to either `true` or `false`, uppercase + representations of boolean values, like `True` or `TRUE`, are considered equivalent + to their lowercase representations. See *expression_operators_guide.md* for a list of + operators to work with and/or return boolean values. + +- **String Values:** + String value expressions are expressions that return a string of characters that + do not match any id assigned to an existing entity or property within a context. + strings composed of multiple words must be enclosed within double single quotes when + used as sub-expressions. String values can embed expressions within them by enclosing + those expressions within `<<` `>>` blocks. Please read *string_values_guide.md* for + more details + +- **Entity Values:** + Entity value expressions are expressions that resolve into an *entity*. *Entities* + are a special kind of value that encapsulate in-game entities like polities, factions, + agents, cells, groups, etc. An entity can have one more attributes that can be + accessed through the `.` operator. Entity attributes can have a value type (number, + boolean, string, entity) or return a function with resolves into a value or an + effect. See *entities_guide.md* for more details on entities. + +### EFFECTS + +Effect expressions are a special kind of expression that do not resolve into a value. +Instead, they produce an in-game effect which depends on the type of expression. +Most effects are associated with with entity attributes. Some others are associated +with function expressions. More details about specific effect expressions can be +found in either *entities_guide.md*, *function_expressions_guide.md*, or *expression_operators_guide.md* diff --git a/Modding Guide/Guides/expressions_guide.txt b/Modding Guide/Guides/expressions_guide.txt deleted file mode 100644 index 03dba70a..00000000 --- a/Modding Guide/Guides/expressions_guide.txt +++ /dev/null @@ -1,77 +0,0 @@ ----- Expressions Guide ---- - -Expressions are scripting elements within a mod that are evaluated during the game -execution. They can be used to evaluate conditions, set parameters, and modify a -game entity behavior through effects. - -An expression takes the form of a logical or mathematical statement like the following: - -"[unary-operator]exp-element-A [binary-operator exp-element-B]" - -The square bracket enclosed elements are optional, and an expression element (or exp-element) -can be any of the following: - -- a numeric value (1, 3, 5.3442, 0.2332, etc...) -- a boolean value (true, false) -- a string value ("hello world!") -- an entity value (polities, factions, agents, cells, groups, properties, etc...) -- an entity attribute value (example: faction.leader, faction.core_group, - polity.get_random_group()) -- a function (min(), max(), normalize(), etc...) -- a sub-expression ("1 + 1", "3 * (2 + 1)", etc...) - -There are two main types of expressions, VALUE expressions, and EFFECT expressions. -Value expressions are expressions that upon being evaluated, return a value of a -specific type such as a number, a boolean, a string, or an entity. Effect expressions, -when evaluated, do not return anything, but instead, have an effect within the game, -such as modifying an entity's attribute value, creating a new entity, or destroying -it. More info below. - -Function expressions are a special type of expression that are composed of a function -id and a list of 0 or more parameters enclosed within parentheses. For example, -"max(2,3)" is a function expression that returns the greater value within the list -of inputs ('3' in this case). There's only a limited set of valid function expressions. -A list of all currently available functions can be found in function_expressions_guide.txt. - --- VALUE TYPES -- - -Each value expression is expected to return a value of a specific type. Here's a -list of each value type and its properties. - -- Numeric Values: - Numeric value expressions are expressions that return a number as a result. This - number can be an integer or a decimal value, and the range of values can go from - -3.40282347E+38 to 3.40282347E+38. Though the expression system does not support - fixed number representations larger than 10 digits. See expression_operators_guide.txt - for a list of operators to work with and/or return numeric values. - -- Boolean Values: - Boolean value expressions are expressions that return a boolean value as a result. - The result of the expression has to resolve to either "true" or "false", uppercase - representations of boolean values will automatically be converted to lowercase - for parsing purposes. See expression_operators_guide.txt for a list of operators to work - with and/or return boolean values. - -- String Values: - String value expressions are expressions that return a string of characters that - do not match any id assigned to an existing entity or property within a context. - strings composed of multiple words must be enclosed within single quotes when - used as sub-expressions. String values can embed expressions within them by enclosing - those expressions within '<<' '>>' blocks. Please read string_values_guide.txt for more - details - -- Entity Values: - Entity value expressions are expressions that resolve into an entity. Entities - are a special kind of value that encapsulate in-game entities like polities, factions, - agents, cells, groups, etc. AN entity can have one more attributes that can be - accessed through the '.' operator. Entity attributes can have a value type (number, - boolean, string, entity) or return a function with resolves into a value or an - effect. See entities_guide.md for more details on entities. - --- EFFECTS -- - -Effect expressions are a special kind of expression that do not resolve into a value. -Instead, they produce an in-game effect which depends on the type of expression. -Most effects are associated with with entity attributes. Some others are associated -with function expressions. More details about specific effect expressions can be -found in either entities_guide.md, function_expressions_guide.txt, or expression_operators_guide.txt diff --git a/Modding Guide/Guides/factors_guide.txt b/Modding Guide/Guides/factors_guide.txt deleted file mode 100644 index abf87e82..00000000 --- a/Modding Guide/Guides/factors_guide.txt +++ /dev/null @@ -1,74 +0,0 @@ ----- Factors Guide ---- - -Factors are properties that can be used to modify other properties like, for example, and event time-to-trigger. Note that factors will always have values between 0 and 1 (inclusive). - -- Factor operators - - -[SQ] - SQUARE: A factor's effect can squared (i.e. multiply the factor by itself) before being applied to the affected property by using the [SQ] prefix. - -[INV] - INVERSE: A factor's effect can be inversed by applying the [INV] prefix so that the affected property becomes inversely proportional (i.e. '[INV]' equals '1 - '). - - -Operators must be enclosed together with factors within single quotes. Modifiers can be used together using parenthesis to set modifier priority (values between parenthesis evaluate first). -Example: '[SQ]([INV])' - ---- - -Here's a list of the current types of factors (more to be added in future versions) and how they work: - -- 'cell_accessibility' - Returns the accessibility (i.e. how accessible the terrain is) of the terrain cell as a value between 0 and 1 - - Examples: 'cell_accessibility', '[INV]cell_accessibility' - -- 'cell_arability' - Returns the arability (i.e. how arable the land is) of the terrain cell as a value between 0 and 1 - - Examples: 'cell_arability', '[INV]cell_arability' - -- 'cell_foraging_capacity' - Returns the foraging capacity (i.e. how many resources can be extracted through foraging) of the terrain cell as a value between 0 and 1 - - Examples: 'cell_foraging_capacity', '[INV]cell_foraging_capacity' - -- 'cell_survivability' - Returns the survivability (i.e. how easy is for humans to survive on that cell) of the terrain cell as a value between 0 and 1 - - Examples: 'cell_survivability', '[INV]cell_survivability' - -- 'cell_hilliness' - Returns the hilliness (i.e. how hilly the terrain is) of the terrain cell as a value between 0 and 1 - - Examples: 'cell_hilliness', '[INV]cell_hilliness' - -- 'cell_flowing_water' - Returns the amount of flowing water on the terrain cell, divided by the 'max_flowing_water' parameter (a value between 10 and 100000), as a value between 0 and 1 - - Examples: 'cell_flowing_water:2000', '[INV]cell_flowing_water:5000' - -- 'cell_biome_presence' - Returns the presence of a particular biome (i.e. percentage of area in cell covered by such biome) of the terrain cell as a value between 0 and 1 - - Examples: 'cell_biome_presence:forest', '[INV]cell_biome_presence:desert' - -- 'cell_biome_type_presence' - Returns the presence of a particular biome type (i.e. percentage of area in cell covered by biomes of said type) of the terrain cell as a value between 0 and 1 - - Examples: 'cell_biome_type_presence:water', '[INV]cell_biome_type_presence:land' - -- 'neighborhood_biome_type_presence' - Calculates the total amount of biomes of a particular type present in the target cell and all neighboring cells surrounding the cell. The factor's value will fall within the range of 0 (no type presence in the target cell nor any surrounding cell) and 1 (all 9 cells have 100% biome presence of type) - - Examples: 'neighborhood_biome_type_presence:water', '[INV]neighborhood_biome_type_presence:ice' - -- 'cell_biome_trait_presence' - Returns the presence of a particular biome trait (ie. 'wood', 'sea') of the terrain cell as a value between 0 and 1 - - Examples: 'cell_biome_trait_presence:sea', '[INV]cell_biome_trait_presence:wood' - -- 'neighborhood_biome_trait_presence' - Calculates the total presence of a particular biome trait in the target cell and all neighboring cells surrounding the cell. The factor's value will fall within the range of 0 (no trait presence in the target cell nor any surrounding cell) and 1 (all 9 cells have 100% biome presence of trait) - - Examples: 'neighborhood_biome_trait_presence:sea', '[INV]neighborhood_biome_trait_presence:wood' - --- diff --git a/Modding Guide/Guides/language_structures_modding_guide.md b/Modding Guide/Guides/language_structures_modding_guide.md new file mode 100644 index 00000000..898e6bf7 --- /dev/null +++ b/Modding Guide/Guides/language_structures_modding_guide.md @@ -0,0 +1,50 @@ +# Language Structures Modding Guide + +Procedurally generated languages in *Worlds* are built by "translating" English words and sentences defined in mod files like *elements.json*, *region_attributes.json* and sometimes within the game itself. In order for this to work, the input strings given in those documents must follow a format that instructs the word parser on how to understand each word or phrase. This document attempts to describe the structure and keywords used to facilitate the parsing process. + +### NOUNS + +Nouns are single words that are used to identify people, groups of people, locations or other types of objects within the game. These can be used in singular or plural form and be merged together with other nouns or adjectives. They can be built from verbs or other type of words through processes like verb nominalization. + +In most cases, nouns must be defined in 'plural' form. If done correctly, the parser will be able to recognize the singular part of the word. To do so, the noun definition must separate the plural suffix element, `s` or `es`, using a colon `:` like in the following examples: + + `stone:s`, `sun:s`, `moon:s`, `bush:es`, `box:es`, `potato:es` + +For irregular nouns, the `in` annotation, encased within brackets, is prefixed. The annotation must include as a parameter the noun's singular spelling. Here are some examples: + + `[in(foot)]feet`, `[in(tooth)]teeth`, `[in(sky)]skies`, `[in(knife)]knives`, `[in(man)]men`, `[in(child)]children` + +Certain collective nouns, like `people`, can also be assigned a singular spelling `[in(person)]people`. This should be rarely done as it can lead to translation ambiguities. + +#### Agent Nouns + +Agent nouns are nouns constructed from words (in this case specifically, verbs) denoting actions. Examples are `runner`, `builder`, `carrier`. *Worlds*' language generator can identify the verb part of agent nouns if properly annotated. In this way, the language builder can make both the verb and the noun derived from it share a root on generated languages. There are two ways to annotate agent nouns: + - Regular agent nouns (nouns terminating with `er` or `r`) are prefixed within brackets with the annotation `ran` and separate the suffix element with `:`. Examples: + + `[ran]breath:er`, `[ran]throw:er`, `[ran]burn:er`, `[ran]dance:r`, `[ran]swim:mer`, `[ran]cut:ter` + + - Irregular agent nouns (slight noun spelling variation) are prefixed within brackets with the annotation 'ian' with the original verb spelling as a parameter. Examples: + + `[ian(carry)]carrier`, `[ian(translate)]translator` + +#### Noun Adjuncts + +Noun Adjuncts are single-word nouns that are associated with other nouns much in the same way as adjectives. These must be annotated with the keyword `nad`. Here are some examples: + + `[nad]ice cap`, `[nad]ice sheet`, `[nad]wood table`, `[nad]stone tower` + +### VERBS + +Though not fully implemented yet, the language generator can produce translations for a limited set of verbal conjugations to construct noun phrases. + +To translate a regular verb, the conjugation must be prefixed with the `rv` annotation and two parameters, the grammatical person, and the grammatical tense. The suffix must be separated of the verb using `:`. Here are some examples: + + `[rv(ts,past)]scare:d`, `[rv(ts,past)]soak:ed` + +To translate a irregular verb, the conjugation must be prefixed with the `iv` annotation and three parameters, the uninflected verb, the grammatical person, and the grammatical tense. Here are some examples: + + `[iv(bear,ts,past)]born`, `[iv(pin,ts,past)]pinned`, `[iv(cut,ts,past)]cut` + +## Notes: +1. There are some cases of regular action nouns or verbs that can't be parsed using the annotations `ran` or `rv`. In those cases it is Ok to use the irregular form annotations `ian` or `iv` respectively. +2. The language generation process is still very limited. Please report any issues to the author (**drtardigrage -at- gmail.com**). Please provide examples of the particular issues found when reporting. diff --git a/Modding Guide/Guides/language_structures_modding_guide.txt b/Modding Guide/Guides/language_structures_modding_guide.txt deleted file mode 100644 index 3e6906ca..00000000 --- a/Modding Guide/Guides/language_structures_modding_guide.txt +++ /dev/null @@ -1,55 +0,0 @@ ----- Language Structures Modding Guide ---- - -Procedurally generated languages in 'Worlds' are built by "translating" English words and sentences defined in mod files like elements.json and region_attributes.json and sometimes within the game itself. In order for this to work, the input strings given in those documents must follow a format that instructs the word parser on how to 'understand' each word or phrase. This document attempts to describe the structure and keywords used to facilitate the parsing process. - --- NOUNS -- - -Nouns are single words that are used to identify people, groups of people, locations or other types of objects within the game. These can be used in singular or plural form and be merged together with other nouns or adjectives. They can be built from verbs or other type of words through processes like verb nominalization. - -In most cases, nouns must be defined in 'plural' form. If done correctly, the parser will be able to recognize the singular part of the word. To do so, the noun definition must separate the plural suffix element, 's' or 'es', using a colon ':' like in the following examples: - - 'stone:s', 'sun:s', 'moon:s', 'bush:es', 'box:es', 'potato:es' - -For irregular nouns, the 'in' annotation, encased within brackets, is prefixed. The annotation must include as a parameter the noun's singular spelling. Here are some examples: - - '[in(foot)]feet', '[in(tooth)]teeth', '[in(sky)]skies', '[in(knife)]knives', '[in(man)]men', '[in(child)]children' - -Certain collective nouns, like 'people', can also be assigned a 'singular' spelling ([in(person)]people). This should be rarely done as it can lead to translation ambiguities. - -- Agent Nouns - - -Agent nouns are nouns constructed from worlds (in this case specifically, verbs) denoting actions. Examples are runner, builder, carrier. Worlds' language generator can identify the verb part of agent nouns if properly annotated. In this way, the language builder can make both the verb and the noun derived from it share a root on generated languages. There are two ways to annotate agent nouns: - - Regular agent nouns (nouns terminating with '*er' or 'r') are prefixed within brackets with the annotation 'ran' and separate the suffix element with ':'. Examples: - - '[ran]breath:er', '[ran]throw:er', '[ran]burn:er', '[ran]dance:r', '[ran]swim:mer, '[ran]cut:ter' - - - Irregular agent nouns (slight noun spelling variation) are prefixed within brackets with the annotation 'ian' with the original verb spelling as a parameter. Examples: - - '[ian(carry)]carrier', '[ian(translate)]translator' - -- Noun Adjuncts - - -Noun Adjuncts are single-word nouns that are associated with other nouns much in the same way as adjectives. These must be annotated with the keyword 'nad'. Here are some examples: - - '[nad]ice cap', '[nad]ice sheet', '[nad]wood table', '[nad]stone tower' - --- VERBS -- - -Though not fully implemented yet, the language generator can produce translations for a limited set of verbal conjugations to construct noun phrases. - -To translate a regular verb, the conjugation must be prefixed with the 'rv' annotation and two parameters, the grammatical person, and the grammatical tense. The suffix must be separated of the verb using ':'. Here are some examples: - - '[rv(ts,past)]scare:d', '[rv(ts,past)]soak:ed' - -To translate a irregular verb, the conjugation must be prefixed with the 'rv' annotation and three parameters, the uninflected verb, the grammatical person, and the grammatical tense. Here are some examples: - - '[iv(bear,ts,past)]born', '[iv(pin,ts,past)]pinned', '[iv(cut,ts,past)]cut' - --- - -Notes: -1. There are some cases of regular action nouns or verbs that can't be parsed using the annotations 'ran' or 'rv'. In those cases it is OK to use the irregular form annotations 'ian' or 'iv' respectively. - -Important: The language generation process is still very limited. Please report any issues to the author (drtardigrage -at- gmail.com). Please provide examples of the particular issues found when reporting. - --- diff --git a/Modding Guide/Guides/layer_modding_guide.txt b/Modding Guide/Guides/layer_modding_guide.md similarity index 70% rename from Modding Guide/Guides/layer_modding_guide.txt rename to Modding Guide/Guides/layer_modding_guide.md index 1d4ce426..8ef00b22 100644 --- a/Modding Guide/Guides/layer_modding_guide.txt +++ b/Modding Guide/Guides/layer_modding_guide.md @@ -1,9 +1,11 @@ ----- Layer Modding guide ---- +# Layer Modding guide -Layer modding files are located within the 'Layers' folder. To be valid, mod files must have the .json extension and have the following file structure: +Layer scripting mod files are located within the *Layers* folder. To be valid, mod files must have the .json extension and have the following file structure: --- File Structure -- +#### File Structure +Note: *.json* files do not support comments. Remove texts enclosed within double dashes `--` +``` { "layers": [ -- list of layers -- { @@ -32,12 +34,12 @@ Layer modding files are located within the 'Layers' folder. To be valid, mod fil ... -- additional layers -- ] } +``` --- Notes -- +## Notes 1. Remove any trailing commas or the file won't be parsed -2. Optional 'min' attribute values (altitude/rainfall/temperature) not defined will be assigned the minimum attribute value of its category -3. Optional 'max' attribute values (altitude/rainfall/temperature) not defined will be assigned the maximum attribute value of its category -4. Saturation represents how close is particular biome from filling a particular cell and it helps calculate the relative strength of a particular biome in regards to others within a single cell. The saturation slope indicates how quickly a particular biome reaches it's saturation point within a cell. A saturation slope of 0 indicates that the biome never increases it's saturation level above 0. A slope of 1 indicates that the biome reaches it's maximum saturation at the exact midpoint between the minimum and maximum values of a particular property. A slope greater than 1 indicates the biome reaches it's maximum saturation faster. A slope less than 1 indicates the biome won't reach it's saturation point. When undefined, the default saturation slope is 1 +2. Optional `min` or `max` attribute values (`altitude`, `rainfall`, `temperature`) not defined will be assigned the minimum or maximum attribute value of its category, respectively +3. *Saturation* represents how close is particular biome from filling a particular cell and it helps calculate the relative strength of a particular biome in regards to others within a single cell. The saturation slope indicates how quickly a particular biome reaches its saturation point within a cell. A saturation slope of `0` indicates that the biome never increases its saturation level above 0. A slope of `1` indicates that the biome reaches its maximum saturation at the exact midpoint between the minimum and maximum values of a particular property. A slope greater than `1` indicates the biome reaches its maximum saturation faster. A slope less than `1` indicates the biome won't reach its saturation point. When undefined, the default saturation slope is `1` -- diff --git a/Modding Guide/Guides/options_modding_guide.txt b/Modding Guide/Guides/options_modding_guide.md similarity index 96% rename from Modding Guide/Guides/options_modding_guide.txt rename to Modding Guide/Guides/options_modding_guide.md index f2ef29c7..36d8417d 100644 --- a/Modding Guide/Guides/options_modding_guide.txt +++ b/Modding Guide/Guides/options_modding_guide.md @@ -1,10 +1,11 @@ ----- Options Modding Guide ---- +# Options Modding Guide Options are JSON sub-objects that are added to decisions or other mod objects that can generate buttons to display within a dialog. They have the following structure: --- Object Structure -- +### Object Structure +``` { "id": -- (required) Unique option identifier. Each option must have a unique id within the list of options @@ -18,7 +19,7 @@ can generate buttons to display within a dialog. They have the following structu on how to define valid properties. "text": -- (required) Text to generate when this option - object is evaluated. See string_values_guide.txt + object is evaluated. See string_values_guide.md to find more about how to define valid dynamic text values. @@ -39,11 +40,12 @@ can generate buttons to display within a dialog. They have the following structu "effects": -- (required) List of EFFECTS that will trigger when this option is selected either by a human - player or the AI. Please read effects_guide.txt + player or the AI. Please read effects_guide.md for more details on how to define valid effects. } +``` --- Notes -- +## Notes 1. List of values must be enclosed within square brackets and separated by commas. Remove any trailing commas on any list enclosed by square brackets, or you'll get a JSON parsing error. diff --git a/Modding Guide/Guides/phrase_association_guide.md b/Modding Guide/Guides/phrase_association_guide.md new file mode 100644 index 00000000..62226426 --- /dev/null +++ b/Modding Guide/Guides/phrase_association_guide.md @@ -0,0 +1,32 @@ +# Phrase Association Guide + +Phrase associations are used along with the element and one or more adjectives to build translatable composite words or noun phrases. + +An association can be used to form a noun phrase. I which case it must be defined as follows: `,,
` + + Here's a description of each part: + + - ``: an action noun or attributive verb. Refer to language_modding_guide.md for more details on how to define translatable nouns and verbs + - ``: one or more prepositions (separated by pipes `|`) that can be used to link the association word with the element + - ``: one or more grammatical forms (separated by pipes `|`) the element can take as part of the noun phrase. They can be one of the following: + - `ns`: proper name singular. Examples: "The Stone", "Mount" + - `ds`: definite singular. Examples: "the mount", "stone" + - `is`: indefinite singular. Examples: "a stone", "an arch" + - `dp`: definite plural. Examples: "the stones", "mounts" + - `ip`: indefinite plural. Examples: "stones", "archs" + - `u`: uncountable. Examples: "water, "air" + +Example association strings that can be used to form noun phrases: + + - `[nrv]throw:er,of,ip|ns` (Examples: "thrower of the stone", "thrower of boulders", or "rockthrower") + - `[iv(bear,ts,past)]born,between,ip` (Examples: "born between trees" or "waterborn") + - `[nrv]break:er,of,ip|ns` (Examples: "breaker of chains", "Breaker of The Stone Wall" or "wallbreaker") + - `[iv(bear,ts,past)]born,under,ns` (Examples: "born under the sky", "born under clouds" or "starborn") + - `[nrv]cut:ter,of,u` (Examples: "cutter of grass" or "woodcutter") + +Associations can also be used exclusively to form composite words. In such cases, only the `` part is needs to be defined. + +Example association strings that can be used to only form composite words: + + - `[ran]work:er` (Examples: "stoneworker", "woodworker") + - `[ran]dance:r` (Examples: "skydancer", "raindancer") diff --git a/Modding Guide/Guides/phrase_association_guide.txt b/Modding Guide/Guides/phrase_association_guide.txt deleted file mode 100644 index a1479d33..00000000 --- a/Modding Guide/Guides/phrase_association_guide.txt +++ /dev/null @@ -1,33 +0,0 @@ ----- Phrase Association Guide ---- - -Phrase associations are used along with the element and one or more adjectives to build translatable composite words or noun phrases. - --- An association can be used to form a noun phrase. I which case it must be defined as follows: ',,' - - Here's a description of each part: - - : an action noun or attributive verb. Refer to language_modding_guide.txt for more details on how to define translatable nouns and verbs - - : one or more prepositions (separated by pipes, '|') that can be used to link the association word with the element - - : one or more grammatical forms (separated by pipes, '|') the element can take as part of the noun phrase. They can be one of the following: - -- 'ns': proper name singular. Examples: "The Stone", "Mount" - -- 'ds': definite singular. Examples: "the mount", "stone" - -- 'is': indefinite singular. Examples: "a stone", "an arch" - -- 'dp': definite plural. Examples: "the stones", "mounts" - -- 'ip': indefinite plural. Examples: "stones", "archs" - -- 'u': uncountable. Examples: "water", "air" - - Example association strings that can be used to form noun phrases: - - '[nrv]throw:er,of,ip|ns' (Examples: "thrower of the stone", "thrower of boulders", or "rockthrower") - '[iv(bear,ts,past)]born,between,ip' (Examples: "born between trees" or "waterborn") - '[nrv]break:er,of,ip|ns' (Examples: "breaker of chains", "Breaker of The Stone Wall" or "wallbreaker") - '[iv(bear,ts,past)]born,under,ns' (Examples: "born under the sky", "born under clouds" or "starborn") - '[nrv]cut:ter,of,u' (Examples: "cutter of grass" or "woodcutter") - --- Associations can also be used exclusively to form composite words. In such cases, only the '' part is needs to be defined. - - Example association strings that can be used to only form composite words: - - '[ran]work:er' (Examples: "stoneworker", "woodworker") - '[ran]dance:r' (Examples: "skydancer", "raindancer") - --- diff --git a/Modding Guide/Guides/properties_guide.md b/Modding Guide/Guides/properties_guide.md index de339a1c..8904e120 100644 --- a/Modding Guide/Guides/properties_guide.md +++ b/Modding Guide/Guides/properties_guide.md @@ -34,7 +34,7 @@ A property's value can be accesses by its id. For example, a property with id `" and value `"2 + 3"` can be used within an expression like this `"two_plus_three + 4"` which evaluates to **9**. A property value can also be accessed by it's attribute `"value"` like in this example expression `"1 + two_plus_three.value"` which evaluates to **6**. -See *expressions_guide.txt* for more details on how to define expressions. +See *expressions_guide.md* for more details on how to define expressions. A property can reference properties that were defined previously within that same context like in the following example: @@ -49,4 +49,4 @@ to itself in the previous example. 1. Remove any trailing commas or the file won't be parsed 2. A value expression is any expression that returns a value like a **boolean**, **numeric**, **entity**, or **string** expression. But not an **effect** expression. Refer to - *expressions_guide.txt* for more details + *expressions_guide.md* for more details diff --git a/Modding Guide/Guides/region_attribute_modding_guide.txt b/Modding Guide/Guides/region_attribute_modding_guide.md similarity index 58% rename from Modding Guide/Guides/region_attribute_modding_guide.txt rename to Modding Guide/Guides/region_attribute_modding_guide.md index 20db6b91..229a5dd0 100644 --- a/Modding Guide/Guides/region_attribute_modding_guide.txt +++ b/Modding Guide/Guides/region_attribute_modding_guide.md @@ -1,9 +1,10 @@ -----Region Attribute Modding Guide ---- +# Region Attribute Modding Guide -Region attribute modding files are located within the 'RegionAttributes' folder. To be valid, mod files must have the .json extension and have the following file structure: structure: +Region attribute mod script files are located within the *RegionAttributes* folder. To be valid, mod files must have the **.json** extension and have the following file structure: --- File Structure -- +### File Structure +``` { "region_attributes": [ -- list of attributes -- { @@ -18,22 +19,22 @@ Region attribute modding files are located within the 'RegionAttributes' folder. ... -- additional attributes -- ] } +``` --- Notes -- +## Notes 1. Remove any trailing commas or the file won't be parsed 2. At least one variant must be present for each attribute: - Variant nouns are defined as follow: ({():})(:({...}))... - Parts enclosed within parenthesis denote optional definition elements. Parts enclosed within brackets indicate that the variant should be decomposed into two variants, one of which omits the enclosed part. The "" keyword (enclosed in '<' and '>') is used to denote parts that should be filtered when constructing specific types of phrases (mostly used to filter plural nouns). + Variant nouns are defined as follow: `({():})(:({...}))...` + Parts enclosed within parenthesis denote optional definition elements. Parts enclosed within brackets indicate that the variant should be decomposed into two variants, one of which omits the enclosed part. The `` keyword (enclosed in `<` and `>`) is used to denote parts that should be filtered when constructing specific types of phrases (mostly used to filter plural nouns). Here are some variant examples: - "glacier{:s}" - which decomposes into variants "glacier" and "glacier:s" - "shrub:land{:s}" - which decomposes into variants "shrub:land" and "shrub:land:s" - "grass:land{:s}" - which decomposes into variants "grass:land" and "grass:land:s" - "forest{:s}" - which decomposes into variants "forest" and "forest:s" - "waste{:land}{:s}" - which decomposes into variants "waste", "waste:s", "waste:land", and "waste:land:s" - Refer to language_modding_guide.txt for more details on how to define translatable nouns. + - `"glacier{:s}"` which decomposes into variants `"glacier"` and `"glacier:s"` + - `"shrub:land{:s}"` which decomposes into variants `"shrub:land"` and `"shrub:land:s"` + - `"grass:land{:s}"` which decomposes into variants `"grass:land"` and `"grass:land:s"` + - `"forest{:s}"` which decomposes into variants `"forest"` and `"forest:s"` + - `"waste{:land}{:s}"` which decomposes into variants `"waste"`, `"waste:s"`, `"waste:land"`, and `"waste:land:s"` -3. Each region constraint is used to decide whether or not to associate the element with a particular region. If any of the constraints fails then the attribute won't be associated with the region. Refer to region_constraints_guide.txt for more details on how to define and use region constraints -4. Each phrase association is used to form nouns or noun phrases for procedurally generated proper names and other types of texts. Refer to phrase_association_guide.txt for more details on how to define phrase associations + Refer to language_modding_guide.md for more details on how to define translatable nouns. --- +3. Each region constraint is used to decide whether or not to associate the element with a particular region. If any of the constraints fails then the attribute won't be associated with the region. Refer to *region_constraints_guide.md* for more details on how to define and use region constraints +4. Each phrase association is used to form nouns or noun phrases for procedurally generated proper names and other types of texts. Refer to *phrase_association_guide.md* for more details on how to define phrase associations diff --git a/Modding Guide/Guides/region_constraints_guide.txt b/Modding Guide/Guides/region_constraints_guide.md similarity index 60% rename from Modding Guide/Guides/region_constraints_guide.txt rename to Modding Guide/Guides/region_constraints_guide.md index 145a169d..afc3f767 100644 --- a/Modding Guide/Guides/region_constraints_guide.txt +++ b/Modding Guide/Guides/region_constraints_guide.md @@ -1,68 +1,66 @@ ----- Region Constraints Guide ---- +# Region Constraints Guide Region Constraints are rules that are used by region attributes and elements to decide whether or not to be assigned or associated with a particular region. When a new region is created, every attribute and every element tests their constraints against the region. If any of the constraints assigned to the element or attribute fail, then the element or attribute is ignored. Here's a list of the current types of region constraints (more to be added in future versions) and how they work: -- 'coast_percentage_above' - Tests if the amount of 'sea' cells surrounding a particular region is above (or equal) a certain percentage (expressed as a number between 0.0 and 1.0 inclusive). Example: 'coast_percentage_above:0.65' +- `coast_percentage_above` + Tests if the amount of *sea* cells surrounding a particular region is above (or equal) a certain percentage (expressed as a number between 0.0 and 1.0 inclusive). Example: `coast_percentage_above:0.65` -- 'coast_percentage_below' - Tests if the amount of 'sea' cells surrounding a particular region is below a certain percentage (expressed as a number between 0.0 and 1.0 inclusive). Example: 'coast_percentage_below:1.0' +- `coast_percentage_below` + Tests if the amount of *sea* cells surrounding a particular region is below a certain percentage (expressed as a number between 0.0 and 1.0 inclusive). Example: `coast_percentage_below:1.0` -- 'altitude_above' - Tests if the average altitude of a region is above (or equal) a certain altitude (expressed in meters). Example: 'altitude_above:0' +- `altitude_above` + Tests if the average altitude of a region is above (or equal) a certain altitude (expressed in meters). Example: `altitude_above:0` -- 'altitude_below' - Tests if the average altitude of a region is below a certain altitude (expressed in meters). Example: 'altitude_below:1000' +- `altitude_below` + Tests if the average altitude of a region is below a certain altitude (expressed in meters). Example: `altitude_below:1000` -- 'relative_altitude_above' - Tests if the average altitude of a region is above (or equal) a certain altitude relative the surrounding borders (expressed in meters). Example: 'relative_altitude_above:200' +- `relative_altitude_above` + Tests if the average altitude of a region is above (or equal) a certain altitude relative the surrounding borders (expressed in meters). Example: `relative_altitude_above:200` -- 'relative_altitude_below' - Tests if the average altitude of a region is below a certain altitude relative the surrounding borders (expressed in meters). Example: 'relative_altitude_below:-200' +- `relative_altitude_below` + Tests if the average altitude of a region is below a certain altitude relative the surrounding borders (expressed in meters). Example: `relative_altitude_below:-200` -- 'rainfall_above' - Tests if the average yearly rainfall of a region is above (or equal) a certain value (expressed in millimeters per year). Example: 'rainfall_above:675' +- `rainfall_above` + Tests if the average yearly rainfall of a region is above (or equal) a certain value (expressed in millimeters per year). Example: `rainfall_above:675` -- 'rainfall_below' - Tests if the average yearly rainfall of a region is below a certain value (expressed in millimeters per year). Example: 'rainfall_below:1775' +- `rainfall_below` + Tests if the average yearly rainfall of a region is below a certain value (expressed in millimeters per year). Example: `rainfall_below:1775` -- 'temperature_above' - Tests if the average temperature of a region is above (or equal) a certain value (expressed in centigrade). Example: 'temperature_above:-15' +- `temperature_above` + Tests if the average temperature of a region is above (or equal) a certain value (expressed in centigrade). Example: `temperature_above:-15` -- 'temperature_below' - Tests if the average temperature of a region is below a certain value (expressed in centigrade). Example: 'temperature_below:10' +- `temperature_below` + Tests if the average temperature of a region is below a certain value (expressed in centigrade). Example: `temperature_below:10` -- 'flowing_water_above' - Tests is the average amount of flowing water within a region is above a certain value (expressed as a number between 0.0 and 100000000.0 inclusive). Example: 'flowing_water_above:100.0' +- `flowing_water_above` + Tests is the average amount of flowing water within a region is above a certain value (expressed as a number between 0.0 and 100000000.0 inclusive). Example: `flowing_water_above:100.0` -- 'flowing_water_below' - Tests is the average amount of flowing water within a region is below a certain value (expressed as a number between 0.0 and 100000000.0 inclusive). Example: 'flowing_water_below:10000.0' +- `flowing_water_below` + Tests is the average amount of flowing water within a region is below a certain value (expressed as a number between 0.0 and 100000000.0 inclusive). Example: `flowing_water_below:10000.0` -- 'biome_presence_above' - Tests if the number of cells within a region that have a particular biome is above (or equal) a certain percentage (expressed as comma separated pair of a biome identifier (id) and a number between 0.0 and 1.0 inclusive). Example: 'biome_presence_above:ice_sheet,0.65' +- `biome_presence_above` + Tests if the number of cells within a region that have a particular biome is above (or equal) a certain percentage (expressed as comma separated pair of a biome identifier (id) and a number between 0.0 and 1.0 inclusive). Example: `biome_presence_above:ice_sheet,0.65` -- 'biome_presence_below' - Tests if the number of cells within a region that have a particular biome is below a certain percentage (expressed as comma separated pair of a biome identifier (id) and a number between 0.0 and 1.0 inclusive). Example: 'biome_presence_below:desert,0.50' +- `biome_presence_below` + Tests if the number of cells within a region that have a particular biome is below a certain percentage (expressed as comma separated pair of a biome identifier (id) and a number between 0.0 and 1.0 inclusive). Example: `biome_presence_below:desert,0.50` -- 'layer_value_above' - Tests if the number of cells within a region that have a particular layer is above (or equal) a certain value (expressed as comma separated pair of a layer identifier (id) and a number between 0.0 and 1000000.0 inclusive). Example: 'layer_value_above:,20.0' +- `layer_value_above` + Tests if the number of cells within a region that have a particular layer is above (or equal) a certain value (expressed as comma separated pair of a layer identifier (id) and a number between 0.0 and 1000000.0 inclusive). Example: `layer_value_above:,20.0` -- 'layer_value_below' - Tests if the number of cells within a region that have a particular layer is below a certain value (expressed as comma separated pair of a biome layer (id) and a number between 0.0 and 1000000.0 inclusive). Example: 'layer_value_below:,100.0' +- `layer_value_below` + Tests if the number of cells within a region that have a particular layer is below a certain value (expressed as comma separated pair of a biome layer (id) and a number between 0.0 and 1000000.0 inclusive). Example: `layer_value_below:,100.0` -- 'main_biome' - Tests if any of the biomes within the given list is the biome with the most presence within the region (expressed as comma separated list of biome ids). Example: 'main_biome:forest,taiga,tundra,rainforest' +- `main_biome` + Tests if any of the biomes within the given list is the biome with the most presence within the region (expressed as comma separated list of biome ids). Example: `main_biome:forest,taiga,tundra,rainforest` -- 'any_attribute' - Tests if any attribute within the given list is assigned to the region (expressed as comma separated list of strings). Example: 'any_attribute:desert,delta,peninsula,island,coast' +- `any_attribute` + Tests if any attribute within the given list is assigned to the region (expressed as comma separated list of strings). Example: `any_attribute:desert,delta,peninsula,island,coast` -- 'no_attribute' - Tests if no attribute within the given list is assigned to the region (expressed as comma separated list of strings). Example: 'no_attribute:rainforest,jungle,taiga,forest' +- `no_attribute` + Tests if no attribute within the given list is assigned to the region (expressed as comma separated list of strings). Example: `no_attribute:rainforest,jungle,taiga,forest` -- 'zero_primary_attributes' - Tests if no attribute has been assigned to the region. Example: 'zero_primary_attributes' +- `zero_primary_attributes` + Tests if no attribute has been assigned to the region. Example: `zero_primary_attributes` NOTE: This constraint should only be used with secondary attributes - - -- diff --git a/Modding Guide/Guides/string_values_guide.md b/Modding Guide/Guides/string_values_guide.md new file mode 100644 index 00000000..73aef5ab --- /dev/null +++ b/Modding Guide/Guides/string_values_guide.md @@ -0,0 +1,32 @@ +# String Values Guide + +String Values and Expressions have some properties that make them different from +other value types (numerics, booleans). + +There are two types of string values, *identifier strings*, and *text strings*. + +*Identifier strings* are strings that are composed by a single word with no spaces +or special characters within other than dash `-` or underscore `_`. These are mostly +used as inputs or parameters and do not need to be enclosed within quotes themselves +when used as part of an expression. + +Example: `"target.type == clan"`, Here, `target.type` is an entity attribute that returns +an identifier string. `clan` is the identifier string the attribute is being compared +against. + +*Text strings* are strings that can be composed of multiple words and can include special +characters. Text strings can only be assigned to the `text` attributes of certain +JSON definitions, like decision descriptions and effects. Text strings must be +enclosed within double single quotes `''` themselves to be recognized as such when used as elements within larger expressions. + +Text strings can contain embedded sub-expressions whose values get resolved when the +text is used within the game. Embedded expressions must be enclosed within `<<` and `>>` +for the game to be able to recognize them within a string value. + +Example: +`"text": "A new clan splits from clan <> taking from <> to <> of its influence from it"`. +In this example of a decision's effect text, `target` resolves to the name of the +decision's target clan. `percent(min_inf_percent_to_transfer)` is a function that +returns the value of `min_inf_percent_to_transfer` formatted as a percentage string. +Likewise, `percent(max_inf_percent_to_transfer)` returns `max_inf_percent_to_transfer` +formatted as a percentage string. diff --git a/Modding Guide/Guides/string_values_guide.txt b/Modding Guide/Guides/string_values_guide.txt deleted file mode 100644 index abad8802..00000000 --- a/Modding Guide/Guides/string_values_guide.txt +++ /dev/null @@ -1,33 +0,0 @@ ----- String Values Guide ---- - -String Values and Expressions have some properties that make them different from -other value types (numerics, booleans). - -There are two types of string values, identifier strings, and text strings. - -IDENTIFIER STRINGS are strings that are composed by a single word with no spaces -or special characters within other than dash '-' or underscore '_'. These are mostly -used as inputs or parameters and do not need to be enclosed within quotes themselves -when used as part of an expression. - -Example: "target.type == clan", Here, 'target.type' is an entity attribute that returns -an identifier string. 'clan' is the identifier string the attribute is being compared -against. - -TEXT STRINGS are strings that can be composed of multiple words and can include special -characters. Text strings can only be assigned to the 'text' attributes of certain -JSON definitions, like decision descriptions and effects. Text strings must be -enclosed within double quotes '"' themselves to be recognized as such. - -Text strings can contain embedded sub-expressions whose values get resolved when the -text is used within the game. Embedded expressions must be enclosed within '<<' and '>>' -for the game to be able to recognize them within a string value. - -Example: -"text": "A new clan splits from clan <> taking from <> -to <> of its influence from it". -In this example of a decision's effect text, 'target' resolves to the name of the -decision's target clan. 'percent(min_inf_percent_to_transfer)' is a function that -returns the value of 'min_inf_percent_to_transfer' formatted as a percentage string. -Likewise, 'percent(max_inf_percent_to_transfer)' returns 'max_inf_percent_to_transfer' -formatted as a percentage string. diff --git a/Modding Guide/modding_guide.md b/Modding Guide/modding_guide.md index 775512da..5c6bd75f 100644 --- a/Modding Guide/modding_guide.md +++ b/Modding Guide/modding_guide.md @@ -27,39 +27,39 @@ Here's a quick preview of each supported mod component: ### Adjective Mods -Adjective definitions are used to define the possible adjectives used in language generation. You can find more information on how to write an adjective mod within the *adjective_modding_guide.txt* file located in the *Guides* folder. +Adjective definitions are used to define the possible adjectives used in language generation. You can find more information on how to write an adjective mod within the *adjective_modding_guide.md* file located in the *Guides* folder. ### Biome Mods -Biome definitions are used to define the biomes assigned to each cell on a newly generated planet. You can find more information on how to write a biome mod within the *biome_modding_guide.txt* file located in the *Guides* folder. +Biome definitions are used to define the biomes assigned to each cell on a newly generated planet. You can find more information on how to write a biome mod within the *biome_modding_guide.md* file located in the *Guides* folder. ### Action Mods -Action definitions are used to define the possible action that player led factions can use during a game. You can find more information on how to write a discovery mod within the *action_modding_guide.txt* file located in the *Guides* folder. +Action definitions are used to define the possible action that player led factions can use during a game. You can find more information on how to write a discovery mod within the *action_modding_guide.md* file located in the *Guides* folder. ### Decision Mods -Decision definitions are used to define the possible decisions that player and non-player led factions can be confronted with during a game. You can find more information on how to write a discovery mod within the *decision_modding_guide.txt* file located in the *Guides* folder. +Decision definitions are used to define the possible decisions that player and non-player led factions can be confronted with during a game. You can find more information on how to write a discovery mod within the *decision_modding_guide.md* file located in the *Guides* folder. ### Discovery Mods -Discovery definitions are used to define the possible discoveries that can be made by humans across a world's history. You can find more information on how to write a discovery mod within the *discovery_modding_guide.txt* file located in the *Guides* folder. +Discovery definitions are used to define the possible discoveries that can be made by humans across a world's history. You can find more information on how to write a discovery mod within the *discovery_modding_guide.md* file located in the *Guides* folder. ### Element Mods -Element definitions are used to define the types of associations between elements and regions. You can find more information on how to write a element mod within the *element_modding_guide.txt* file located in the *Guides* folder. +Element definitions are used to define the types of associations between elements and regions. You can find more information on how to write a element mod within the *element_modding_guide.md* file located in the *Guides* folder. ### Event Mods -Event definitions are used to define group and faction events that can occur during the game. You can find more information on how to write a element mod within the *element_modding_guide.txt* file located in the *Guides* folder. +Event definitions are used to define group and faction events that can occur during the game. You can find more information on how to write a element mod within the *element_modding_guide.md* file located in the *Guides* folder. ### Layer Mods -Layer definitions are used to define the layers assigned to each cell on a newly generated planet. You can find more information on how to write a layer mod within the *layer_modding_guide.txt* file located in the *Guides* folder. +Layer definitions are used to define the layers assigned to each cell on a newly generated planet. You can find more information on how to write a layer mod within the *layer_modding_guide.md* file located in the *Guides* folder. ### Region Attribute Mods -Region Attribute definitions are used to define the attributes of a region. You can find more information on how to write a region attribute mod within the *region_attribute_modding_guide.txt* file located in the *Guides* folder. +Region Attribute definitions are used to define the attributes of a region. You can find more information on how to write a region attribute mod within the *region_attribute_modding_guide.md* file located in the *Guides* folder. ### Cultural Preference Mods