Dynamic Policy Effects

LeeS

Imperator
Joined
Jul 23, 2013
Messages
7,241
Location
Illinois, USA
Dynamic Policy Effects


I've redrafted this quite a bit and am now referring to it as "Dynamic Policy Effects", and it is now a true utility in the sense that it allows a fairly easy method to create a dynamic effect system for any sort of policy effect. I have included within the mod the ability to dynamically specify within an lua function how much of any of the following to add to a player's empire:
  1. Integer Happiness
  2. Integer UnHappiness
  3. Percentage Unhappiness Increase
  4. Percentage Unhappiness Decrease
  5. Percentage Empire Science Yield Increase
  6. Percentage Empire Production Yield Increase
  7. Percentage Empire Gold Yield Increase
  8. Percentage Empire Food Yield Increase
The methods I am using make it relatively pain-free to add a new effect to the list. The current list of effects should be viewed as being templates for how to impliment in this system a new dynamic effect.

How The System Works:
  1. The system uses the same basic method as the Dynamic Tourism System that allows buildings to add any dynamically specified amount of Tourism to be added to a city.
    • This basic method is a 'data-bits' system, where turning on and off individual bits in specific combinations results in specific numeric results.
    • This approach is extremely useful where there can never be more than one copy of one individual item active at any one time, as is the case with policies.
    • The solution is not to 'stack' multiple copies of the same policy, but rather to add individual policies each of which has its own unique additive integer value.
  2. Since this system is a 'data-bits' system, policies are grouped where the group is defined by the effect being adjusted.
    • There is no particular 'magic' in the assignments of policies to a 'group'. It is more about use of a systematic naming convention for all the policies added to the game using this system.
    • For the Integer Happiness group, I simply assigned all policies to be used for that effect with XML names such as POLICY_HAPPY_INT_001, POLICY_HAPPY_INT_002, etc., and then assigned to each of these policies the column ExtraHappiness with the appropriate (and matching) numerical value.
  3. For any individual desired effect to be added onto this system, there must be a valid policy for data bit-assignments of [1], [2], [4], [8], [16], [32], [64], [128], [256], [512], and [1024]
    • For the Integer Happiness group, I created these policies with the effect specified using the <Policies> column ExtraHappiness

      Policy Name <Description> Text ExtraHappiness value
      POLICY_HAPPY_INT_001 001 HAPPY_INT 1
      POLICY_HAPPY_INT_002 002 HAPPY_INT 2
      POLICY_HAPPY_INT_004 004 HAPPY_INT 4
      POLICY_HAPPY_INT_008 008 HAPPY_INT 8
      POLICY_HAPPY_INT_016 016 HAPPY_INT 16
      POLICY_HAPPY_INT_032 032 HAPPY_INT 32
      POLICY_HAPPY_INT_064 064 HAPPY_INT 64
      POLICY_HAPPY_INT_128 128 HAPPY_INT 128
      POLICY_HAPPY_INT_256 256 HAPPY_INT 256
      POLICY_HAPPY_INT_512 512 HAPPY_INT 512
      POLICY_HAPPY_INT_1024 1024 HAPPY_INT 1024
    • The requirement for the bit assignments needed means that all of the pre-created 'groups' listed earlier can dynamically add an integer value of between 0 and 1024 of the desired policy effect. So for the Integer Happiness effect, up to 2047 extra Happiness can be added to the player's empire using this system. The Integer Unhappiness group uses the same basic format and the same actual policy column, but with negative values as the integer assignments to the ExtraHappiness column within the table <Policies>.
    • So for the Integer UnHappiness group, I created these policies with the effect specified using the <Policies> column ExtraHappiness

      Policy Name <Description> Text ExtraHappiness value
      POLICY_UNHAPPY_INT_001 001 UNHAPPY_INT -1
      POLICY_UNHAPPY_INT_002 002 UNHAPPY_INT -2
      POLICY_UNHAPPY_INT_004 004 UNHAPPY_INT -4
      POLICY_UNHAPPY_INT_008 008 UNHAPPY_INT -8
      POLICY_UNHAPPY_INT_016 016 UNHAPPY_INT -16
      POLICY_UNHAPPY_INT_032 032 UNHAPPY_INT -32
      POLICY_UNHAPPY_INT_064 064 UNHAPPY_INT -64
      POLICY_UNHAPPY_INT_128 128 UNHAPPY_INT -128
      POLICY_UNHAPPY_INT_256 256 UNHAPPY_INT -256
      POLICY_UNHAPPY_INT_512 512 UNHAPPY_INT -512
      POLICY_UNHAPPY_INT_1024 1024 UNHAPPY_INT -1024

Requirements and Instructions to Use the System in Your Mod:
  1. You must use William Howard's DLL - Various Mod Components of version #77 or later. There is no way around this because William's VMC cures too many issues that crop up when a single player recieves very many policies from direct lua methods. In your mod you must therefore set up a dependancy to William Howard's VMC as like I have done here:
    Code:
      <Dependencies>
        <Mod id="d1b6328c-ff44-4b0d-aad7-c657f83610cd" minversion="77" maxversion="999" title="DLL - Various Mod Components" />
      </Dependencies>
    This means that William's VMC mod must be enabled for your mod to work.​
    • Gazebo's CP patch dll may also serve, but this is not verified.
  2. Download and extract the mod for the Dynamic Policy Effects system.
  3. Copy the file DynamicPolicyEffects (v 4)\LUA\DynamicPolicyEffects.lua into your mod and set its property in ModBuddy as ImportIntoVFS=true
  4. Copy the file DynamicPolicyEffects (v 4)\Policy XML\DynamicPolicy.xml into your mod and set its actions in Modbuddy as "OnModActivated" > "UpdateDatabase"
  5. In your mod's main lua file, add the following line of code:
    Code:
    include("DynamicPolicyEffects.lua")
  6. You can use one of the pre-created effects from the mod's existing code, but the problem with that is every mod that might be using this system at the same time as yours could be trying to give or take away the same exact policies as your mod is doing, and this at the very least is going to cause muddle and confusion.
  7. The best solution, then, is to use the existing system as a template of examples on how to create your own effects specific to your mod.
  8. So, if I want to mimic the empire-wide % science effect of the pre-provided "Percentage Empire Science Yield Increase", but I want to give the policies I am going to use a set of XML names no one else is likely to be using, I would do the following:
    • Create a Main Lua file that is set-up to be an "InGamUIAddin", and add the "include" statement as previously directed, then add this line to it:
      Code:
      DynamicPolicyEffects.LeeSciencePolicyEffect = "POLICY_LEES_SCIENCE"
      as shown here​
      Code:
      -- PlayerDoTurnEvent
      -- Author: LeeS
      -- DateCreated: 6/26/2015 9:45:39 PM
      --------------------------------------------------------------
      
      include("DynamicPolicyEffects.lua")
      DynamicPolicyEffects.LeeSciencePolicyEffect = "POLICY_LEES_SCIENCE"
      
      
      
      function SetPlayerRandomPolicyEffects(iPlayer)
      	local pPlayer = Players[iPlayer]
      	
      	if pPlayer:IsHuman() then
      		local iRandomChance = math.random(1000)
      		SetDynamicPolicyEffects(DynamicPolicyEffects.LeeSciencePolicyEffect, pPlayer, iRandomChance)
      	end
      end
      GameEvents.PlayerDoTurn.Add(SetPlayerRandomPolicyEffects)
      
      print("The Dynamic Policy Effects PlayerAdoptPolicy/PlayerDoTurn loaded")
    • Then I would add an XML-file to my mod, with the following code:
      Code:
      <GameData>
      	<Policies>
      		<InsertOrAbort Type="POLICY_LEES_SCIENCE_1" Description="TXT_KEY_POLICY_LEES_SCIENCE" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="POLICY_LEES_SCIENCE_2" Description="TXT_KEY_POLICY_LEES_SCIENCE" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="POLICY_LEES_SCIENCE_4" Description="TXT_KEY_POLICY_LEES_SCIENCE" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="POLICY_LEES_SCIENCE_8" Description="TXT_KEY_POLICY_LEES_SCIENCE" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="POLICY_LEES_SCIENCE_16" Description="TXT_KEY_POLICY_LEES_SCIENCE" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="POLICY_LEES_SCIENCE_32" Description="TXT_KEY_POLICY_LEES_SCIENCE" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="POLICY_LEES_SCIENCE_64" Description="TXT_KEY_POLICY_LEES_SCIENCE" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="POLICY_LEES_SCIENCE_128" Description="TXT_KEY_POLICY_LEES_SCIENCE" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="POLICY_LEES_SCIENCE_256" Description="TXT_KEY_POLICY_LEES_SCIENCE" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="POLICY_LEES_SCIENCE_512" Description="TXT_KEY_POLICY_LEES_SCIENCE" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="POLICY_LEES_SCIENCE_1024" Description="TXT_KEY_POLICY_LEES_SCIENCE" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      	</Policies>
      	<Policy_YieldModifiers>
      		<Replace PolicyType="POLICY_LEES_SCIENCE_1" YieldType="YIELD_SCIENCE" Yield="1" />
      		<Replace PolicyType="POLICY_LEES_SCIENCE_2" YieldType="YIELD_SCIENCE" Yield="2" />
      		<Replace PolicyType="POLICY_LEES_SCIENCE_4" YieldType="YIELD_SCIENCE" Yield="4" />
      		<Replace PolicyType="POLICY_LEES_SCIENCE_8" YieldType="YIELD_SCIENCE" Yield="8" />
      		<Replace PolicyType="POLICY_LEES_SCIENCE_16" YieldType="YIELD_SCIENCE" Yield="16" />
      		<Replace PolicyType="POLICY_LEES_SCIENCE_32" YieldType="YIELD_SCIENCE" Yield="32" />
      		<Replace PolicyType="POLICY_LEES_SCIENCE_64" YieldType="YIELD_SCIENCE" Yield="64" />
      		<Replace PolicyType="POLICY_LEES_SCIENCE_128" YieldType="YIELD_SCIENCE" Yield="128" />
      		<Replace PolicyType="POLICY_LEES_SCIENCE_256" YieldType="YIELD_SCIENCE" Yield="256" />
      		<Replace PolicyType="POLICY_LEES_SCIENCE_512" YieldType="YIELD_SCIENCE" Yield="512" />
      		<Replace PolicyType="POLICY_LEES_SCIENCE_1024" YieldType="YIELD_SCIENCE" Yield="1024" />
      	</Policy_YieldModifiers>
      	<Language_en_US>
      		<Replace Tag="TXT_KEY_POLICY_LEES_SCIENCE" Text="Dynamic Policy - LeeS Science" />
      	</Language_en_US>
      </GameData>
    • Note how this:
      Code:
      DynamicPolicyEffects.LeeSciencePolicyEffect = "[color="blue"]POLICY_LEES_SCIENCE[/color]"
      Matches to this in all cases:​
      Code:
      <GameData>
      	<Policies>
      		<InsertOrAbort Type="[color="blue"]POLICY_LEES_SCIENCE[/color]_1" Description="TXT_KEY_[color="blue"]POLICY_LEES_SCIENCE[/color]" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="[color="blue"]POLICY_LEES_SCIENCE[/color]_2" Description="TXT_KEY_[color="blue"]POLICY_LEES_SCIENCE[/color]" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="[color="blue"]POLICY_LEES_SCIENCE[/color]_4" Description="TXT_KEY_[color="blue"]POLICY_LEES_SCIENCE[/color]" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="[color="blue"]POLICY_LEES_SCIENCE[/color]_8" Description="TXT_KEY_[color="blue"]POLICY_LEES_SCIENCE[/color]" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="[color="blue"]POLICY_LEES_SCIENCE[/color]_16" Description="TXT_KEY_[color="blue"]POLICY_LEES_SCIENCE[/color]" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="[color="blue"]POLICY_LEES_SCIENCE[/color]_32" Description="TXT_KEY_[color="blue"]POLICY_LEES_SCIENCE[/color]" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="[color="blue"]POLICY_LEES_SCIENCE[/color]_64" Description="TXT_KEY_[color="blue"]POLICY_LEES_SCIENCE[/color]" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="[color="blue"]POLICY_LEES_SCIENCE[/color]_128" Description="TXT_KEY_[color="blue"]POLICY_LEES_SCIENCE[/color]" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="[color="blue"]POLICY_LEES_SCIENCE[/color]_256" Description="TXT_KEY_[color="blue"]POLICY_LEES_SCIENCE[/color]" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="[color="blue"]POLICY_LEES_SCIENCE[/color]_512" Description="TXT_KEY_[color="blue"]POLICY_LEES_SCIENCE[/color]" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      		<InsertOrAbort Type="[color="blue"]POLICY_LEES_SCIENCE[/color]_1024" Description="TXT_KEY_[color="blue"]POLICY_LEES_SCIENCE[/color]" Dummy="1" PortraitIndex="24" IconAtlas="POLICY_ATLAS" IconAtlasAchieved="POLICY_A_ATLAS" />
      	</Policies>
      	<Policy_YieldModifiers>
      		<Replace PolicyType="[color="blue"]POLICY_LEES_SCIENCE[/color]_1" YieldType="YIELD_SCIENCE" Yield="1" />
      		<Replace PolicyType="[color="blue"]POLICY_LEES_SCIENCE[/color]_2" YieldType="YIELD_SCIENCE" Yield="2" />
      		<Replace PolicyType="[color="blue"]POLICY_LEES_SCIENCE[/color]_4" YieldType="YIELD_SCIENCE" Yield="4" />
      		<Replace PolicyType="[color="blue"]POLICY_LEES_SCIENCE[/color]_8" YieldType="YIELD_SCIENCE" Yield="8" />
      		<Replace PolicyType="[color="blue"]POLICY_LEES_SCIENCE[/color]_16" YieldType="YIELD_SCIENCE" Yield="16" />
      		<Replace PolicyType="[color="blue"]POLICY_LEES_SCIENCE[/color]_32" YieldType="YIELD_SCIENCE" Yield="32" />
      		<Replace PolicyType="[color="blue"]POLICY_LEES_SCIENCE[/color]_64" YieldType="YIELD_SCIENCE" Yield="64" />
      		<Replace PolicyType="[color="blue"]POLICY_LEES_SCIENCE[/color]_128" YieldType="YIELD_SCIENCE" Yield="128" />
      		<Replace PolicyType="[color="blue"]POLICY_LEES_SCIENCE[/color]_256" YieldType="YIELD_SCIENCE" Yield="256" />
      		<Replace PolicyType="[color="blue"]POLICY_LEES_SCIENCE[/color]_512" YieldType="YIELD_SCIENCE" Yield="512" />
      		<Replace PolicyType="[color="blue"]POLICY_LEES_SCIENCE[/color]_1024" YieldType="YIELD_SCIENCE" Yield="1024" />
      	</Policy_YieldModifiers>
      	<Language_en_US>
      		<Replace Tag="TXT_KEY_[color="blue"]POLICY_LEES_SCIENCE[/color]" Text="Dynamic Policy - LeeS Science" />
      	</Language_en_US>
      </GameData>
      This is intentional and a critical method of the mod. Any effect you add should follow this pattern.​
 

Attachments

Suggestions or Requests for Additions / Changes

Suggestions for additional effects to be rolled directly into the system are welcome, but please bear in mind there are certain constraints:
  1. no "one-shot" effects.
    • this means no requests for units, techs, etc.
  2. No requests for effects that would as a general rule be given at game-start to a specific civ, and the amount of the effect would not normally vary during gameplay. Such cases are better done just creating a direct dummy policy and giving the player said policy at game start-up.
  3. No use of columns from within the <Policies> game-table that are "boolean" columns. (this is essentially the same as #1, but not quite the same).
 
Looks fantastic and hopefully even I might be able to work out how to use it! Thank-you ;).
 
Wow, this looks really great. I can think of one civ I made with a happiness-impacted UA that could have really benefited from this method (instead of the work-around I used). This could open up more opportunities to be creative in design. Nice work.
 
I've updated and reworked the explainations in the OP. Hopefully it is less confusing now :)

The system requires William Howard's VMC because whoward69's dll simply cures too many issues that came up with giving and taking away dummy social policies that are otherwise too much a cumbersome to want to deal with.
 
Back
Top Bottom