Extending the generic property system

Property Tutorial
This tutorial will give you some information about how to deal with the extended property system and use it to model interesting behaviors.

As first example we will try to change the crime property. Instead of the current system that calculates a constant crime rating depending on the buildings in a city we will instead use the buildings as a constant crime source that then moves to plots resulting in a crime value in all plots and cities.

First step is to change the property from the current behavior towards a property that has sources and drains. Open Assets/XML/GameInfo/CIV4PropertyInfos.xml where the properties are defined. Change <bDrainSource>1</bDrainSource> to the crime property.

Now we need to change the buildings so they don't just add a value on construction and remove a value when they are destroyed but instead act as a source each turn.
Open the CIV4BuildingInfos.xml that contains the building you want to change. If the building currently influences crime, it has XML code like this:
Code:
<Properties>
	<Property>
		<PropertyType>PROPERTY_CRIME</PropertyType>
		<iPropertyValue>20</iPropertyValue>
	</Property>
</Properties>
Remove that.
Instead we now add a source. A source is a property manipulator. Everything that allows you to add sources also allows you to add the other types of manipulators (interactions, propagators). This includes buildings, unit types, promotions, terrain types, ...
You add them in these tags:
Code:
<PropertyManipulators>
  Add your sources, interactions, propagators here. Order does not matter.
</PropertyManipulators>
So now lets add 20 crime each turn. The source type that does that is PROPERTYSOURCE_CONSTANT and takes iAmountPerTurn as a parameter.
Code:
<PropertyManipulators>
  <PropertySource>
    <PropertySourceType>PROPERTYSOURCE_CONSTANT</PropertySourceType>
    <PropertyType>PROPERTY_CRIME</PropertyType>
    <iAmountPerTurn>20</iAmountPerTurn>
  </PropertySource>
</PropertyManipulators>

Now our buildings produce crime per turn which gets added to the cities the buildings are in (depending on what you tag your manipulator to the value will be added to different game objects, e.g. terrain type sources will be added to the plot with that terrain).
Since we don't want the crime to just accumulate in our cities, we now need to add propagators. That behavior should be global instead of just on specific features, so we add it to the property itself.
In CIV4PropertyInfos.xml add PropertyManipulators tags (in a property, due to some loading issues that I will fix later you are actually better off to add them to the flammability property) and in there we add a PropertyPropagator.
Currently implemented are PROPERTYPROPAGATOR_SPREAD, which spreads the property without decreasing it on the source object and PROPERTYPROPAGATOR_GATHER, which collects properties from other objects and moves it to the object with the propagator. Here we actually want the soon to be implemented PROPERTYPROPAGATOR_DIFFUSE which moves a property from a source object to target objects with a rate depending on the difference between them. The parameter is iPercent representing by how much you want the difference reduced per turn. First lets diffuse from the city to all plots in a distance of 1.
Code:
<PropertyManipulators>
  <PropertyPropagator>
    <PropertyPropagatorType>PROPERTYPROPAGATOR_DIFFUSE</PropertyPropagatorType>
    <PropertyType>PROPERTY_CRIME</PropertyType>
    <GameObjectType>GAMEOBJECT_CITY</GameObjectType>
    <TargetObjectType>GAMEOBJECT_PLOT</TargetObjectType>
    <RelationType>RELATION_NEAR</RelationType>
    <iDistance>1</iDistance>
    <iPercent>2</iPercent>
  </PropertyPropagator>
</PropertyManipulators>
So this means diffuse crime from cities to nearby plots in a distance of max 1 with 2%.
But it will not spread it any further so we need more propagators.
Lets assume routes spread crime.
So open CIV4RouteInfos.xml and add a diffuse propagator to each route type:
Code:
<PropertyManipulators>
  <PropertyPropagator>
    <PropertyPropagatorType>PROPERTYPROPAGATOR_DIFFUSE</PropertyPropagatorType>
    <PropertyType>PROPERTY_CRIME</PropertyType>
    <TargetObjectType>GAMEOBJECT_PLOT</TargetObjectType>
    <RelationType>RELATION_NEAR</RelationType>
    <iDistance>1</iDistance>
    <iPercent>2</iPercent>
  </PropertyPropagator>
</PropertyManipulators>
Now crime on routes will be diffused to nearby plots which should slowly move crime along the roads.

Crime likes a place to hide. Forests are good for hiding. So lets add a gather propagator to forests so crime concentrates there if any gets nearby. Open CIV4FeatureInfos.xml and add this to the forest type:
Code:
<PropertyManipulators>
  <PropertyPropagator>
    <PropertyPropagatorType>PROPERTYPROPAGATOR_GATHER</PropertyPropagatorType>
    <PropertyType>PROPERTY_CRIME</PropertyType>
    <TargetObjectType>GAMEOBJECT_PLOT</TargetObjectType>
    <RelationType>RELATION_NEAR</RelationType>
    <iDistance>1</iDistance>
    <iAmountPerTurn>1</iAmountPerTurn>
  </PropertyPropagator>
</PropertyManipulators>

Finally a percentage decay should be added to all objects so our crime does not reach ever higher numbers. That is actually a source (to be added): PROPERTYSOURCE_DECAY and uses iPercent as parameter.
 
Property Tutorial
This tutorial will give you some information about how to deal with the extended property system and use it to model interesting behaviors.

All i can say is WOW:eek::worship:
 
We need a propagator PROPAGATOR_DECAY that just decays the value around a set non-decay point, otherwise we'll be likely to be introducing non-convergent series with the end result of unstoppbale rampant crime (or unstoppable rampant order) asymptotically.

<PROPERTYPROPAGATOR_DECAY noDecayValue="0" decayRate="50" />

Each turn:

Value(N+1) = Value(N) - (Value(N) - noDecayValue)*decayRate/100

where Value(N) is the value of ther property the decay propagator is attached to on turn N.
 
We need a propagator PROPAGATOR_DECAY that just decays the value around a set non-decay point, otherwise we'll be likely to be introducing non-convergent series with the end result of unstoppbale rampant crime (or unstoppable rampant order) asymptotically.

<PROPERTYPROPAGATOR_DECAY noDecayValue="0" decayRate="50" />

Each turn:

Value(N+1) = Value(N) - (Value(N) - noDecayValue)*decayRate/100

where Value(N) is the value of ther property the decay propagator is attached to on turn N.
Indeed (mentioned in the last line of the tutorial). That is actually a source type as the change it applies only depends on one property of one object and only changes that same property.
But good idea to add the iNoDecayValue and not only iPercent.

The alternative to decay to prevent rampant values is limited sources, interactions and propagators (a limited source would only create properties until a certain storage limit).
 
1) Does this mean that we can use this to replace the interesting but seriously flawed Realistic Culture Spread? Anything that requires chopping down trees is flawed imho.

2) I would like to replace the current crime buildings that Hydro introduced. Plus change Revolutions in this regard also.

The following should all increase crime in a city
- Unhappiness
- Different ethnicity
- Lack of expected services, which means buildings​

Things that decrease crimes may include
- Law inforcement buildings
- Law makers including law specialists
- reconcilation between different sets of laws (ethnicity and religion)
- provision of "bread and circuses"​

When crime reaches a certain point a bad person is born to counter all the good ones currently in the game. What that bad person can do depends on all sorts of things but they may be able to establish a "Family Business" in another city, a rival gang in this city or maybe just a build one of the current crime buildings which are adjusted to only have bad effects.

This is all very preliminary at the moment.
 
1) Does this mean that we can use this to replace the interesting but seriously flawed Realistic Culture Spread? Anything that requires chopping down trees is flawed imho.
While in principle possible it is probably better to fix any problem with Realistic Culture Spread in the existing code which is already specialized for that.

What I think should be done first with this system is nomads, diseases and some resources, that are limited, can be converted and are used up.

Btw, PROPERTYSOURCE_CONSTANT_LIMITED and PROPERTYSOURCE_DECAY are in now.
 
Property Tutorial
This tutorial will give you some information about how to deal with the extended property system and use it to model interesting behaviors.

Oh My Gosh. Aside from multiple maps, this may be the single biggest feature that will define C2C. Great Work!:goodjob:
 
@AIAndy

Now that I am well rested I have some questions before I start changing all the building code.

1. I assume I need to update all my building schemas right? Do I grab C2C_CIV4BuildingsSchema from the core file or should I wait until you have added the decay stuff?

2. If I understand you right all of the old code must be replace by your new code correct?

3. When having 2 properies on a building do you write it like this?

Code:
<PropertyManipulators>
  <PropertyPropagator>
    <PropertyPropagatorType>PROPERTYPROPAGATOR_DIFFUSE</PropertyPropagatorType>
    <PropertyType>PROPERTY_CRIME</PropertyType>
    <TargetObjectType>GAMEOBJECT_PLOT</TargetObjectType>
    <RelationType>RELATION_NEAR</RelationType>
    <iDistance>1</iDistance>
    <iPercent>2</iPercent>
  </PropertyPropagator>
  <PropertyPropagator>
    <PropertyPropagatorType>PROPERTYPROPAGATOR_DIFFUSE</PropertyPropagatorType>
    <PropertyType>PROPERTY_FLAMMBILITY</PropertyType>
    <TargetObjectType>GAMEOBJECT_PLOT</TargetObjectType>
    <RelationType>RELATION_NEAR</RelationType>
    <iDistance>1</iDistance>
    <iPercent>2</iPercent>
  </PropertyPropagator>
</PropertyManipulators>

4. For say buildings (which will be the main stuff I am fixing) I will want to use GAMEOBJECT_CITY as <TargetObjectType>?

5. What would you put for <RelationType>?

6. So you have all this crime or flammability but what do they actually DO? Will the crime set off crime events or is that not set up yet? Are all the events still need to be done by Ori? Also what is the threshold to set off Flammability events? I am never sure if the fire events are random or because of buildings in my games.

@Dancing Hoskuld

1. What do you want to replace my crime buildings with? And why?

2. Is the "Bad Person" like a "Great Person" but they just can build Crime buildings?

3. Are you thinking of having the crime buildings automatically building themselves? If so why could someone not just go into CTRL+A and delete the building? Note this is not considered cheating like say going into World Builder and deleting the building.
 
Speaking of Schemas, does this mean that I (and everyone else) will have to update Unit Schemas as well? Heck, do ALL the schemas in C2C need an update?
 
Speaking of Schemas, does this mean that I (and everyone else) will have to update Unit Schemas as well? Heck, do ALL the schemas in C2C need an update?

In general yes. That's why we name our schemas after ourselves. Those are the ones we have to personally maintain. Thus if you use a schema it is cusomary to name it after yourself. Such as "ls612_CIV4BuildingsSchema.xml"
 
In general yes. That's why we name our schemas after ourselves. Those are the ones we have to personally maintain. Thus if you use a schema it is cusomary to name it after yourself. Such as "ls612_CIV4BuildingsSchema.xml"

Good. Do I need to name the new schema something other than ls612_CIV4UnitsSchema, ie ls612v2_CIV4UnitsSchema or something?
 
I think so. Any time you add something modular I just replace the schema with my own name. This should not matter if they eventually get merged into the core since that info of calling that file will not be merged.

For example at the top of a file it has ...

<Civ4BuildingClassInfos xmlns="x-schema:Hydro_CIV4BuildingsSchema.xml">

But if it gets merged into the core they have ...

<Civ4BuildingClassInfos xmlns="x-schema:C2C_CIV4BuildingsSchema.xml">
 
@AIAndy

Now that I am well rested I have some questions before I start changing all the building code.

1. I assume I need to update all my building schemas right? Do I grab C2C_CIV4BuildingsSchema from the core file or should I wait until you have added the decay stuff?
Yes, you need to update your schemas to use it.
Decay is in now but it is not unlikely that more things are added in the next days that change the schema.

2. If I understand you right all of the old code must be replace by your new code correct?
No, the old things still work fine. There is no must to replace and I don't think it makes even sense for flammability to use the new part of the system. They are different kinds of properties.
But when you change a certain property to the new system you need to change the old occurances. Either a property has sources and drains or is an accumulated value over buildings. It cannot be mixed on the same property but different properties can use the different system parts.

3. When having 2 properies on a building do you write it like this?

Code:
<PropertyManipulators>
  <PropertyPropagator>
    <PropertyPropagatorType>PROPERTYPROPAGATOR_DIFFUSE</PropertyPropagatorType>
    <PropertyType>PROPERTY_CRIME</PropertyType>
    <TargetObjectType>GAMEOBJECT_PLOT</TargetObjectType>
    <RelationType>RELATION_NEAR</RelationType>
    <iDistance>1</iDistance>
    <iPercent>2</iPercent>
  </PropertyPropagator>
  <PropertyPropagator>
    <PropertyPropagatorType>PROPERTYPROPAGATOR_DIFFUSE</PropertyPropagatorType>
    <PropertyType>PROPERTY_FLAMMBILITY</PropertyType>
    <TargetObjectType>GAMEOBJECT_PLOT</TargetObjectType>
    <RelationType>RELATION_NEAR</RelationType>
    <iDistance>1</iDistance>
    <iPercent>2</iPercent>
  </PropertyPropagator>
</PropertyManipulators>
Correct.

4. For say buildings (which will be the main stuff I am fixing) I will want to use GAMEOBJECT_CITY as <TargetObjectType>?
Most common on buildings will be property sources or property interactions which don't have a TargetObjectType. Only propagators have that. They have a GameObjectType though which when it is omitted will be considered as city on buildings (later you will be able to have a building use a source with GAMEOBJECT_PLAYER and source into the player object but that is not yet implemented).

5. What would you put for <RelationType>?
The current options for RelationType on propagators are:
  • RELATION_ASSOCIATED, which depending on the TargetObjectType can mean owner, owned (e.g. from a team object with target type city it will mean all cities of that team, from a plot to a player it will mean the owner of that plot)
  • RELATION_TRADE, which currently is only defined for cities with target cities and means the cities with which the city has trade routes
  • RELATION_NEAR, which uses iDistance and means all objects within that distance of the TargetObjectType (e.g. with target object GAMEOBJECT_UNIT and iDistance 2 it will mean all units within the plot on which the source object is)
  • RELATION_SAME_PLOT is more or less the same as RELATION_NEAR with a distance of 0

6. So you have all this crime or flammability but what do they actually DO? Will the crime set off crime events or is that not set up yet? Are all the events still need to be done by Ori? Also what is the threshold to set off Flammability events? I am never sure if the fire events are random or because of buildings in my games.
Currently there is very little in terms of ties back into other game mechanics. Events can be further added that use that, especially when Ori is back.
But here are the further plans for uses of the new system:
  • Automatic addition of buildings specified in the property when a certain level in the property is surpassed (unremovable) but will be automatically removed when it drops below that.
  • Similar promotions that are added to a unit when the amount of a property gets over a certain level and removed when it drops back below.
  • For plots there might be something similar with either feature or improvement
  • For player objects that could be traits.
  • Special abilities (outcome missions) that are fuelled by a property so you need that amount to activate it and that cost is removed from the property (used for the nomad feature but might be used for other things as well).
 
Currently there is very little in terms of ties back into other game mechanics. Events can be further added that use that, especially when Ori is back.

Ori implemented quiet a few flammability events and they are working fine. They are pretty unlikely below flammabilities of 200+ though.

Edit - @AIAndy:

I might have missed it, bu do you plan to add preReqPropertyMax/preReqPropertyMin type attributes on things like buildings/units/promotions to tie it back more into the rest of the system (apart from event usage)?
 
@AIAndy

Yes, you need to update your schemas to use it.
Decay is in now but it is not unlikely that more things are added in the next days that change the schema.

Ok I will wait a bit until you get all your stuff worked out. No need to do things twice, especially since much of the events are not even in place to be triggered.

No, the old things still work fine. There is no must to replace and I don't think it makes even sense for flammability to use the new part of the system. They are different kinds of properties.
But when you change a certain property to the new system you need to change the old occurances. Either a property has sources and drains or is an accumulated value over buildings. It cannot be mixed on the same property but different properties can use the different system parts.

So I can skip flammability? Wonderful! That is the most extensive property. I am guessing I just need to focus on crime then since that is more or less what your new system was deigned for. However what about the Law buildings? Should negative crime building follow this system too?

Most common on buildings will be property sources or property interactions which don't have a TargetObjectType. Only propagators have that. They have a GameObjectType though which when it is omitted will be considered as city on buildings (later you will be able to have a building use a source with GAMEOBJECT_PLAYER and source into the player object but that is not yet implemented).

So should <RelationType>RELATION_NEAR</RelationType> be in the code or not when adding your new code to a building?

I am just a bit confused still. :crazyeye:
 
Ori implemented quiet a few flammability events and they are working fine. They are pretty unlikely below flammabilities of 200+ though.

Edit - @AIAndy:

I might have missed it, bu do you plan to add preReqPropertyMax/preReqPropertyMin type attributes on things like buildings/units/promotions to tie it back more into the rest of the system (apart from event usage)?
Yes, I might go one step further though and add a generic condition class that works on the game object wrapper classes which also allows me to add the ability to form expressions with and/or. I need one for target filtering for the propagators anyway.
 
So I can skip flammability? Wonderful! That is the most extensive property. I am guessing I just need to focus on crime then since that is more or less what your new system was deigned for.
Actually the system was designed for diseases at first and then extended for the gathering nomad needs but for this tutorial I decided to go with an easy example that is nearly ready to work.

However what about the Law buildings? Should negative crime building follow this system too?
If you change the positive crime buildings, you have to change the negative crime buildings too. Of course you could alternatively add a separate property for law and have the law buildings source that. Interactions could then model the struggle between crime and law.

So should <RelationType>RELATION_NEAR</RelationType> be in the code or not when adding your new code to a building?
RelationType is only used by propagators.
Most of what you will add to buildings will be sources or drains.
There are some buildings for which you might consider a propagator in addition. Like a Smuggler's Shanty moving more crime to the nearby water plots.
 
Here are some other things that could use this system:

-Corporations: Could each be given unique spread propagators, adding another level to Realistic Corporations.
-Terrorism: ala WLBO, terror groups/drug cartels could be spread, countered, and supported using this. You may even be able diplomatically to implement something like the Bush Doctrine, and declare war on sponsors of terror.
-Revolutions: instead of using the opaque and python-based REV, we could convert a lot of this to the new properties.
-Guilds: Similar to corporations, they could be spread by this, using spread rules so as to be more 'Guildlike' in their behavior.
-Mercenaries: This was one of my let ideas before I was a member of the team, and I might be able to do it entirely in XML now that this system is in place.

This is just my Grand Ideas List for now, obviously we won't have ALL of this in v22.

One quick question; Does the AI know how to handle this, or does it need to be told about each individual property, or both?
 
Here are some other things that could use this system:

-Corporations: Could each be given unique spread propagators, adding another level to Realistic Corporations.
-Terrorism: ala WLBO, terror groups/drug cartels could be spread, countered, and supported using this. You may even be able diplomatically to implement something like the Bush Doctrine, and declare war on sponsors of terror.
-Revolutions: instead of using the opaque and python-based REV, we could convert a lot of this to the new properties.
-Guilds: Similar to corporations, they could be spread by this, using spread rules so as to be more 'Guildlike' in their behavior.
-Mercenaries: This was one of my let ideas before I was a member of the team, and I might be able to do it entirely in XML now that this system is in place.

This is just my Grand Ideas List for now, obviously we won't have ALL of this in v22.

One quick question; Does the AI know how to handle this, or does it need to be told about each individual property, or both?

It needs to be told. For the existing property system (as used for flammability and crime) there is an aiweight, and an operational range specified in the properties XML. The ai knows that higher values are either good or bad based on the sign of the aiweight. It knows the range over which the property operates (values below which or above which further improvements or degradations won't really make any practical difference), and based on where it is in that range currently it weighs buildings that add to or subtract from the property in question.

The evaluation system should still work fine with the new system (for cities at least) , with relatively small additions to teach the AI about sources and propagators.

For buildings and properties on cities this should be very easy. For properties on anything other than cities, and sources on anything other an buildings, if we want the AI to be able to react meaningfully to it, then we'll need new code, and at least for anything unit or route propagated, whole new strategy and tactical routines.

For these reasons I suggest that, at least for now, we limit ourselves one or more of:
  • properties that matter really only in cities, and are sourced by buildings
  • properties that are used to model environmental factors, the impact of which players (and the AI) need to deal with, but which they cannot be expected to have much actual control over
In the future we can put in place strategic routines to handle things like properties spread by units (e.g. Deliberately sending diseased units to enemy cities), but that will require quite a bit more work.
 
Top Bottom