The Outcome System

I experimented a bit with direct interactions with the Python DLL.
As a result it is now possible to code outcome effects in Python and include that code right in the XML for the outcome (now means when someone next checks in the compiled DLL).

An example:
Code:
<Outcome>
	<OutcomeType>OUTCOME_BEAR_POWER</OutcomeType>
	<iChance>5</iChance>
	<PythonName>BearWithMeModule</PythonName>
	<Python>						
		def isPossible(unit, plot):
			return unit.isHuman()

		def doOutcome(unit, plot, eDefPlayer, eDefUnitType):
			unit.changeExperience100(1000, -1, False, False, False)
							
		def getDisplay(unit, plot):
			return u"Bear POWER"
							
		def getAIValue(unit, plot):
			return 1
	</Python>
</Outcome>
Anything that you could do in a Python module is allowed within that tag (so you could import other modules and similar). PythonName can be anything. It is only used for code error messages in PythonErr. Ignore any "traceback" it claims if your PythonName appears there.
The four functions need exactly that signature but you can leave any of them out (so if you leave out isPossible, because you don't want to alter when the outcome is possible, then that is ok).

If isPossible(unit, plot) returns false, then this outcome is not possible for the given unit on the given plot.

doOutcome(unit, plot, eDefPlayer, eDefUnitType) is executed when the outcome is triggered with a given unit. If it is a kill outcome, then eDefPlayer is the player to whom the killed unit belonged and eDefUnitType is the type of the killed unit. The plot is given so the function signature is similar to the others but is currently always the plot of the given unit.

getDisplay(unit, plot) can return a string that is displayed in the result brackets of the help text for that outcome (like when you mouse over an action outcome).

getAIValue(unit, plot) allows you to give an estimate of the value of the Python effect to the AI (like when it tries to decide what to do with a subdued animal).

Forgive my ignorance of the inner workings of the current (or pre-this-change) functioning of the Outcome Mechanism but I have a few questions that may come across as shamefully lacking understanding here.

1) So this enables us to basically program the outcome variables (with python language) right into the xml of the unit, unitcombat, etc itself?
2) What then is the need for referring to a python module at all? What further python will be necessary - it seems to me the whole process can be encapsulated here.
3) How do you compile the 'chances' of an outcome?
4) Is this purely useful in combat results at the moment? Or does it have other potential effects?
5) To what info types do this <Outcome> tag apply to?
6) If a unit is getting an <Outcome> ability from it's base unit info, a combat class, and a promotion, do they in any way seamlessly tally up somehow?

Sorry... again - I'm shamefully confused still on what Outcomes are and how they work (to an extent.) And I'm just trying to get this cleared up for myself.
 
While this is a nice addition I doubt its usefulness. Having one piece of code in a Python module is much easier to maintain than having the same bit of code in each of the 200+ animals for example.
 
While this is a nice addition I doubt its usefulness. Having one piece of code in a Python module is much easier to maintain than having the same bit of code in each of the 200+ animals for example.

If it is the same for e.g. 200 animals it is not usefull but if it would be different for each of them it would be usefull.
 
Forgive my ignorance of the inner workings of the current (or pre-this-change) functioning of the Outcome Mechanism but I have a few questions that may come across as shamefully lacking understanding here.

1) So this enables us to basically program the outcome variables (with python language) right into the xml of the unit, unitcombat, etc itself?
2) What then is the need for referring to a python module at all? What further python will be necessary - it seems to me the whole process can be encapsulated here.
3) How do you compile the 'chances' of an outcome?
4) Is this purely useful in combat results at the moment? Or does it have other potential effects?
5) To what info types do this <Outcome> tag apply to?
6) If a unit is getting an <Outcome> ability from it's base unit info, a combat class, and a promotion, do they in any way seamlessly tally up somehow?

Sorry... again - I'm shamefully confused still on what Outcomes are and how they work (to an extent.) And I'm just trying to get this cleared up for myself.
1) It mainly allows you to hook some Python into outcomes and have the specific code right in the XML.
2) There is no further Python needed but it is possible to use it.
3) The chance of each outcome is its chance parameter divided by the sum of the chances of the other outcomes or 100 if it is smaller.
4) It applies to both kill outcomes and mission outcomes (which e.g. the subdued animals use) but in general it is mainly an experiment and the pattern can be used anywhere you want to mesh Python and C++.
5) Outcomes can currently be applied to unit types and to unit combat types (in both cases kill outcomes and mission outcomes are possible).
6) The unit has missions for outcomes on the unit combat types and unit types available to it separately. Kill outcome lists on both are combined into one list and then executed.

While this is a nice addition I doubt its usefulness. Having one piece of code in a Python module is much easier to maintain than having the same bit of code in each of the 200+ animals for example.
Mind that for Python this is a module and you can import other modules.
So you could have your main code in some Python module file in the Python folder and then import that into each of these XML parts and call your code with different parameters for instance.

Example:
Code:
<Python>
  import DHDiplos
  def doOutcome(unit, plot, eDefPlayer, eDefUnitType):
    DHDiplos.DiploGreeting(unit,plot,150,7,true)
</Python
 
On 5 and 6 - I have tried this out and have it working in some instances but could not get it to work in others. I need to get back to the subdued animals and identify the problems again so you can help me sort it out. If I remember I had moved the "culture" outcome for all "Tales of..." units into the one for that combat class but could not do similar for any other grouping eg I wanted one for sharks and another for whales. I'll try again now that the combat classes have settled down.

edit You know this python in XML may be the solution to a problem I have with the captives settling as slaves....
 
1) It mainly allows you to hook some Python into outcomes and have the specific code right in the XML.
That is just fascinating and far beyond what I would've thought possible or would've seen any usefulness in developing (though I can now that you're providing some examples and good explanations.)
2) There is no further Python needed but it is possible to use it.
Now that makes sense then and tells me I'm not quite as confused as I thought.

3) The chance of each outcome is its chance parameter divided by the sum of the chances of the other outcomes or 100 if it is smaller.
Very clever math. Very clever indeed. I've never considered that sort of random model but it has a lot of benefits to it.

4) It applies to both kill outcomes and mission outcomes (which e.g. the subdued animals use) but in general it is mainly an experiment and the pattern can be used anywhere you want to mesh Python and C++.
hmm... ok. I'd have to look deeper to see how each are applied but it helps me understand the current limits.

5) Outcomes can currently be applied to unit types and to unit combat types (in both cases kill outcomes and mission outcomes are possible).
Not promotions? I thought promos could add to the chances for specified outcomes and from what you say next it would seem to me that it would follow suit that would be the way to get the two to blend into a final total for the unit right?

6) The unit has missions for outcomes on the unit combat types and unit types available to it separately. Kill outcome lists on both are combined into one list and then executed.
So from what I understand, if a given outcome is used on both a combat class and the core unit info then it'll combine into one unified likelihood right?

Now... this also suggests, since we're defining the outcome as a game object itself and calling to that outcome for definition, what if you have differing python on the same outcome between the unitcombat and the unit info? Based on what you show here I'm thinking that might be possible to cause a conflicting result sequence:
Code:
<Outcome>
	<OutcomeType>OUTCOME_BEAR_POWER</OutcomeType>
	<iChance>5</iChance>
	<PythonName>BearWithMeModule</PythonName>
	<Python>						
		def isPossible(unit, plot):
			return unit.isHuman()

		def doOutcome(unit, plot, eDefPlayer, eDefUnitType):
			unit.changeExperience100(1000, -1, False, False, False)
							
		def getDisplay(unit, plot):
			return u"Bear POWER"
							
		def getAIValue(unit, plot):
			return 1
	</Python>
</Outcome>

So if I have OUTCOME_BEAR_POWER on both the unit and the unitcombat - on the unit specifying different python processing than it does on the unitcombat, which takes the dominant role then?


Mind that for Python this is a module and you can import other modules.
So you could have your main code in some Python module file in the Python folder and then import that into each of these XML parts and call your code with different parameters for instance.

Example:
Code:
<Python>
  import DHDiplos
  def doOutcome(unit, plot, eDefPlayer, eDefUnitType):
    DHDiplos.DiploGreeting(unit,plot,150,7,true)
</Python
wow... truly fascinating indeed.

I'll try again now that the combat classes have settled down.
Hopefully you now have yet more useful definitions available there! And yeah, I think the crust is solidifying on that project pretty well so you shouldn't have to account for strongly drastic adjustments taking place in that realm anytime soon - or ever.
 
So if I have OUTCOME_BEAR_POWER on both the unit and the unitcombat - on the unit specifying different python processing than it does on the unitcombat, which takes the dominant role then?
They are separate, both has its own chance. The outcome type only applies some extra conditions and allows it to be overridden by some other outcome type specifying that it overrides that outcome type (which would then remove both instances of OUTCOME_BEAR_POWER).
 
Not promotions? I thought promos could add to the chances for specified outcomes and from what you say next it would seem to me that it would follow suit that would be the way to get the two to blend into a final total for the unit right?

There are
- outcome definitions which define the changes promotions has and where the outcome can happen eg hostile territory.

- Missions which define the buttons and

- outcomes and kill outcomes on the unit that link this all to the unit.
 
@ anyone

what is the difference between these??

<iAmountPerTurn>
<Div>
<Mult>
<AttributeType>ATTRIBUTE_POPULATION</AttributeType>
<Constant>9</Constant>
</Mult>
<Constant>2</Constant>
</Div>
</iAmountPerTurn>

and

<iAmountPerTurn>
<Mult>
<AttributeType>ATTRIBUTE_POPULATION</AttributeType>
<Constant>5</Constant>
</Mult>
</iAmountPerTurn>

schema has this???

<ElementType name="Minus"/>
<ElementType name="Mult"/>
<ElementType name="Div"/>
<ElementType name="IntegrateSum"/>

In the Handicap XML??
 
I believe that's the crime/population right?

The first is saying 9 crime per 2 population while the second is saying 5 crime per population (a touch more than the first).
 
I believe that's the crime/population right?

The first is saying 9 crime per 2 population while the second is saying 5 crime per population (a touch more than the first).

OK so why would IMMORTAL have the "extra" and then Deity does not?? Looks like every "other" handicap have the extra???
 
the extra?

Looking at the file it shows
Deity: 5 crime per population (which is 10 crime per 2 population right?)
Immortal: 9 crime per 2 population (which is 4.5 crime per population)
Emperor: 4 crime per population (or 8 crime per 2 population)
Monarch: 7 crime per 2 population (3.5 crime per pop)
Prince: 3 crime per population (6 crime per 2 population)
Noble: 5 crime per 2 population (2.5 crime per pop)
Warlord: 2 crime per population (4 crime per 2 population)
Chieftain: 3 crime per 2 population (1.5 crime per pop)
Settler: 1 crime per population (2 crime per 2 population)

if by 'the extra' you mean the bolded part in your above post, this is what's required to express 'per 2 population' so you'll see it in use with every other one, Chieftain, Noble, Monarch, Immortal. Whichever ones don't have just a full integer amount per single population.
 
the extra?

Looking at the file it shows
Deity: 5 crime per population (which is 10 crime per 2 population right?)
Immortal: 9 crime per 2 population (which is 4.5 crime per population)
Emperor: 4 crime per population (or 8 crime per 2 population)
Monarch: 7 crime per 2 population (3.5 crime per pop)
Prince: 3 crime per population (6 crime per 2 population)
Noble: 5 crime per 2 population (2.5 crime per pop)
Warlord: 2 crime per population (4 crime per 2 population)
Chieftain: 3 crime per 2 population (1.5 crime per pop)
Settler: 1 crime per population (2 crime per 2 population)

if by 'the extra' you mean the bolded part in your above post, this is what's required to express 'per 2 population' so you'll see it in use with every other one, Chieftain, Noble, Monarch, Immortal. Whichever ones don't have just a full integer amount per single population.

So when i make more then the next one and then 3rd one i make MUST have the "extra" constant in it, correct??
 
the extra?

Looking at the file it shows
Deity: 5 crime per population (which is 10 crime per 2 population right?)
Immortal: 9 crime per 2 population (which is 4.5 crime per population)
Emperor: 4 crime per population (or 8 crime per 2 population)
Monarch: 7 crime per 2 population (3.5 crime per pop)
Prince: 3 crime per population (6 crime per 2 population)
Noble: 5 crime per 2 population (2.5 crime per pop)
Warlord: 2 crime per population (4 crime per 2 population)
Chieftain: 3 crime per 2 population (1.5 crime per pop)
Settler: 1 crime per population (2 crime per 2 population)

if by 'the extra' you mean the bolded part in your above post, this is what's required to express 'per 2 population' so you'll see it in use with every other one, Chieftain, Noble, Monarch, Immortal. Whichever ones don't have just a full integer amount per single population.

From your post then is there a potential problem then with the game engine rounding the levels with x.5 per pop up to the next value? Example chieftain 1.5 the engine would round up to 2 making Chieftain actually equivalent to Warlord. Did anyone check to see if this does occur?

And why such a convoluted flip-flop method? Besides that Hydro stated that Crime base was 4 crime per pop. He had lowered it to 3 at one point because I protested it was climbing too fast. Then "others" started complaining about Crime reducing buildings taking it back down too fast. So he re-upped it back to 4. How does this play into this adjustment?

JosEPh
 
From your post then is there a potential problem then with the game engine rounding the levels with x.5 per pop up to the next value? Example chieftain 1.5 the engine would round up to 2 making Chieftain actually equivalent to Warlord. Did anyone check to see if this does occur?

And why such a convoluted flip-flop method? Besides that Hydro stated that Crime base was 4 crime per pop. He had lowered it to 3 at one point because I protested it was climbing too fast. Then "others" started complaining about Crime reducing buildings taking it back down too fast. So he re-upped it back to 4. How does this play into this adjustment?

JosEPh
This was the final answer to that flip-flopping. We, after some long deliberation as I recall, decided as a group to make the amount of crime per population be determined by the difficulty setting about a year ago.

It's not convoluted, it's a very simple linear mathematical progress from 1 crime per population to 5 crime per population at deity. The game won't round the 1.5 crime per population - rather it's stating, quite specifically, that it's an amount of crime per 2 population - 3 crime for every 2 pop. It means that the 1st pop won't incur added crime but the every second one will add 3. It does have the disadvantage that a clever player knowing very well what setting he's on may decide to keep his population at odd values to minimize the crime levels but in play this is rarely even viable strategically. It also may make it appear at first, with new pop 1 cities, that a harder setting may not be having any crime per population while the previous setting did, but once the city reaches pop 2 it will quickly make up the difference. So there is a little off-handed handicap effect simply for selecting Chieftain, Noble, Monarch, or Immortal level difficulty but it's a very subtle difference in play.

It was either we did it this way or introduce a (decimal) float value over the normal integer usage there and I think AIAndy was reluctant to do that for numerous understandable reasons.
 
Yes but I believe there already IS some education drain by population... And the housing buildings... we had a discussion on that - I'm still pretty sure it would be hard to get a good reflection of what you're trying to achieve there without some further developments but I can't recall quite what I had thought that was at the time... we could certainly re-strike up that conversation.
 
Pre v35 release a bug has been discovered in the Captives outcomes which I can't fix in the XML as far as I can see. The remove slavery etc needs to only be available in your cities. Currently it checks for the building in the city that the unit is in and that the city is friendly. This means that if you are in a city of a vassal, colony or nation you have open borders or better with and they have the building in that city your GP has the option to remove slavery.
 
Top Bottom