FANDOM


Effects and triggers can make use of variables (called Arguments) to enhance their complexity.

The Values contained within a decision's triggers or effects can contain variables (called Arguments) that resolve into a numerical value when the decision is fired.

The Effects can filter out certain regions/leaders/theaters/decisions depending on certain customizable conditions.

Value Arguments

Value arguments are the advanced mode of decision modding. These arguments allow full access to set up custom effect values and the ability to filter where such effects are applied.

  • An Effect's or Trigger's Value can be a mathematical expression that evaluates to a number
  • Such mathematical expressions can have Arguments: they are a set of named variables that represent a certain quantity
  • All arguments present in a given Value's expression have to be defined in the same enclosing Effect's block
  • The definitions are enclosed in a list called ValueArguments

An Argument is defined as follows:

Property Values Description
Name Any string The name represents how the Argument is identified
Type Mutually exclusive with TriggerType. Any of the following:
  • Interest
  • DoomsdayClock
  • Timeline
  • UnitsInCommandReserve
  • RepeatedTimes
  • RelativeInfluenceInRegion
  • FlagValue
  • VictoryPoints
  • NuclearTechnology
  • SpaceRace
  • LeaderPower
  • InfluenceInTheaterPercentage
  • CharacPower
The Type represents what the Argument equates to. If it's DoomsdayClock, then it's equal to whatever the doomsday clock value is, etc.
InterestType Any kind of InterestType if Type is Interest
RegionId A region number if Type is AbsoluteInfluenceInRegion
DecisionId A decision ID number if Type is RepeatedTimes
LeaderId A leader ID if Type is LeaderPower
Theater A theater if Type is InfluenceInTheaterPercentage
Target Any of the following:
  • Player
  • Opponent
  • USA
  • USSR
  • ALL

Used when the Type relates to something player-related, e.g. Interest or UnitsInCommandReserve

TriggerType Any kind of TriggerType. Mutually exclusive with Type. Used for Filters (see below)
NOT If true, the argument evaluates to true if its condition is false. Used for TriggerTypes
Value A number. Used for TriggerTypes
StrValue A string. Used for FlagValue

Effect Examples

  • An Effect where the Player is granted Victory Points for the Value that is equal to twice the Doomsday Clock
"Effects": [
 {
   "Type": "ChangeVictoryPoint",
   "Target": "Player",
   "Value": "2 * EXAMPLENAME",
   "ValueArguments":
   [
     {
       "Name": "EXAMPLENAME",
       "Type": "DoomsdayClock"
     }
   ]
 }
]
  • A trigger where the value is the minimum between the Doomsday Clock, the Player's People interest and 5
{
  "ID": 8000,
  "Name": "...",
  ...,
  "TriggersAll":
  [
    {
      "Type": "RegionPolNumber",
      "Target": "Player",
      "Value": "min(EXAMPLENAME1, EXAMPLENAME2, 5)",
      "ValueArguments":
      [
        {
          "Name": "EXAMPLENAME1",
          "Type": "DoomsdayClock"
        },
        {
          "Name": "EXAMPLENAME2",
          "Type": "Interest",
          "InterestType": "People"
        }
      ]
    }
  ]
}

Math functions

  • Much of this system's power lies on the myriad of mathematical functions that can be used to one's heart's content, such as min(x, y) used in the example above
  • The system makes use of the excellent library mXparser, therefore all functions provided there work here with the same syntax;
  • There are other functions purposedly built for the game thus not present in the library documentation:
    • RandomInt(X, Y) provides a random integer between X and Y. Don't use it for Triggers (they wouldn't make sense)

Effect Filters

  • An Effect may make use of lists such as RegionAll, LeadersAll etc.
  • With Filters, there is a way to filter in only the elements that fulfill certain conditions, e.g. only the regions in RegionAll that aren't a warzone
  • For this to happen, an Effect must include a "Filter" attribute which, similarly to "Value", accepts a mathematical expression
  • Contrary to Value, whose mathematical expression evaluates to a number, the Filter ultimately evaluates to either True or False, therefore it is a logical expression (e.g. "2 < 3 AND 1 < 10" is a valid logical expression and it evaluates to True)
  • As a consequence, the Arguments evaluate to True or False, not numbers
  • The filter expression is checked against every element of whichever list is used in the Effect: RegionAll, LeadersAll, etc.: the elements that pass the "test" stay, while the others are discarded
  • Similarly to ValueArguments, the Filter arguments are defined in a list called "FilterArguments"
  • These arguments make use of TriggerTypes that normally make use of RegionAll, LeadersAll etc., such as LandBasedUnitInRegion, RegionController etc.; it's similar to defining a trigger, where the list is not declared because it uses the Effect's list to check the trigger type and values against
  • Just as mathematical expressions can be combined into more complex expressions by operators such as "+", "*" etc., logical expressions (e.g. "2 < 3", i.e. "True") can be combined by logical operators such as "NOT", "AND", "OR". For example, "(2 < 3) AND NOT (1 > 2 OR 4 >= 3)" evaluates to "(True) AND NOT (False OR True)" => (True) "AND NOT (True)" => "(True) AND (False)" => "False"

Effect Filter Examples

  • An effect that applies the same amount of influence as Doomsday Clock value to regions 1,2,3 that aren't occupied by land based units (Army, Fighter or Bomber Command) and are in player's control
"Effects": [
 {
   "Type": "ChangeInfluenceToRegion",
   "Target": "Player",
   "Value": "EXAMPLE",
   "ValueArguments":
   [
     {
        "Name": "EXAMPLE",
        "Type": "DoomsdayClock"
     }
   ],
   "RegionAll": [1, 2, 3],
   "Filter": "NOT Occupied AND InControl",
   "FilterArguments":
   [
     {
       "Name": "Occupied",
       "TriggerType": "LandBasedUnitInRegion",
       "Target": "Player"
     },
     {
       "Name": "InControl",
       "TriggerType": "RegionPolNumber",
       "Target": "Player",
       "Value": 3
     }
  ]
 }
]

Effect filters by related values

The Theory
Premise
  • A filter "F" operates on a list "L" with elements "A", "B", "C"... by applying a "test" function "T" to each of its elements. Such function returns either true or false: T[A] = true, T[B] = false...;
  • The filter then returns a list purged of its elements that answered "false" to the test function: F[L] = Q, with Q being a subset of L;
  • The test function operates on L's elements, but it might be necessary to operate on elements that are in relationship with them, i.e. we do not want to test on A, B, C... but on values A', B', C'... manipulated by a function;
  • By calling such a function "FV" such that FV[A] = A', the filter would then test A', B', C'... and not A, B, C: T[FV[A]] = T[A'] etc.;
  • The test is performed on A', and if T[A'] succeeds, then A, and not A', is added to the filtered list Q (otherwise L might as well have been A', B', C'... and not A, B, C, ...).
Implementation
  • The function "FV" is called "FilterValue" and it is a mathematical expression with a single argument, which must be called "X".
The Practice
  • One instance where this transformation is needed is where decision IDs have to be translated into region IDs for filtering purposes;
  • The decision ID regime allows for 100 decisions per region: <region><ID> like 8000, 8001 being decisions #00 and #01 somehow tied to region 80;
  • We might want a decision that affects certain region-based decisions' chance, but we can't do that with regular filters. An incorrect effect is as follows:
"Effects":
[
    {
        "Type": "ChangeChance",
        "DecisionIDValues": [ 8059, 8060, 8151, 8253 ],
        "Value": 20,
        "Filter": "Presence",
        "FilterArguments":
        [
            {
                "Name": "Presence",
                "TriggerType": "RegionPOLNumber",
                "Target": "USSR",
                "Value": 1
            }
        ]
    }
]
  • The idea is that, if the USSR has at least 1 influence in regions #80 and #82, then only decisions #8059, #8060 and #8253 will be affected. But that won't happen as the filter will test L = { 8059, 8060, 8151, 8253 } -> T[8059] = ?, T[8060], = ? ..., obviously complaining about such regions not existing;
  • Therefore we need another function that manipulates DecisionIDValues's elements before feeding them to the filter;
  • Such a function needs to transform 8059 into 80, 8060 into 80, 8151 into 81 and 8253 into 82;
  • A simple function such as X / 100 will do, so instead of testing 8059 the filter will test 80 and so on;
  • Such a function needs to be defined in "FilterValue", a function with a single argument which must be called "X", such as in the following snippet illustrating an effect that filters custom values:
"Effects":
[
    {
        "Type": "ChangeChance",
        "DecisionIDValues": [ 8059, 8060, 8151, 8253 ],
        "Value": 20,
        "Filter": "Presence",
        "FilterValue": "X / 100",
        "FilterArguments":
        [
            {
                "Name": "Presence",
                "TriggerType": "RegionPOLNumber",
                "Target": "USSR",
                "Value": 1
            }
        ]
    }
]

Logical operators

  • Predicates can be combined with the usage of logical operators such as NOT(p), AND(p, q), and so on;
  • The system makes use of the excellent library mXparser, therefore all functions provided there work here with the same syntax;
  • Documentation on the available logical operators can be found here, where "&&", "||" and "~" may also be written as "AND", "OR" and "NOT" respectively.
Community content is available under CC-BY-SA unless otherwise noted.