It seems that you're using an outdated browser. Some things may not work as they should (or don't work at all).
We suggest you upgrade newer and better browser like: Chrome, Firefox, Internet Explorer or Opera

×
Hello everyone...is there any specification about how AC - Speed - to Hit modifier works in these engines? I know that Speed gives a bonus in AC but how is the attack roll being calculated specifically?
Post edited January 30, 2018 by Leprosy57
I don't know the exact mechanics here, but I suspect the formula is something like the following:
Level + Accuracy Bonus + Heroism + RN - AC > constant

RN is a random number, probably something in the 1-20 range (because D&D used a d20); it's definitely a fixed range, as accuracy starts to become not-so-random at higher levels. Accuracy bonus is based on a table, the same ones that other stats use; note that the bonus increases more slowly when the stat gets higher, so it's more important to boost the stat that has a lower value.

Speed affects the character's AC (the bonus is added to the AC from armor, bless, and fountains); it does not have any other effect on the accuracy calculation. It does affect turn order, however, and that can be important.

There are a few things to note:
* Party member melee attacks get multiple hit chances; each is calculated independently (so like Wizardry rather than Bard's Tale); hence, if the stats are such that attacks will sometimes miss, a sufficiently high level character will consistently do some damage, but not as much as if they were strong enough to always hit.
* Bow attacks only get one hit; this makes bows useless later in the game.
* Enemies get only one hit chance; hence, when attacks sometimes miss, you will actually see enemy attacks fail completely some of the time. Note that some enemies make multiple attacks on their turn, each of which is separately targeted; other enemies get one attack on each party member. (There is at least one enemy that physically attacks the entire party at once; I think it's those insects in MM4.)
* There does not appear to be any rule that allows for a minimum or maximum chance for an attack to hit.
* Not all enemies use physical attacks. Quite a few (perhaps even the majority?) enemies use elemental attacks; these attacks always hit, but may be subject to resistance. Note that Protection from Elements does not work the same way as resistance, and resistance doesn't work the same way (from my observations) for party members as it does for enemies. AC only protects against physical attacks; when enemies don't use physical attacks, AC is useless. In particular, I note that Vertigo is one example of an area where AC is useless becuse no enemies use physical attacks.
* Scripted events that do physical damage do not need to make an attack roll; hence AC is useless against them. The only way to defend against such attacks, other than having high HP, is Power Shield.
* I note that an attack that hits but fails to do damage will also fail to cause status ailments. This is partly why Protection from Elements and Power Shield are so useful. (There's one enemy that, in MM3, can kill multiple party members at once, likely leading to lots of game overs in a certain area; Power Shield would be a good idea there.)
avatar
Leprosy57: Hello everyone...is there any specification about how AC - Speed - to Hit modifier works in these engines? I know that Speed gives a bonus in AC but how is the attack roll being calculated specifically?
At least for World of Xeen, you can see the relevant game logic for calculating the "to hit" value against AC in my ScummVM reimplementation here:
https://github.com/scummvm/scummvm/blob/346d09f69b259f270eef65b6da306b96eb6ed765/engines/xeen/combat.cpp#L933
There's also some relevant getArmorClass in character.cpp that calculates what the armor class is.

Even if you're not familiar with C++, the logic should hopefully be clear enough if you trace into the relevant methods to see how each value is calculated.
avatar
Leprosy57: Hello everyone...is there any specification about how AC - Speed - to Hit modifier works in these engines? I know that Speed gives a bonus in AC but how is the attack roll being calculated specifically?
avatar
dreammaster: At least for World of Xeen, you can see the relevant game logic for calculating the "to hit" value against AC in my ScummVM reimplementation here:
https://github.com/scummvm/scummvm/blob/346d09f69b259f270eef65b6da306b96eb6ed765/engines/xeen/combat.cpp#L933
There's also some relevant getArmorClass in character.cpp that calculates what the armor class is.

Even if you're not familiar with C++, the logic should hopefully be clear enough if you trace into the relevant methods to see how each value is calculated.
So, according to the ScummVM implementation, it appears that, at least when a monster is the one attacking:
* If the target is sleeping, the attack automatically hits. (ScummVM only checks for sleeping; can paralyzed characters dodge attacks?)
* There does appear to be a guaranteed chance of hitting or missing (I believe
* If h is the monster's hit chance, the game (or at least the ScummVM implementation of it) seems to add a number between h/4 and (h + h/4), rather than just h; hence, there is more random variation if it is an enemy doing the attack.
* Defending boosts your AC by 5 + half the character's level; hence, if enemies like to attack a certain character, having that character defend might not be a good idea (assuming the attack is physical).

Note that it's possible that the ScummVM implementation might not be entirely accurate to the original, as it is a separate implementation of the original mechanics. (I have not tried to actually test the accuracy; maybe I might test this out once this project reaches a state where it's ready for bug reports.)

Anyway, one question; did you actually reverse engineer the original code to figure this out? If not, how dod you fighre this out?
avatar
Leprosy57: Hello everyone...is there any specification about how AC - Speed - to Hit modifier works in these engines? I know that Speed gives a bonus in AC but how is the attack roll being calculated specifically?
avatar
dreammaster: At least for World of Xeen, you can see the relevant game logic for calculating the "to hit" value against AC in my ScummVM reimplementation here:
https://github.com/scummvm/scummvm/blob/346d09f69b259f270eef65b6da306b96eb6ed765/engines/xeen/combat.cpp#L933
There's also some relevant getArmorClass in character.cpp that calculates what the armor class is.

Even if you're not familiar with C++, the logic should hopefully be clear enough if you trace into the relevant methods to see how each value is calculated.
Question: where did you get this logic from?
avatar
dreammaster: At least for World of Xeen, you can see the relevant game logic for calculating the "to hit" value against AC in my ScummVM reimplementation here:
https://github.com/scummvm/scummvm/blob/346d09f69b259f270eef65b6da306b96eb6ed765/engines/xeen/combat.cpp#L933
There's also some relevant getArmorClass in character.cpp that calculates what the armor class is.

Even if you're not familiar with C++, the logic should hopefully be clear enough if you trace into the relevant methods to see how each value is calculated.
avatar
dtgreene: Anyway, one question; did you actually reverse engineer the original code to figure this out? If not, how dod you fighre this out?
The engine is based on a disassembly of World of Xeen first started by WizardStan, and then worked on further by me before I started using it to implement the ScummVM engine. So barring the possibility of the occasional bug, the code should be a faithful representation of the combat formulas.

On a side note, note that the code area I referred to was indeed just the handling code for dealing with AC for purely physical attacks. If you look at line 290 in the same file, you'll see that for non physical attacks (that if on line 289 should be clearer as monsterData._attackType != DT_PHYSICAL) that it calls c.charSavingThrow with the monster's attack type.

Interestingly enough, the Character::charSavingThrow in character.cpp doesn't use anything from the attacking monster beyond the attack type.. all the logic for checking if the character resists the attack is purely based on the character themselves. Which means characters have just as much chance of getting a non-physical save against a high level monster vs a low level one.
avatar
dreammaster: Interestingly enough, the Character::charSavingThrow in character.cpp doesn't use anything from the attacking monster beyond the attack type.. all the logic for checking if the character resists the attack is purely based on the character themselves. Which means characters have just as much chance of getting a non-physical save against a high level monster vs a low level one.
From playing the game, I noticed that the saving throw mechanic seems to be the same (or at least similar) from scripted elemental damage. For example, there's a trap in the Dragon's Tower that deals 10000 points of fire damage to the party; this would be game ending if it weren't for the fact that you can save multiple times against the effect to reduce it to something survivable.

On the other hand, against scripted physical damage, Power Shield seems to be the only protection; this is why a certain even on the Elemental Plane of Earth is so deadly. You *might* need to use that 2500 HP fountain to survive the attack. (Of course, there's the occasional scripted event that kills/eradicates the entire party; there's obviously no surviving these.)

By the way, I noticed that the code for elemental damage gives you a saving throw to halve the damage before showing the animation, then gives you more chances to save against the attack (until you fail) afterwords. In other words, if you fail the first saving throw attempt, you still get another chance. Is this correct?
avatar
dtgreene: By the way, I noticed that the code for elemental damage gives you a saving throw to halve the damage before showing the animation, then gives you more chances to save against the attack (until you fail) afterwords. In other words, if you fail the first saving throw attempt, you still get another chance. Is this correct?
I double-checked, and that's what the original has, yes. There's the first saving throw that can reduce the damage by half before the character's resistance to that type is subtracted. Then, afterwards, it does a saving throw again, and as so long as it succeeds, it keeps reducing the resulting damage by half and then doing another throw. So a lucky series of saving throws can significantly cut down the damage done by an attack.

I'm attaching a screenshot from the relevant section of the doCharDamage method in my IDA disassembly in case anyone is interested.
Attachments:
Post edited January 31, 2018 by dreammaster
avatar
Leprosy57: Hello everyone...is there any specification about how AC - Speed - to Hit modifier works in these engines? I know that Speed gives a bonus in AC but how is the attack roll being calculated specifically?
avatar
dreammaster: At least for World of Xeen, you can see the relevant game logic for calculating the "to hit" value against AC in my ScummVM reimplementation here:
https://github.com/scummvm/scummvm/blob/346d09f69b259f270eef65b6da306b96eb6ed765/engines/xeen/combat.cpp#L933
There's also some relevant getArmorClass in character.cpp that calculates what the armor class is.

Even if you're not familiar with C++, the logic should hopefully be clear enough if you trace into the relevant methods to see how each value is calculated.
Amazing! Thank you very much... everything is clear when you look at the code ;)
I was waiting for years waiting when someone will finally disassemble MM3-5 combat mechanics. I am glad to see that people working with SCUMMVM finally did that!

It would be great if someone made a wiki page somewhere to summarize combat mechanics in one neat place.
In MM3 your chance to do damage to monsters with good AC is lower than in WoX where a bigger random factor seems to be involved.
avatar
Sarisio: I was waiting for years waiting when someone will finally disassemble MM3-5 combat mechanics. I am glad to see that people working with SCUMMVM finally did that!
I'm happy that there'll be people looking forward it when it's completed. :). I'm also actually kind of excited to see what else might come from it in the future. After all, Swords of Xeen was done as a mod of M&M5.. it would be so much easier for someone to create custom editing tools with game source available, particularly all the needed scene rendering code. Another thing I've wondered, is whether parts of the UI would be transferrable to other games. For example, imagine M&M2's scene and automap transplanted into the Xeen UI. I never played the game because I disliked all the text on-screen I saw in Youtube playthroughs. But I could envisage playing it with Xeen party glyphs, and proper popup status dialogs, etc.

Though I hurry to point out this is just an idle fancy that would require reverse engineering M&M2 first. And I've already got tentative plans for the next several years after I finish on Xeen working on Legend Entertainment games like Companions of Xanth. Maybe someone with reverse engineering skills can follow in the steps of WizardStan and start working on a disassembly for us.
avatar
Leprosy57: Hello everyone...is there any specification about how AC - Speed - to Hit modifier works in these engines? I know that Speed gives a bonus in AC but how is the attack roll being calculated specifically?
avatar
dreammaster: At least for World of Xeen, you can see the relevant game logic for calculating the "to hit" value against AC in my ScummVM reimplementation here:
https://github.com/scummvm/scummvm/blob/346d09f69b259f270eef65b6da306b96eb6ed765/engines/xeen/combat.cpp#L933
There's also some relevant getArmorClass in character.cpp that calculates what the armor class is.

Even if you're not familiar with C++, the logic should hopefully be clear enough if you trace into the relevant methods to see how each value is calculated.
I'm looking at the code...so far, the process has been very insightful. However, I stumbled upon this line:

#1673: return chance >= (monsterData._accuracy + 10);

I understand this is the check to see if the character has a chance to hit the monster. However, the monster data used to do the check it's the monster's accuracy. Shouldn't be it's Armor Class instead? Or is there something that I'm not considering here?

Thanks!
avatar
dreammaster: At least for World of Xeen, you can see the relevant game logic for calculating the "to hit" value against AC in my ScummVM reimplementation here:
https://github.com/scummvm/scummvm/blob/346d09f69b259f270eef65b6da306b96eb6ed765/engines/xeen/combat.cpp#L933
There's also some relevant getArmorClass in character.cpp that calculates what the armor class is.

Even if you're not familiar with C++, the logic should hopefully be clear enough if you trace into the relevant methods to see how each value is calculated.
avatar
Leprosy57: I'm looking at the code...so far, the process has been very insightful. However, I stumbled upon this line:

#1673: return chance >= (monsterData._accuracy + 10);

I understand this is the check to see if the character has a chance to hit the monster. However, the monster data used to do the check it's the monster's accuracy. Shouldn't be it's Armor Class instead? Or is there something that I'm not considering here?

Thanks!
There are 2 possibilities here:
1. The ScummVM develpoers made a mistake; in this case, ScummVM has a bug and it should be fixed.
2. World of Xeen has a bug, and ScummVM faithfully re-implements that bug. In this case, ScummVM should be left as is (otherwise, game balance will be affected).

One consequence; this bug (regardless of the source) means that the Accuracy of Annihilators and Autobots would actually matter; does anyone know what the values are? (The list I've seen with enemy stats omits the accuracy of monsters with non-physical attacks.) I distinctly remember my attacks not always hitting against those enemies.

Perhaps some testing might be in order here.
avatar
Leprosy57: I understand this is the check to see if the character has a chance to hit the monster. However, the monster data used to do the check it's the monster's accuracy. Shouldn't be it's Armor Class instead? Or is there something that I'm not considering here?

Thanks!
Good catch. It is actually meant to be Armor Class; it's just incorrectly named, but I confirmed the logic is still correct. The field is named "acc" when looking at the details in the Xeen Wiki, as in:
acc 0 Monster's armor class (physical defence)

When I was setting up the monster structure, I must have presumed that was short for accuracy without looking at the full description :)