About JS magic and MagicDamage
-
Grimson
- Developer
- Posts: 802
- Joined: Sat Jun 04, 2005 1:52 am
- Location: Germany
- Has thanked: 0
- Been thanked: 0
About JS magic and MagicDamage
I noticed that in level1targ.js there is a JS version of MagicDamage(). Would't it be easier to just expose the MagicDamage() function from magic.cpp to the JS engine? Or is this unwanted?
-
Grimson
- Developer
- Posts: 802
- Joined: Sat Jun 04, 2005 1:52 am
- Location: Germany
- Has thanked: 0
- Been thanked: 0
Then the JS version of MagicDamage() needs a whole lot of work, it doesn't contain the reputation handling (making chars criminal and/or murderers), it doesn't contain the calculation for elemental resistance and it doesn't create a reaction from the attacked target (you can attack with JS magic and the attacked NPC will do nothing).giwo wrote:We, eventually, want to handle all magic through the JS engine.
So exposing MagicDamage() to the JS engine would be superfluous.
In my opinion we shouldn't put too much into JS and keep some more complex functions in the source, if the user wants he can still write his own JS functions to handle such things. But that's just my opinion.
-
giwo
- Developer
- Posts: 1780
- Joined: Fri Jun 18, 2004 4:17 pm
- Location: California
- Has thanked: 0
- Been thanked: 0
Thus why all the spells aren't currently in the JS. I haven't had the time (nor the desire) to push it out to JS, and no one else seems interested in moving functionality to the JS engine.
However there's no good reason not to put the entire system into the JS. Unlike combat it's not incredibly time-sensitive, and this makes it very modifiable for the end-users.
However there's no good reason not to put the entire system into the JS. Unlike combat it's not incredibly time-sensitive, and this makes it very modifiable for the end-users.
Scott
-
Maarc
- Developer
- Posts: 576
- Joined: Sat Mar 27, 2004 6:22 am
- Location: Fleet, UK
- Has thanked: 0
- Been thanked: 0
- Contact:
Fame and Karma are definitely not handled at the moment, I know that, but that was part of the damage tracking I had intended to do. Rather than the half dozen spots where we do something like:
I was hoping to wrap this into a character function that gets called on Damage/Heal applied. By doing all damage/healing through the damage tracking functions, we always know who the last attacker is. The function I was looking at for doing this is currently empty, and is CChar::Die(). So if that gets fleshed out, and called, as appropriate, from Damage() and Heal(), you can hide a lot of that fame and karma stuff (as Damage() already knows the last attacker, if it's passed).
It's no surprise the elemental damage stuff isn't in there, though, as you've only just added it
As for the reputation stuff, all I can say is that the MagicDamage() that is in the JS file was accurate at the time it was created (26th January, 2006). It seems that subsequent updates to MagicDamage() in code, in regards to reputation, were not mirrored into this file.
Code: Select all
if( PlayerHealth <= 0 )
{
KarmaAdjust();
FameAdjust();
KillPlayer();
}
It's no surprise the elemental damage stuff isn't in there, though, as you've only just added it
As for the reputation stuff, all I can say is that the MagicDamage() that is in the JS file was accurate at the time it was created (26th January, 2006). It seems that subsequent updates to MagicDamage() in code, in regards to reputation, were not mirrored into this file.
-
Grimson
- Developer
- Posts: 802
- Joined: Sat Jun 04, 2005 1:52 am
- Location: Germany
- Has thanked: 0
- Been thanked: 0
Ok, sounds like a much better solution.Maarc wrote:Fame and Karma are definitely not handled at the moment, I know that, but that was part of the damage tracking I had intended to do. Rather than the half dozen spots where we do something like:
I was hoping to wrap this into a character function that gets called on Damage/Heal applied. By doing all damage/healing through the damage tracking functions, we always know who the last attacker is. The function I was looking at for doing this is currently empty, and is CChar::Die(). So if that gets fleshed out, and called, as appropriate, from Damage() and Heal(), you can hide a lot of that fame and karma stuff (as Damage() already knows the last attacker, if it's passed).Code: Select all
if( PlayerHealth <= 0 ) { KarmaAdjust(); FameAdjust(); KillPlayer(); }
I added both of them to the source version of MagicDamage(), as I didn't saw first that there is a (IMHO superfluous) version in JS. And as I still think that exposing and using the source version, as I have done (together with .tempWeight) for my personal builds, is better I have also no intention to update the JS version.Maarc wrote:It's no surprise the elemental damage stuff isn't in there, though, as you've only just added it
As for the reputation stuff, all I can say is that the MagicDamage() that is in the JS file was accurate at the time it was created (26th January, 2006). It seems that subsequent updates to MagicDamage() in code, in regards to reputation, were not mirrored into this file.
-
Maarc
- Developer
- Posts: 576
- Joined: Sat Mar 27, 2004 6:22 am
- Location: Fleet, UK
- Has thanked: 0
- Been thanked: 0
- Contact:
Well, the JS version *will* have to be updated, because long term, the goal is to shift out the behaviour of all magic to the JS engine, and leave nothing in the code except hooks. So it's something that will have to be dealt with regardless
It's the code that is ultimately superfluous, not the JS engine stuff 
Primarily, it's because none of the JS engine magic stuff is terribly time sensitive. There's nothing in there that can't run just a touch slower. And it gives the users a great deal more flexibility (not to mention the ability to tweak damage algorithms with reloads, rather than recompiles).
Primarily, it's because none of the JS engine magic stuff is terribly time sensitive. There's nothing in there that can't run just a touch slower. And it gives the users a great deal more flexibility (not to mention the ability to tweak damage algorithms with reloads, rather than recompiles).
-
Grimson
- Developer
- Posts: 802
- Joined: Sat Jun 04, 2005 1:52 am
- Location: Germany
- Has thanked: 0
- Been thanked: 0
Like I said, the code will stay in my personal builds as I prefer to handle such things there. So if the JS version has to be update you'll have to do it yourselfMaarc wrote:Well, the JS version *will* have to be updated, because long term, the goal is to shift out the behaviour of all magic to the JS engine, and leave nothing in the code except hooks. So it's something that will have to be dealt with regardlessIt's the code that is ultimately superfluous, not the JS engine stuff
Even with having the code version of MagicDamage() as a (reliable) base a user can write his own damage function in JS, if he actually needs it. My "philosophy" is to keep most functionality working in code, but let the user override it in JS when he really wants itMaarc wrote:Primarily, it's because none of the JS engine magic stuff is terribly time sensitive. There's nothing in there that can't run just a touch slower. And it gives the users a great deal more flexibility (not to mention the ability to tweak damage algorithms with reloads, rather than recompiles).
-
giwo
- Developer
- Posts: 1780
- Joined: Fri Jun 18, 2004 4:17 pm
- Location: California
- Has thanked: 0
- Been thanked: 0
By doing what you have stated then you are creating a superfluous extra. Why bog down the executable with functionality that a user is just going to change? The only time it makes sense to do so is when that functionality is time-sensitive, and thus operates as quickly as possible by default, allowing the user to customize (and thus slow down) at his perrogative.
Ultimately whatever you do on your own personal build is fine, that's why UOX3 is open source in the first place. Just remember the direction the project itself is headed.
If you are interested in other subystems that should basically cease to exist in UOX3's future, you can checkout the Update Priority List in the Documents section of the SF OpenUO page.
Ultimately whatever you do on your own personal build is fine, that's why UOX3 is open source in the first place. Just remember the direction the project itself is headed.
If you are interested in other subystems that should basically cease to exist in UOX3's future, you can checkout the Update Priority List in the Documents section of the SF OpenUO page.
Scott
Just a thought from a player and non-cvs contributer:
I think it's great to have magic completley exported to .js so we can customize it.
But in my opinion, before we export all of the hardcoded magic and delete it (basically rewriting what has already been re-written but in.js instead of c++), why not focus on the other things that could add more noticable depth to the shards?
the weather system is awesome. Treasure maps would be a great implementation, getting the "fighter books" to work may be neat (I don't know, I've never used them). Maybe even OSI's version of growing plants could be cool to implement. Even adding more pet control would be cool. (IRRC, on OSi you could tell your dogs to "sit" and "speak".)
There is just a ton that can be added to UOx3, it'd be a shame to spend time re-writting what is already written when a user can already over-ride spells.
That said, if someone wants to do this and would enjoy it, by all means go for it. We are all in this for the fun of creating our own worlds anyway.
.
I think it's great to have magic completley exported to .js so we can customize it.
But in my opinion, before we export all of the hardcoded magic and delete it (basically rewriting what has already been re-written but in.js instead of c++), why not focus on the other things that could add more noticable depth to the shards?
the weather system is awesome. Treasure maps would be a great implementation, getting the "fighter books" to work may be neat (I don't know, I've never used them). Maybe even OSI's version of growing plants could be cool to implement. Even adding more pet control would be cool. (IRRC, on OSi you could tell your dogs to "sit" and "speak".)
There is just a ton that can be added to UOx3, it'd be a shame to spend time re-writting what is already written when a user can already over-ride spells.
That said, if someone wants to do this and would enjoy it, by all means go for it. We are all in this for the fun of creating our own worlds anyway.
-
Maarc
- Developer
- Posts: 576
- Joined: Sat Mar 27, 2004 6:22 am
- Location: Fleet, UK
- Has thanked: 0
- Been thanked: 0
- Contact:
Well, it's a little bit different to a rewrite, that's the thing. Porting out the spells stuff to JS has a few additional benefits
1) We isolate the differences between JS and code that stop us being able to do it, resulting in a more thorough API
2) It potentially reduces the need for binary releases. Fixes/changes to spells behaviour becomes JS driven, not code, and so updating/fixing spell work would mostly mean changing the JS. No more extra binaries, and easier to fix all around.
3) It's not, technically, a rewrite. Barring the reputation stuff, if you look at MagicDamage() in code, and JS, they're virtually identical. Our JS API is starting to look very similar to the C++ code, so it's less rewriting, and more making minor changes
And I guess there's a few other things for my mind, as well. We're trying to reduce the amount of C++ code that has to be written to support new features, or maintain things. From a developer's perspective, it's about streamlining, and trying to reduce code complexity, while adding more flexibility.
There's also the (to my mind) important point of: port out what is relatively simple now, before trying to tackle lots of new features. New features are big bullet points, I know, but it's a sizable chunk of code, magic, and getting it out would be a big boost, for customisation and other things.
But the bigger thing about getting it to a state it can be entirely done in JS is that it has knock on effects. It forces us to look at fame/karma handling, reputation and criminalisation, and ensuring that the API for that is complete. I'm sure you can dream up things that might want to tinker with the reputation system, but we haven't exposed enough to cope with it.
But yes, it's less about rewriting, more about modification/porting, really
1) We isolate the differences between JS and code that stop us being able to do it, resulting in a more thorough API
2) It potentially reduces the need for binary releases. Fixes/changes to spells behaviour becomes JS driven, not code, and so updating/fixing spell work would mostly mean changing the JS. No more extra binaries, and easier to fix all around.
3) It's not, technically, a rewrite. Barring the reputation stuff, if you look at MagicDamage() in code, and JS, they're virtually identical. Our JS API is starting to look very similar to the C++ code, so it's less rewriting, and more making minor changes
And I guess there's a few other things for my mind, as well. We're trying to reduce the amount of C++ code that has to be written to support new features, or maintain things. From a developer's perspective, it's about streamlining, and trying to reduce code complexity, while adding more flexibility.
There's also the (to my mind) important point of: port out what is relatively simple now, before trying to tackle lots of new features. New features are big bullet points, I know, but it's a sizable chunk of code, magic, and getting it out would be a big boost, for customisation and other things.
But the bigger thing about getting it to a state it can be entirely done in JS is that it has knock on effects. It forces us to look at fame/karma handling, reputation and criminalisation, and ensuring that the API for that is complete. I'm sure you can dream up things that might want to tinker with the reputation system, but we haven't exposed enough to cope with it.
But yes, it's less about rewriting, more about modification/porting, really
-
giwo
- Developer
- Posts: 1780
- Joined: Fri Jun 18, 2004 4:17 pm
- Location: California
- Has thanked: 0
- Been thanked: 0
Hear hear!
In addition to what Maarc said, and as a bit of an answer to stranf:
Exactly what you said is why it has not been done (in its entirety) yet. The simple lack of developer time vs important bug fixes / system overhauls needed. If you notice, though, with every release I try to move SOMETHING out to JS (mostly skills recently). Every time I do so (and I mean every time) I find and fix a bug in the process (admittedly, I may create one or two as well
). Thus moving things out to JS helps us to evaluate the current code (much of which is years old) and update it as necesarry.
The end result of moving non-essential subsystems to JS (aside from customizability) is that we as developers have fewer lines of code to wade through when making changes. Skills, for instance, was somewhere between 5,000 and 6,000 lines of code before I started moving them out to JS. That same file is now half the size (2,600 lines) with all that functionality out in the JS engine. This means if I make a reasonably large change in the UOX3 source (that would have forced me to update many lines of that file) I can basically skip that file now, since the JS API by-and-large remains the same. This is a developers dream.
In addition to what Maarc said, and as a bit of an answer to stranf:
Exactly what you said is why it has not been done (in its entirety) yet. The simple lack of developer time vs important bug fixes / system overhauls needed. If you notice, though, with every release I try to move SOMETHING out to JS (mostly skills recently). Every time I do so (and I mean every time) I find and fix a bug in the process (admittedly, I may create one or two as well
The end result of moving non-essential subsystems to JS (aside from customizability) is that we as developers have fewer lines of code to wade through when making changes. Skills, for instance, was somewhere between 5,000 and 6,000 lines of code before I started moving them out to JS. That same file is now half the size (2,600 lines) with all that functionality out in the JS engine. This means if I make a reasonably large change in the UOX3 source (that would have forced me to update many lines of that file) I can basically skip that file now, since the JS API by-and-large remains the same. This is a developers dream.
Scott
-
Grimson
- Developer
- Posts: 802
- Joined: Sat Jun 04, 2005 1:52 am
- Location: Germany
- Has thanked: 0
- Been thanked: 0
Maybe I should explain better what I had in mind. I wanted to create different damage functions and expose them to JS, something like:
PhysicalDamage() - This can be used to apply physical damage, taking in mind the armor def values of the char.
MagicalDamage() or better
ElementalDamage() - This can be used to apply elemental damage, taking in mind the elemental resistance of the char and his armor.
And maybe:
PoisonDamage() - This can be used to poison a char, taking in mind the poison resistance of the char and his armor.
They should be using Maarcs Damage() function, which then should take care of turning a char criminal and creating a proper reaction from NPCs. Turning a char into a murderer can be handled by Die(), together with Karma and Fame.
This way a user can easily apply any sort of damage through JS without having to worry about too much things.
Edit:
I will add those to my personal build during the next days. If you want I'll also add them to CVS. But only if you want, there is no sense in adding them when they get removed shortly after.
PhysicalDamage() - This can be used to apply physical damage, taking in mind the armor def values of the char.
MagicalDamage() or better
ElementalDamage() - This can be used to apply elemental damage, taking in mind the elemental resistance of the char and his armor.
And maybe:
PoisonDamage() - This can be used to poison a char, taking in mind the poison resistance of the char and his armor.
They should be using Maarcs Damage() function, which then should take care of turning a char criminal and creating a proper reaction from NPCs. Turning a char into a murderer can be handled by Die(), together with Karma and Fame.
This way a user can easily apply any sort of damage through JS without having to worry about too much things.
Edit:
I will add those to my personal build during the next days. If you want I'll also add them to CVS. But only if you want, there is no sense in adding them when they get removed shortly after.
-
Grimson
- Developer
- Posts: 802
- Joined: Sat Jun 04, 2005 1:52 am
- Location: Germany
- Has thanked: 0
- Been thanked: 0
As you might have noticed I moved quite a bit of the damage related stuff into the damage function in CChar. But I'm not to happy with this currently as I prefer smaller, more specialized functions. So I'm thinking about moving some of the stuff out again, but before doing so I wanted to get some opinions about that.
What the damage function currently does:
The damage function will then only apply basic damage, display the damage, track the damage and handle the reputation stuff.
This would IMHO make it easier to use and maintain those functions.
And if someone wants to customize combat or magic in JS he only needs to write that part he wants to customize and can use the already existing functions for the rest. For example he could create his own defense calculation but still use the other functions to handle all other effects.
What the damage function currently does:
- Calculate and apply the defense effects of armor and elemental resistance.
- Adjust race based damage bonuses.
- Display the damage.
- Do reputation handling.
- Handle parts of the peace skill effect.
- Let the damage NPC attack if he "knows" the attacker.
- Create two additional damage functions. PhysicalDamage() and ElementalDamage(), let those handle the defense effects of armor resp. resistance and the damage bonuses.
- Create a function ReactOnDamage() that will handle all NPC reactions when they take damage (fight back and breaking the peace effect).
The damage function will then only apply basic damage, display the damage, track the damage and handle the reputation stuff.
This would IMHO make it easier to use and maintain those functions.
And if someone wants to customize combat or magic in JS he only needs to write that part he wants to customize and can use the already existing functions for the rest. For example he could create his own defense calculation but still use the other functions to handle all other effects.
-
Maarc
- Developer
- Posts: 576
- Joined: Sat Mar 27, 2004 6:22 am
- Location: Fleet, UK
- Has thanked: 0
- Been thanked: 0
- Contact:
I think breaking them out into smaller chunks like you are suggesting would actually be a good thing. Initially, the damage routine was there just to keep a track of the damage that people are dealing to one another, and I know I did want flexibility on defense, with the assumption that defense occurred separately.
However, while I agree that breaking them out would be good, I don't think you want too many functions either
I think ReactOnDamage() would be a good function to have, absolutely. Not sure about the separation of Physical and Elemental damage though. Perhaps something like:
* ApplyDamageBonuses()
* ApplyDefenseModifiers()
That separates attack from defense, and the Defense aspect would take into account elemental stuff (if any). I'd expect that to be a parameter passed in, sort of thing. Also makes it easier to override if you only want to modify attack, or defense.
But exposing them all to the JS would be a good thing, definitely.
However, while I agree that breaking them out would be good, I don't think you want too many functions either
I think ReactOnDamage() would be a good function to have, absolutely. Not sure about the separation of Physical and Elemental damage though. Perhaps something like:
* ApplyDamageBonuses()
* ApplyDefenseModifiers()
That separates attack from defense, and the Defense aspect would take into account elemental stuff (if any). I'd expect that to be a parameter passed in, sort of thing. Also makes it easier to override if you only want to modify attack, or defense.
But exposing them all to the JS would be a good thing, definitely.
-
Grimson
- Developer
- Posts: 802
- Joined: Sat Jun 04, 2005 1:52 am
- Location: Germany
- Has thanked: 0
- Been thanked: 0
Ah yes, your right. Seperating attack from defense sounds actually better.Maarc wrote:I think ReactOnDamage() would be a good function to have, absolutely. Not sure about the separation of Physical and Elemental damage though. Perhaps something like:
* ApplyDamageBonuses()
* ApplyDefenseModifiers()
That separates attack from defense, and the Defense aspect would take into account elemental stuff (if any). I'd expect that to be a parameter passed in, sort of thing. Also makes it easier to override if you only want to modify attack, or defense.
But exposing them all to the JS would be a good thing, definitely.