Smarter Orcs (a FfH II mod)

Who knows how the AI will perform in 0.3x; always hope for the best ;) (I'll stay with SmarterOrcs for the combat changes alone--and also, uhm, because I technically work on it as well ;P) (hey, I added like one Python function the other day! I'm not one hundred percent useless!)
Quite the contrary; performing the XML changes was non-trivial, and really the first thing that was ready. In any event, there should be more to do as more is exposed to the XML.
 
There are two ways to "reduce the randomness" implemented; one is based on my suggestion; the other is based on yours. I think both work.

Xanaqui's approach:
Take X;

Divide COMBAT_DAMAGE by X
multiply COMBAT_DENOMINATOR by X
multiply FIRST_STRIKE_FACTOR by X
multiply STONESKIN_FACTOR by X

This will give you much the same effect as if your HP were multiplied by X, other than rounding at the end of combat. Note that it will not affect anything outside of normal combat.

Bringa's approach:

multiply MAX_HIT_POINTS by X
multiply FIRST_STRIKE_FACTOR by X
multiply STONESKIN_FACTOR by X
multiply HEALING_FACTOR by X
multiply MAGIC_DAMAGE_FACTOR by X
multiply COLLATERAL_COMBAT_DAMAGE by X

This will give you the effect as if your HP were multiplied by X (note that I haven't played with COLLATERAL_COMBAT_DAMAGE - it may not need changing).

However, you can get other effects. For example, if you want all damage to be calculated in tenths, to change the point at which certain "jumps" occur in combat, you could do so:
set COMBAT_DENOMINATOR to 10

Or if you want Lifesparks to be more significant, you could do so:
set LIFESPARK_BASE_HEAL to 80

Or if you want magic to be less significant, you could follow the multiply HP approach above, but use a lower value for MAGIC_DAMAGE_FACTOR.

Once again, if someone is interested in placing these changes in their mod, I'd be happy to write up exactly how to do them. Note that It involves C++, Python, and XML changes.
 
So if I read this right, a way to implement "Xanaqui's derandomizer" would be to set:

COMBAT_DAMAGE to 2
COMBAT_DENOMINATOR to 10
FIRST_STRIKE_FACTOR to 10
STONESKIN_FACTOR to 10

and not change anything else. Correct? And then the damage inside the actual combat is calculated as non-integer?

Whereas "Bringa's derandomizer" would go like:

MAX_HITPOINTS 1000
FIRST_STRIKE_FACTOR 10
STONESKIN_FACTOR 10
HEALING_FACTOR 10
MAGIC_DAMAGE_FACTOR 10
COLLATERAL_COMBAT_DAMAGE 100 (untested)

So to be clear, in Bringa's derandomizer you wouldn't need to touch the denominator?

What I don't quite understand is why in xanaqui's derandomizer one needs to BOTH lower combat damage AND raise the denominator... I would have thought both achieve much the same thing.

EDIT: I just ran a test with "xanaqui's randomizer" and it definitely looks like we have pronounced "steps" in the results. I've got to get to work now, but I'll test with the other version later tonight.
 
So if I read this right, a way to implement "Xanaqui's derandomizer" would be to set:

COMBAT_DAMAGE to 2
COMBAT_DENOMINATOR to 10
FIRST_STRIKE_FACTOR to 10
STONESKIN_FACTOR to 10

and not change anything else. Correct? And then the damage inside the actual combat is calculated as non-integer?

Whereas "Bringa's derandomizer" would go like:

MAX_HITPOINTS 1000
FIRST_STRIKE_FACTOR 10
STONESKIN_FACTOR 10
HEALING_FACTOR 10
MAGIC_DAMAGE_FACTOR 10
COLLATERAL_COMBAT_DAMAGE 100 (untested)

So to be clear, in Bringa's derandomizer you wouldn't need to touch the denominator?

What I don't quite understand is why in xanaqui's derandomizer one needs to BOTH lower combat damage AND raise the denominator... I would have thought both achieve much the same thing.

EDIT: I just ran a test with "xanaqui's randomizer" and it definitely looks like we have pronounced "steps" in the results. I've got to get to work now, but I'll test with the other version later tonight.
The problem is that if you don't increase the denominator in "xanaqui's randomizer", there's a giant step between the 1:1 and 1:1.01 odds that people on the other thread didn't like; basically, it gives huge advantages to tiny odds differences.

In either case, it's a substantial change to combat - basically, either dramatically increases the number of rounds. So while average damage to the winning unit should remain about the same, the odds of winning will skew sharply towards the stronger unit. You will also get more "steps"; exactly how many would require analysis, but I'd guess that they're multiplied roughly by X.

Of course, with a multiplier less than 10, there will be less of a skew. I'd expect that even as small of a number as 2 would have a substantive effect.
 
Very cool. I will keep experimenting tonight and report back.

Different question (and this is really low priority): how much trouble do you think it would be to modify the combat routines once more so that there's a distinct cutoff point at a certain ratio where once more a weaker unit has no chance of hurting a stronger one (I'm thinking of seriously impossible combats like 1 vs 40; I'm not sure yet, but I have a feeling that these changes of ours may introduce some problem in the very late game. I imagine that very powerful units become much less untouchable now, and while often that's a good thing, I'm not sure how I feel about I don't know the Mishabber of Dis being killed by a hundred scouts.
 
Very cool. I will keep experimenting tonight and report back.

Different question (and this is really low priority): how much trouble do you think it would be to modify the combat routines once more so that there's a distinct cutoff point at a certain ratio where once more a weaker unit has no chance of hurting a stronger one (I'm thinking of seriously impossible combats like 1 vs 40; I'm not sure yet, but I have a feeling that these changes of ours may introduce some problem in the very late game. I imagine that very powerful units become much less untouchable now, and while often that's a good thing, I'm not sure how I feel about I don't know the Mishabber of Dis being killed by a hundred scouts.
This could be done. just specify exactly how you want the cutoff defined.
 
TheJopa posted elsewhere a thought that above a certain odds ratio (he said %85, indicating it should be based on the more elaborate percent chance of success rather than the (for example) 5 vs 4.6 'raw' odds), the favored unit ought to be Unable to fail. Instead, if the battle as normally played out were to result in a loss for a much stronger unit, it should win but come away with only one HP left.

This sounds like a good idea to me if the goal is to avoid 'legendary' upsets, but if I was using this 'rule' I'd still prefer not to be able to be certain of victory by ruling them out altogether, so maybe it should come with its own user determined %likelihood.
 
Okay, since I want great resolution in combat results (meaning I'd rather see a stack ending up with 5.9, 5.8, 5.9, 6.1, 5.7, 5.8, 6.0, 5.7 than with 6.2, 6.2, 6.2, 5.8, 6.2, 5.8, 5.8 even though statistically speaking both might amount more or less to the same) I'm experimenting along the way of Bringa's derandomizer. One of the first things I found out is that combining higher MAX_HP with using DENOMINATOR does not work; it seems to break the combat logic (for instance, str 9 units regularly lose to str 6 units). I'm currently testing with the following settings:

MAX_HIT_POINTS
1000

COMBAT_DAMAGE
20

COLLATERAL_COMBAT_DAMAGE
100 (not quite sure about this yet)

COMBAT_DENOMINATOR
1

FIRST_STRIKE/STONESKIN/HEALING/MAGIC_DAMAGE_FACTOR
10

LIFESPARK_BASE_HEAL
800 (because I agree that as they were, Lifesparks were very useless)

I'm going to play a real game with these settings now (because I got tired of testing them in Worldbuilder situations ;P) and report back later.
 
Okay, since I want great resolution in combat results (meaning I'd rather see a stack ending up with 5.9, 5.8, 5.9, 6.1, 5.7, 5.8, 6.0, 5.7 than with 6.2, 6.2, 6.2, 5.8, 6.2, 5.8, 5.8 even though statistically speaking both might amount more or less to the same) I'm experimenting along the way of Bringa's derandomizer. One of the first things I found out is that combining higher MAX_HP with using DENOMINATOR does not work; it seems to break the combat logic (for instance, str 9 units regularly lose to str 6 units). I'm currently testing with the following settings:
There are presently several limits in the code; if you (or someone else) feels that they need both, or in general need X to be much higher than 10, I'll be happy to test to find the problem (and remove it).
 
If you are looking to improve lifespark, I would allow it to remove negative promotions (poisoned, possibly diseased, fatigued, possibly fear, etc) If you are not playing areligion with cure disease, that alone would be enough reason to get it.
 
There are presently several limits in the code; if you (or someone else) feels that they need both, or in general need X to be much higher than 10, I'll be happy to test to find the problem (and remove it).

Nono, definitely not needed. I just wanted to point it out in case someone else was playing with those values.

I think what we should eventually arrive at is one or two sets of recommended setting changes because for the casual "let's try this out" ffh gamer this all is surely too confusing.


jwin said:
If you are looking to improve lifespark, I would allow it to remove negative promotions (poisoned, possibly diseased, fatigued, possibly fear, etc) If you are not playing areligion with cure disease, that alone would be enough reason to get it.

But we aren't looking to improve lifespark ;) Gotta draw a line somewhere. Smarter Orcs is about the AI. Combat randomness has long been a pet peeve of mine, and I'm happy that xanaqui decided to make it part of SO, but strictly speaking that's already outside our scope. Surely we don't want to touch anything beyond this that changes balance. After all, the hope is that this project will arrive at something that the real team can use later for a better AI in FFH.
 
TheJopa posted elsewhere a thought that above a certain odds ratio (he said %85, indicating it should be based on the more elaborate percent chance of success rather than the (for example) 5 vs 4.6 'raw' odds), the favored unit ought to be Unable to fail. Instead, if the battle as normally played out were to result in a loss for a much stronger unit, it should win but come away with only one HP left.

If thats included i would prefer it at 99+% odds.
Otherwise i thing its to strong.
But maybe you could add a second limit at lets say 90% where the weaker unit, should it really win, gets reduced to 1HP.
 
Why would you want it to remove Fear? Fear is a powerful positive promotion, which indicates that other units are afraid of the unit, not that the unit is afraid.
 
Version 0.10 is released. Note the following:
  1. This is still a 0.22h mod. the 0.23 merge will be in the next minor revision or so (barring releases due to major defects).
  2. This will break saved games. This was needed to fix a resource issue from Vanilla Civ. Hopefully the city resource issues are now resolved.
Bonus logic

The major feature in this release (and why it's a major revision, instead of a minor one) is the Bonus logic. Essentially, it is now possible for the AI to value bonuses correctly. For example, it increases the value of mana if:
  1. A player has units that can benefit from affinity.
  2. A player has units that can summon other units that can benefit from affinity.
  3. A player has units that can gain one or more new promotions due to that mana resource.
  4. A player has units that gains a free promotion due to that mana resource.
Furthermore, I put many hooks in the XML, so that parameters that are off can be changed via XML (detail here).

Note that this initial version won't have perfect evaluation of bonuses. The effect this feature has is that we can start to evaluate bonuses correctly, not that they are being evaluated correctly yet. Please report any bonus-related behavior that you find
suspicious; hopefully most fixes can be preformed by tweaking the XML.

Sprawling
The main sprawling fix this time around is so that the AI correctly evaluates sprawling-related information if they are the Kuriotates, and they haven't built only super-cities up to their capacity.

Resource issue
I replaced the earlier fix I had for resources by something which accounts correctly for bonus resources. Hopefully this logic will work better. Unfortunately, it breaks saved games.

Technology change
I noted that the preference for cheap technologies by the AI seemed to be high, so I halved it.
 
I don't know if it's a good idea to make a 0.23 merge, as combat in 0.23 seems broken and Kael is currently working on the BtS conversion
 
I don't know if it's a good idea to make a 0.23 merge, as combat in 0.23 seems broken and Kael is currently working on the BtS conversion
I have no objections to fixing defects, regardless of their source. When I think that the FfH II team would also consider it a defect (their definition of defect is far less broad than mine), I post it on their bug thread.

Could you refer me to the present 0.23c combat problems? I was reading one such thread a while ago, but I was having difficulty in parsing between people who didn't understand how combat works, and those with legitimate complaints.

Here are the changes between 0.22h and 0.23c that directly affect combat:

  1. maxCombatStr (used as an input into combat odds) now uses getExtraCombatPercent() when attacking, and getExtraCombatPercentDefense() when defending.
  2. fortifyModifier returns double the value when this unit has PROMOTION_DEFENSIVE.
  3. UNIT_PYRE_ZOMBIE now has different behavior in CombatWon when it looses (it does damage & sets fires to all in a 1 plot radius).


The indirect effects:

  1. getCombatOdds - the attacker's strength attempts to account for the defender.

I think the problem is that getCombatOdds (the combat odds display to a human) does not match updateCombat (the main combat function).

Here's the getCombatOdds version:
Code:
	iAttackerStrength = pAttacker->currCombatStr(NULL, pDefender, NULL, true);
	iAttackerFirepower = pAttacker->currFirepower(NULL, NULL, true);

	iDefenderStrength = pDefender->currCombatStr(pDefender->plot(), pAttacker, NULL, false);
	iDefenderFirepower = pDefender->currFirepower(pDefender->plot(), pAttacker, false);
Here's the
updateCombat version of the same information:
Code:
			iAttackerStrength = currCombatStr(NULL, NULL, &cdAttackerDetails, true);
			iAttackerFirepower = currFirepower(NULL, NULL, true);
			iDefenderStrength = pDefender->currCombatStr(pPlot, this, &cdDefenderDetails, false);
			iDefenderFirepower = pDefender->currFirepower(pPlot, this, false);

cdAttackerDetails and cdDefenderDetails are irrelevant; essentially they are for the logging function of combat. However, iAttackerStrength is being calculated differently in both places. It looks like the combat odds version is wrong. I'll report this on the main bug thread.
 
I haven't noticed any particular issues in 23 myself, but then, I have always taken combat odds with a grain of salt, as they never seemed entirely accurate anyway.
I am eager to see this come to 23. I tend to jump in and wrangle with the latest versions... of course I don't do any real fine detail work like AI changes :) I'd love to get this into my last modmod update for the "Vanilla" version.
Thanks for all the cool code work guys!

Cheers!
 
My problem with 023 was the non-effectiveness of magic resistance/fire, poison etc resistance. Essentially I ignored the combat odds and just performed plenty of combats of fireballs vs a unit that's strong enough to survive (arquebus for instance) and looked at the difference between arquebuses with and without the resistances. There were no differences. The magic resistance DOES show up in combatodds though.

I don't know what else is broken, maybe Gandalf can tell us?
 
My problem with 023 was the non-effectiveness of magic resistance/fire, poison etc resistance. Essentially I ignored the combat odds and just performed plenty of combats of fireballs vs a unit that's strong enough to survive (arquebus for instance) and looked at the difference between arquebuses with and without the resistances. There were no differences. The magic resistance DOES show up in combatodds though.

I don't know what else is broken, maybe Gandalf can tell us?

Ah... thank you. I see the problem now, and why this apparently erroneous change was made.

here is the central damage type and resistance code (from CvUnit::maxCombatStr):
Spoiler :
Code:
    if (pAttacker != NULL)
    {
        if (getCombatCold() != 0)
        {
            iCombat += getCombatCold() * (100 - pAttacker->getResistCold());
        }
        if (getCombatDeath() != 0)
        {
            iCombat += getCombatDeath() * (100 - pAttacker->getResistDeath());
        }
        if (getCombatFire() != 0)
        {
            iCombat += getCombatFire() * (100 - pAttacker->getResistFire());
        }
        if (getCombatHoly() != 0)
        {
            iCombat += getCombatHoly() * (100 - pAttacker->getResistHoly());
        }
        if (getCombatLightning() != 0)
        {
            iCombat += getCombatLightning() * (100 - pAttacker->getResistLightning());
        }
        if (getCombatPoison() != 0)
        {
            iCombat += getCombatPoison() * (100 - pAttacker->getResistPoison());
        }
        if (getCombatUnholy() != 0)
        {
            iCombat += getCombatUnholy() * (100 - pAttacker->getResistUnholy());
        }
    }
    else
    {
        if (getCombatCold() != 0)
        {
            iCombat += getCombatCold() * 100;
        }
        if (getCombatDeath() != 0)
        {
            iCombat += getCombatDeath() * 100;
        }
        if (getCombatFire() != 0)
        {
            iCombat += getCombatFire() * 100;
        }
        if (getCombatHoly() != 0)
        {
            iCombat += getCombatHoly() * 100;
        }
        if (getCombatLightning() != 0)
        {
            iCombat += getCombatLightning() * 100;
        }
        if (getCombatPoison() != 0)
        {
            iCombat += getCombatPoison() * 100;
        }
        if (getCombatUnholy() != 0)
        {
            iCombat += getCombatUnholy() * 100;
        }
    }

The upshot is that it never accounts for the defender's resistances (only the attacker's). This defect has been in here for a while, likely since damage types were added in the first place.
 
Version 0.11 is released. Note that this is based on FfH II 0.22h.

Settlers
I worked significantly on the Settlement code. There were major defects in how the Kuriotates settle, and more minor defects in how other civilizations settle. There still, I'm sure, are issues, but they should be reduced.

Great Works
The first unit-based special feature is in. Prophets and Disciples can now both create Great Works, and will do so as a fairly low-priority task, and only when both the unit has relatively little XP, and the benefit is regarded as large (for example, a city with 0 culture). The AI will also create a great work instead of destroying a unit. Question: should this also be done for human players, or can someone think of a reason why a human wouldn't want a great work instead of destruction (obviously, only in cases where the great work is valid)?

Defect fix
A early Smarter Orcs defect has been removed, having to do with sprawling on maps that had other than 3 Sprawling cities.

Combat fixes
A combat fix from 0.23c is in, but the most major change is that defending units now get the full benefit of their resistances (previously, they were ignored, save in 0.23 combat odds, which had other problems). Note that at the moment, the minimum combat strength of a unit is 0.01, so a fireball attacking a creature with 100%+ fire resistance will still be able to attack with a 0.01 strength. Please inform me if you think this is essential to change. I think that changing this feature may be significant work.
 
Back
Top Bottom