Sword of Moonlight Forum

Sword of Moonlight => SOM Addons => Topic started by: Holy_Diver on March 28, 2013, 03:10:00 pm

Title: Damage calculator
Post by: Holy_Diver on March 28, 2013, 03:10:00 pm
I know there was a damage calculator spreadsheet around here somewhere. I was hoping someone could repost it and explain the damage formulas since I probably won't be able to open the spreadsheet up :smash2:
Title: Re: Damage calculator
Post by: Verdite on March 28, 2013, 04:18:52 pm
I hope Wolf doesnt mind me linking to his thread, its his work

 :grumble: :science: :zx11shocked:

http://www.swordofmoonlight.com/bbs/index.php?topic=493.msg5821#msg5821
Title: Re: Damage calculator
Post by: Holy_Diver on March 28, 2013, 05:30:38 pm
Yeah that's the problem with this "calculator" I see (again) now. I can't use it, and can't even open the file in a text editor to look for formulas because its all binary or encrypted or something one.

If the calculator works, how come we don't have a document explaining how damage is calculated? Or must I figure that out myself and publish the information for everyone (as always) too? :1782:
Title: Re: Damage calculator
Post by: Verdite on March 28, 2013, 07:02:40 pm
I'm sure wolf knows best.
Title: Re: Damage calculator
Post by: HwitVlf on March 28, 2013, 07:18:55 pm
I don't mind you linking at all Ben. Once I post it, it's "open season" :wink:

Mick, there are several Excel readers readily available that don't require Microsoft Office, including tools that convert Excel into free-standing EXE files and the formula is easily viewable in the (who would have guessed) "FORMULA BAR". 

If you want my advice, the damage formula should be the first thing you yank out with your Ex wrapper. A simple system where "damage = attack-defense" would be better.

SoM's current setup is designed to make damage increase/decrease  exponentially as player/enemy stats get further apart. Which means that lower level enemies will get "1-hit killed" and higher level enemies will be overpowering. So the only game area that will be challengingly fun to play is the area designed to match your current level. Everywhere else will be easy or deadly.

The simple way of thinking of the formula is if ATK=DEF then damage = ATK/2.

P.S. Continually saying you "always have to do everything yourself" is probably the best way to insure you WILL have to do everything yourself.
Title: Re: Damage calculator
Post by: Holy_Diver on March 28, 2013, 09:21:52 pm
So far I have done everything on the technical end myself. I've had assistance, but nothing would get done otherwise.

If you could make the calculator an EXE it would be a lot more accessible. If it works, then why not post the formulas? Or is that a proprietary secret?

The calculator does factor in Strength and Magic right? If not, how is that done? Or is it just player damage, and is Strength not a factor?


PS: I would have thought "attack-defense" without having ever tried anything myself. Is that all for player damage? You can see enemy damage in at least two ways with Ex. But player damage you'd just have to watch the HP drop and do the math without adding anything new.

I am about to add a Damage section for setting up falling damage, or impact damage rather, you could explain how you think that should work to override the default behavior WRT to all types of damage if you want to influence that... although its a little bit early for that because I have no idea to go about changing things in this dept. But if there was a really good game plan and a lot of demand that might make things more attractive.
Title: Re: Damage calculator
Post by: Holy_Diver on March 29, 2013, 10:05:29 am
P.S. Continually saying you "always have to do everything yourself" is probably the best way to insure you WILL have to do everything yourself.

Just to be doubly clear on this, I can honestly care less why people opt not to do good in the world. It's totally not my business (there's obviously no shortage of people not being part of the solution. And even if some kind of nonsensical (borderline insane) mental gymnastics can remedy that, it's not worth the headache (nor tempting insanity) or the time and effort while there is so much work to be done :1zhelp:)


I just want to add, its almost irrelevant, but I've been putting a lot of thought into a different damage system that I think would be ideal for King's Field, but works just as well for any game. It leads me to think that the damage calculation should be broken up into two parts. The first part can probably be called the damage model, and the second part the damage formula.

There may be more parts, but this seems to be logical, because the system I have in mind changes the model, but not the formula. Or in other words it is independent of the formula. In the post up above "ATK=DEF then damage = ATK/2" expresses the formula. And the classical model is simply ATK=ATK and DEF=DEF.


Now I will explain a new model, I've decided to call the Void model. In the Void model only the magical affinities deal damage, so that the physical affinities cancel out. But first the magical affinities are modulated by the physical affinities, in the form of N dimensional unit vectors, where N is equal to the number of physical affinities. The formula is applied to each component of the vectors. So there are N*M sources of damage (instead of N+M) where M is the number of magical affinities....

In other words, you don't have a fire attack and a slash attack, you have a slashing fire attack. And you can't have a slashing fire attack and a piercing water attack in the same attack. You can have a slashing and piercing fire and water attack though.

So if a piece of armor has 0 fire defense and some slashing defense, and is attacked with a slashing fire attack, then the slashing defense is not a factor, the fire attack passes through unscathed. You could say the slashing defense is voided, but that's not why its called the Void model...


It's called the Void model because it introduces a 4th physical affinity and a 6th magical affinity, but the two affinities happen to be mutually exclusive because of the way they are calculated. Technically they are a dual affinity, so that one is positive and one is negative, or vice versa. Together they are called the Void affinity. And they occupy the hole after the Stab affinity, and the hole after the Holy affinity. You can even treat them as separate affinities if you want to as long as you keep in mind that they can't both exist on the same piece of equipment (not a problem if you only use one or the other)

For the sake of discussion we can call the physical affinity Avoid and the magical affinity Ovoid, or Alpha and Omega void. These affinities only exist if the sum of the physical affinities does not match the sum of the magical affinities. In which case the difference goes into Avoid if negative, or Ovoid if positive. Since physical affinities cancel out in the Void model, the damage itself can simply be said to be Void damage. Void in this case is equal to the Ovoid affinity, since only magical affinities deal damage.

You could probably use whatever kanji SOM_PRM uses for Magical and Physical, but it would just confuse things I think (and not translate into English well) because the void affinities are really remainders, so the Ovoid magical affinity really represents physical damage, so if you were to translate it this way, then you'd have a magical affinity being called Physical.

The simple way to think about this, is if an author setup an attack with 10 Fire damage, and 0 on all of the physical affinities, without the Void affinities then this attack would deal 0 damage. Obviously that's probably not what we want. So after you calculate the difference, there is 10 physical affinity unallocated, so that goes in Avoid, and now you have an attack which has none of the classical physical affinities, so its like a Magic wave attack or something, you can imagine the attack cooking the target from the inside out. Of course you can have armor that can defend against such an attack, or a magical field might be better, but said armor can't defend against an Avoid attack and an Ovoid attack simultaneously.

An Ovoid attack is pretty straight forward. It represents a weapon with no magical properties more or less. One way of looking at it is if a game took place in a contemporary setting, everyday objects would probably deal Ovoid attacks. Since they have not magical properties.


Finally,  I just want to say that I don't think conventional King's Field games require a Dark affinity, like in KF4. But a Void affinity can take its place more or less. That said Void is not at all supposed to represent darkness. But Dark Souls does have an odd kind of Dark magic that deals physical damage and is connected to humanity, so that could be a way to think of it, if you wanted to make a class of magic that deals strictly Void damage. But any magic can deal (a)Void damage in varying degrees. It would probably be interesting if (a)Void magic was a class of attack that can't be defended by natural means, Eg. no equipment can defend it, but spells can, or only a special class of equipment can. But (o)Void damage could potentially be a quality of all equipment if you wanted it to play a significant role in your game. In fact Dark Souls's Dark Magic would almost definitely be Ovoid variety.

Back to KF. The way I see it, any magic that literally manipulates light (or darkness) should use the Holy affinity. But if its like necromancy it should mainly use the Earth affinity. But all of the elements can have a role in necromancy. For example ghosts and skeletons are animated by Wind, unless underwater, then by Water. And unless I have my monsters mixed up a Wraith is really a ghost made of Fire.


PS: By default the void affinities will be hidden, like dark matter/energy you might miss them/not realize the true potential of a weapon or spell. But they will be translatable, so that a game can show them and call them whatever it likes. Also the model will have variations. Like void+1 to convert the first magical affinity to a physical affinity, and void-1 to do the opposite, and so on. And void-less to simply normalize the physical affinities so that no void affinities shall exist and everything is easier to setup.
Title: Re: Damage calculator
Post by: Holy_Diver on March 29, 2013, 11:52:50 am
EDITED: I think another useful variable would be a weighting system, so that you don't have to think about things, like for example, if Fire magic is always stronger than the other elements, then an automatic weighting system can make sure it always gets a damage boost. I think for KF since Earth is healing, and Water is lesser healing (poison) then, the general damage weights would look like Fire > Wind > Water > Earth (edited: also just happens to roughly line up with the familiar physical states of matter; plasma, gas, liquid, solid)

I don't know if the weights should be pre-applied or post-applied (would be much simpler WRT the Void model; so probably) or if the results of the weighting should appear in the stats in the Equip menu or not. It would be more informative of actual damage output, but would also make the stats appear much more noisy, which when you are dealing with so many affinities already, might not help players make informed decisions about equipment (at the very least it would be tougher to gauge the stats at a glance if they say 77, 66, 55, 44, instead of 60, 60, 60, 60 or whatever... plus if would make a sword like the Dark Slayer look like it is shifted towards fire, when really it is all elements being equal)
Title: Re: Damage calculator
Post by: HwitVlf on March 29, 2013, 12:35:21 pm
Here you go. I copied the formula from the Excel. Now you can't ever say you had to do everything yourself.
Damage =
ROUNDDOWN
(IF(ATK<1,0,
IF(DEF<1,ATK+(STR/5),
IF(((((ATK+(STR/5))+DEF)/DEF-(DEF+DEF)/(ATK+(STR/5)))+1)*(ATK+(STR/5))/2<1,1,
[otherwise](((((ATK+(STR/5))+DEF)/DEF-(DEF+DEF)/(ATK+(STR/5)))+1)*(ATK+(STR/5))/2))))
,0) [round down end]

MAG would be substituted for ATK for Magic damage types. Now aren't you glad you asked? Personally, I wouldn't "bake in" any damage formula. I would set up a simple default formula which is loaded from an external configuration text document. Thus letting users insert their own formula if they want.
Title: Re: Damage calculator
Post by: Holy_Diver on March 29, 2013, 02:53:56 pm
Here you go. I copied the formula from the Excel. Now you can't ever say you had to do everything yourself.

Lets not be so bitter now.

Quote
Damage =
ROUNDDOWN
(IF(ATK<1,0,
IF(DEF<1,ATK+(STR/5),
IF(((((ATK+(STR/5))+DEF)/DEF-(DEF+DEF)/(ATK+(STR/5)))+1)*(ATK+(STR/5))/2<1,1,
[otherwise](((((ATK+(STR/5))+DEF)/DEF-(DEF+DEF)/(ATK+(STR/5)))+1)*(ATK+(STR/5))/2))))
,0) [round down end]

This is a lot to tease apart. Lets see...

Quote

IF(ATK<1) RETURN 0;

ELSE ATK = ATK+STR/5; IF(DEF<1) RETURN ATK;

RETURN (1+(ATK+DEF)/DEF-DEF*2/ATK)*ATK/2+1;

Does this look correct? Syntax aside. I am pretty sure that SOM rounds up if non-zero. I just stuck +1 on the end to guarantee damage. I actually think damage should be rounded down to zero, but that's another story.

Did you use an exponential function to generate this? I expected something that would convert to some number between 0 and 1 and probably do a simple square operation to yield the exponential curve.

The simple take away is you seem to get a full point bonus for every 5 strength. If you can confirm for me this simplification is correct (parenthesis overload) I intend to take a second look and see if it can't be better expressed in terms of ratios. How certain are we that this will always produce the same results in game?

Quote
MAG would be substituted for ATK for Magic damage types. Now aren't you glad you asked?

It's all in a days work. Dealing with unsavory characters is what I do :cool:

But are you positive that Magic is used for the magical affinities? It seems like it would make more sense if Strength was for weapons, and Magic was for magic missiles.

Quote
Personally, I wouldn't "bake in" any damage formula. I would set up a simple default formula which is loaded from an external configuration text document. Thus letting users insert their own formula if they want.

That is the idea, since its a formula after all. But some kinds of operations can be a bit much to express in simple calculator like syntax. Once you get to the formula part it should be like defining a simple kernel with just ATK and DEF as inputs.


EDITED: It looks to me like this function can only decrease the damage. So its not obvious how you could end up doing one hit kills unless the attack power exceeds the monster's HP in the first place. In other words, aside from the linear Strength/Magic bonus, the function appears to just be modeling defensive armor.
Title: Re: Damage calculator
Post by: Holy_Diver on March 29, 2013, 04:08:41 pm
I've had some ideas about how to implement this stuff. The ATK/DEF bit would be pretty straight forward to do. But I am not sure it is even necessary to...

At first I thought the model could be done by adjusting the monsters' attack/defense whenever the player changes equipment, but I quickly realized that that would not cut it.

But it made me hopeful to keep thinking. I think what should be able to work is to simply precompute the results for all of the attacks/defense pairings whenever the player changes equipment. Same thing pretty much.

Except never really letting SOM do anything. So just do something like zero out the stats for the monsters, and just put the resulting damage in the first affinity and have it deal direct damage to the player. And more or less the same for defense, though its more complicated.

But I realize just now that the trouble with this is monsters can hit other monsters, or at least their magic can. So I think the only way this problem can possibly be approached assuming SOM does the hit detection, is to just try to find the bits of the game that identifies the attacking/defending parties and scoop it out, or if it goes through a subroutine, send it to one of our subroutines instead. And if it doesn't well then fill the scooped out bit with a subroutine call that does.

So more or less the way I probably would've opted to implement the formula calculator. Just at a higher level (assuming that's even possible)

I try not to go about reprogramming SOM this way if I can help it. But I am damned near convinced this is the only way in this case. I did a job similar to this for the first time a little while back in order to decouple the look axes so turning could be faster during fast turns without also speeding up the vertical axis.

That is enabled by extension. The only difference in this case is rerouting or injecting a call jump. It will be new territory. But I intend to look into equipping items here in a bit, and I assume that is done as a subroutine because it just isn't the kind of thing that is done in a main loop. It feels like the time is right to bump things up to this level of tampering even though I am pretty sure the EULA expressly forbids disassembly :sweatdrop:
Title: Re: Damage calculator
Post by: Holy_Diver on March 31, 2013, 10:12:08 pm
So I double checked everything, and this ((1+(ATK+DEF)/DEF-DEF*2/ATK)*ATK/2) simplification does look right. Don't know that it matches SOM's output, but it matches the formula above.

Here is a plot. You (HwitVlf) have probably done this already. But just if anyone wants to see what it looks like. Here is a plot with 40 defense (there are also 3D plotters available if you search for it and don't mind using Java plugins)

http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoMSsoeCs0MCkvNDAtNDAqMi94KSp4LzIiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMTE4LjQyOTcwOTkwMTMzNDQ5IiwiMTkxLjUxNDQ0MjkzMDY5NDkiLCItNzguNjY5MDI3NDU3Mjk2MDciLCIxMTIuMDY1ODM1ODIzOTUyNjQiXX1d

I can see how this works. But I am pretty sure I would (or will) never be able to figure out this function even if I had the patience to stare down the numbers. I don't know if its an awful formula, but it does rather lend itself to Final Fantasy like games where levels are very stratified and the numbers become very unwieldy when outclassed (though I'd expect that at least one of the KF games probably works this way)

What worries me is the player doesn't know if their weapon is having any effect. But I guess you'd give up after hacking away for too long. But suddenly a monster that seemed insurmountable might become a pushover if you can get a stat up 10 more points (if defense is 40 as in the plot)

Ultimately I agree though. I think KF is better suited to slow (or no) progression. Lord knows a game doesn't really take long enough to make any real kind of progression in real life anyway. And if it did it probably wouldn't be fun to play. Not to mention that Damage=Attack-Defense would probably be easier for authors to wrap their head around. I like to feel like I've made some progress by the end of the game, but I don't need to feel like a superman. 

The real problem I see here is one affinity would dominate. In other words unless the affinities are very close together, the lower ones will either have no effect, or the higher ones will be overkill. Of course if a monster has a immunity to an affinity or two, having extras doesn't hurt.


PS: I can see now how Magic could drive damage bonuses for the magical affinities. I kind of always assumed that Strength would be multiplied by the affinity rather than added on top of of it. I mean if you have 0 Strength how can you hit for any damage right??

I think I still prefer (myself) the notion that the magic is just a quality of the weapon, so swinging it harder just hits harder. IOW the Magic stat should be limited to spells only (if it isn't; I should probably do an experiment to see for myself)


EDITED: By the way, it will be interesting to find out what this looks like in SOM's program. Kudos if its identical.
Title: Re: Damage calculator
Post by: Verdite on April 01, 2013, 10:33:55 am
Dont mean to derail things but some input is better than none.

"What worries me is the player doesn't know if their weapon is having any effect."

Usually a monsters hit animation indicates this, you could have 3 animations depending on how you hit... First one would be a short wince, second would be a wince with a step back, third would be as devastating as you want and could stagger the opponent back thus giving you the option of rushing or retreating.

THEN you could remove all the damage numbers from the players view in the inventory  :eek: and replace the damage numbers with 'sharp' to 'dull' for blades and 'solid' or 'rickety' for maces. Examples.

For a decent cutting sword it could read
Slash :  Good - depending on metal and craftsmanship
Stab: Poor - depending on sword class, rapiers would be different
Smash : Average - depending on weight and swing type, swords can break bones with impact on armour
Durability : Broken through to excellent.
Then you could have the same for armour defences. Remove the numbers and replace it with something slightly more mysterious.
Title: Re: Damage calculator
Post by: Holy_Diver on April 01, 2013, 05:16:22 pm
Dont mean to derail things but some input is better than none.

"What worries me is the player doesn't know if their weapon is having any effect."

Usually a monsters hit animation indicates this, you could have 3 animations depending on how you hit... First one would be a short wince, second would be a wince with a step back, third would be as devastating as you want and could stagger the opponent back thus giving you the option of rushing or retreating.

Well I am not referring to hypotheticals here--I try to make that clear if that is the case. I meant with plain vanilla SOM you always stun the monster. And with this damage formula, there are good odds you'll be hitting for 0 if your attack power is below the damage window. But with SOM the damage is always rounded up to 1 if it isn't exactly 0. I think actually that all of the affinities are summed together before that rounding happens.

I actually don't think KF2 works this way. Because there would be a lot of stories of people trying to kill the Giant Kraken but not succeeding if so. Unless that is its HP is actually low enough that each hit is taking off exactly 1 hp regardless before it goes down (which is very possible too)

Anyway I basically agree that this is probably not an ideal formula for most games going forward.


PS: I honestly didn't mean for this thread to turn this way. Or I didn't want it to go beyond sussing out the damage formula itself. If you want to recommend anything here, I would just like to ask what variables should be provided to the formula? I will probably call this Attack variable HP and the armor variable AP. I can see the sum of all of the affinities being useful (both divided by category and altogether) and having access to the counters is a no brainer...

Strength and Magic bonuses will be separate formulas. And I am pretty sure if the affinity is 0 it won't be considered for bonuses or damage.

And before I call it quits. Per that Void system. I have the sneaking feeling that instead of the physical affinities being presented to the player as percentiles, if any it will be the magical affinities that will be so. The system still works the same, but this is because I reckon the magical affinities won't change. But I can easily see the physical affinities changing based on the swing ID. So you'd have to present a range like 0-10, and that wouldn't work well with percentiles. Plus there are likely to be fewer physical affinities, so players can more easily appraise the weapon if the raw power is a function of those affinities...

Another consideration is if we chose to represent one of the affinities as percentiles (you don't have to do this but it seems likely as it saves the player from doing a lot of work in their head) then the affinity group that is not percentiles almost definitely has to have its Void affinity visible. My guess is that usually the aVoid affinity would be called Magic and it would represent a magical component of a weapon's attack that cannot normally be defended against. You'd probably want it to be boosted by the Magic stat somehow (whereas the other physicals would be boosted by Strength)

I think it will still be hidden by default though, as many games would probably opt to just not use the aVoid affinity.
Title: Re: Damage calculator
Post by: Holy_Diver on April 01, 2013, 05:27:18 pm
THEN you could remove all the damage numbers from the players view in the inventory  :eek: and replace the damage numbers with 'sharp' to 'dull' for blades and 'solid' or 'rickety' for maces. Examples.

For a decent cutting sword it could read
Slash :  Good - depending on metal and craftsmanship
Stab: Poor - depending on sword class, rapiers would be different
Smash : Average - depending on weight and swing type, swords can break bones with impact on armour
Durability : Broken through to excellent.
Then you could have the same for armour defences. Remove the numbers and replace it with something slightly more mysterious.

I see what you are doing here. Basically you want a way to translate stats into grades. I think this has merit myself, just because you might want to convert 100 to 10 to make it less intimidating, assuming there is some reason to not just use 10. And like I've said I do think a fuzzy stat presentation might be an improvement (even though most RPG nerds would probably protest)

Anyway. This seems like it would naturally be part of the Script since its simply translating in game text (my idea was to just use ABCDEFS as From' games have a history of doing that... but Armored Core games also often include a wordier grading system for appraising the AC; Poor, Fine, Good, Excellent spring to mind)
Title: Re: Damage calculator
Post by: Holy_Diver on April 01, 2013, 07:17:49 pm
Assuming "Excellent" will fit in the space allocated,

A=Fine
B=Good
C=Average
D=Fair
E=Poor
F=whatever

If you used this for affinities, I am not sure what you'd do about ranges... eg. Poor-Fine doesn't really make sense. So I think numbers are still best here. Likewise, just because a spear is not made for smashing, doesn't make it a Poor weapon.

Anyway, Excellent is for S. Which means Fine condition with mastery. I included Average (as suggested) because it looks weird if all of the grades are four letter words (and C had to be something)

I don't think weapons (or spells) should level up more than once. But I do think having mastery of similar weapons could accelerate the mastery of similar weapons, and that would not be difficult to implement (fyi: something like the Excellector is not the same as mastery)
Title: Re: Damage calculator
Post by: Holy_Diver on April 10, 2013, 11:15:33 pm
I noticed with all zero on a weapon it still deals 1 damage. That suggests that SOM just adds 1 after all the damage is added up. Will probably find out soon enough.

I did confirm for myself that Strength gives damage bonuses to magic. I suppose that makes sense if you literally throw the fireball or whatever, but I don't know if the analogy can apply to other kinds of magic attacks. It could be used exclusively with bullets attacks I suppose.

One thing I totally don't understand is if you leave a monsters defenses at all 0 you deal attack+strength/5. But if they have defense I am able to deal wild amounts of damage. If this represents a simplified system when all defenses are at 0 that's fine. But if this rule applies to individual affinities then that would be a bug wouldn't it?

Or does the monster defense settings represent weakness? I totally don't get it. I also wonder what happens if a monster's defense are negative. You can't see that in the graph in SOM_PRM. But would that give them an acute weakness to the affinity?

PS: I assumed before that an attack can never deal more damage than its damage rating. But this wasn't based on looking at the formula as much much as the if defense is 0 condition. But without taking the time to analyze. This is simply not what I am seeing. If I give a skeleton a small amount of defense I can deal massive damage. I just tested this and it is per affinity...

So the only way this isn't a bug is if the numbers in SOM_PRM are inverted, so that -2 is defense and +2 is weakness. And that isn't the case either! So is this a bug or what? I don't get it.

Basically it seems like if you leave any ratings set to 0 that affinity plays by totally different rules. If its a small number versus the damage devastating damage is dealt. But if its 0 then just the damage itself is dealt. Which at most can be 255 according to SOM_PRM. What say you. Is this a bug?

Negative defense BTW receives more damage than 0, but nothing astronomical like a small amount of defense will. In fact full negative defense (-128) yields 189 damage instead of 100. Where as 1 yields 5119.

Clearly 0 and less defense doesn't use this formula. It seems like a bug, or SOM is offering two different damage systems. But if you mix the systems then the result is clearly a bug...

So if you don't set all defenses to greater than 0, or all defenses to 0 or less, then you end up with a game that appears to be buggy :movingeyes:


I really like SOM. But if me or someone like me didn't exist to rehabilitate it it would be a straight up lost cause.


Title: Re: Damage calculator
Post by: Holy_Diver on April 10, 2013, 11:30:49 pm
EDITED: This seems like a bug to me. Because the negative number system looks much more friendly if you were to make a game where everything is tweaked by hand. But its pretty much useless because it can't represent defense. It can only represent weakness. And if you do give the monster some defense, more than likely you are just opening it up to astronomically damaging attacks (ironically) so its really baffling how this is supposed to work.

I guess you could represent defense purely by HP if you use only 0 or less defenses. The problem though is you can't do the same with armor, not using SOM_PRM anyway (if at all) so that the damage system would not be symmetrical. Looks like lose lose. If you are making a game without Ex (after I can add some extensions for damage here in a bit) just don't forget to set all defenses to at least 1 :doh:


PS: The behavior at and below 0 defense is baffling to me. I don't know whether it should be removed as a bug or what. The only place I can see it being useful is in a game where there is no armor. So that you just have the starting armor to determine the player's defense ratings. Or a variation would be having the armor approximate the negative damage formula behavior as well as you could. I think it would be possible if all armor has around the same defense in every slot with slight deviations up to 189%. In fact that would probably be the best way to make your game if you can figure out how to do that.


EDITED: Actually using the negative numbers, the weaker the weapon the more damage it deals in relative terms. It doesn't seem to be using the damage formula (with negative numbers plugged in) above at all. So I am unsure if it should be discounted as a bug or what. Well actually with a 255 weapon it literally deals less damage than a 100 weapon. So yeah, seems like a bug to me.

At 50 damage you deal 169. At 100 189. At 255 you deal 139.
Title: Re: Damage calculator
Post by: Holy_Diver on June 13, 2013, 09:15:49 am
MAG would be substituted for ATK for Magic damage types. Now aren't you glad you asked? Personally, I wouldn't "bake in" any damage formula. I would set up a simple default formula which is loaded from an external configuration text document. Thus letting users insert their own formula if they want.

Here is your formula system. I've been working on it for nearly a month, it will probably be another week before there is anything to demo. So I thought I'd give anyone who wants to a chance to study up on it in advance. Maybe sink some time into what you'd like to do with it.

http://en.swordofmoonlight.org/wiki/Sword_of_Moonlight_Extension_Library/list_of_numbers

Not everything is covered yet, but I've finally settled on a terminology for communicating these concepts. Everything has been covered here (http://www.swordofmoonlight.net/bbs2/index.php?topic=142)


EDITED: The Preface in the wiki covers the non-technical terminology. However the rest of the document doesn't yet reflect it. I've struggled in terms of how to explain things with it for some time.

The analogs for SOM's counters are: a counter is a "sum". Its number is a "subscript". All of the counters together is a "Number". Specifically a variable. With 1024 sums denoted by 1024 subscripts.
Title: Re: Damage calculator
Post by: HwitVlf on June 13, 2013, 02:54:58 pm
Sounds neat.  Wouldn't  it work just as well to use simple math tags like:
Damage=(Attack1-Defense1)+(Attack2-Defense2)... etc

I can see how such labels could fall short for advanced stuff, but it would be quite simple for beginners to pick up.
Title: Re: Damage calculator
Post by: Holy_Diver on June 13, 2013, 05:50:05 pm
Sounds neat.  Wouldn't  it work just as well to use simple math tags like:
Damage=(Attack1-Defense1)+(Attack2-Defense2)... etc

I can see how such labels could fall short for advanced stuff, but it would be quite simple for beginners to pick up.

That's how it works. It's like a calculator. For that you would do:

hit_outcome_quantifier = 1_-2_

Or:

hit_outcome_quantifier = _[1]-_[2]

Or if parameter labels are implemented for extensions:

hit_outcome_quantifier = _[HP]-_[AP]

Or:

hit_outcome_quantifier = _[Attack]-_[Defense]
Title: Re: Damage calculator
Post by: HwitVlf on June 14, 2013, 02:23:48 pm
I think this would be extremely helpful to SoM users.  I just meant using simple terminology in the labels seemed like a good idea. Being a lifelong lover of 'communication through written words', things like "hit_outcome_quantifier" seem needlessly computer-geekish to me (ala concatenation, obfuscation, parse etc). But the functionality is the main part and that's great.

When you get it up and running, please post. I might take the effort to revamp SoM's starting enemy stat slots so that people can start with balanced "leveled" creatures built in. :band:
Title: Re: Damage calculator
Post by: Holy_Diver on June 14, 2013, 05:25:56 pm
I think this would be extremely helpful to SoM users.  I just meant using simple terminology in the labels seemed like a good idea. Being a lifelong lover of 'communication through written words', things like "hit_outcome_quantifier" seem needlessly computer-geekish to me (ala concatenation, obfuscation, parse etc). But the functionality is the main part and that's great.

Well if you call it "Damage" what kind of damage is it? This extension is in the [Damage] section already. If its not called _quantifier then how do you know what it is? That tells you that there are input parameters involved. How do you search for it in the documentation? And how do you differentiate it from 100s if not 1000s of other extensions? Truth is the name here is quite short. It's part of a group of hit_ extensions, of which there are quite a few. There are extensions with much longer names.

Simple isn't always simpler. It doesn't scale. If you do things simple, then you are limited to doing everything simple, and simple can never be more than, you guessed it, simple. Besides just the process of parsing and evaluating an infix mathematical expression with operator precedence (in other words calculator syntax) is an incredibly complicated (this is one of if not the biggest jobs I've yet to do in service of SOM. And just the (1+2)-(3*4) bit alone is a good chunk of it.)

Also consider. I didn't ask what Attack1 and Attack2 means. Why two? How many are there? But if you add them together with just (A-B)+(A-B) you won't get the results you are looking for. You'd have to do something like max(0,A-B)+max(0,A-B) and as you can see that is already far from simple.

Quote
When you get it up and running, please post. I might take the effort to revamp SoM's starting enemy stat slots so that people can start with balanced "leveled" creatures built in. :band:

Starting enemy stat slots? What does that mean? The monsters in the King's Field sample? Anyway. I would leave everything alone. The default behavior will be the same as SOM uses no matter what. I would remove the bug where stats are 0 or negative, but I worry it would break existing games because the math is so messed up...

Probably I will fix the bug because its a bug. And older games will just have to turn off the fix. Or better yet, fix their monster's stats. I wonder if any of the monsters in the KF remake have 0 stats.


PS/EDITED: I too love communicating via the written word. That's why the names of the extensions are very literate. Or at least I am not a fan of cryptic configuration files. I'm not sure which is which. But the site I visit the most while I am working is thesaurus.com.

PPS: Literate programming is also a thing, which I am a strong advocate of and adherent too (edited: but don't go by http://en.wikipedia.org/wiki/Literate_programming ... that isn't literate programming, that's programming with literature. No one in the real world does that. I'd never even heard of that. Anyway, literate programming is programming without commentary because the code itself can be read like a book so any comment you could write would just be translating things for non-programmers -- who of course don't read code)
Title: Re: Damage calculator
Post by: HwitVlf on June 14, 2013, 06:51:11 pm
Pardon me if I'm being dense, but I thought the only "damage" in a SoM game was the final uhh... damage total the player receives. If you want to set up a game that has multiple "damage" subgroups(stab slash etc) , they still all end up a single totaled number ..."damage". 

Regardless of what fancy "elemental" label a person slaps on damage ingame, I think it's always going to boil down to three terms: "attack" which is the attacker's ability to inflict damage, "defense" which is the defender's ability to resist attack, and "damage" which is the resulting HP loss after attack and defense are processed.

My term "attack1" and "attack 2" were simple labels for damage sub-groups. For instance "Attack1" could be the attackers fire stat, "attack2" the attacker's stab stat.

Anything that works is fine. This was just my opinion about good labeling practices.

As far as setting "starting enemy stat slots", the default enemy stat/AI values are loaded when you make a new enemy slot in the Parameter Editor. The 'defaults' are read from one of SoM's file. The file's presets are rather useless which means a game maker has to manually adjust a bunch of settings for every new monster. I just meant, I could make an optional file that would make the defaults loaded for new enemies more intelligent and scaled so that game makers wouldn't have to do everything manually. They could still change things if they wanted.
Title: Re: Damage calculator
Post by: Holy_Diver on June 14, 2013, 09:26:24 pm
Pardon me if I'm being dense, but I thought the only "damage" in a SoM game was the final uhh... damage total the player receives. If you want to set up a game that has multiple "damage" subgroups(stab slash etc) , they still all end up a single totaled number ..."damage". 

Regardless of what fancy "elemental" label a person slaps on damage ingame, I think it's always going to boil down to three terms: "attack" which is the attacker's ability to inflict damage, "defense" which is the defender's ability to resist attack, and "damage" which is the resulting HP loss after attack and defense are processed.

My term "attack1" and "attack 2" were simple labels for damage sub-groups. For instance "Attack1" could be the attackers fire stat, "attack2" the attacker's stab stat.

I am not sure what all different sources of damage there are or will possibly be. Damage is a very broadly defined term. Here are all the extensions for traditional whops on the head:

   EX_INI_NUMBER(0,0,INF) hit_point_quantifier;
   EX_INI_NUMBER(0,0,INF) hit_point_quantifier2;
   EX_INI_NUMBER(0,0,INF) _hit_point_quantifier;
   EX_INI_NUMBER(0,0,INF) _hit_point_quantifier2;
   EX_INI_NUMBER(0,0,INF) hit_outcome_quantifier;
   EX_INI_NUMBER(0,0,INF) hit_penalty_quantifier;

The last one is for Poison damage. To reproduce the way SOM works you'd need to setup hit_point_quantifier for physical bonus. hit_point_quantifier2 for magical bonus. And hit_outcome_quantifier for the HP hit after defense.

If you want to do things differently for each affinity that takes extra work. The affinity would probably be in _[3] if there is a demand for that.

Should impact damage work like a whop on the head? What about monster damage? What about monster on monster damage? Should fall damage be distinct from impact damage? Environmental damage? Equipment damage? Internal damage? Brain damage :1782:

And don't forget you have to satisfy everyone's needs.

Quote
Anything that works is fine. This was just my opinion about good labeling practices.

Don't worry. My decisions are always best. Which is even better than good. I've never regretted anything. I make sure that I won't because it's better to do something right than do something twice. It will be possible to translate the Ex.ini files. I don't think it would help anything. But you could translate hit_outcome_quantifier to "damage". I think ultimately though that the exercise would just help you see why this wouldn't work out so well. You don't really see the problems clearly until you have to define them down to the quantum level of computing.

I think I saw what the Half Life config files looked like the other day in a forum. Those configuration keys were even longer than these.

Quote
As far as setting "starting enemy stat slots", the default enemy stat/AI values are loaded when you make a new enemy slot in the Parameter Editor. The 'defaults' are read from one of SoM's file. The file's presets are rather useless which means a game maker has to manually adjust a bunch of settings for every new monster. I just meant, I could make an optional file that would make the defaults loaded for new enemies more intelligent and scaled so that game makers wouldn't have to do everything manually. They could still change things if they wanted.

That's the first I've heard of this. I don't think I've ever noticed any defaults. I assumed everything would be zeroed out. Is that in the PRF files? I think a better system might be to have template projects. I don't think defaults would be useful. But that could make it a lot easier to just make your first map just to test drive the editors.
Title: Re: Damage calculator
Post by: HwitVlf on June 14, 2013, 10:13:16 pm
My vote is for the 'brain damage' label to be:
contactual_cephalic_discombobulation_recursion_index  :biggrin:

If memory serves, its the PRM files that contain the presets. They're not zeroed out by default, but pretty close. Size is set to 1, recognition is off, attacking is off and HP is set to 0.
Title: Re: Damage calculator
Post by: Holy_Diver on June 14, 2013, 10:58:01 pm
If memory serves, its the PRM files that contain the presets. They're not zeroed out by default, but pretty close. Size is set to 1, recognition is off, attacking is off and HP is set to 0.

While I am aware of that. I don't think it would help to change it up. I would say I don't see how, but that sounds even more dismissive. I took you to mean that there were defaults for each PRF's attack and defense ratings.

I think that's something that would be worth adding to the a .PNT (paint) format I am working on. I wish I could remember how that works. It must be either an extension to PRF or a file that indicates a PRF or a PRT. Either way it lets you apply a paint job, decals, change a rock projectile attack to an ice attack, change the PRF name from Giant to Ice Giant. That sort of thing.
Title: Re: Damage calculator
Post by: Holy_Diver on June 14, 2013, 11:59:34 pm
I think I had a good idea to remove the hit_extra_quantifier extensions just now. I never liked the name of those ones. I thought they'd be handy to set things up so that Magic attacks are based on the Magic stat. Which I think probably has a wider appeal than the way SOM (and presumably all of the KF games) work.

I thought it was an esoteric thing, because there is just nothing else in the world like "magic" so that only fantasy games would use it. Anyway. It dawned on me that its very unlikely that you'd want to differentiate between the physical and magical affinities if you were going to play that way. So it makes way more sense to just have the meaning of hit_point_quantifier2 change by switching on some other option.

I'm sure I would've realized this about 1 minute into actually implementing things. But its a big relief. I think I probably got there by working backwards from where I wanted to end up.

As for the others, _hit_point_quantifier is for defense bonus. I don't like to start extensions with an underscore. That's usually just a shorthand. But it represents a minus sign. The formal name might be even longer, but I can't think of anything. There may be some bit in front of hit_point that can just be left off for the traditional stuff (or plain hit_point might be the default formula where other specialized ones are not specified)
Title: Re: Damage calculator
Post by: Holy_Diver on June 22, 2013, 08:15:28 pm
^Per _hit_point_quantifier, leading underscore. It's going to be called hit_offset_quantifier instead. And I am very pleased that this stuff has gradually worked itself out.

It looks like there is going to be a hit_point_mode in addition to the hit_point_model. I think mode 2 will prove popular. It lets you control things based on the kind of attack instead of the kind of affinity. So the Magic stat can give bonuses to magic attacks likewise for defense with hit_offset_quantifier2...

So it would be nice to figure out a system for communicating what monster attacks are Strength vs. Magic based. Never mind that monsters don't have those stats. But for  hit_offset_quantifier in mode 2 its necessary to figure out which extension to use. The initial approach I am sure will just assume that if the attack is direct it is Strength based, and if not Magic based. Whether that is based on animation IDs or just whether or not the damage source is a magical effect it's too soon to say.
Title: Re: Damage calculator
Post by: Holy_Diver on June 23, 2013, 07:52:20 pm
EDITED: Actually. Probably the simplest thing to do would be to just leave hit_offset_quantifier2 alone in mode 2...

That's probably even more practical than having a stat produce a magic wall, even though that is pretty common in video games. By not setting up that extension you'd just be saying that once the magic attack is out of the barn, its a physical phenomenon just like anything else. And so a strong man is in a better position to defend themselves from the attack than a old wizard would be.

Anyway, that would be much more compatible with SOM because monsters don't have Strength and Magic stats as such, and it isn't obvious if their attacks are one or the other based... the same way it is with the player, where you always press the Magic button for Magic attacks.

You could also just combine Strength and Magic for defense as if you can draw from either source to defend yourself.
Title: Re: Damage calculator
Post by: Holy_Diver on July 02, 2013, 12:19:35 pm
I've finished initial work on the calculator features:

http://svn.swordofmoonlight.net/ex/Ex.number.h
http://svn.swordofmoonlight.net/ex/Ex.number.cpp

Not bad for more than a month of work. But before it can really be demoed the Damage extensions must be setup. In other words I'll be taking a break before resigning myself to staring at disassembled ASM until that works itself out.

EDITED: This is the single largest job I think I've ever programmed for SOM. The next largest is probably the menus interpreter. Mostly its just years and years of little things that all blend together with no one else ever appreciating the imperceptible differences.
Title: Re: Damage calculator
Post by: HwitVlf on July 02, 2013, 02:49:45 pm
That's a lot of coding and seems like a full featured damage tweak.

What disassembler are you using?
Title: Re: Damage calculator
Post by: Holy_Diver on July 03, 2013, 01:52:09 am
That's a lot of coding and seems like a full featured damage tweak.

Well I hope you realize this, but just for readers, none of that code pertains to damage. It's a calculator programming language basically. Maybe people should call it calculator code. It's a very elegant programming language (that I've developed) that maps as elegantly as possible to what any kid would be taught in grade school. Although for some reason talking about it (without resorting to programmers' idioms) I find very difficult.

Quote
What disassembler are you using?

Mainly the one built into SOM. do_disasm F11 function overlay. Sometimes the crude disassembly features built into Microsoft Visual Studio. People can hate all they want on Microsoft. But almost nothing compares to Visual Studio for productivity. Competitors are Eclipse and Netbeans but they are still not as nice and I am sill using MSVC2005. It's probably Microsoft's strongest product.
Title: Re: Damage calculator
Post by: HwitVlf on July 04, 2013, 02:41:35 pm
I think Microsoft made some very good tools in their heyday. But, most every software I've seen from them since around the time of Vista, has been a step in the wrong direction.

Since you already have a hook in the damage process to display damage on screen, don't you already know where to inject you calculator without having to do a bunch of assembly tracing?
Title: Re: Damage calculator
Post by: Holy_Diver on July 05, 2013, 04:25:13 am
I think Microsoft made some very good tools in their heyday. But, most every software I've seen from them since around the time of Vista, has been a step in the wrong direction.

That's pretty much true of all Microsoft software. However their C++ developer tools are used by Microsoft to develop Windows. For the longest time nothing was even close. But free software is catching up. But still there is nothing that can match the muscle of Microsoft's tools. If you don't use them development takes much longer. So it's best to do all of the real development on Windows and then do the porting work however you can. If not for MSVC Microsoft might be bankrupt. It's the tendency to develop first for Windows that probably keeps the company in good standing with the people who develop all of the software that makes Windows attractive.

Quote
Since you already have a hook in the damage process to display damage on screen, don't you already know where to inject you calculator without having to do a bunch of assembly tracing?

If only everything was that simple. No. You can just monitor the HP of things. If it goes down then they were damaged.
Title: Re: Damage calculator
Post by: HwitVlf on July 05, 2013, 05:51:40 am
Can't you just negate/reverse SoM's normal HP change and use that as a trigger to poll attack/defense stats to adjust damage according to your calculator's setup?
Title: Re: Damage calculator
Post by: Holy_Diver on July 05, 2013, 06:15:23 am
Can't you just negate/reverse SoM's normal HP change and use that as a trigger to poll attack/defense stats to adjust damage according to your calculator's setup?

No. You wouldn't know the source and mode of the damage. And the trigger wouldn't be evident until too late.
Title: Re: Damage calculator
Post by: Holy_Diver on July 05, 2013, 09:05:06 am
Fun fact. Monsters can kill NPCs with their indirect attacks. Something to watch out for.

That seems like something that either there should be a simple way to disable it. Or monsters should be able to kill NPCs with melee for completeness. I wouldn't mind investing time into having monsters hunt targets other than the player if that's pretty straightforward to do. I've always thought monsters should be more interested in each other than the player.

I wouldn't do a total overhaul of SOM's AI at this stage. But it can probably be easily tricked into thinking another NPC is the player on a per AI basis.

To be honest I'm more interested in blurring the line between NPC and enemy. It might make sense for authors to just setup their damage formulas to not harm individuals. On the other hand, do_not_harm_defenseless_characters would be easy enough to setup.
 
Another thing that's always bothered me is the player being the most powerful thing in the game. It seems like many things in most games should just be beyond the player's ability to vanquish period. In other words, you're just wasting your time to even try.


Anyway. I've also been thinking about the Void model. It's tricky, but I think it's a superior model. One thing I think it needs is a stat for the weapons and armor that just shows the raw power. Which is possible in the void model. And that would be a big help just comparing equipment side by side for class I think. It is going to take some rearranging of the menus. It won't be in the next release. Or probably even in the one after that.


Another thought I've had is instead of letting the player master a weapon. I reckon we might as well take that to the logical extreme and let them master individual ways of swinging individual weapons, since every swing is a different movement. This can be represented in equipment stats too if instead of showing percentiles you showed grades as Verdite has been asking for. One thing that makes me lean towards grades SABCDEF is I am not convinced a % will look so nice in the menus, and F for 50% or less would be a lot more compact, especially if you do C-A to demonstrate a maximum and minimum range of all swings available. To see a breakdown on the basis of individual swings you'd have to access a large table of some kind. Probably best to do that with a virtual manual that would not factor in mastery and durability.


EDITED: According to the void model the affinities of each type must add up to 100% so that AAA on all physical should not be possible to do. Since you are directing a portion of the weapons raw power in different ways. But I suppose through mastery you could go over 100% since it would just represent a scaling of the effectiveness. Another need for a raw power rating is the Void model hides stats in the empty spaces after the Stab and Holy affinities. So without a Raw total if all of the power was in a void slot the weapon would appear to be powerless, which is not right if you ask me.

For the physical affinities using grades it would still appear powerless. No Slash/Smash/Stab or whatever, but the Raw power would be the sum of the magical or material affinities, so you could conclude that the power does not take the form of one of the physical affinities, which would actually be the case. In other words it would be a "vorpal" sword of some kind, or more likely a magic spell...

Although I'm not sure how you could represent mastery of spells or such a weapon for that matter. Even grades in the physical affinities really would not make sense for spells. Oh well. You can't see stats for sword magic either. And you could always reveal the Void slots if you have too. But I still think the not knowing is fun. Probably the best way to show off spell mastery would be more impressive special effects. Wizards often don't realize that they are rusty until their spell is less impressive than expected. Such is the nature of magic.
Title: Re: Damage calculator
Post by: HwitVlf on July 05, 2013, 02:00:44 pm
I suppose that makes sense since it's possible for an enemy to get damaged from another enemy. but still the "reduce HP" step should be just downstream from the damage calculation. It's not likely that SoM would calculate damage, then hold the result in memory and do a bunch of other stuff like trigger the "getting hit" animation before actually reducing HP.
Title: Re: Damage calculator
Post by: Holy_Diver on July 05, 2013, 03:59:49 pm
I suppose that makes sense since it's possible for an enemy to get damaged from another enemy. but still the "reduce HP" step should be just downstream from the damage calculation. It's not likely that SoM would calculate damage, then hold the result in memory and do a bunch of other stuff like trigger the "getting hit" animation before actually reducing HP.

Actually that's exactly what SOM does as it turns out. But anyway. Computers do things in sequence. You have to wait your turn if you are not the man in the middle. So if the word "downstream" even makes sense then you are already inside of the code somehow.

When the damage monitoring HUD looks at HP doesn't really matter. It just does it once per frame. A few things use it.


EDITED: I can post the details on what SOM actually does, at least with respect to the formula tomorrow. I am too exhausted right now.
Title: Re: Damage calculator
Post by: HwitVlf on July 05, 2013, 05:11:37 pm
Well yeah, single thread processors run one op at a time, but the code is still just going to reflect the sequence the programmers set up.  Even if they ran a subroutine like "trigger Hit animation" between damage calculation and HP reduction, you should still be able to skip past that subroutine and get the damage calculation section without much searching. Anyways, it's pointless to discuss. It takes what it takes based on your skill level and game.exe's stupidliness.

A quick look shows around 400 sub routines in game.exe; most of them quite short. Have you charted any of their functions?
Title: Re: Damage calculator
Post by: Holy_Diver on July 06, 2013, 05:17:15 am
Well yeah, single thread processors run one op at a time, but the code is still just going to reflect the sequence the programmers set up.  Even if they ran a subroutine like "trigger Hit animation" between damage calculation and HP reduction, you should still be able to skip past that subroutine and get the damage calculation section without much searching. Anyways, it's pointless to discuss. It takes what it takes based on your skill level and game.exe's stupidliness.

See you seem to be basing your conception here on having some code injected somewhere. If that's the case you may as well inject the code anywhere; edited: as in, the best place possible. If there is no code injected however, it just runs where it runs.

I wonder too if you realize that the HP loss is just the final result of attack and defense with respect to eight variables, so you can't extract all of that from the HP loss. It's like being handed a 4 and being asked whether its 1+3 or 2+2. You can't say.

Quote
A quick look shows around 400 sub routines in game.exe; most of them quite short. Have you charted any of their functions?

After this next release SomEx.dll is going to standardize around som_db.exe, specifically the final patched version. Other exe files are no longer going to be supported. So if someone wanted to they could start documenting the subroutines of that image.

I think it would be useful to have a big graph of the EXE with curved lines linking call jumps that you can zoom in and out of in order to help visualize it. But I looked for a product like that yesterday and didn't find anything. I could probably make such a graph myself with a graphing library. I don't know if there would be too much program for it to be practical or not.

I know it pretty well instinctively. It just takes a few afternoons to do whatever I want to do with it when something needs to be done.

EDITED: Also just for the record. Even in multi thread applications, or a massively parallel architecture, things are happening at the rate of nanoseconds, so you just can't presume concurrency. Everything must be run in sequence. If two execution threads must interact that's an interlock point which can bring everything to a grinding stop. It's a miracle just to keep the concurrent tasks from clobbering one another at the speed of light.
Title: Re: Damage calculator
Post by: Holy_Diver on July 06, 2013, 05:41:45 am
Quote
To be honest I'm more interested in blurring the line between NPC and enemy. It might make sense for authors to just setup their damage formulas to not harm individuals. On the other hand, do_not_harm_defenseless_characters would be easy enough to setup.

EDITED: I did just remember that there is a box you can check to make NPCs invincible in the parameter editor. Still do_not_harm_defenseless_characters would let the player harm these NPCs while forbidding other NPCs from doing the same. It probably wouldn't hurt to add a confirmation dialogue extension to let the player confirm their decision to harm the NPC so that they can't do that on accident.

It seems like such a dialog should be the in-game variety. So you'd have to mimic that, and also there needs to be an extension to keep players from accidentally advancing / cancelling dialogs too. So such a dialog may be a ways away.
Title: Re: Damage calculator
Post by: Holy_Diver on July 06, 2013, 05:52:31 am
Here is reproduction of the damage formula with the ASM in /*comments*/

Code: [Select]
/*
00404470 83 EC 14         sub         esp,14h
00404473 53               push        ebx 
00404474 8B 5C 24 1C      mov         ebx,dword ptr [esp+1Ch]
00404478 81 7B 14 18 1A 9C 01 cmp         dword ptr [ebx+14h],19C1A18h
0040447F 56               push        esi 
00404480 C7 44 24 0C 00 00 00 00 mov         dword ptr [esp+0Ch],0
00404488 C7 44 24 10 00 00 00 00 mov         dword ptr [esp+10h],0
00404490 C7 44 24 14 00 00 00 00 mov         dword ptr [esp+14h],0
00404498 C7 44 24 18 00 00 00 00 mov         dword ptr [esp+18h],0
004044A0 C7 44 24 08 00 00 00 00 mov         dword ptr [esp+8],0
004044A8 75 2F            jne         004044D9
*/
float srcBase[2] = {0,0};
float dstBase[2] = {0,0};
if(*(DWORD*)(ebx+0x14)==0x19C1A18)
{
//always player, but src must be a weapon
//with the holder's stats in front instead???
//assert(src==player_src);  

/*
004044AA 33 C0            xor         eax,eax
004044AC 66 8B 03         mov         ax,word ptr [ebx]
004044AF 33 C9            xor         ecx,ecx
004044B1 66 8B 4B 02      mov         cx,word ptr [ebx+2]
004044B5 89 44 24 20      mov         dword ptr [esp+20h],eax
004044B9 DB 44 24 20      fild        dword ptr [esp+20h]
004044BD 89 4C 24 20      mov         dword ptr [esp+20h],ecx
004044C1 D8 0D BC 82 45 00 fmul        dword ptr ds:[4582BCh]
004044C7 D9 5C 24 0C      fstp        dword ptr [esp+0Ch]
004044CB DB 44 24 20      fild        dword ptr [esp+20h]
004044CF D8 0D BC 82 45 00 fmul        dword ptr ds:[4582BCh]
004044D5 D9 5C 24 10      fstp        dword ptr [esp+10h]
*/
srcBase[0] = float(*(WORD*)(ebx))/5;
srcBase[1] = float(*(WORD*)(ebx+2))/5;
}
/*
004044D9 8B 73 40         mov         esi,dword ptr [ebx+40h]
004044DC 81 FE 18 1A 9C 01 cmp         esi,19C1A18h
004044E2 75 3A            jne         0040451E
*/
DWORD esi = *(DWORD*)(ebx+0x40);
if(esi==0x19C1A18)
{
assert(dst==player_dst); //19C1C24 is Strength. 19C1C28 Magic
/*
004044E4 8B 15 24 1C 9C 01 mov         edx,dword ptr ds:[19C1C24h]
004044EA A1 28 1C 9C 01   mov         eax,dword ptr ds:[019C1C28h]
004044EF 81 E2 FF FF 00 00 and         edx,0FFFFh
004044F5 89 54 24 20      mov         dword ptr [esp+20h],edx
004044F9 DB 44 24 20      fild        dword ptr [esp+20h]
004044FD 25 FF FF 00 00   and         eax,0FFFFh
00404502 89 44 24 20      mov         dword ptr [esp+20h],eax
00404506 D8 0D BC 82 45 00 fmul        dword ptr ds:[4582BCh]
0040450C D9 5C 24 14      fstp        dword ptr [esp+14h]
00404510 DB 44 24 20      fild        dword ptr [esp+20h]
00404514 D8 0D BC 82 45 00 fmul        dword ptr ds:[4582BCh]
0040451A D9 5C 24 18      fstp        dword ptr [esp+18h]
*/
dstBase[0] = float(SOM::L.pcstatus[SOM::PC::str])/5;
dstBase[1] = float(SOM::L.pcstatus[SOM::PC::mag])/5;
}
/*
0040451E 83 7B 3C 02      cmp         dword ptr [ebx+3Ch],2
00404522 55               push        ebp 
00404523 57               push        edi 
00404524 75 6A            jne         00404590
*/  
float mystery = 0; //???
if(*(DWORD*)(ebx+0x3C)==2)
{
/*
00404526 33 C0            xor         eax,eax
00404528 66 8B 46 20      mov         ax,word ptr [esi+20h]
0040452C 8D 0C 40         lea         ecx,[eax+eax*2]
0040452F 8D 0C 89         lea         ecx,[ecx+ecx*4]
00404532 8D 14 88         lea         edx,[eax+ecx*4]
00404535 8B 4E 68         mov         ecx,dword ptr [esi+68h]
00404538 33 C0            xor         eax,eax
0040453A 66 8B 04 D5 C8 A1 4D 00 mov         ax,word ptr [edx*8+4DA1C8h]
00404542 8D 3C D5 C8 A1 4D 00 lea         edi,[edx*8+4DA1C8h]
00404549 51               push        ecx 
0040454A 8B 2C 85 C8 67 4C 00 mov         ebp,dword ptr [eax*4+4C67C8h]
00404551 E8 3A CF 03 00   call        00441490
00404556 8B 8E 40 02 00 00 mov         ecx,dword ptr [esi+240h]
0040455C 83 C4 04         add         esp,4
0040455F 83 F9 0C         cmp         ecx,0Ch
00404562 75 2C            jne         00404590
*/
DWORD eax = *(WORD*)(esi+0x20), edx = eax+(eax*3*5*4);
DWORD ecx = *(DWORD*)(esi+0x68), edi = edx*8+0x4DA1C8;

eax = *(WORD*)(edi);

DWORD ebp = *(DWORD*)(eax*4+0x4C67C8);

DWORD before = *(DWORD*)(esi+0x240);

((VOID (__cdecl*)(DWORD))0x441490)(ecx);

DWORD after = *(DWORD*)(esi+0x240);

if(after==0) //cmp ecx,0Ch
{
/*
00404564 33 D2            xor         edx,edx
00404566 8A 95 89 00 00 00 mov         dl,byte ptr [ebp+89h]
0040456C 3B D0            cmp         edx,eax
0040456E 7F 20            jg          00404590
00404570 33 C9            xor         ecx,ecx
00404572 8A 8D 8A 00 00 00 mov         cl,byte ptr [ebp+8Ah]
00404578 3B C1            cmp         eax,ecx
0040457A 7F 14            jg          00404590
0040457C 33 D2            xor         edx,edx
0040457E 8A 97 46 01 00 00 mov         dl,byte ptr [edi+146h]
00404584 89 54 24 28      mov         dword ptr [esp+28h],edx
00404588 DB 44 24 28      fild        dword ptr [esp+28h]
0040458C D9 5C 24 10      fstp        dword ptr [esp+10h]
*/

edx = *(BYTE*)(ebp+0x89);

if(edx<=eax) //cmp edx,eax
{
ecx = *(BYTE*)(ebp+0x8A);

if(eax<=ecx) //cmp eax,ecx
{
edx = *(BYTE*)(edi+0x146);

mystery = edx; assert(0); //???
}
}
}
}
/*
00404590 8B 44 24 30      mov         eax,dword ptr [esp+30h]
00404594 8B 6C 24 2C      mov         ebp,dword ptr [esp+2Ch]
00404598 C7 00 00 00 00 00 mov         dword ptr [eax],0
*/
DWORD ebp = dst; *out = 0;
for(esi=0;esi<8;esi++,ebp+=2)
{
/*
0040459E 33 F6            xor         esi,esi
004045A0 33 C0            xor         eax,eax
004045A2 8A 44 33 04      mov         al,byte ptr [ebx+esi+4]
004045A6 84 C0            test        al,al
004045A8 74 77            je          00404621
004045AA 0F BF 4D 00      movsx       ecx,word ptr [ebp]
004045AE 25 FF 00 00 00   and         eax,0FFh
004045B3 83 FE 03         cmp         esi,3
004045B6 89 44 24 28      mov         dword ptr [esp+28h],eax
004045BA DB 44 24 28      fild        dword ptr [esp+28h]
004045BE 89 4C 24 28      mov         dword ptr [esp+28h],ecx
004045C2 DB 44 24 28      fild        dword ptr [esp+28h]
004045C6 D8 44 24 10      fadd        dword ptr [esp+10h]
004045CA D9 5C 24 28      fstp        dword ptr [esp+28h]
*/
float rating = *(BYTE*)(ebx+esi+4); if(!rating) continue;

//mystery: unsure what else fadd could be doing
float offset = *(SHORT*)(ebp); offset+=mystery;
/*
004045CE 7D 0E            jge         004045DE
004045D0 D8 44 24 14      fadd        dword ptr [esp+14h]
004045D4 D9 44 24 28      fld         dword ptr [esp+28h]
004045D8 D8 44 24 1C      fadd        dword ptr [esp+1Ch]
004045DC EB 0C            jmp         004045EA
004045DE D8 44 24 18      fadd        dword ptr [esp+18h]
004045E2 D9 44 24 28      fld         dword ptr [esp+28h]
004045E6 D8 44 24 20      fadd        dword ptr [esp+20h]
*/
rating+=srcBase[esi>=3]; offset+=dstBase[esi>=3];
/*
004045EA D9 C1            fld         st(1)
004045EC D8 D9            fcomp       st(1)
004045EE DF E0            fnstsw      ax   
004045F0 F6 C4 41         test        ah,41h
004045F3 75 0D            jne         00404602
004045F5 D9 C1            fld         st(1)
004045F7 D8 E1            fsub        st,st(1)
004045F9 E8 3A B3 04 00   call        0044F938
004045FE 8B F8            mov         edi,eax
00404600 EB 02            jmp         00404604
00404602 33 FF            xor         edi,edi
*/    
LONG edi = rating-offset;
/*
00404604 D9 C1            fld         st(1)
00404606 D8 CA            fmul        st,st(2)
00404608 D9 C9            fxch        st(1)
0040460A DC C0            fadd        st(0),st
0040460C DE F9            fdivp       st(1),st
//not sure what this does but INF becomes 0//
0040460E E8 25 B3 04 00   call        0044F938
00404613 DD D8            fstp        st(0)
00404615 03 F8            add         edi,eax
*/

rating*=rating; offset+=offset;

if(offset) edi+=rating/offset;

/*
00404617 85 FF            test        edi,edi
00404619 7E 06            jle         00404621
0040461B 8B 44 24 30      mov         eax,dword ptr [esp+30h]
0040461F 01 38            add         dword ptr [eax],edi
00404621 46               inc         esi
00404622 83 C5 02         add         ebp,2
00404625 83 FE 08         cmp         esi,8
00404628 0F 8C 72 FF FF FF jl          004045A0
*/

*out+=edi;
}
/*
0040462E 8B 43 14         mov         eax,dword ptr [ebx+14h]
00404631 BF 18 1A 9C 01   mov         edi,19C1A18h
00404636 3B C7            cmp         eax,edi
00404638 75 1B            jne         00404655
*/
DWORD edi = 0x19C1A18;
if(*(DWORD*)(ebx+0x14)==edi) //0x19C1A18
{
//player power gauge
/*
0040463A 8B 4C 24 30      mov         ecx,dword ptr [esp+30h]
0040463E 33 D2            xor         edx,edx
00404640 66 8B 53 0E      mov         dx,word ptr [ebx+0Eh]
00404644 B8 59 17 B7 D1   mov         eax,0D1B71759h
00404649 0F AF 11         imul        edx,dword ptr [ecx]
0040464C F7 E2            mul         eax,edx
0040464E C1 EA 0C         shr         edx,0Ch
00404651 89 11            mov         dword ptr [ecx],edx
00404653 EB 04            jmp         00404659
*/

LONG edx = *out**(WORD*)(ebx+0xE);

edx = (0xD1B71759ULL*edx)>>32; //mul edx

*out = edx>>0xC;
}
/*
00404655 8B 4C 24 30      mov         ecx,dword ptr [esp+30h]
00404659 83 39 00         cmp         dword ptr [ecx],0
0040465C 75 06            jne         00404664
0040465E C7 01 01 00 00 00 mov         dword ptr [ecx],1
*/
if(*out==0) *out = 1;
Title: Re: Damage calculator
Post by: Holy_Diver on July 06, 2013, 06:05:59 am
I think the "mystery" bit (in the code above) is probably the monsters' evade maneuver defense bonus come to think of it just now.

The Strength and Magic bonuses are added to the player's defense as well as attack.

The formula is simpler than ((1+(ATK+DEF)/DEF-DEF*2/ATK)*ATK/2).

It's simply ATK-DEF+ATK*ATK/(DEF*2) where ATK and DEF are positive numbers.

EDITED: Actually with further testing it turns out it is max(0,ATK-DEF)+ATK*ATK/(DEF*2). In other words if DEF is greater than ATK the first term is 0. Why? Who can say.

If DEF*2 is 0 then the second additive term becomes infinity, which is undefined behavior when converted to an integer. But the 0044F938 subroutine produces 0 for infinity.

I think the subroutine just does floating point to integer conversion. There are at least 3 separate subroutines that do that in this chunk of code. And they are inline subroutines. So the 400 subroutine figure quoted above probably includes a lot of junk subroutines like these.

Anyway, since the ASM loads the result of the undefined operation into a register, it gets added to the total as 0.


To my mind I don't see the logic in this method of calculating damage. Why two different damage terms, one linear, one exponential, the exponential one collapsing to 0 on infinity damage, none of it makes sense to me, but I wouldn't be surprised if its the same formula used in the King's Field games, however the undefined bits might have played out differently on the PS1.

I think probably the thing to do in terms of looking at this as a bug, would be to take the linear term out. And treat 0 defense against nonzero attack as infinity damage. Whatever is done, clamping to 0 seems like a good place to begin.


PS: @HwitVlf: neither am I convinced that just doing ATK-DEF would work so well in terms of game play. I don't think players would like it so much unless it was coupled with a way to chip away at the opponents' defenses (that doesn't involve leveling up.)


EDITED: Also, the last bit is if there was no damage, then the damage is 1. This subroutine also does bad status infliction as a result of an attack, but I've not included that part above.
Title: Re: Damage calculator
Post by: Holy_Diver on July 06, 2013, 06:36:04 am
EDITED: I think something that could capture the spirit of this formula would be ATK-DEF where DEF can be chipped away at by ATK*ATK/(DEF*2). In other words, the DEF stat would be brought down with every swing according to an exponential function. The remainder could then be applied to ATK-DEF.

And then instead of 0 DEF being infinity damage, it would just be no defense.
Title: Re: Damage calculator
Post by: Holy_Diver on July 06, 2013, 01:45:43 pm
For the physical affinities using grades it would still appear powerless. No Slash/Smash/Stab or whatever, but the Raw power would be the sum of the magical or material affinities, so you could conclude that the power does not take the form of one of the physical affinities, which would actually be the case. In other words it would be a "vorpal" sword of some kind, or more likely a magic spell...

I think one approach to dealing with this could be to just not award mastery for the Void physical affinity. Since it would be an innate power in the weapon. No amount of swinging practice would make a difference. And since how you apply the weapon would have no relation to the stat then it wouldn't be clear how each swing relates to the effectiveness of the damage output. Could make these kinds of weapons popular with wizard players because they would be just as effective with or without mastery.

I reckon magic spells could work the same way too. So that if they don't have any physical affinities, then there is no benefit from mastery. Actually the power of the spell should probably just be a function of the Magic stat. Where mastery only awards modest benefits. Probably you would want to go up to 150%, so that anything over 100% is S. That way if the weapon/swing is a 50% F with complete mastery of the swing you could get a 100% A hit.

Title: Re: Damage calculator
Post by: HwitVlf on July 06, 2013, 04:50:29 pm
I expected the actual damage formula would look different than what I used in the excel, but it worked, and no one ever used the Excel anyways so it didn't really matter. Still, comparing the two, I can't easily see how they came to the same conclusion. Not worth the brain power to figure out.

I believe the KF damage formula was designed to be a limiter to exploration. If an enemies stats are significantly unbalanced from the player's, it results in giving/receiving massive damage.  In an open world game, that works to keep the player out of advanced areas until they're at the proper level. The down side to the KF formula is: it's not user friendly when making up a game, and it completely takes the challenge out of defeating enemies who are at a lower level.
 
People should be able to customize their damage formula with your plugin, but I like "damage=atk-def" for the default setting because it's simple for new developers to understand and use. As long as they have the option to change it, starting with the simplest formula makes sense to me.
Title: Re: Damage calculator
Post by: Holy_Diver on July 07, 2013, 03:10:49 am
People should be able to customize their damage formula with your plugin, but I like "damage=atk-def" for the default setting because it's simple for new developers to understand and use. As long as they have the option to change it, starting with the simplest formula makes sense to me.

When it comes to defaults I don't deviate from SOM if there is not a technical reason to do so. I don't want to usurp its identity. Besides _1-_2 is easy enough to write into a text file.

Still I think that formula could present problems. I wonder if there is a website that documents popular damage formulas. If not we should make one. I reckon once the people have a tool to experiment with a standard formula will emerge. I for one wish game play was more standardized. Every game working differently, detracts from the story telling potential in games I think. It's hard to consume games like books and movies when every one is different. That's not to say that experimentation should not occur. It should just occur behind the scenes IMO. After 30yrs of gaming some standards should have emerged by now.

EDITED: IMO the game mechanics should not detract or add to the experience. They should only exist to make the experience more visceral. Since that is the strength of the medium.

EDITED: I think one formula that might work as a default could be ATK-max(0,DEF-ATK*ATK/(DEF*2))

This says that the exponential formula negates the DEF and then what remains goes through the defenses. It's as if the armor regenerates after each hit. I think armor could be an interesting concept. It would certainly take the all powerfulness away from healing magic in video games, since the healing would heal the body but not the armor. So you might be full HP but standing naked. A game could have living armor that could be healed, lessening the effect of the heal on HP in the process, but I doubt that would fit into many games. Though it might become a popular trope. Like in King's Field probably only the Dark Armor would have that property.

Anyway, the damage formula is pretty buggy. So changing it to some degree is a necessity. Using that formula would at least look similar to the original formula. I want to keep the exponential curve regardless. And I'd like for the results to be similar. I think that formula would basically reduce down to the linear component. But the exponential curve means that it is more forgiving than atk-def would be.
Title: Re: Damage calculator
Post by: Holy_Diver on July 07, 2013, 07:34:00 am
I've taken a look at ATK-max(0,DEF-ATK*ATK/(DEF*2)). I am a little hesitant about using a completely different damage formula by default. But it has some nice properties.

For one. You can obviously never do more damage than the weapon+bonus itself. Which I think is very intuitive. It isn't as unforgiving as ATK-DEF would be.

Specifically I think you can start doing damage if your rating is within square root of 0.5 or 70.71% of the defense rating. That's a fairly auspicious number. It shows up in circles. For instance it's how far you can move diagonally when pressing the movement buttons.

Whereas with ATK-DEF you would have to be at 100% of the defense rating before you can deal damage. Which seems unrealistic, though I've no doubt games use this. It's reasonable to suspect that a weapon with a rating just below the armor can do more than 0 damage.

When the weapon and armor are equally matched you deal 55.90% of the weapon's damage. I am not sure if this number is significant (it almost definitely is) but it is the same number that SOM's classical formula yields. So that seems good (edited: I have a feeling this may be 50%. Could be rounding and stat bonuses were making the difference. Still seems like an awful big difference. May be worth revisiting sometime)

I expect when the weapon is 141.42% over the armor you will deal the weapon's maximum damage. This is square root of 2. Or the length of the diagonal of a square enclosing a unit circle. Whereas square root of 0.5 is the width of the square formed by that diagonal clipped at the edge of the circle.  Anyway at this point the armor is no longer effective (edited: for the record, this hunch seems to checkout)


It would be easy to draw a diagram of these relationships. It would be a circle in a square with another square just inside one of the quadrants of the circle.

I mean. Considering the limited range of the stats. I think this is about as good as anything you could come up with. It's intuitive. And based on literally round numbers. And uses the two terms of the original formula exclusively.


EDITED: I like this formula I think. If this is what the bugfix does. Because there must be a fix. Then to get the original formula minus its bugs I guess you'd just have to manually use that formula itself. It seems unlikely that anyone would want to. And I kind of feel like weapons doing more damage than their ratings is a bug in and of itself. Plus I don't have the reservations for this formula that I have for ATK-DEF.
Title: Re: Damage calculator
Post by: Holy_Diver on July 07, 2013, 09:49:03 am
One thing that occurred to me.

I was wondering what would happen if you had well over 255 armor. Because since monsters can do at most 255 damage, and you can wear so many pieces of armor, that seems like it would be easy to achieve if the author is not wary of this.

Essentially you should be invincible at this point. So I dawned two pieces of 255 armor. And setup a monster with 255 damage. I wasn't sure what would happen with the armor being more than the damage since, it seems like that would produce negative damage. I wondered if it could possibly be yet another bug.

Well that was not how things played out. It turns out there is another wrinkle in the formula. Basically if the armor is more than the damage, the ATK-DEF part of the equation is skipped: max(0,ATK-DEF)+ATK*ATK/(DEF*2).

And in this case the result of the exponential function was around 63 damage. Again skipping the first term of the equation seems like its totally arbitrary to me. But it does indicate that the original formula has a much larger damage window than square root 0.5 to 2. Whether it works the same way when DEF is less than ATK who is to say.

It's definitely a very piecewise function to say the least. Which is not good for authors.


All and all. I think ATK-max(0,DEF-ATK*ATK/(DEF*2)) is a pretty solid formula. You could probably add some parameters to it to increase its damage window, but I don't think such parameters should be extensions. It's easy enough to setup a custom function. It's much better behaved. But you do need to be cautious about not letting the player wear too much armor.

You could scale the armor in the hit_offset_quantifier extension if you wanted to use the entire range. Or scale up the attacks one. I wouldn't recommend that though unless its just a last ditch desperate attempt, or a test, better to just keep the armor pieces from stacking too high.


EDITED: I think things will be complicated when better hit detection arrives and authors would like to have weapon versus individual piece of armor. The weapons will have to be recalibrated or vice versa, and coverall armor would have to be adjusted to have the stats of a single piece of armor. Not sure how that could all be managed. Probably would just have to make do with custom formulas. It would be easy enough to do.
Title: Re: Damage calculator
Post by: Holy_Diver on July 07, 2013, 12:38:55 pm
I wouldn't be surprised if after all of this work this new default formula is good enough that no one will even care to setup a custom formula. Still its important work.

It's going to take me a while to flesh out all of the details for a demo but the basics are already up and running.

I've decided not to label parameters of extensions for the time being. They are easy enough to lookup. You'd have to lookup the labels anyway.

I've also decided to hold off on passing the affinity number as a parameter unless someone demands that. I think it's an obvious 3rd parameter for the final hit_outcome_quantifier extension. But I don't know if it should be second or third or what for the bonus extensions.

For the bonuses the pc global built in number or whatever--like c is for counters--refers to the player or NPC with the stats in question. Here pc can refer to a monster or NPC. There is also an npc number for the character on the other end, but its not going to be supported until necessary.

pc[0] or just pc is 1 for the player and 0 for NPCs (including enemies) and will be 2 for player character 2 if that is ever a thing.

pc[1] is Strength. And pc[2] is Magic. These are 0 for monsters. 3 is reserved for a Speed stat. And 4 is the weapon. 5 is the helmet I think. And so on. I believe these go in the order of the Equip menu. They are in the order they are in in the save file. For monsters equipment is NaN which will void your formula if you don't work around it.

You can label these yourself. I don't know what to label them. The only obvious labels would be Japanese. So I am letting the end user label them however they want or just use the numbers until I have a better idea.

For now pc is all NaN inside of the hit_outcome_quantifier extension. In other words it is source / target neutral. It will probably stay that way, but if it ever changes pc will refer to the character taking damage.

I don't know if hit_penalty_quantifier extension will make it into the next release or not. It lets you customize poison. Maybe other ailments too.


PS: While I am fairly pleased with this default formula. I am not a fan of the additive bonuses. Has anyone thought about how you'd like to figure the bonuses? Something multiplicative seems better to me. There is probably a website with information about how muscles effect the impact of an instrument out there somewhere...

What is the natural minima and maxima for humans. That would be interesting stuff.
Title: Re: Damage calculator
Post by: HwitVlf on July 07, 2013, 05:41:20 pm
I understand if you don't want to change SoM's default mechanics, but it sounds like you are changing the default formula so I don't quite get how your new formula is any better than the old.

Quite a few games have used damage=atk-def, as a matter of fact, I'm pretty sure Brigandine does with a slight randomizer and elemental adjustments. My desire for SoM has always been to make it easier for the common fan to make a game. And the problem that everyone mentions about SoM damage is that it's too abstract to adjust without tons of trial and error or calculation. That's just wasted time that would be better spent on other aspects of game development. 

The bottom line is "how many hits does it take to kill something". No matter how fancy the damage formula is, it always boils down to that same thing. If a player with 29 ATK goes against an enemy with 100 HP, 18 DEF how many hits would it take to kill the enemy using this formula: ATK-max(0,DEF-ATK*ATK/(DEF*2)) ? Good luck without a calculator.

But if the formula is "damage=atk-def", most people can do the math instantly in their head (29-18=11 100/11 = 9.x = 10 hits). Because of that, players can also evaluate equipment in a meaningful way. In KF, if I found a weapon with "56 Slash atk", I had no idea what that meant other than it was better than "55 slash".  With a simple formula, players can weigh the pros and cons of equipment and plan strategically. That adds potential enjoyment to the game.

SoM's default formula IS "damage = 1.5xATK - DEF" as long as stats are balanced. The only point in deviating from that formula as stats grow apart is to restrict players from going into areas where they aren't supposed to be yet - aka "rat in a maze" game design.  If someone wants to make a linear "rat in a maze" game, there are far easier ways of doing it.

I've said all there is to say, and you never change your mind once you've decided so I'm done talking on that particular topic.
Title: Re: Damage calculator
Post by: Holy_Diver on July 07, 2013, 11:50:39 pm
I understand if you don't want to change SoM's default mechanics, but it sounds like you are changing the default formula so I don't quite get how your new formula is any better than the old.

From reply #49:

Quote
Specifically I think you can start doing damage if your rating is within square root of 0.5 or 70.71% of the defense rating. That's a fairly auspicious number. It shows up in circles. For instance it's how far you can move diagonally when pressing the movement buttons.

Whereas with ATK-DEF you would have to be at 100% of the defense rating before you can deal damage. Which seems unrealistic, though I've no doubt games use this. It's reasonable to suspect that a weapon with a rating just below the armor can do more than 0 damage.

When the weapon and armor are equally matched you deal 55.90% of the weapon's damage. I am not sure if this number is significant (it almost definitely is) but it is the same number that SOM's classical formula yields. So that seems good (edited: I have a feeling this may be 50%. Could be rounding and stat bonuses were making the difference. Still seems like an awful big difference. May be worth revisiting sometime)

I expect when the weapon is 141.42% over the armor you will deal the weapon's maximum damage. This is square root of 2. Or the length of the diagonal of a square enclosing a unit circle. Whereas square root of 0.5 is the width of the square formed by that diagonal clipped at the edge of the circle.  Anyway at this point the armor is no longer effective (edited: for the record, this hunch seems to checkout)


Quote
Quite a few games have used damage=atk-def, as a matter of fact, I'm pretty sure Brigandine does with a slight randomizer and elemental adjustments. My desire for SoM has always been to make it easier for the common fan to make a game. And the problem that everyone mentions about SoM damage is that it's too abstract to adjust without tons of trial and error or calculation. That's just wasted time that would be better spent on other aspects of game development. 

This new formula is atk-def. It just has a damage window from about 70% to 140%. This models real life expectations better than atk-def. Since if you bang two things together that are approximately the same hardness they damage one another. Whereas atk-def only begins to produce damage when ATK is harder than DEF. Please read posts carefully so I don't have to repeat myself so much.

Quote
The bottom line is "how many hits does it take to kill something". No matter how fancy the damage formula is, it always boils down to that same thing. If a player with 29 ATK goes against an enemy with 100 HP, 18 DEF how many hits would it take to kill the enemy using this formula: ATK-max(0,DEF-ATK*ATK/(DEF*2)) ? Good luck without a calculator.

In that case the ATK overwhelms the defense and does 29 damage. Around 12 ATK it can't penetrate the defense and deals 0 damage. Or 1 using the 0=1 handicap. This is like real life armor. If you just remember that when the two are matched 50% of damage is dealt you'll be fine. The formula is well behaved. Unlike SOM's.

Quote
But if the formula is "damage=atk-def", most people can do the math instantly in their head (29-18=11 100/11 = 9.x = 10 hits). Because of that, players can also evaluate equipment in a meaningful way. In KF, if I found a weapon with "56 Slash atk", I had no idea what that meant other than it was better than "55 slash".  With a simple formula, players can weigh the pros and cons of equipment and plan strategically. That adds potential enjoyment to the game.

Yeah, but it doesn't model anything like real physical dynamics. So its more confusing. And very unforgiving. You can't have parity between the weapons and the armor, since the weapons must always be harder to make the slightest dent.

Quote
SoM's default formula IS "damage = 1.5xATK - DEF" as long as stats are balanced. The only point in deviating from that formula as stats grow apart is to restrict players from going into areas where they aren't supposed to be yet - aka "rat in a maze" game design.  If someone wants to make a linear "rat in a maze" game, there are far easier ways of doing it.

Well that's why this formula. When matched it produces the same results. Plus it isn't a radical departure from SOM's identity. It just shifts its terms around very slightly to produce something that is not so impenetrable, if not ill conceived.

Quote
I've said all there is to say, and you never change your mind once you've decided so I'm done talking on that particular topic.

You'll prefer this formula. I didn't expect it. It just emerged organically. Call it divine providence.


PS: For the record. My concern is always for the player. Both in game. And when they first open up the Ex.ini file out of curiosity. I want them to feel welcome and get sucked in. Just like reading a book. Writing is difficult. Reading should be easy.

EDITED: News Flash. There is also handicap_quantifier to change the behavior of 0=1. There will probably a Player handicap preference too, but it will be a straight scalar. This one is intended for authors.

BTW: Am I the only one that gets freezed out of this site after a couple page reloads? I just expect for this site to go dead for 5 minutes at least once every time I use it. Might want to clean the lent trap on the database.
Title: Re: Damage calculator
Post by: Holy_Diver on July 08, 2013, 03:34:39 am
Just out of curiosity, can you define "rat in a maze"?

Do you mean for instance you can't go somewhere because it will be Game Over if you get touched?

Or is it you can't dispose of an obstacle? Because if its the latter, say a giant in a doorway with 127 defense. Then with ATK-DEF you are going to being doing 0 damage unless your weapon is at 128. Unless you can make it under the giants legs he may as well be a locked door.

Whereas with this formula if your weapon is at 127 you do 63 damage. And at 89 you do 1 damage. At 177 or more you do 177.

Compare to 127 is 0 damage. 89 is 0 damage. And 177 is 50 damage.

Remember you are stuck between 0 and 255.


PS: Also consider ATK-DEF while being unintuitive also throws out at least half of the range. If you make a monster that has 250 defense. Then the best weapon the player can muster can only possibly do 5 damage plus bonus. Whereas if you hit that monster with a 250 weapon with SOM's formula you do 128 damage, which is what you expect when two equally matched opponents square off. In other words, a tie.
Title: Re: Damage calculator
Post by: Holy_Diver on July 08, 2013, 06:07:10 am
For the record, the affinity is going to be supplied as a third parameter in case anyone wants it.

The second parameter turned out to be the evasion defense bonus that monsters get. I reckon players will get it too somehow if they are holding up a shield. The second argument for attackers is 0. But if there was a similar mechanic for attackers it will be nonzero. That would have to be an extension. For example how you can do extra damage when falling in Dark Souls.

So in other words, you must incorporate the evasion into hit_offset_quantifier if you set that up. Or else. The bonus won't be in play.


PS: I have no idea what to do about the power gauge yet. Basically it happens before handicap_quantifier and scales down your damage linearly. I don't think it's part of damage per se. So I am not setting up any extensions for it until I have a better idea of what to do. Seems fine the way it is for now.

I think it falls more into a physical simulation category than damage gamification. Whereas gamers we don't want to know how materials are torn apart. We don't want to play a game that cares about that. Because it wouldn't be a game. But how your arm moves is something much simpler, and familiar...

Also I have long concluded that the gauges do not represent power or stamina. They are timing gauges. To the extent that they will represent power will only be to the extent that you use them as an aid to hit the right timing. With the exception of the magic gauge. Sometimes it can represent power draining out. Like air when swimming. Or A magic field waning in strength over time.
Title: Re: Damage calculator
Post by: Holy_Diver on July 08, 2013, 06:49:49 am
^Actually. Supplying the affinity is really handy. I was thinking about implementing weights for the affinities as an extension. But you don't need that since you can just setup a bank of weights and use that parameter to get at them.

For example. For King's Field I think Fire should deal more damage than Earth. Automatically. So you don't have to think about that when setting up the stats. And likewise Fire should have less defense than Earth. So you'd just setup a number like so:

[Number]
;1 1 1, Fire Wind Water Earth, Holy
hpWeights = 1 1 1, 1 0.9 0.8 0.7, 1
_hpWeights = 1 1 1, 0.7 0.8 0.9 1, 1

Then use those in your bonus formulas.

[Damage]
;Magic stat bonuses
hit_point_quantifier2 = (1_+2pc/5+2_)*hpWeights[3_]
hit_offset_quantifier2 = (1_+2pc/5+2_)*_hpWeights[3_]

In this case you could just compute _hpWeights with (1-hpWeights[3_]). In this case you could also factor in the weights with hit_outcome_quantifier instead in most cases. Wherever its easier to read would usually be best.

This is going to be a big load off my back and help keep the number of extensions to a minimum.
Title: Re: Damage calculator
Post by: Holy_Diver on July 08, 2013, 07:11:11 am
^Looking at that reminds me that using an additive bonus (+2pc/5) is really broken. Because if it adds, then it should add to 0 stats too. And you basically get a huge bonus just for the weapon having a 1 rating affinity, since that enables the bonus on that affinity.

Multiplication based bonuses has to be the way to go. I'm tempted to even use a different bonus formula by default, since it seems so broken the way it works :movingeyes:
Title: Re: Damage calculator
Post by: Holy_Diver on July 08, 2013, 11:56:18 am
For what it's worth you could hexedit your PRM file to make a monster that inflicts more than one status ailment. It would do them all at once (like the Lovecraftian plant monster in Final Fantasy games) but I can't see any reason why it wouldn't work.
Title: Re: Damage calculator
Post by: Holy_Diver on July 08, 2013, 02:14:08 pm
FYI: I've attached a demo to this post (http://www.swordofmoonlight.net/bbs2/index.php?topic=142.msg1196#msg1196) but I haven't yet announced it in the thread. I'll do that tomorrow after getting some sleep.

If your numbers have a syntax error you'll get a game over popup box. It's better than nothing for now. The error is not described. But the expression is in the popup's title bar.

Also. I went and changed handicap_quantifier to hit_handicap_quantifier...

The following mentioned extensions are not implemented and odds are good they won't be in the next release.

hit_point_mode
hit_point_model
hit_penalty_quantifier

The damage loop looks like this:

Code: [Select]
DWORD ebp = dst; *out = 0;
for(esi=0;esi<8;esi++,ebp+=2)
{
/*
0040459E 33 F6            xor         esi,esi
004045A0 33 C0            xor         eax,eax
004045A2 8A 44 33 04      mov         al,byte ptr [ebx+esi+4]
004045A6 84 C0            test        al,al
004045A8 74 77            je          00404621
004045AA 0F BF 4D 00      movsx       ecx,word ptr [ebp]
004045AE 25 FF 00 00 00   and         eax,0FFh
004045B3 83 FE 03         cmp         esi,3
004045B6 89 44 24 28      mov         dword ptr [esp+28h],eax
004045BA DB 44 24 28      fild        dword ptr [esp+28h]
004045BE 89 4C 24 28      mov         dword ptr [esp+28h],ecx
004045C2 DB 44 24 28      fild        dword ptr [esp+28h]
004045C6 D8 44 24 10      fadd        dword ptr [esp+10h]
004045CA D9 5C 24 28      fstp        dword ptr [esp+28h]
*/
float offset = *(SHORT*)(ebp);
float rating = *(BYTE*)(ebx+esi+4);

if(!rating) continue; //todo: extension to bypass this?
/*
004045CE 7D 0E            jge         004045DE
004045D0 D8 44 24 14      fadd        dword ptr [esp+14h]
004045D4 D9 44 24 28      fld         dword ptr [esp+28h]
004045D8 D8 44 24 1C      fadd        dword ptr [esp+1Ch]
004045DC EB 0C            jmp         004045EA
004045DE D8 44 24 18      fadd        dword ptr [esp+18h]
004045E2 D9 44 24 28      fld         dword ptr [esp+28h]
004045E6 D8 44 24 20      fadd        dword ptr [esp+20h]
*/
if(&hp->hit_point_quantifier)
{
SOM::L.pcstatus = srcStatus;

if(esi<3||!&hp->hit_point_quantifier2)
{
rating = hp->hit_point_quantifier(rating,0,esi);
}
else rating = hp->hit_point_quantifier2(rating,0,esi);
}
else rating+=srcBase[esi>=3];

if(&hp->hit_offset_quantifier)
{
SOM::L.pcstatus = dstStatus;

if(esi<3||!&hp->hit_offset_quantifier2)
{
offset = hp->hit_offset_quantifier(offset,evasion,esi);
}
else offset = hp->hit_offset_quantifier2(offset,evasion,esi);
}
else offset+=dstBase[esi>=3]+evasion;
/*
004045EA D9 C1            fld         st(1)
004045EC D8 D9            fcomp       st(1)
004045EE DF E0            fnstsw      ax   
004045F0 F6 C4 41         test        ah,41h
004045F3 75 0D            jne         00404602
004045F5 D9 C1            fld         st(1)
004045F7 D8 E1            fsub        st,st(1)
004045F9 E8 3A B3 04 00   call        0044F938
004045FE 8B F8            mov         edi,eax
00404600 EB 02            jmp         00404604
00404602 33 FF            xor         edi,edi
*/    
LONG edi = 0; //max(0,rating-offset);
/*  
00404604 D9 C1            fld         st(1)
00404606 D8 CA            fmul        st,st(2)
00404608 D9 C9            fxch        st(1)
0040460A DC C0            fadd        st(0),st
0040460C DE F9            fdivp       st(1),st
//not sure what this does but INF becomes 0//
0040460E E8 25 B3 04 00   call        0044F938
00404613 DD D8            fstp        st(0)
00404615 03 F8            add         edi,eax
*/
if(&hp->hit_outcome_quantifier)
{
SOM::L.pcstatus = 0; //NaN

*out = //custom formula
hp->hit_outcome_quantifier(rating,offset,esi);
}
else if(!bf||bf->do_fix_damage_calculus)
{
if(offset>0) //default formula
{
edi = rating-
max(0,offset-(rating*rating/(offset*2)));
if(edi<0) edi = 0;
}
else edi = rating;
}
else //classic formula with bugs
{
edi = max(0,rating-offset);

rating*=rating; offset+=offset;

if(offset) edi+=rating/offset;
}
/*
00404617 85 FF            test        edi,edi
00404619 7E 06            jle         00404621
0040461B 8B 44 24 30      mov         eax,dword ptr [esp+30h]
0040461F 01 38            add         dword ptr [eax],edi
00404621 46               inc         esi
00404622 83 C5 02         add         ebp,2
00404625 83 FE 08         cmp         esi,8
00404628 0F 8C 72 FF FF FF jl          004045A0
*/
*out+=edi; //why jle and not je???
}
/*
0040462E 8B 43 14         mov         eax,dword ptr [ebx+14h]
00404631 BF 18 1A 9C 01   mov         edi,19C1A18h
00404636 3B C7            cmp         eax,edi
00404638 75 1B            jne         00404655
*/
DWORD edi = 0x19C1A18;
if(*(DWORD*)(ebx+0x14)==edi) //0x19C1A18
{
//player power gauge
/*
0040463A 8B 4C 24 30      mov         ecx,dword ptr [esp+30h]
0040463E 33 D2            xor         edx,edx
00404640 66 8B 53 0E      mov         dx,word ptr [ebx+0Eh]
00404644 B8 59 17 B7 D1   mov         eax,0D1B71759h
00404649 0F AF 11         imul        edx,dword ptr [ecx]
0040464C F7 E2            mul         eax,edx
0040464E C1 EA 0C         shr         edx,0Ch
00404651 89 11            mov         dword ptr [ecx],edx
00404653 EB 04            jmp         00404659
*/

LONG edx = *out**(WORD*)(ebx+0xE);

edx = (0xD1B71759ULL*edx)>>32; //mul edx

*out = edx>>0xC;
}
SOM::L.pcstatus = pcstatus;
/*
00404655 8B 4C 24 30      mov         ecx,dword ptr [esp+30h]
00404659 83 39 00         cmp         dword ptr [ecx],0
0040465C 75 06            jne         00404664
0040465E C7 01 01 00 00 00 mov         dword ptr [ecx],1
*/
if(&hp->hit_handicap_quantifier)
{
SOM::L.pcstatus = dstStatus;
*out = hp->hit_handicap_quantifier(*out);
SOM::L.pcstatus = pcstatus;
}
else if(*out==0) *out = 1;

I would like to change the default bonus if I don't forget. I'd like to hear any suggestions.


EDITED: I don't think I am going to do anymore work with this. The one thing I may do is better error messages for number syntax errors. Especially if anyone has problems. Of course there is a lot of documentation to do. And also. Very important. The damage extensions only work with som_db.exe. So until this release is done, they will only be in effect for project trials.
Title: Re: Damage calculator
Post by: HwitVlf on July 08, 2013, 04:25:29 pm
You'll prefer this formula. I didn't expect it. It just emerged organically. Call it divine providence.
Gee tanks fer tellin me cause I two stupt to no whats I like lesn somun tell me. Maybe it's divine providence punishing you for your irreverence by giving you a bad idea? Joking aside, I don't mean your formula is bad for game players, just that it's not optimized for the common fan game maker.

Quote
BTW: Am I the only one that gets freezed out of this site after a couple page reloads? I just expect for this site to go dead for 5 minutes at least once every time I use it. Might want to clean the lent trap on the database.
haven't had any problem like that in a long time.

Just out of curiosity, can you define "rat in a maze"?

Do you mean for instance you can't go somewhere because it will be Game Over if you get touched?

Or is it you can't dispose of an obstacle? Because if its the latter, say a giant in a doorway with 127 defense. Then with ATK-DEF you are going to being doing 0 damage unless your weapon is at 128. Unless you can make it under the giants legs he may as well be a locked door.

Whereas with this formula if your weapon is at 127 you do 63 damage. And at 89 you do 1 damage. At 177 or more you do 177.

Compare to 127 is 0 damage. 89 is 0 damage. And 177 is 50 damage.

Remember you are stuck between 0 and 255.


PS: Also consider ATK-DEF while being unintuitive also throws out at least half of the range. If you make a monster that has 250 defense. Then the best weapon the player can muster can only possibly do 5 damage plus bonus. Whereas if you hit that monster with a 250 weapon with SOM's formula you do 128 damage, which is what you expect when two equally matched opponents square off. In other words, a tie.

In this instance, by "rat in a maze" I meant you were given the illusion of being able to go where you want, but in truth, you would get 1 hit KO'd by creatures a few levels higher than you so you're actually stuck following the developer's choreographing.  In general, I use "rat in a maze" to describe anything that limits the player's actions to a single choreographed path- both environmentally: as in there is only a single ravine that you must follow to it's end, and intellectually: as in you can shoot an atomic weapon at a boss and he won't die, but if you use your trusty dagger to collapse the ledge above him, he gets crushed to death.

As far as all the rest, plenty of games have used dam=atk-def, so if you're confused as to how it would work, maybe you should do some research. You're ignoring HP as a factor, and SoM does this damage calculation for each of its eight damage types, then adds the results.  So the damage limit would actually be 128x8, and you're not factoring in elemental weaknesses which would be essentially added to ATK. I did of course mean 0 damage =1, but that would happen behind the scenes and therefore would not be a significant part of the formula that the designer would have to keep track of.

It's this simple:
If the designers wants an enemy to get killed in two hits: HP=20, DEF=10, Player ATK=20
After twenty hits, HP=200, DEF=10, Player ATK=20,
A hundred: HP=1000, DEF=10, Player ATK=20
A thousand hits HP=1000 DEF=20, Player ATK = 20
You know as well as I do how it would work. Why do you keep bringing this up? Are you hoping to prove my idea is dumb? Who cares; I have dumb ideas all the time.  Here, I'll save you the effort "my idea for damage=atk-def was a dumb idea and would make any game that used it completely boring and unplayable". Now can we move on?

You asked somewhere if there was a disassembler that charted sub routines. Yes, IDA is one. But usually each sub routine is charted on a separate page or you would just have a tangled mess. All I meant by "chart" was to catalog the function of the sub-rouines you work on for future reference.
Title: Re: Damage calculator
Post by: Holy_Diver on July 09, 2013, 06:27:50 am
You'll prefer this formula. I didn't expect it. It just emerged organically. Call it divine providence.
Gee tanks fer tellin me cause I two stupt to no whats I like lesn somun tell me. Maybe it's divine providence punishing you for your irreverence by giving you a bad idea? Joking aside, I don't mean your formula is bad for game players, just that it's not optimized for the common fan game maker.

I am just making a prediction. Don't take things so personally. You're wrong to doubt my judgement though. And that's not a prediction.

Quote
As far as all the rest, plenty of games have used dam=atk-def, so if you're confused as to how it would work, maybe you should do some research. You're ignoring HP as a factor, and SoM does this damage calculation for each of its eight damage types, then adds the results.  So the damage limit would actually be 128x8, and you're not factoring in elemental weaknesses which would be essentially added to ATK. I did of course mean 0 damage =1, but that would happen behind the scenes and therefore would not be a significant part of the formula that the designer would have to keep track of.

SOM doesn't have elemental weaknesses. While its true everything is by a factor of 8. That just means if you have 128 on all 8 affinities you can hit the giant for 8 HP instead of 1 HP. If he has lots of HP that's going to be a long fight. I like monsters to go down in about 5 hits or less myself.

I mean its besides the point. We established the giant has 127 defense. That doesn't mean he has 0 fire defense. That means he has 127 defense no matter what you use. Which is likely to be the case, because most ordinary things don't have elemental weaknesses.

Quote
It's this simple:
If the designers wants an enemy to get killed in two hits: HP=20, DEF=10, Player ATK=20
After twenty hits, HP=200, DEF=10, Player ATK=20,
A hundred: HP=1000, DEF=10, Player ATK=20
A thousand hits HP=1000 DEF=20, Player ATK = 20

You can also just take the monsters defense. Cut it in half to suppose the player and monster are equally matched. And multiply that by the number of hits you want.

Quote
You know as well as I do how it would work. Why do you keep bringing this up? Are you hoping to prove my idea is dumb? Who cares; I have dumb ideas all the time.  Here, I'll save you the effort "my idea for damage=atk-def was a dumb idea and would make any game that used it completely boring and unplayable". Now can we move on?

You are projecting here. I'm just arguing the merits of two damage schema. I assume ATK-DEF has merits. It supposes when equally matched no damage is dealt. If I am doing anything humanitarian, it is saving you from the trouble of setting up a map and discovering you are unhappy with the results.

Quote
You asked somewhere if there was a disassembler that charted sub routines. Yes, IDA is one. But usually each sub routine is charted on a separate page or you would just have a tangled mess. All I meant by "chart" was to catalog the function of the sub-rouines you work on for future reference.

There are tools usually used to document APIs that arrange all of the subroutines and draw lines of dependencies between them. They automatically figure out the best way to arrange things. Even if the best you can get is a tangled mess that's better than no graphical representation at all.

I suspect SOM's games would not be that complicated of a program once you pruned away all of the junk subroutines. There might only be a handful of logical units.
Title: Re: Damage calculator
Post by: Holy_Diver on July 09, 2013, 08:46:11 am
BTW: I am very serious about rethinking the bonuses.

But I am not sure how to proceed. One very promising concept is to incorporate the map scales into the damage. It seems reasonable that a 2x sized monster would have 2x damage output and 2x defenses.

I will probably bring this up in my demo announcement post later today.


PS: Intuitively it seems like the Strength bonus should work in reverse. So you are penalized for not being at maximum Strength. Or maybe it should work on a bell curve. The only problem is there is no standard for what degree of Strength is achievable in a game. So its almost too soon to say. Its also a little presumptive to assume human strength.

The scaling concept kind of supports the idea of going over 255. Since a 2x monster with 255 attack would do 510 damage. So if you want to make a giant monster, you can just make him small, and scale him up on the map to go way over the 255 limit. So within this concept rising strength is a lot like scaling the player up. I think this is the right way of thinking about this anyway. So I made this post to celebrate.

EDITED: Also I would like to settle on something before the release happens.

PPS: The 999 hp limit is pretty arbitrary. You can map to any HP. But you can also go up to 65535 HP. The limit is just imposed by SOM_SYS's text fields. Shadow Tower uses more than 999 HP even from the start of the game I think. So a fix will be in order sooner or later. Of course you can also just scale things down in the hit_handicap_quantifier.