DM mechanics - Azizi through the mirror of dawn

Discuss anything about the original Dungeon Master on any of the original platforms (Amiga, Atari, etc.).
This forum may contain spoilers.

Moderator: Ameena

Forum rules
Please read the Forum rules and policies before posting.
User avatar
Automaton
Journeyman
Posts: 88
Joined: Sat Aug 28, 2004 10:49 am

DM mechanics - Azizi through the mirror of dawn

Post by Automaton »

A bit of a story to start..

DM has always been magical for me. I come back to it every 5 years or so to see what's new.

I looked at Legend or Grimrock, but it didn't feel the same, you know.. ..that feeling when you've driven the best and nothing else will just quite do. I am open to new ideas, but I have not found many games that have engaged me quite as DM did. I did spend a few years in X3, with one game save and such big fleets and factory complexes. Ive put quite a few hours into cities skylines, using my art and blender skills to create my own models and stuff and I've played world of tanks in my clan for many years, but the nostalgia for DM is strong.

I first posted here in 2004 I think, and when coming back this time, I was surprised that my lastpass wanted to autolog me - I'd forgotten I was here all those years ago. And before I start on the point of this thread, I want to give a huge shout out to Paul Stevens, Christophe F, George Gilbert and Sophia for the amazing work they have done in constructing and deconstructing DM so that we can muck about a bit. Equally huge shout to the extremely helpful forum regulars - you know who you are. Also kudos to Zolaerla for his vid
So, I find myself on holiday, but stuck at home mostly (I do go out with the kids from time to time, we have a crazy golf obsession) because covid cancelled my holiday :(

I'm a composer and former beta tester for FL studio, XOR I am known as (and XOR42 if you play world of tanks on the eu servers). You can find my stuff here and here if you are interested.

Anyhoo - I was remixing some stuff and my mind went back to the B.I.G Demo on the atari ST - so I went, got hatari, got a rom, found an image and managed to get the B.I.G Demo working on my PC.

Big mistake, it made me think of DM straight away. I started watching Gears of Games hes got a 46 part DM playthrough that he started mid last year. Oh dear, I had to have a go again..

Downloaded CSBwin
Downloaded ADGE
Downloaded CSBwin source
Downloaded ReDMCSB

Started browsing these forums again....

..and for some reason I stumbled across the comment on DM encyclopedia that anti-fire and anti-magic never worked on any Atari version of the game (Due to a compiler error according to Christophe)

I chatted to Paul about it and he showed me the comments in the code (seems it is fixed to work in CSBwin)

What else was DM hiding?

So I've being looking at my CSBwin trace logs and trying to follow it through in the source code. For some reason, my brain finds it fun to dig through this stuff and find out what the actual F is going on. So hopefully (as long as I keep finding it interesting) I'll keep going.

Part 1 - What the actual F is going on when you hit a monster with a weapon?

The trace log as quotes, bits of pseudo code, code, source code as code, my enlightened comments outside of these two.

I'm using CSBwin 17_6 and the latest source file package I could find.

Dungeon Master Encyclopedia is shortened to DME here after

For the different action stats on DME

Here is my character, GOFFER attacking a Trolin at the end of level 2

We start in..

//Function RESTARTABLE _Attack, line 1629, attack.cpp
GOFFER attacks from 02(1d,19) to 02(1d,1a)
Attacking from location x to location y
Attack type = 2 = CHOP
He's using chop on the falchion
Skill number required = 06
Hidden skill 6 (club) selected
Byte20046[attackType=2] = 8
Stamina cost of using chop = 8
staminaCost = Byte20046[attackType=2] + Random(1) = 9
staminacost is = action_stamina_cost + (0-1), so 8-9
experiencedGained = Byte20178[attackType=2] = 10
experiencegained = actions_experience_gain stat, so 10 for chop
Attack BASH/HACK/BERZERK/KICK/SWING/CHOP
Enter AttackWithPhysicalForce (attackType=2, skillNumber=6)
D6W=Byte20002[attackType=2]=48
D7W=Byte19958[attackType=2]=48
//function AttackWithPhysicalForce, line 1048, attack.cpp

D6 gets loaded with action_hit_probability (byte20002) of attackType 2 which in this case is 48 for chop. According to the DME this value is out of 75, so chop has a 48/75 % chance to hit, in this case 64%
D7 gets loaded with action_base_damage (byte19958) of attackType 2 which in this case is 48 for chop
The function looks at if the attack is valid or not (facing the right way, something infront of you etc...) and then calls the next function...
Calling DeterminePhysicalAttackDamage(character, monster, D5W-1, D6W, D7W, skillNumber)
Entering DeterminePhysicalAttackDamage(char=1,monster,P4=0,P7=48,P8=48,skillNumber=6)
levelDifficulty = 1
pi26 word2 &0x40 == 0 or vorpalOrDisrupt
//function DeterminePhysicalAttackDamage, line 532, attack.cpp

Checks wether a physical attack is possible, whether you are trying to attack with a dead character etc.
levelDifficulty = 1 is obvious, its the dungeon level experience multiplier DME
It also sets up a variable "objNI_attackWeapon" which is basically to know what weapon you are using
Checks whether the attack is a vorpal blade or disrupt attack and then calls the next function, quickness..
Entering function to determine character's Quickness
quickness = (Dexterity=52) + (random(8)=6) --> 58
About to compute Maximum load
Loading effect=(quickness/2)*(load=154)/(maxload=470)-->9
Subtract loading effect from quickness -->49
Low Limit = random(8) + 1 --> 8
High Limit = 100-random(8) --> 93
Final quickness = 24
character's quickenss = 24

//function Quickness, line 2210, character.cpp

Well, Paul calls it quickness, but the above code works out your classic D&D "to hit roll" vs the monsters "needed to hit roll"

So to_hit = your current dexterity + rand(8), so for GOFFER this would be (52-60), I got 58

The next 2 lines work out your load penalty and subtract it from to_hit:

Loading effect=(to_hit/2)*(load=154)/(maxload=470)-->9 I think this is pretty obvious. GOFFER is carrying 15.4 kg / 47 kg.
Therefore if my load had been 0 I would have had a penalty of 0. A load of 47 kg, would have been 29 which means the penalty is 0-50% of your to_hit roll

So, my to_hit is 58 minus my weight penalty of 9 = 49

It then checks to see if you are sleeping and if true to_hit is halved (How do you attack whilst sleeping?)

Then your to_hit is flat divided by 2, so I get 24 (it's rounded down, obvs.)

Then two random limits are set up loLimit = rand(8)+1, hiLimit = 100-rand(8), so the limits are 1-9 to 92-100, if your to_hit falls outside the limits, it gets set to them

Quickness ends returning your to_hit chance, for this case 24

Important note: Notice that action_hit_probability is not used anywhere in calculating your to_hit chance. This seems odd to me. In fact the action_hit_probability is only used in your luck roll, if you miss normally.

//Back to DeterminePhysicalAttackDamage
required quickness = (pi26.uByte8[4]=41) + (random(32)=0) + (levelDifficulty=1) - 16 = 26
Required quickness is the needed_to_hit. It's calculated in D1. It combines pi26.uByte8[4] which is the monsters defence rating (41) for the Trolin I am attacking with a rand (32), the dungeon level experience multiplier (1 for level 2) and then a - 16. I get 26.

So for a Trolin on level 2, it's needed_to_hit could range from 26 to 58

hyp: for a Trolin on level 13, it's needed_to_hit could range from 31 to 63 //dungeon level experience multiplier=6
hyp: for a Dragon on level 13, it's needed_to_hit could range from 60 to 92 //dungeon level experience multiplier=6, defence=70
hyp: for a Wasp on level 6, it's needed_to_hit could range from 137 to 169 //dungeon level experience multiplier=3, defence=150 (highest monster defence rating)
Attack was successful because Lucky Hit (1 chance in 4)
Next come 3 checks to see if "you hit"

Code: Select all

1. if your to_hit is > needed_to_hit, you hit. If not, next option
2. a rand(3) is generated, if it's = 0, you hit, if not, next option
3. Call IsCharacterLucky (pchA3, 75 - P7, nextTracePrefix(traceID))
You can see above, my to_hit failed, but my option 2 lucky number succeeded, but lets look at option 3 for completeness.

//function IsCharacterLucky, line 2166, character.cpp

pchA3 is the character performing the attack

The important stat is the 75-P7, which the function calls "luckNeeded", with P7 being the value for action_hit_probability which is 48 for the chop action. So 75 - 48 = 27.

Important note: As stated above, action_hit_probability only seems to be used here in luck.

Bizzarely it looks like there are 2 checks in the code;

Code: Select all

1. if a rand(100) > luckNeeded return true  - i.e. you hit!
2. if a rand(yourcurrentluck) > luckNeeded , deduct 2 from ourcurrentluck and return true (you hit!) else add 2 to yourcurrentluck and return false
So this is (maybe one of) the mechansim(s) that increase your luck if you fail and reduce it if you succeed

//Back to DeterminePhysicalAttackDamage

So if all your to_hit chances fail, it deducts 2+rand(1) from your stamina and that's it, the attack ends with no damage.

Otherwise, it moves on to work out how much damage you do.. with a 2 phase calculation starting with a call to function DetermineThrowingDistance

Buckle yourselves in, this one is rough..... :twisted:
46 47 33 29 79 0 4 87 0 43
ThrowingDistance char=1 hand=1 value=43
//function DetermineThrowingDistance, line 2268, character.cpp

I'll colour the numbers orange as I go down so you can see where they are coming from.

That line of numbers I got with the timer trace turned on as well as the attack trace. Deciphering them was a little trickier.
I've pointed out to Paul that this function name is misleading, it's actually working out the base damage done. If you are getting hung up on all the D numbers these are just registers hold variables, just follow the logic and it might make sense. Here's what that string of figures in the trace file are...

D3 is loaded with current character strength. I got 46 on GOFFER
D7 is loaded current character strength + rand(15). I got +1 so 47, D7 is the damage_coefficient it is working on
D6 is loaded with the weight of the weapon you are using. So 33 for the falchion (it's 3.3 KG) I'll call it weapon_weight
D5 is loaded with current characters max load / 16. So 47 for GOFFER divided by 16 = 2.93, hence the 29, this is load_coefficient

Next comes some very convoluted math to determine a weighted bonus

Code: Select all

if weapon_weight (D6) <= load_coefficient (D5) then damage_coefficient (D7) = damage_coefficient (D7) + weapon_weight- 12
This is untrue in this case because the weapon_weight of the falchion is 33 which is greater than load_coefficient of 29 but it would have been = 47+33-12 = 68

Code: Select all

else 
	
temp_coefficient_A = ((load_coefficient-12)/2+load_coefficient)
This would be ((29-12)/2+29) = 37 (37.5 but rounded down)

Code: Select all

temp_coefficient_B = temp_coefficient_A

if weapon_weight <= temp_coefficient_B then damage_coefficient = (damage_coefficient + (weapon_weight -load_coefficient)/2)
So the load_coefficient (D5) which is 29 has been dropped for temp_coefficient_B which is 37, obviously, the 33 weight falchion is going to pass this test

It works out as (47+(33-29)/2) = 49 for GOFFER because it's true

Code: Select all

else damage_coefficient = (damage_coefficient - 2 * (weapon_weight - temp_coefficient_A))
This would be (47-2*(33-37) = 55 if it were true, but it is not

Now a small check...

Code: Select all

if held obj !=null and is a weapon then damage_coefficient = (damage_coefficient + weapon_base_damage)
This is 49+30 (my current damage_coefficient + 30, the base damage of the falchion) and this is where the 79 comes from in the string of figures.
If I had passed test 1 it would be 68+30= 98 or if it had passed test 3 it would have been 55+30 = 85

Important: it's weapon_base_damage (the falchion) not action_base_damage (chop)

Next it checks a byte on the weapon to work out which type of mastery it should use as a damage multiplier, for the falchion byte1 = 0 which is the next figure after the 79

If I am correct reading the code;

Code: Select all

1. if byte1 = 0 or 2, then get mastery of skill 4 (swing)
2. if byte1 != 0 and < 16 then get mastery of skill10 (Throw)
3. if byte1 >= 16 and < 112 then get mastery of skill 11(Shoot)
Odd to me that if byte= 2 it could pass both tests 1 and 2. Dagger, Axe, Hardcleave have a value of 2. //note to self, ask Paul

Anyhow, It calls the function DetermineMastery on the result which is 4 and my mastery_level in swing is 4, Apprentice

Code: Select all

damage_coefficient=(damage_coefficient + 2 * mastery_level)
This is (79+2*4) = 87. If I had << master in swing, it would be ((79+2*10) = 99.

Next it does a funky little function call to StaminaAdjustedAttribute with my damage_coefficient of 87

//function StaminaAdjustedAttribute, line 4291, Code11f52.cpp

Paul makes this one easy with his comments "// If below half stamina"

Basically, if you are below half stamina it divides damage_coefficient by 2 and adds a portion back based on your current stamina vs maximum stamina. Otherwise it does nothing and returns the original value it was given.

In my case , it does not affect me, so the next figure in the string of numbers stays at 87

//Back to DetermineThrowingDistance

Next, this function works out if you are hurt in the hand. I am not, so the next figure in the string of numbers is 0, not hurt.

Code: Select all

if hurt = true and hand = true then damage_coefficient=damage_coefficient / 2
If your hand is hurt, damage_coefficient is halved.

Code: Select all

damage_coefficient=damage_coefficient / 2
damage_coefficient is arbitrarily halved given the final figure in the string, 43 (43.5 rounded down)

Phew, we finished the DetermineThrowingDistance which is actually base damage.
D7W = Throwing distance=43
D7W = D7W+random(D7W/2+1) = 50
D7W = D7W*(P8=48)/32 = 75
Now we are modifying D7 (a new temp version of damage_coefficient) again first by a random of itself/2+1 so this would be 43 + (0 to 22) + 1 which gives a range of 44-66
then it's multiplying it by action_base_damage/32 which is (48/32) = 1.5 so 50*1.5 = 75

Important: this is the action_base_damage, so chop which is 48, not the weapon_damage.

Now we have our final temporary damage, time to work out how much the monsters AC mitigates it...
D4W = (i26->uByte8[0]=28) + (levelDifficulty=1) + (random(32)=20) = 49
So D4 is the monsters AC_coefficient, formed from it's static AC (ubtye8), 28 for a Trolin, +1 for dungeon level difficulty + rand(32). So I get 49 (well the monster does). See here for monster stats. This Trolin could have had an AC_coefficient of 29-61

A few more examples;

for a rockmonster this would be (0 to 32)+170+1 = AC_coefficient of 171-203
for a screamer this would be (0 to 32)+5+1 = AC_coefficient of 6-38

Now you can see why you get such small damage against rockmonsters, it's easy enough to win the to_hit roll, but nearly all the damage you do gets mitigated.

Now that variable objNI_attackWeapon comes into play..

Code: Select all

if (objNI_attackWeapon == objNI_DiamondEdge) then AC_coefficient=AC_coefficient-(AC_coefficient/4)
If you are using the Diamond edge, 25% of the monsters AC_coefficient is lopped off

Code: Select all

if (objNI_attackWeapon == objNI_Executioner) then AC_coefficient=AC_coefficient-(AC_coefficient/8)
If you are using the Executioner, 12.5% of the monsters AC_coefficient is lopped off
D7W = D7W + (random(32)=15) - (D4W=49) = 41
The big line, this works out how much temp damage_coefficient gets through or not

D7 (temp version of damage_coefficient) + rand(32) - monster AC_coefficient, so this could have been 75 + (0 to 32) - 49. So D7 (temp version of damage_coefficient) = 26 to 58
D6W = D7W = 41
What happens next is mad - lots of chances to do damage basically...

It places the value of D7 (temp version of damage_coefficient) into D6 so it can do the following check:

Code: Select all

if damage_coefficient = 0 or D6 <=1 then 
basically you hit but are about to do 0 damage

Code: Select all

	D7 = rand(3)  

In which case the character gets another 3 in 4 random chance to inflict damage.

Code: Select all

	if D7 = 0
	
		character_stamina=character_stamina - 2+rand(1) // (2 to 3)
	
		return 0

Luck out, reduce stamina and return a 0 damage

Code: Select all

	if D7 != 0
	
		D1 = rand(16) // (0-16)
		D6 = D6 + D1

It adds a random(16) to your D6 (the copy of temp version of damage_coefficient)

Code: Select all

	if D6 > 0 or rand(boolean) = true then 

Yup! even if your rand in D6 was a 0, you still get another 1 in 2 chance for this to be true (the random boolean). The game really wants you to do some token damage

Code: Select all

	D7 = D7 + rand(3)
	
	if rand(3) = 0 

Yet another 1 in 4 chance to do damage

Code: Select all

	D7 = D7 + rand(16) + D6

The rand(16) is limited to a max of D6

Finally out of all that random shenanigans!

Now that we have passed the damage mitigation part and got into the "so how much damage am I going to do" part, we are going to run through, what looks like to me, a set of normalisation algorithms
Divide D7W by 2 --> 20
D0W=random(D7W) --> 3

So D7 (temp version of damage_coefficient) is halved, D0 becomes a rand of D7, so rand(20) in this case, and D1 (not seen in the trace) is a rand (3).
D7W += (random(4)=3) + (D0W=3) --> 26
Now added together. This had the range of 20 + rand (20) + rand(3) so 20-43
D7W += (random(D7W)=2)--> 28
Then if D7 != 0 add another rand of (D7) which is now 26 so the result could have been 26 + rand(26) so 26-52
Divide D7W by 4 --> 7
Now D7 / 4 so; 28 / 4 = 7
D7W += (random(4)=0) + 1 --> 8
AND FINALLY damage = D7 + rand (3) + 1 which is 8, all that math to arrive at 8 hps of damage

There is also a similar section of code, just to workout vorpal blade damage which I won't go into here.

But it's not entirely finished. The next bit of code is not in my log, but if it does happen it will output to the log

Code: Select all

D0 = rand(64)
//function DetermineMastery, line 13, charactercode17818
Enter DetermineMastery(hero=GOFFER, skill=6)
Extract two flags from skill number.
flag8000 = skill&0x8000 --> 0
flag4000 = skill&0x4000 --> 0
SkillNumber = 6
Mastery = log2(Experience=469) --> 3
Mastery of skill 6 is 3

Code: Select all

D1 = DetermineMastery(pParam->charIdx, pParam->skillNumber, traceID==NULL?NULL:traceID-2))
You can see in the log the function of this and result, Mastery of skill 6 is 3 or I'm a novice at club

//Back to DeterminePhysicalAttackDamage

Code: Select all

if D0 < D1 then D7=D7+10
So D7 is the final damage you do to the monster, but if on a rand(64) you roll less than you skill_ mastery_level(skillNumber) which you recall is 3, the level of my (club) skill then it adds 10 damage.

So as a neophyte in club, you have a 1 in 32 chance of adding 10 damage
So as a << master in club, you have a 1 in 6 chance of adding 10 damage

I believe this to be a "critical hit" mechanic

Then this happens in the c++ code....

Code: Select all

pParam->attdep.physicalAttack.monsterDamage = D7W;
...which actually damages the monster.

D0W = ((D7W=8) * (Bits8_11(i26.word16)=1)/16) + 3 --> 3
Working out some experience here for the damage done

D0 = (D7) * ((Bits8_11(i26.word16)=1)/16) +3 so; According to ADGE, bits 8-11 of word 16 are "Skill" DME calls it "Experience class"

My Trolin is skill=1 which means the above is (8*0.0625)+3 so; 3.5 rounded down to 3 :(

A few examples plugged into the above formula
Giant scorpion=9 (8*(9/16))+3 = 7
Materializer=12 (8*(12/16))+3 = 9
AdjustSkills((skill=6), (D0W=3))
Decrement Stamina by random(4)+4 = 7

So adjust skill 6 by 3xp , meh.

Decrement stamina by 4 + rand(3) (I know the log says 4, but the c++ says STRandom0_3 which I take as 0-3, so 4 values possible)

Again, another section of code after this describes the process for a vorpal weapon. Not going into that here.
AdjustSkills chidx=01 skill=06 by 03 skill[06]=000002cd skill[00]=00000bd7
Skill 6 up by 3 xp, skill 0 up by 3 xp
Monster[0] at 02(1d,1a) {HP=48} loses 08 hitpoints
w_2 = DamageMonster() --> 8
PhysicalAttack returning D7W = 8
Word20264 = Result of calling DeterminePhysicalAttackDamage = 8
Return 1

Just returning values, nothing to see here.
000144a0 timer create 003 02 DLY=0008 0b 01 00 cd cd cd c783 de224393
Just something in the log.
AdjustSkills chidx=01 skill=06 by 0a skill[06]=000002e1 skill[00]=00000beb
Although not in the log, just before this code stamina gets decremented by our staminacost of (9)

This line is showing the 10 xp for chop stored in experiencedGained being added to skill 6 and skill 0 (0a being 10 in hex)
Increase skill 06 by 0a to 2e1
Yup.

End of attack trace and end of part 1.

2.06 am tired, going to bed.
Nick K
User avatar
jayrshaw
Lo Master
Posts: 388
Joined: Fri Jun 12, 2020 3:39 pm
Location: Washington, DC

Re: DM mechanics - Azizi through the mirror of dawn

Post by jayrshaw »

Hi Nick,

Thanks for posting this information - it's really interesting. I have to admit that some of the code went over my head, but I think I at least took away the fact that the experience multiplier for the level of the dungeon you are on actually factors into the difficulty of the monsters located on that level.

One thing that I wasn't able to figure out from trying to parse the damage portions of the code is what causes the amount of damage dealt to an enemy to vary by a sometimes extreme amount from blow to blow. I've been killing a lot of screamers on Floor 3 of the dungeon, and the amount of damage my characters deal to a screamer in a single blow can vary from less than 15 points of damage to in excess of 180 points of damage (this is using the "Stab" attack with a dagger). I saw a bunch of random variables in the code you posted, but I couldn't immediately identify anything that stuck out as something that would cause as high a variation in the amount of damage dealt as what I have been witnessing. Since I am probably just missing it, could you point out the specific function(s) that might account for this variation? Is it just the combination of a bunch of random variables from several functions working in my favor when my characters deal in excess of 150 damage? If it means anything, I would say that my characters deal 10-50 damage about 75% of the time they score a hit; however, if they deal damage higher than that amount, there is a high chance that the amount of damage they deal is *much* higher than that (often in excess of 100 points of damage).

Thanks again for posting this information!


--Jay
User avatar
Paul Stevens
CSBwin Guru
Posts: 4318
Joined: Sun Apr 08, 2001 6:00 pm
Location: Madison, Wisconsin, USA

Re: DM mechanics - Azizi through the mirror of dawn

Post by Paul Stevens »

Automoton wrote:2.06 am tired, going to bed
I'm tired just reading what you wrote. Wow! What an amazing piece of research.
I might as well try to understand the proof of the four color theorem.
User avatar
Automaton
Journeyman
Posts: 88
Joined: Sat Aug 28, 2004 10:49 am

Re: DM mechanics - Azizi through the mirror of dawn

Post by Automaton »

Hi Jay,

It took me a couple of hours to do this, but it was worth it A) to help you out and B) prove what my first post was on about.

I few pre notes;

1. If you didn't get it from my initial wall, it's built into the code that if your to_hit roll passes, but at the end of the damage calculations it comes out almost 0 or 0, there are multiple catch mechanisms that try to give you a little bit of damage done. If these were not here, I am sure low level characters would "seem to miss" a lot more often.

2. Looking at the math, I am almost certain that action_damage is more important than most other variables.

3. if you look at the notes at row 72, you will see (probably) what I think, it is no accident many action_damage values are multiples of 32 (what it gets divided by to work out the multiplier). Bezerk at 96 (x3), chop, kick, stab, cleave at 48 (x1.5), punch at 32 (x1), swing, slash, stun at 16 (x0.5)

Here goes..

So I set up for your screamer on level 3 using stab... all the variables are there. Min is worst case scenario, Max is rolls royce time.

I am assuming we have already passed the to_hit part and now we are calculating damage.

Image
Image
Image

Hopefully it's understandable?
Cheers
Nick K.
User avatar
Automaton
Journeyman
Posts: 88
Joined: Sat Aug 28, 2004 10:49 am

Re: DM mechanics - Azizi through the mirror of dawn

Post by Automaton »

Part 1a - To hit and AC coefficient tables for all the monsters on the levels they are found

Notes.

Wasps are clearly not meant to be hit physically (if you do you are relying on luck to hit them), hence the 0 poison and magic resist that they have

Your to_hit roll can never be greater than 100

Image
Last edited by Automaton on Tue Jul 14, 2020 3:46 pm, edited 1 time in total.
User avatar
jayrshaw
Lo Master
Posts: 388
Joined: Fri Jun 12, 2020 3:39 pm
Location: Washington, DC

Re: DM mechanics - Azizi through the mirror of dawn

Post by jayrshaw »

Thanks again, Nick! As I study the damage spreadsheet more carefully, I'm seeing quite a few places where random factors are applied to the working damage coefficient. From what I can tell, the random factors applied on Rows 68, 94, 99, 113, and 117 appear to be the ones that would have the most impact on actual damage output; if I'm reading the spreadsheet correctly, it looks like some of these random factors (e.g., the ones on Row 113 and 117) can individually double damage output prior to moving on to the next step of the equation. I guess all of these random factors combined can have a major impact on how much damage is dealt to the enemy.

One more thing I'm getting out of this is that you never want your characters' stamina levels to fall below 50% of their maximum. In addition to having some negative impact on your characters' carrying capacity (if I remember correctly from some older posts), being below this level also apparently reduces your characters' damage coefficient by 25%!


--Jay
User avatar
jayrshaw
Lo Master
Posts: 388
Joined: Fri Jun 12, 2020 3:39 pm
Location: Washington, DC

Re: DM mechanics - Azizi through the mirror of dawn

Post by jayrshaw »

Automaton wrote: Tue Jul 14, 2020 3:36 pm Part 1a - To hit and AC coefficient tables for all the monsters on the levels they are found

Notes.

Wasps are clearly not meant to be hit physically (if you do you are relying on luck to hit them), hence the 0 poison and magic resist that the have

I wonder if this is something that was somehow modified (i.e., made less difficult) on the SNES version of the game. While playing the SNES version of the game, I have never experienced too much difficulty hitting giant wasps with ordinary physical attacks. In fact, I considered the wasps to be one of the easiest enemies in the game to take down due to their very low health values (they usually go down after just a couple of swings). I do recall having more difficulty with gigglers, though (especially since they tend to run away so quickly)...


--Jay
slickrcbd
Adept
Posts: 279
Joined: Sun Dec 09, 2007 7:49 am

Re: DM mechanics - Azizi through the mirror of dawn

Post by slickrcbd »

Sounds like they have definitely been nerfed then. Those wasps are annoying and really hard to land a decent blow on. Most attacks just do superficial damage to the point where using the rapier to jab them is often more effective than almost anything else.

Yet they die almost instantly to LO OH VEN on level 6 ("The Riddle Room") (with two exceptions that need an UM OH VEN or two LO OH VENs).
Later on when you meet them deeper in the dungeon they all die to ON level spells, and IIRC a good deal will die to UM OH VEN.
User avatar
jayrshaw
Lo Master
Posts: 388
Joined: Fri Jun 12, 2020 3:39 pm
Location: Washington, DC

Re: DM mechanics - Azizi through the mirror of dawn

Post by jayrshaw »

That's really interesting. I just chop at the wasps like I do most other enemies, and they tend to go down really quickly (sometimes in one hit due to their low HP). I would like to know what other differences there are between the SNES version of the game I've been playing and the more standard versions of the game typical members of this forum play.

One other difference I'm pretty certain about is that gigglers in the SNES version of the game can steal random items from your characters' inventory (not just your hands). I'll have to verify this once I get down to the levels where they show up in the dungeon, but I distinctly remember an earlier playthrough where I ended up retrieving all sorts of random stuff that was stolen from my characters' inventory by a giggler on Floor 7 of the dungeon (the floor with the huge open area that makes it easy for the giggler to retreat from you). I also remember that it was not especially easy to kill gigglers in the SNES version of the game, either (this is how the one on Floor 7 was able to steal so much stuff from me before I took it down). I could hit them with physical attacks without too much difficulty, but I recall them being able to withstand quite a few direct hits before they actually died. As a result, I would hazard a guess that the SNES gigglers have a significantly higher base HP value than gigglers in more standard versions of Dungeon Master, but significantly lower evasion; I recall them even being able to withstand a couple of relatively powerful fireballs before going down (and this was with a party that could kill most types of enemies using a single fireball).


--Jay
User avatar
Automaton
Journeyman
Posts: 88
Joined: Sat Aug 28, 2004 10:49 am

Re: DM mechanics - Azizi through the mirror of dawn

Post by Automaton »

Paul Stevens wrote: Tue Jul 14, 2020 8:50 am
Automoton wrote:2.06 am tired, going to bed
I'm tired just reading what you wrote. Wow! What an amazing piece of research.
I might as well try to understand the proof of the four color theorem.
Thank you Paul.

I just upped the ante - I finally got CSB to compile today after many hours of faffing about.

I tried to get it to compile in code::blocks using the gcc compiler for about 4 hrs, but just kept getting errors (mostly #error Unsupported architecture - I'm guessing there are many params and options I am unaware of, even though I managed to get it plugged into all the MS SDK includes)

I fell back to visual studio, had to download a few MS SDKs, had to re-target the source, but I got it working (albeit with Japanese in the title bar)

Image

What this means though is that Pandora's box is open!

I can place trace comments anywhere I please and track down exactly what is going on.

By hook or by crook I will find out:

How piercing attacks from monsters work

How effective magic shield and fire-shield really are

How effective ranged weapons are

What the F happens when a monster attacks you.

Anyhow, if you have any insights or nuggets of wisdom to share please feel free, I could use the help.

Cheers,
Nick K

P.S. What does the function trace do? I've never been able to turn it on.
User avatar
jayrshaw
Lo Master
Posts: 388
Joined: Fri Jun 12, 2020 3:39 pm
Location: Washington, DC

Re: DM mechanics - Azizi through the mirror of dawn

Post by jayrshaw »

Looking forward to reading about the results of your research - thanks again for posting your results/findings in the community forums here!


--Jay
User avatar
Paul Stevens
CSBwin Guru
Posts: 4318
Joined: Sun Apr 08, 2001 6:00 pm
Location: Madison, Wisconsin, USA

Re: DM mechanics - Azizi through the mirror of dawn

Post by Paul Stevens »

What does the function trace do
I don't really know. I turned it on and ran around the Hall of Champions
a bit. Appears pretty useless. Here is what I found in the "trace.log":

....
....
UIM_TIMER
Returned
msg=WM_PAINT
msg=WM_TIMER
UIM_TIMER
Returned
msg=WM_PAINT
msg=WM_TIMER
UIM_TIMER
Returned
msg=WM_PAINT
msg=WM_TIMER
UIM_TIMER
Returned
....
....
User avatar
Automaton
Journeyman
Posts: 88
Joined: Sat Aug 28, 2004 10:49 am

Re: DM mechanics - Azizi through the mirror of dawn

Post by Automaton »

Part 2 - What the actual F do the weapons actually do in DM?

My ongoing dive into the CSBwin source code continues. Ever wondered what the weapons and their actions actually do? Wonder no further.

Notes:

1. This is assuming you have hit a monster
2. You can see the variables used, str=50, maxload=50, skillevel=4 (Artisan), Monster, I used Trolin (28 AC and level 2 difficulty)
3. Maxload = (STR*8+100)/10
4. 0 or negative value Final hits have several checks to put them positive by a small amount of damage.
5. Passing test 1 is better than test 2 which is better than passing test 3.
6. The first test that is passed is the value used going from 1 to 3
7. Required maxload to hit coefficient is very important - i.e. you need 104 maxload (117 STR) before the hardcleave becomes really effective.
Some common STRs needed to get the best out of a weapon (i.e. passing the first test):

Diamond edge 62
Inquisitor 66
Hardcleave 117
Axe 74
Fury 82
Stone Club 207 (Hawhaw)
Morning Star 87

8. Once you get 60 maxload (62 STR), the diamond edge is awesome, with stab standing out as the best dps - In fact it is the best all-rounder in the game.
9. Most random numbers have been assigned mid value (so 16 for a rand(32), 2 for a rand (4) etc
10. The mace of orders +5 STR has been calculated in.
11. The Diamond edge's -25% monster AC has been calculated in.
12. The Hardcleave's -12.5% monster AC has been calculated in.
13. If you are under half maxstamina, damage will be +/-75% of normal
14. If you are injured in the hands, damage will be +/-50% of normal

Image
Image
Image

Something not clear - feel free to ask.
I can also make the google sheet public if there is interest
Cheers!
Nick K.
Last edited by Automaton on Thu Jul 16, 2020 10:39 pm, edited 1 time in total.
User avatar
Automaton
Journeyman
Posts: 88
Joined: Sat Aug 28, 2004 10:49 am

Re: DM mechanics - Azizi through the mirror of dawn

Post by Automaton »

Paul Stevens wrote: Thu Jul 16, 2020 1:39 am
What does the function trace do
I don't really know. I turned it on and ran around the Hall of Champions
a bit. Appears pretty useless. Here is what I found in the "trace.log":

....
....
UIM_TIMER
Returned
msg=WM_PAINT
msg=WM_TIMER
UIM_TIMER
Returned
msg=WM_PAINT
msg=WM_TIMER
UIM_TIMER
Returned
msg=WM_PAINT
msg=WM_TIMER
UIM_TIMER
Returned
....
....
Yeah, I checked the code - plenty of (AttackTraceActive) (TimerTraceActive) (AITraceActive) (DSATraceActive)..

No (FunctionTraceActive) to be found.
User avatar
jayrshaw
Lo Master
Posts: 388
Joined: Fri Jun 12, 2020 3:39 pm
Location: Washington, DC

Re: DM mechanics - Azizi through the mirror of dawn

Post by jayrshaw »

Hi Nick,

As usual, I have to admit that a lot of this is going over my head. However, from looking at the spreadsheets you've posted, I am gathering that your characters' strength does seem to factor quite a bit into the damage calculations. I also believe I understand what the Final Hit and DPS columns represent. It's funny to see that the Stab technique I have been using with a dagger to kill screamers actually isn't that terrible compared to various other weapons; I've mainly been using the Stab technique because it doesn't give Fighter experience, which I don't want to earn outside of using the War Cry technique (doing so would cause my characters' Healer levels to get out of sync with one another).

What does it mean when Final Hit and DPS are negative, though? Does it just mean that the attack failed and did zero damage?

Also, do the Final Hit and DPS rankings change significantly if the character has a higher strength than you assumed in your variables? If I'm reading the spreadsheets right, you can get a somewhat significant bonus for passing the maxload/weapon weight test if you're using a heavier weapon; however, the character you're using doesn't have a high enough strength value to pass this test for most weapons.

Also, unless I'm mistaken, I would recommend for users of the spreadsheet to pay attention to both the Final Hit and DPS columns and not just the DPS column. This is because you can get around longer recovery times to a certain extent by rotating to a second character and attacking with him/her while your first character is recovering from his/her attack.


--Jay
User avatar
Automaton
Journeyman
Posts: 88
Joined: Sat Aug 28, 2004 10:49 am

Re: DM mechanics - Azizi through the mirror of dawn

Post by Automaton »

jayrshaw wrote: Thu Jul 16, 2020 11:29 pm It's funny to see that the Stab technique I have been using with a dagger to kill screamers actually isn't that terrible compared to various other weapons;
Hey Jay,

See my post in "best way to level"to know why attacking screamers is a bad idea ;-)

I'm pretty sure the devs knew they were safe farming.
jayrshaw wrote: Thu Jul 16, 2020 11:29 pm What does it mean when Final Hit and DPS are negative, though? Does it just mean that the attack failed and did zero damage?
See note 4
jayrshaw wrote: Thu Jul 16, 2020 11:29 pm Also, do the Final Hit and DPS rankings change significantly if the character has a higher strength than you assumed in your variables? If I'm reading the spreadsheets right, you can get a somewhat significant bonus for passing the maxload/weapon weight test if you're using a heavier weapon; however, the character you're using doesn't have a high enough strength value to pass this test for most weapons.
117 STR and <<master - what you need to pass test 1 with the hardcleave

Image
jayrshaw wrote: Thu Jul 16, 2020 11:29 pm Also, unless I'm mistaken, I would recommend for users of the spreadsheet to pay attention to both the Final Hit and DPS columns and not just the DPS column. This is because you can get around longer recovery times to a certain extent by rotating to a second character and attacking with him/her while your first character is recovering from his/her attack.


--Jay
Yes, final hit (big alpha damage) and high dps both have their places. If you are circling around a monster, longer time, big alpha damage can be useful.

Cheers!
Nick K.

P.S. Have not tested it yet, and never did when I first played DM many years ago, but punch on the eye of time looks very good for training - normal punch has no weapon damage, eye of time has 2 weapon damage.
User avatar
Paul Stevens
CSBwin Guru
Posts: 4318
Joined: Sun Apr 08, 2001 6:00 pm
Location: Madison, Wisconsin, USA

Re: DM mechanics - Azizi through the mirror of dawn

Post by Paul Stevens »

No (FunctionTraceActive) to be found.
Example code from "CSBwin.cpp":

Code: Select all

    case WM_TIMER:
      MTRACE("WM_TIMER\n");
      csbMessage.type=UIM_TIMER;
      if (CSBUI(&csbMessage) != UI_STATUS_NORMAL)
      {
        PostQuitMessage(0);
        break;
      };
      MTRACE("   Returned\n");
      break;
		case WM_DESTROY:
      MTRACE("WM_DESTROY\n");
			PostQuitMessage(0);
			break;
 
User avatar
jayrshaw
Lo Master
Posts: 388
Joined: Fri Jun 12, 2020 3:39 pm
Location: Washington, DC

Re: DM mechanics - Azizi through the mirror of dawn

Post by jayrshaw »

Thanks for posting the revised spreadsheet, Nick! That diamond edge looks like it should be a real beast; the only disadvantage is that Stab has a -20 defense modifier attached to it, whereas Chop has a defense modifier of 0. Any idea of how much of an impact the defense modifier actually has on how much damage a character takes when attacked by an enemy?


--Jay
User avatar
jayrshaw
Lo Master
Posts: 388
Joined: Fri Jun 12, 2020 3:39 pm
Location: Washington, DC

Re: DM mechanics - Azizi through the mirror of dawn

Post by jayrshaw »

Weird - based on the spreadsheet, I just noticed that if you meet the required strength threshold, an ordinary axe can do more damage than a Delta sword. That's something I wouldn't have guessed on my own!


--Jay
User avatar
Gambit37
Should eat more pies
Posts: 13715
Joined: Wed May 31, 2000 1:57 pm
Location: Location, Location
Contact:

Re: DM mechanics - Azizi through the mirror of dawn

Post by Gambit37 »

It's fascinating to me that there are still people digging into the mechanics of this game. I'm right at the other end of gaming: I don't really care what's going on behind the scenes, the visuals, atmosphere, gameplay and "immersion" are all that matter to me, and DM did a pretty good job of hiding stuff that isn't really that important to gamers like me. It's one reason I still love it. Funny how we can get such different things out of games. :-)
User avatar
Automaton
Journeyman
Posts: 88
Joined: Sat Aug 28, 2004 10:49 am

Re: DM mechanics - Azizi through the mirror of dawn

Post by Automaton »

jayrshaw wrote: Fri Jul 17, 2020 2:00 am Any idea of how much of an impact the defense modifier actually has on how much damage a character takes when attacked by an enemy?
I have this planned to do!

Cheers!
Nick K
User avatar
Automaton
Journeyman
Posts: 88
Joined: Sat Aug 28, 2004 10:49 am

Re: DM mechanics - Azizi through the mirror of dawn

Post by Automaton »

jayrshaw wrote: Fri Jul 17, 2020 2:45 am Weird - based on the spreadsheet, I just noticed that if you meet the required strength threshold, an ordinary axe can do more damage than a Delta sword. That's something I wouldn't have guessed on my own!


--Jay
Yes, if a weapon passes test 1 and is heavy, it's going to do the biz due to part of the formula being weapon_weight*10-12

For a dgger it works out as 5-12 whereas the axe is 43-12

Cheers,
Nick K.
User avatar
Automaton
Journeyman
Posts: 88
Joined: Sat Aug 28, 2004 10:49 am

Re: DM mechanics - Azizi through the mirror of dawn

Post by Automaton »

Gambit37 wrote: Fri Jul 17, 2020 12:55 pm It's fascinating to me that there are still people digging into the mechanics of this game. I'm right at the other end of gaming: I don't really care what's going on behind the scenes, the visuals, atmosphere, gameplay and "immersion" are all that matter to me, and DM did a pretty good job of hiding stuff that isn't really that important to gamers like me. It's one reason I still love it. Funny how we can get such different things out of games. :-)
Hi there - I quite agree!

I got DM very early after it's launch on the Atari, I'm closing in on the big 50 (Although mentally, my wife and kids will tell you I never got past 14) and I probably have quite a different view to most.

I've done most everything in DM that can be done and I'm just so curious about how the game was treating me all those years ago. Since I've started getting my head round the CSBwin source code, I've had several moments of "Oooooooh, that's what the bloody thing was doing in 1988!".

I've been looking for an excuse to upgrade my "novice" c++ skills for some time now, and somehow, meandering through the DM code is like visiting an old friends house and seeing what's behind all the locked doors.

Cheers!
Nick K
User avatar
jayrshaw
Lo Master
Posts: 388
Joined: Fri Jun 12, 2020 3:39 pm
Location: Washington, DC

Re: DM mechanics - Azizi through the mirror of dawn

Post by jayrshaw »

Automaton wrote: Fri Jul 17, 2020 4:09 pm Yes, if a weapon passes test 1 and is heavy, it's going to do the biz due to part of the formula being weapon_weight*10-12

For a dgger it works out as 5-12 whereas the axe is 43-12

Cheers,
Nick K.

Yeah - I guess the Chop technique with an axe was always my standard method of killing things on the earlier floors of the dungeon for a reason. I'm using the strongest party in the game and making sure I gain the maximum amount of strength on Fighter/Ninja levels, so my characters would generally be meeting the 74 strength threshold for getting the axe's weapon weight bonus by the time they reached Artisan or Adept in their Fighter/Ninja skills. My group even has an extra axe since Stamm starts out with one.

I guess the axes eventually get outclassed by weapons like the Diamond Edge, Fury, and Hardcleave (although you probably need buffed strength for Hardcleave to be effective), but they still look like they are one of the best weapons even later in the game...


--Jay
User avatar
Automaton
Journeyman
Posts: 88
Joined: Sat Aug 28, 2004 10:49 am

Re: DM mechanics - Azizi through the mirror of dawn

Post by Automaton »

Part 3 - What's with the getting XP for just getting hit?

Yup you get XP when getting hit.

I've scoured the source code and monster experience class (See here on DME for details) is used in only 2 places.

1. As a multiplier to XP when you hit a monster
Determining XP-----------------------------------------------------

> XP = ((XP=46) * ((Monster experience class=0)/16)) + 3 = 3
> Decrement stamina by rand(4)+3 = 6
> Calculating XP for damage done...
2. When a monster hits you
MONSTER ATTACK $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

$ Attacking WAFFLE
$ Calculating XP with (monster XP class=0) because a monster hit you...

|Entering function to Adjust skills (6) --------------------------

| Base XP=0 target skill=[7] XP*dungeon level multiplier (2) = 0
| [skill >=4] A monster attacked you < 4.17 seconds ago so XP*2 = 0
| skill[7] so Base skill is [0] with mastery level [5]

|Leaving function to Adjust skills XP=0 --------------------------
Os you can see above, all monsters will give you XP if they attack you and this is done before the game has decided if the monster actually damages you.

..apart from the screamers.

Because their monster experience class is 0, they can never give you XP when they hit, regardless of penalties and bonuses for whatever timer checks are going on. (0 * dungeon level is 0, 0*2 because a monster attacked you less than 4.17 seconds ago is 0)

So as an example, a mummy on dungeon level 7;

It hits you, you get 4 (the mummy's experience class) * the dungeon level multiplier (3) with the possibility of /2 if a monster has not attacked you since 25 seconds and a *2 if a if a monster has attacked you in the last 4.17 seconds

So you get 12 XP in the first case and, 6 XP if the timer has run out and 24 XP if a monster has attacked you in the last 4.17 seconds

Cheers!
Nick K.
User avatar
jayrshaw
Lo Master
Posts: 388
Joined: Fri Jun 12, 2020 3:39 pm
Location: Washington, DC

Re: DM mechanics - Azizi through the mirror of dawn

Post by jayrshaw »

Automaton wrote: Sun Jul 19, 2020 1:21 pm Os you can see above, all monsters will give you XP if they attack you and this is done before the game has decided if the monster actually damages you.

..apart from the screamers.

Because their monster experience class is 0, they can never give you XP when they hit, regardless of penalties and bonuses for whatever timer checks are going on. (0 * dungeon level is 0, 0*2 because a monster attacked you less than 4.17 seconds ago is 0)


Yeah, this conforms to my own experience (pun intended!) while exploring the dungeon. I have accidentally gained Fighter levels from being attacked by magenta worms and wasps, but I have never gained a level from being hit by a screamer despite the fact that I have let them attack my characters for several hours while training various skills. However, this is something that might vary depending on which version of the game you are playing; in the "Best Way to Level" thread, slickrcbd posted that he has definitely gained levels from being attacked by screamers (he said he took note of it because he was making a point to avoid gaining Fighter levels on Floor 2 by only using daggers to attack enemies).


--Jay
User avatar
Automaton
Journeyman
Posts: 88
Joined: Sat Aug 28, 2004 10:49 am

Re: DM mechanics - Azizi through the mirror of dawn

Post by Automaton »

Part 4 - What the actual F is going on when a monster hits you?

Wow - It took a long time to understand what all the code is doing, but I got there. There are some surprising results!

Part 4a - Put simply....

This is the large picture;
1 Give character XP for getting hit
2 Monster to hit roll vs characters required to hit
3 Decide on body part to attack
4 Get monster base damage
5 Get Absorb
6 If you have a shield, add its value to Absorb
7 Add word64 to Absorb
8 Add Shield strength (spell) to Absorb (YA BRO)
9 Add Party shield (spell) to Absorb (YA IR)
10 Add value of item in body part attacked to Absorb
11 Modify monster damage if damage type is 06 (Psychic)
12 Modify monster damage if damage type is 05 (Magic)
13 Modify monster damage if damage type is 01 (Fire)
14 Modify monster damage if damage type is 02 (Critical)
15 Main damage calculation. (Monster damage * (130-Absorb)) / 64
16 Decide if the body part attacked gets injured
17 Do damage to the character
18 Decide if the character gets poisoned (If monster is able to poison)
1 - XP added to 07 Parry. Base XP = monster experience class. XP/2 if last monster attack timer >25 secs. XP*2 if last monster attack < 4.17secs. XP*dungeon level multiplier

2. Uses the same roll as character vs monster. See detailed version for info.

3. Calculations based on a random number to decide which body part to attack. Uses monster wound/head/torso/legs/feet values

4. Mostly Monster damage = (2*dungeon level multiplier) + monster attack power + rand(16) - (2*characters parry skill). but with a few multiplies and divides after to normalise the vlaue

5. Is a random number mod (VIT/8+1). Mod as in mathematical mod (i.e. get the remainder). So if you have 60 VIT it could be 0 to 8, 100 VIT would be 0 to 13. The higher your VIT the better, but it is random.

6. If you are holding a shield, it has 2 components.

First it does a damage roll on the shield (as shields have no weapon damage, this is mostly your STR).

Second it works out the AC (Armour Class). If the damage type is 03 (normal), this is just the AC of the armour (i.e. 17 for a leather jerkin). If the damage type is 04 (sharp attack) this is AC*(sharp resistance+4) /8 (i.e a leather jerkin is 17 AC and 3 sharp resistance so (17*(3+4))/ 8 )=14).

Then the first and second values are added together and multiplied by an arbitrary value held in d.byte142 and finally divided by 32 (or 16 if the body part attacked = to your shield hand)

d.byte1412 is d.Byte1412[0]=5, d.Byte1412[1]=5, d.Byte1412[2]=4, d.Byte1412[3]=6, d.Byte1412[4]=3, d.Byte1412[5]=1. This corresponds to left hand=5 right hand=5 head=4 torso=6 legs=3 feet=1

7. Word64 is unused, there is a comment somewhere in Paul's CSB code that states as much.

8. Add spell shield to absorb (YA BRO, the potion individual shield). This is an odd one.

Being pedantic about the English language, I have always wondered if "Magic Shield" meant "a shield against magic" or "a shield made of magic". Seems in DM, it is both as it works both here and in the test against a magic attack.

Note: This effect stacks! The more potions you drink, the stronger the potions, the more this figure goes up!

9. Add party shield to absorb (YA IR). Same effect as 8.

Note: This effect stacks! The more spells you cast, the stronger the spells, the more this figure goes up! It is possible to stack the effects of both 8 and 9 together to get insane amounts of damage mitigation.

10. Like your shield in 6. result gets added to Absorb.

11. Psychic attacks (Screamers and Ghosts) are tested against 115 WIS, the more WIS you have the more you mitigate the damage. 115 WIS will make you invulnerable to Screamer and Ghost attacks.

12. Magic attacks (Wizard Eye, Vexirk and Materializer) are tested against a check (170-anti-magic). So (Monster damage * result of check) / 128. (i.e. If the monster is doing 50 dmg and you have 70 anti magic, it would be (50*100)/128 = 39). An anti magic of 40 equates to the same damage out as in. Less than 40, you take more damage, more than 40 you reduce damage.

13. Fire attacks (Black flame) are tested against a check (170-anti-fire). So (Monster damage * result of check) / 128. (i.e. If the monster is doing 50 dmg and you have 70 anti fire, it would be (50*100)/128 = 39). An anti fire of 40 equates to the same damage out as in. Less than 40, you take more damage, more than 40 you reduce damage.

14. Critical attacks are not used, but if they were, it would divide Absorb by 2.

15. The main calculation is monster_damage = (monster_damage * (130-absorb)) / 64. absorb gets limited to max 100 so the best result you can have here is 100 absorb which would be (for monster dmg=50) (50*30) / 64 = 23

16. Runs a loop depending on your vitality to see if the monster will injure the body part it's attacking.

17 & 18 Pretty obvious.

Will post the detailed version soon.

Part 4b - What the actual F is a sharp attack?

Monsters that use sharp attack are Giant Scorpion, Pain Rat, Rockpile, Skeleton, Couatl, Magenta Worm, Giant Wasp, Animated Armour, Oitu, Red Dragon.

If a shield or piece of armour on your body is checked, for a normal attack, it will return the base AC (armour class)

If a shield or piece of armour on your body is checked, for a sharp attack, it will return a value based on the following formula;

result = item AC*(sharp resist+4) /8.

This has the following implications;

If a piece of armour has a a sharp resist of 4, 4 gets added to it making it 8 and AC * 8 then / 8 negate themselves giving the result of the base AC of the item.

Therefore, sharp resist =4 can be considered to be neutral, in a sharp resist check it will return the base AC of the item.

If sharp resist <4, a sharp resist check will return a worse value than the base AC of the item.

If sharp resist >4, a sharp resist check will return a better value than the base AC of the item.

Examples (Base AC, sharp resist):
Leather Jerkin (17/3) normal attack AC 17. Sharp attack AC 14.
Leather Boots (25/4) normal attack AC 25. Sharp attack AC 25.
Mithral Aketon (70/7) normal attack AC 70. Sharp attack AC 96

Cheers!
Nick K.
User avatar
jayrshaw
Lo Master
Posts: 388
Joined: Fri Jun 12, 2020 3:39 pm
Location: Washington, DC

Re: DM mechanics - Azizi through the mirror of dawn

Post by jayrshaw »

Wow, Nick - awesome research and information! So, it looks like, contrary to what we were originally thinking, an armor's base defense value does get factored in to the character's damage mitigation against "sharp" attacks, after all.

Also, do you know approximately how many absorb points you can expect to get from a single Mon level (i.e., level 6) Ya Bro shield potion or Ya Ir shield spell? I'm trying to get an idea of how many of these you would need to stack if you wanted to approach the 100 absorb cap you mentioned.

For that matter, do you know how long the shield spells/potions tend to last? I haven't really tried using them during this playthrough yet, but I was considering using them once I start fighting monsters that can't be killed easily with spells (e.g., stone golems, animated armors, etc)...


--Jay
User avatar
Automaton
Journeyman
Posts: 88
Joined: Sat Aug 28, 2004 10:49 am

Re: DM mechanics - Azizi through the mirror of dawn

Post by Automaton »

jayrshaw wrote: Sat Jul 25, 2020 2:12 am Wow, Nick - awesome research and information! So, it looks like, contrary to what we were originally thinking, an armor's base defense value does get factored in to the character's damage mitigation against "sharp" attacks, after all.
Indeed. I was going on the info on DM encyc, but the reality is far more complex.
jayrshaw wrote: Sat Jul 25, 2020 2:12 am Also, do you know approximately how many absorb points you can expect to get from a single Mon level (i.e., level 6) Ya Bro shield potion or Ya Ir shield spell? I'm trying to get an idea of how many of these you would need to stack if you wanted to approach the 100 absorb cap you mentioned.
Yes, I thought that people would want to know "OK, so how do all the values scale and look like? "

An attack on my character, by a screamer on lvl 3..

Base absorb
Character VIT=38. It could have been 0-5 I got a roll of 2

Shield Strength YA BRO
I got 0
But I have worked out:
Lo 13, 15
Um 16
On 19
Ee 21
Pal 24
Mon ?
It seems to vary depending on skill or a rand I think, but I have not checked the code on how potions get made yet. Like I said it's cumulative drinking several will keep raising it. After 50 though the effect of each potion is halved.

Party Strength YA IR
I got 0
But I have worked out:
Lo 8
Um ?
On ?
Ee 20
Pal ?
Mon 28

Shield absorb
My character was holding a wooden shield, the code worked out its absorb was =16

Pre-final result =18
Final result= ApplyLimits(0, D7W >>1, 100)= 9 //This line applies upper and lower limits of 100 and 0 of Pre-final result/2

In terms of weight, I've yet to test with good bits of armour - my test grp is only on level 4.

Base absorb - low weight - 0 to 13 with 100 VIT
Shield Strength- high weight - quite easy to get 80+ with a few high level potions
Party Strength - high weight - quite easy to get 50+ with a few high level spells
Shield absorb - low weight - depends on STR and the shield used. Looks like values of 50+ could be possible with shield of darc.
jayrshaw wrote: Sat Jul 25, 2020 2:12 am For that matter, do you know how long the shield spells/potions tend to last? I haven't really tried using them during this playthrough yet, but I was considering using them once I start fighting monsters that can't be killed easily with spells (e.g., stone golems, animated armors, etc)...


--Jay
Still working on that Jay. I'll get back to you once I understand the mechanics.

Cheers!
Nick K
User avatar
jayrshaw
Lo Master
Posts: 388
Joined: Fri Jun 12, 2020 3:39 pm
Location: Washington, DC

Re: DM mechanics - Azizi through the mirror of dawn

Post by jayrshaw »

Thanks for the additional information, Nick. Based on what you posted, it doesn't seem like it would take too many Mon level Ya Ir shield spells to get a lot of extra absorb points.

Not sure if it this helps or not, but previous posters on this forum have claimed that the effectiveness of potions does not vary at all based on your characters' Healer experience/level. However, the same posters claimed that the effectiveness of missile spells (e.g., fireball, poison bolt, poison cloud, etc.) does improve as you gain Wizard experience/levels. No idea about whether or not Healer experience/levels improve the effectiveness of the Ya Ir shield spells or Ful Bro Neta fireshield spells, though.


--Jay
Post Reply