TWiki Home Tharsis . Design . ObjectLibrary (r1.1 vs. r1.26) Tharsis webs:
Design | Guilds | Combat | Website
Design . { Home | Changes | Index | Search | Go }
 <<O>>  Difference Topic ObjectLibrary (r1.26 - 22 Feb 2005 - FreD)
Added:
>
>

A daemon for giving bodies to things are getting its own shape in BodyAllocationDaemon


 <<O>>  Difference Topic ObjectLibrary (r1.25 - 21 Feb 2005 - FantoM)
Added:
>
>

Recording the current state

We need to determine the state of the things that are already in play.

To this end I've (FantoM) built the first of several tools (or maybe they will all be the same tool) to allow players to walk around the mud and record the details of the things they find.

The tool for describing the body SHAPE of monsters is described in RecordingBodyShape


 <<O>>  Difference Topic ObjectLibrary (r1.24 - 08 Mar 2003 - PumaN)
Added:
>
>


 <<O>>  Difference Topic ObjectLibrary (r1.23 - 08 Mar 2003 - PumaN)
Added:
>
>


 <<O>>  Difference Topic ObjectLibrary (r1.22 - 23 Feb 2003 - PumaN)
Changed:
<
<

  • modifier
>
>

Deleted:
<
<


The advantage of a modified-based system is that fewer static numbers are placed all over the lib.

The sword of Huffintot doesn't have 'strength 50', but instead the huffintot modifier is put on top of a normal sword to alter it's basic properties, by giving it 25% more strength. The sword in turn, has it's strength decided by importances, say 60/40 from material/craftmanship. So the static 'strength' numbers are not to be found until we get down to the material-lib. In this fashion we automatically get a flexible crafting-library at the same time.

Thus we don't have to change all instances that inherits 'sword' when we make a change to 'sword'. That is basically what we are trying to avoid with a library?

-- PumaN - 18 Feb 2003


Beyond my dislike of the word importance we should be able to work it into the above xml (with alterations). In the example above I specified exact numbers in many places. We could utilise defaults in as many cases as possible, eg Steel can have default values for durability and fragility and we can support alteration of the defaults via percentages rather than absolutes.

Ie - to make a sword 95% metal and have it slightly less durable than a normal block of metal and twice as fragile:

  <material name="metal" percentage="95" durability="80%" fragility="200%" /> 

Side issue: Right now that xml implies that an item inherits from only one other item - we may want to change this.

-- FantoM - 18 Feb 2003


I dont think material should be hardcoded in lib, then we get inflexibility, the ObjectGenerator? should set up material at the creation of the actual object. The library might only hold rules for how to set up objects and their functionality, not actual data on specific objects. It is for the generator to combine the library-bits to an actual working unit.

Another specific problem is changing values on the fly, when the sword gets an 'evil' enchantment cast on it, if we change the static numbers, it would become difficult to remove the enchantment.

-- PumaN - 20 Feb 2003


Perhaps we are both talking about the same thing here (quite possible ;)). The definition I had above was only that - a template from which an actual sword would be cloned or extended.

If you choose to extend the lib-sword then you can do so in your own .c file, with a call something like "configure-from-lib(sword)" followed by code to alter the values.

A cloned instance of the sword has it's own values and these can be altered as a result of enchantements/etc and will not effect the original template.
Almost wrote something else here, but this should work as long as we only allow percentage changes, as opposite to point/value-changes - PumaN

As for the ObjectGenerator? (which is roughly analogous to the "configure-from-lib" call) - yes it adds the materials at clone time, the definition above just told the object generator how to do it. I don't see how you can expect the ObjectGenerator? to be able to set up the materials for an object without some hints as to what they should be. Certainly they should not be specified by the person doing the cloning.

-- FantoM - 21 Feb 2003


Wrt (With respect to) to altering the template values and PumaN's comment on percentage values. The same can be said to apply to a sword that extends the template and alters the default values for that sword.

We need to provide alteration methods for this, otherwise people just use "set_wc(10)" because doing "set_wc(get_base_wc() * 0.1)" takes too long.

You'll notice the implication that there is a get_wc() and a get_base_wc(). If we want to retain the original, un-modified value then we need get_base_wc(). Note that this value is the value you get when you clone it, not the template value. A sword that starts with the template can alter the base_wc - eg special sword with magical stone which is extra-sharp should have it's base_wc altered. This value may be further altered (temporarily) with enchantments/curses/etc.

-- FantoM - 21 Feb 2003

Better would be a add_modify_wc(1.1) or modify_wc(1.1), and thus simply disallow a set_wc. Problem is how to code that effectively since its not supported by LPC. - PumaN

Yes - I agree on the modify_wc, and probably modify_base_wc and the disallowing of set_wc. Not sure what is not supported? the disallowing? We could make it a private method. We could make it fail if there is already a wc set, thus making it possible to do set_wc just once, which the ObjectGenerator? will do. Making it fail on the second call to set_wc has advantages for people writing objects that are not based on the lib - they can still call set_wc, where calling modify_wc() is unlikely to produce any good results... 0 * anything being 0. -- FantoM - 21 Feb 2003

I seem to be stuck in some old thoughts...youre right...

Methods:

  • modify_[data](float percent)
  • multiplies the value with percentage (does this mean all values will have to be float or suffer to bad/abuseable roundingeffects?)
  • unmodify_[data](float percent)
  • divides by percentage, thus cancelling effect

-- PumaN - 21 Feb 2003

I like the unmodify idea.

As for float vs int - My initial reponse is to go for int's and ignore the rounding errors. The catch is that unmodify_data might have a problem...

-- FantoM - 21 Feb 2003

More thinking.

An example of how modify/unmodify fail:

If the base is 10 and the percentage is 30% ( we are cursing an item! ) then we modify to get 10 * 0.3 = 3.333 which rounds to 3.  When unmodifying we do 3 / 0.3 = 9. Wups!

How about applying alterations and recording them in modify and in unmodify removing them rather than reversing them.

Thus we get a chain of modifications that are applied to the base and used to provide the value (in the above example we have a base of 10 and one modification of 30%). Unmodify could either match a given value (eg unmodify 30% would look for a 30% modification in the chain and remove it) or could use a key ( modify() returns a number which you use and pass to unmodify().

This has the advantage of being able to hold a bunch of things that need to be done to the base and only incurring a rounding error once. We perform all the modifucations in floating point and then round the result and cache it until a new modify/unmodify is performed.

Also provides the ability to perhaps store more than just a number as the modification... perhaps you cast "flaming halo" on your sword. This provides an enchantment which adds to the damage dealt by fire. Someone else casting "extinguish" could remove this enchantment, but someone casting "blunten" could not (although it would probably cause the damage dealt due to a direct blow to decrease)....

-- FantoM - 21 Feb 2003

Floating points calculations are so expensive you rather store them than use them, huh? Both ints and floats are 32 bits, are they not? I also changed the unmodify, you dont have to invert anything, just divide by the same number for effect. Course, if you store the values, you might as well use other things than just percentages (whatever that would be).

You dont really need float for percent by the way, you could let an int of 1000, 10000 or 100000 equal 100%. The idea of only calculating it when we have a new value is good.

As for fire/blunt damage, Id say we dont really have a simple 'wc' anymore if we have these kind of damages. And the object of course needs to know what enchantments (effects) it has on it, not just a number (if its not a unique id).

-- PumaN


Floating point are more expensive, but in the whole scheme of things not worth worry about the difference. The only reason I was trying to avoid using then was a couple of problems I've had when storing floats, and the issues of having people choosing arbitrarily accurate values for things like wc. I'd prefer to set a scale (0->100 or whatver - certainly bigger than our current 0->20) and use ints.

As for percentage - I agree we don't need to use floats - and I'd go with 0->100 in most cases, tho maybe 0->1000 might be needed sometimes, although why we should support 1/2 percentage changes I don't know...

As for fire/blunt - I agree we should remove wc. this isn't a simple change tho and should probably be considered as part of a future upgrade to combat.

-- FantoM - 23 Feb 2003


Hmm, Im confused, some things on the page seem to not have been saved.

Question: How do we store the modifiers? Its gonna be a lot of data. If we only recalculate the value, this doesn't have the optimizing problem I first thought it would have.

  • One mapping? Each 'value' (wc/weight/color/whatever) could have a unique int assigned to it, mappings index faster on ints.
What does the 'values' in mapping contain?
  • An array of items, each item having an appropriate form for the modification of this modifier?
  • OR a mapping (you suggested they have unique-ids returned) so it can be removed based on ints.

-- PumaN - 23 Feb 2003


We can presume that additions and removals of modifications are much less frequent than usage. Thus we can use a data structure that is efficient for access but doesn't have to be too concerned about insertion/deletion costs.

We might also be able to argue that the usage of the modifications only occurs when we add/remove one because we cache all the possible results - not that this alters the fact that we don't need to concern ourselves with insertion/deletion costs.

First lets investigate what kind of things are going to be considered modifications.

We might be able to argue that there is a known set of modification types, and that coders can use them but can not design one-off new modifications. This is possibly not ideal. It would certainly be nice if there is at least a set of reusuable modifications.

Possible modifications:

  • Permanent alterations to any attribute of the item - eg durability, color, weight (Are these just enchantments as defined below?)
  • Enchantments (wear off over time) - extra damage, elemental damages, light, faster swing. Essentially these are just modifications to other attributes of the item.
  • Curses (wear off over time?) - probably modellable as negative enchantments, although they might be removed in the same way, a remove curse should not remove a nice enchantment.

Things I don't think are modifications

  • Extra abilities - spell casting eg detect traps

At the moment it appears that modifications are only going to alter the values returned by get methods of an item, methods that would be called during the use of the item. Eg "get_damages() - returning sharp:20,fire:10,ice:3" or "get_light" or "get_swing_rate". This also implies that it might be possible to restrict the allowable modifications.

If this is the case it will be possible for these methods to incorporate alterations to their base return value via the modifications, possibly caching the alteration, possibly not.

--
Looking at ways modifications might be added:

  • By the coder. This is a flaming sword, thus he codes a normal sword and adds a permanent "increase fire damage" modification. What happens when someone casts "no-flame" on it? I'd say perhaps any enchantment has a chance of surviving an attempted removal and that the coder could, if he chose, set it to be hard to remove the flame modification.
  • By some external device. Eg player spell or some other item. Such a modification is applied in exactly the same fashion as if by the coder, just later on in the life of the item. It may be a permanent modification, it might be time delayed.

--
Looking at ways modifications might be removed:

  • Timed expiry. A non-permanent modification should remove itself.
  • Attempted forced removal. A "disenchant" equivalent spell. This should call expire() on the modification with some level of force and the modification will be removed if the disenchant is strong enough. Should it be possible to target a particular form of modification when disenchanting? I'd say it probably shouldn't be, although this is getting into the realm of actual command design. The "no-fire" disenchant should just attempt to remove the(all?) "increase flame damage" modification(s).
  • Destruction. The item is destroyed, all modifications go with it.
  • Targetted removal by coder. It may be desirable for a coder to remove a particular modification. This removal should never fail. It is probably possible to just destruct the modification (if it's an object), or have some special removal method.

--
Interesting side thought - what happens when you cast a fire spell on a backpack? Or put a flaming sword into a backpack? What about the encumberance of an item that deals elemental damage...

--
So - how to implement all this.

I agree we need some list of modifications for each attribute of the object.

I think we should implement modifications as closures, similar to hooks.

A modification closure would look like:

   float modify( float current_value )

So you would call each modification in turn, passing it the return value from the call to the previous modification. You'll note I pass/return floats. This does not preclude the rounding of the final value to an int if we choose to do so. Such rounding may be desirable at first to enable us to support existing code - eg lots of code expects weapon_class to be an int.

Creation of these closures - in many cases they would be very simple, we could get people to write:

   add_wc_enchantment( lambda( ({ 'current }), ({ #'*, 'current, 1.1 }) ) ) // 10% enchantment

Lots of opportunity for buggering it up tho.

So - we add some daemon which provides modifications closures.

   add_wc_enchantment( MODIFICATION_D->get_percentage_modification( 10 ) ) ); // permanent 10% 
   add_elemental_enchantment( FIRE, MODIFICATION_D->get_modification( 50 ) ), 30 ); // 30 second, up to 50 fire damage, implies flaming?

To remove a specific enchantment you could record the return closure and use it to remove the enchantment:

   remove_wc_modification( ten_percent_enchantment ); 

To curse, I'd suggest we add add_wc_curse() ... methods, utilising the same MODIFICATION_D methods to produce the closures.

--
I've missed adding the details of the "force" of an enchantment, to be used when removing the enchantment via a "remove enchantment" spell. For now presume that is an optional argument on the end of the call do add the enchantment, like the expiry time.

--
Data structure

We could either go with a single mapping to hold all attributes of the object, in which each key is the attribute id and each value is the list of modifications, or we could go with a separate list of modifications per attribute.

I'm in favour of the mapping containing all attributes because it allows easy future addition of new attributes - ease of code maintenance in favour of execution time, although with LPC's wierdo variable handling who knows whether one big mapping or lists is less efficent than a set of lists.

So - how to store the list. It might as well just be an array.

Each element in the array would store details of a single modification. For this we need to at least store the modification (int/float/closure)as described above. We also need to store the expiry time and force and probably other things that will come along later. We could have a "modification object which holds all these values (and if we went this route we could use it for adding/removing the modification as well). I'm not especially in favour of this due to the potentially very large number of such objects that would have to be created.

An alternative is for each attribute to have an array of values ({ modification, time, force }), a mapping (seems too inefficient).

A further alternative is to have 3 lists for each attribute, one for each of these values.

My preference at this time is to go with a single array of arrays - it's easy to implement and until it's proven to be too inefficient it might as well be used.

--
Optimisations:

  • Allow mixed types rather than just closures to be passed to the add_??_enchantment methods.
    • int would be an exact value alteration
    • float would be a percentage alteration
    • closure would be as described above.
  • The structure described above is horribly inefficent for detecting expiry of a modification over time - you have to traverse the entire list of modifications every time interval checking for any that have expired. We may decide to have a call-out for each modification with an expiry (I think most will NOT have an expiry ). If we don't go with call-outs, or we find we have too many call-outs, then we will have to introduce a central controller which will track all expirable modifications and call remove_enchantment/whatever on the objects when required.

--
Disclaimer:

I've got off the topic of an Object Library a bit here, and more worked on modifications made AFTER the object is designed. The Object Library needs a technique for modifications that is targetted at one object being based on another with some modifications. These ideas presented here may well be applicable in some form tho, and certainly should be considered for a post-design modification system.

-- FantoM - 23 Feb 2003



 <<O>>  Difference Topic ObjectLibrary (r1.21 - 23 Feb 2003 - FantoM)
Added:
>
>

We can presume that additions and removals of modifications are much less frequent than usage. Thus we can use a data structure that is efficient for access but doesn't have to be too concerned about insertion/deletion costs.

We might also be able to argue that the usage of the modifications only occurs when we add/remove one because we cache all the possible results - not that this alters the fact that we don't need to concern ourselves with insertion/deletion costs.

First lets investigate what kind of things are going to be considered modifications.

We might be able to argue that there is a known set of modification types, and that coders can use them but can not design one-off new modifications. This is possibly not ideal. It would certainly be nice if there is at least a set of reusuable modifications.

Possible modifications:

  • Permanent alterations to any attribute of the item - eg durability, color, weight (Are these just enchantments as defined below?)
  • Enchantments (wear off over time) - extra damage, elemental damages, light, faster swing. Essentially these are just modifications to other attributes of the item.
  • Curses (wear off over time?) - probably modellable as negative enchantments, although they might be removed in the same way, a remove curse should not remove a nice enchantment.

Things I don't think are modifications

  • Extra abilities - spell casting eg detect traps

At the moment it appears that modifications are only going to alter the values returned by get methods of an item, methods that would be called during the use of the item. Eg "get_damages() - returning sharp:20,fire:10,ice:3" or "get_light" or "get_swing_rate". This also implies that it might be possible to restrict the allowable modifications.

If this is the case it will be possible for these methods to incorporate alterations to their base return value via the modifications, possibly caching the alteration, possibly not.

--
Looking at ways modifications might be added:

  • By the coder. This is a flaming sword, thus he codes a normal sword and adds a permanent "increase fire damage" modification. What happens when someone casts "no-flame" on it? I'd say perhaps any enchantment has a chance of surviving an attempted removal and that the coder could, if he chose, set it to be hard to remove the flame modification.
  • By some external device. Eg player spell or some other item. Such a modification is applied in exactly the same fashion as if by the coder, just later on in the life of the item. It may be a permanent modification, it might be time delayed.

--
Looking at ways modifications might be removed:

  • Timed expiry. A non-permanent modification should remove itself.
  • Attempted forced removal. A "disenchant" equivalent spell. This should call expire() on the modification with some level of force and the modification will be removed if the disenchant is strong enough. Should it be possible to target a particular form of modification when disenchanting? I'd say it probably shouldn't be, although this is getting into the realm of actual command design. The "no-fire" disenchant should just attempt to remove the(all?) "increase flame damage" modification(s).
  • Destruction. The item is destroyed, all modifications go with it.
  • Targetted removal by coder. It may be desirable for a coder to remove a particular modification. This removal should never fail. It is probably possible to just destruct the modification (if it's an object), or have some special removal method.

--
Interesting side thought - what happens when you cast a fire spell on a backpack? Or put a flaming sword into a backpack? What about the encumberance of an item that deals elemental damage...

--
So - how to implement all this.

I agree we need some list of modifications for each attribute of the object.

I think we should implement modifications as closures, similar to hooks.

A modification closure would look like:

   float modify( float current_value )

So you would call each modification in turn, passing it the return value from the call to the previous modification. You'll note I pass/return floats. This does not preclude the rounding of the final value to an int if we choose to do so. Such rounding may be desirable at first to enable us to support existing code - eg lots of code expects weapon_class to be an int.

Creation of these closures - in many cases they would be very simple, we could get people to write:

   add_wc_enchantment( lambda( ({ 'current }), ({ #'*, 'current, 1.1 }) ) ) // 10% enchantment

Lots of opportunity for buggering it up tho.

So - we add some daemon which provides modifications closures.

   add_wc_enchantment( MODIFICATION_D->get_percentage_modification( 10 ) ) ); // permanent 10% 
   add_elemental_enchantment( FIRE, MODIFICATION_D->get_modification( 50 ) ), 30 ); // 30 second, up to 50 fire damage, implies flaming?

To remove a specific enchantment you could record the return closure and use it to remove the enchantment:

   remove_wc_modification( ten_percent_enchantment ); 

To curse, I'd suggest we add add_wc_curse() ... methods, utilising the same MODIFICATION_D methods to produce the closures.

--
I've missed adding the details of the "force" of an enchantment, to be used when removing the enchantment via a "remove enchantment" spell. For now presume that is an optional argument on the end of the call do add the enchantment, like the expiry time.

--
Data structure

We could either go with a single mapping to hold all attributes of the object, in which each key is the attribute id and each value is the list of modifications, or we could go with a separate list of modifications per attribute.

I'm in favour of the mapping containing all attributes because it allows easy future addition of new attributes - ease of code maintenance in favour of execution time, although with LPC's wierdo variable handling who knows whether one big mapping or lists is less efficent than a set of lists.

So - how to store the list. It might as well just be an array.

Each element in the array would store details of a single modification. For this we need to at least store the modification (int/float/closure)as described above. We also need to store the expiry time and force and probably other things that will come along later. We could have a "modification object which holds all these values (and if we went this route we could use it for adding/removing the modification as well). I'm not especially in favour of this due to the potentially very large number of such objects that would have to be created.

An alternative is for each attribute to have an array of values ({ modification, time, force }), a mapping (seems too inefficient).

A further alternative is to have 3 lists for each attribute, one for each of these values.

My preference at this time is to go with a single array of arrays - it's easy to implement and until it's proven to be too inefficient it might as well be used.

--
Optimisations:

  • Allow mixed types rather than just closures to be passed to the add_??_enchantment methods.
    • int would be an exact value alteration
    • float would be a percentage alteration
    • closure would be as described above.
  • The structure described above is horribly inefficent for detecting expiry of a modification over time - you have to traverse the entire list of modifications every time interval checking for any that have expired. We may decide to have a call-out for each modification with an expiry (I think most will NOT have an expiry ). If we don't go with call-outs, or we find we have too many call-outs, then we will have to introduce a central controller which will track all expirable modifications and call remove_enchantment/whatever on the objects when required.

--
Disclaimer:

I've got off the topic of an Object Library a bit here, and more worked on modifications made AFTER the object is designed. The Object Library needs a technique for modifications that is targetted at one object being based on another with some modifications. These ideas presented here may well be applicable in some form tho, and certainly should be considered for a post-design modification system.

-- FantoM - 23 Feb 2003



 <<O>>  Difference Topic ObjectLibrary (r1.20 - 23 Feb 2003 - PumaN)
Added:
>
>

Hmm, Im confused, some things on the page seem to not have been saved.

Question: How do we store the modifiers? Its gonna be a lot of data. If we only recalculate the value, this doesn't have the optimizing problem I first thought it would have.

  • One mapping? Each 'value' (wc/weight/color/whatever) could have a unique int assigned to it, mappings index faster on ints.
What does the 'values' in mapping contain?
  • An array of items, each item having an appropriate form for the modification of this modifier?
  • OR a mapping (you suggested they have unique-ids returned) so it can be removed based on ints.

-- PumaN - 23 Feb 2003



 <<O>>  Difference Topic ObjectLibrary (r1.19 - 23 Feb 2003 - FantoM)
Added:
>
>

Floating point are more expensive, but in the whole scheme of things not worth worry about the difference. The only reason I was trying to avoid using then was a couple of problems I've had when storing floats, and the issues of having people choosing arbitrarily accurate values for things like wc. I'd prefer to set a scale (0->100 or whatver - certainly bigger than our current 0->20) and use ints.

As for percentage - I agree we don't need to use floats - and I'd go with 0->100 in most cases, tho maybe 0->1000 might be needed sometimes, although why we should support 1/2 percentage changes I don't know...

As for fire/blunt - I agree we should remove wc. this isn't a simple change tho and should probably be considered as part of a future upgrade to combat.

-- FantoM - 23 Feb 2003



 <<O>>  Difference Topic ObjectLibrary (r1.18 - 21 Feb 2003 - PumaN)
Added:
>
>

Floating points calculations are so expensive you rather store them than use them, huh? Both ints and floats are 32 bits, are they not? I also changed the unmodify, you dont have to invert anything, just divide by the same number for effect. Course, if you store the values, you might as well use other things than just percentages (whatever that would be).

You dont really need float for percent by the way, you could let an int of 1000, 10000 or 100000 equal 100%. The idea of only calculating it when we have a new value is good.

As for fire/blunt damage, Id say we dont really have a simple 'wc' anymore if we have these kind of damages. And the object of course needs to know what enchantments (effects) it has on it, not just a number (if its not a unique id).

-- PumaN


 <<O>>  Difference Topic ObjectLibrary (r1.17 - 21 Feb 2003 - FantoM)
Added:
>
>

More thinking.

An example of how modify/unmodify fail:

If the base is 10 and the percentage is 30% ( we are cursing an item! ) then we modify to get 10 * 0.3 = 3.333 which rounds to 3.  When unmodifying we do 3 / 0.3 = 9. Wups!

How about applying alterations and recording them in modify and in unmodify removing them rather than reversing them.

Thus we get a chain of modifications that are applied to the base and used to provide the value (in the above example we have a base of 10 and one modification of 30%). Unmodify could either match a given value (eg unmodify 30% would look for a 30% modification in the chain and remove it) or could use a key ( modify() returns a number which you use and pass to unmodify().

This has the advantage of being able to hold a bunch of things that need to be done to the base and only incurring a rounding error once. We perform all the modifucations in floating point and then round the result and cache it until a new modify/unmodify is performed.

Also provides the ability to perhaps store more than just a number as the modification... perhaps you cast "flaming halo" on your sword. This provides an enchantment which adds to the damage dealt by fire. Someone else casting "extinguish" could remove this enchantment, but someone casting "blunten" could not (although it would probably cause the damage dealt due to a direct blow to decrease)....

-- FantoM - 21 Feb 2003


 <<O>>  Difference Topic ObjectLibrary (r1.16 - 21 Feb 2003 - PumaN)
Changed:
<
<

  • modifies the number by this percentage (does this mean all values will have to be float or suffer to bad/abuseable roundingeffects?)
>
>

  • multiplies the value with percentage (does this mean all values will have to be float or suffer to bad/abuseable roundingeffects?)
Changed:
<
<

  • inverts the percentage and then modifies by this, need to have a central unit for this inverting, so we dont do it by hand each time
>
>

  • divides by percentage, thus cancelling effect

 <<O>>  Difference Topic ObjectLibrary (r1.15 - 21 Feb 2003 - FantoM)
Added:
>
>

I like the unmodify idea.

As for float vs int - My initial reponse is to go for int's and ignore the rounding errors. The catch is that unmodify_data might have a problem...

-- FantoM - 21 Feb 2003


 <<O>>  Difference Topic ObjectLibrary (r1.14 - 21 Feb 2003 - PumaN)
Added:
>
>

I seem to be stuck in some old thoughts...youre right...

Methods:

  • modify_[data](float percent)
  • modifies the number by this percentage (does this mean all values will have to be float or suffer to bad/abuseable roundingeffects?)
  • unmodify_[data](float percent)
  • inverts the percentage and then modifies by this, need to have a central unit for this inverting, so we dont do it by hand each time

-- PumaN - 21 Feb 2003


 <<O>>  Difference Topic ObjectLibrary (r1.13 - 21 Feb 2003 - FantoM)
Changed:
<
<

Wrt (???) to altering the template values and PumaN's comment on percentage values. The same can be said to apply to a sword that extends the template and alters the default values for that sword.

>
>

Wrt (With respect to) to altering the template values and PumaN's comment on percentage values. The same can be said to apply to a sword that extends the template and alters the default values for that sword.

Added:
>
>

Yes - I agree on the modify_wc, and probably modify_base_wc and the disallowing of set_wc. Not sure what is not supported? the disallowing? We could make it a private method. We could make it fail if there is already a wc set, thus making it possible to do set_wc just once, which the ObjectGenerator? will do. Making it fail on the second call to set_wc has advantages for people writing objects that are not based on the lib - they can still call set_wc, where calling modify_wc() is unlikely to produce any good results... 0 * anything being 0. -- FantoM - 21 Feb 2003


 <<O>>  Difference Topic ObjectLibrary (r1.12 - 21 Feb 2003 - PumaN)
Changed:
<
<

Wrt to altering the template values and PumaN's comment on percentage values. The same can be said to apply to a sword that extends the template and alters the default values for that sword.

>
>

Wrt (???) to altering the template values and PumaN's comment on percentage values. The same can be said to apply to a sword that extends the template and alters the default values for that sword.

Added:
>
>

Better would be a add_modify_wc(1.1) or modify_wc(1.1), and thus simply disallow a set_wc. Problem is how to code that effectively since its not supported by LPC. - PumaN


 <<O>>  Difference Topic ObjectLibrary (r1.11 - 21 Feb 2003 - FantoM)
Added:
>
>

Wrt to altering the template values and PumaN's comment on percentage values. The same can be said to apply to a sword that extends the template and alters the default values for that sword.

We need to provide alteration methods for this, otherwise people just use "set_wc(10)" because doing "set_wc(get_base_wc() * 0.1)" takes too long.

You'll notice the implication that there is a get_wc() and a get_base_wc(). If we want to retain the original, un-modified value then we need get_base_wc(). Note that this value is the value you get when you clone it, not the template value. A sword that starts with the template can alter the base_wc - eg special sword with magical stone which is extra-sharp should have it's base_wc altered. This value may be further altered (temporarily) with enchantments/curses/etc.

-- FantoM - 21 Feb 2003



 <<O>>  Difference Topic ObjectLibrary (r1.10 - 21 Feb 2003 - PumaN)
Changed:
<
<

Perhaps we are both talking about the same thing here. The definition I had above was only that - a template from which an actual sword would be cloned or extended.

>
>

Perhaps we are both talking about the same thing here (quite possible ;)). The definition I had above was only that - a template from which an actual sword would be cloned or extended.

Changed:
<
<

A cloned instance of the sword has it's own values and these can be altered as a result of enchantements/etc and will not effect the original template.

>
>

A cloned instance of the sword has it's own values and these can be altered as a result of enchantements/etc and will not effect the original template.
Almost wrote something else here, but this should work as long as we only allow percentage changes, as opposite to point/value-changes - PumaN


 <<O>>  Difference Topic ObjectLibrary (r1.9 - 20 Feb 2003 - FantoM)
Added:
>
>

Perhaps we are both talking about the same thing here. The definition I had above was only that - a template from which an actual sword would be cloned or extended.

If you choose to extend the lib-sword then you can do so in your own .c file, with a call something like "configure-from-lib(sword)" followed by code to alter the values.

A cloned instance of the sword has it's own values and these can be altered as a result of enchantements/etc and will not effect the original template.

As for the ObjectGenerator? (which is roughly analogous to the "configure-from-lib" call) - yes it adds the materials at clone time, the definition above just told the object generator how to do it. I don't see how you can expect the ObjectGenerator? to be able to set up the materials for an object without some hints as to what they should be. Certainly they should not be specified by the person doing the cloning.

-- FantoM - 21 Feb 2003



 <<O>>  Difference Topic ObjectLibrary (r1.8 - 19 Feb 2003 - PumaN)
Added:
>
>

I dont think material should be hardcoded in lib, then we get inflexibility, the ObjectGenerator? should set up material at the creation of the actual object. The library might only hold rules for how to set up objects and their functionality, not actual data on specific objects. It is for the generator to combine the library-bits to an actual working unit.

Another specific problem is changing values on the fly, when the sword gets an 'evil' enchantment cast on it, if we change the static numbers, it would become difficult to remove the enchantment.

-- PumaN - 20 Feb 2003



 <<O>>  Difference Topic ObjectLibrary (r1.7 - 18 Feb 2003 - FantoM)
Changed:
<
<

>
>

Added:
>
>

Beyond my dislike of the word importance we should be able to work it into the above xml (with alterations). In the example above I specified exact numbers in many places. We could utilise defaults in as many cases as possible, eg Steel can have default values for durability and fragility and we can support alteration of the defaults via percentages rather than absolutes.

Ie - to make a sword 95% metal and have it slightly less durable than a normal block of metal and twice as fragile:

  <material name="metal" percentage="95" durability="80%" fragility="200%" /> 

Side issue: Right now that xml implies that an item inherits from only one other item - we may want to change this.

-- FantoM - 18 Feb 2003



 <<O>>  Difference Topic ObjectLibrary (r1.6 - 18 Feb 2003 - PumaN)
Added:
>
>


The advantage of a modified-based system is that fewer static numbers are placed all over the lib.

The sword of Huffintot doesn't have 'strength 50', but instead the huffintot modifier is put on top of a normal sword to alter it's basic properties, by giving it 25% more strength. The sword in turn, has it's strength decided by importances, say 60/40 from material/craftmanship. So the static 'strength' numbers are not to be found until we get down to the material-lib. In this fashion we automatically get a flexible crafting-library at the same time.

Thus we don't have to change all instances that inherits 'sword' when we make a change to 'sword'. That is basically what we are trying to avoid with a library?

-- PumaN - 18 Feb 2003



 <<O>>  Difference Topic ObjectLibrary (r1.5 - 13 Feb 2003 - FantoM)
Added:
>
>

We've experiemented in the past with isolated object libraries - one lib for each type of thing, rather than a global lib.

These were defined in xml and converted to a .h and a .o via an app I wrote. The .o was then loaded by an object library daemon, often a customised one for that library.

A sample xml for the weapon lib which I was experimenting with is

- <!-- 
 basic rules.
   If [inherit="xxx"] is specified for a weapon then all attributes of "xxx" for which "no-inherit" is not specified are inherited into the new weapon.
   If a weapon specifies a value for an attribute then ALL inherited values for that attribute are discarded.
   
   Weapons should alter their fragility based on the the type of thing they are hitting.
   Perhaps just alter the fragility of the most prevalent material.  IE the metal in a sword becomes more fragile if it hits stone, less if it hits bare skin.


  --> 
- <lib>
- <weapon name="weapon" desc="base weapon with no details set">
  <short value="base weapon" no-inherit="true" /> 
  <long value="An unconfigured base weapon" no-inherit="true" /> 
  <alias value="weapon" no-inherit="true" /> 
  <adjective value="base" no-inherit="true" /> 
  <value value="0" /> 
  <weight value="0" /> 
- <!-- 
 skill defines one way that this weapon can be used.  Allowable names are "co.me.*", "co.th.*".
         Also defined is the wc (weapon-class).
            The wc is an indication of how much damage the weapon can deal in a single hit.
            The wc provides a default value for difficulty-to-use, if that is not given.
         Also possibly given is "not-in-combat".  
            All skills that do not specify "not-in-combat" will be used randomly during combat.
         Also possibly defined is the difficulty-to-use.
            0->100.  0 is anyone can use, 100 is impossible to use by all 

  --> 
  <skill name="combat.melee.edged" wc="1" difficulty-to-use="100" no-inherit="true" /> 
- <!-- 
 a material defines what the item is made of.
         The "name" must map to a defined material name in the materials library
         The percentage is how much of the weapon is made of this.  No checking is expected to be done to
            ensure that the percentages total 100.  If not specified this defaults to 100.
         The material definition will provide default values for durability and fragility.
         The durability is how much damage the item can take before it is destroyed or unusable.  
            For a rule of thumb we will presume that each kilogram of the item will increase the durability by 10
         The fragiity is how easy it is to damage the item, 0->10.   Use the values below as a base then alter based on
            how likely the material is to be damaged when the item is in use.
            0 being impossible, 
            1 being almost impossible - adamtine/magically strengthened materials
            2 hard metals/composites
            3 chain mail
            4 hard woods
            5 
            6 studded leather, soft woods
            7 leather
            8 
            9 glass 
            10 objects made of sand or fluids 
         By default if a material durability reaches 0 the item is unusable.  If all materials reach 0 it is destroyed.
      

  --> 
  <material name="metal" percentage="100" durabilty="1" fragility="5" no-inherit="true" /> 
  </weapon>
- <weapon name="sword" desc="standard sword" inherit="weapon">
  <short value="sword" /> 
  <long value="A double edged two and a half foot blade. The pommel is a plain leather wrapped affair with no ornamentation. The last 4 inches of the blade tapers to a point providing a minimal stabbing ability." /> 
  <alias value="sword" /> 
  <value value="100" /> 
  <weight value="2" /> 
  <skill name="combat.melee.edged" wc="7" difficulty-to-use="28" /> 
  <skill name="combat.melee.pointed" wc="2" difficulty-to-use="25" not-in-combat="true" /> 
  <material name="metal" percentage="95" durabilty="20" fragility="4" /> 
- <!--  higher fragility due to the weapon loosing it's edge in use 
  --> 
  <material name="leather" percentage="5" durabilty="5" fragility="1" /> 
- <!--  very low fragility as it is hard to damage this bit in normal use 
  --> 
  </weapon>
- <weapon name="long sword" desc="long sword" inherit="sword">
  <adjective value="long" /> 
  <long value="A double edged five foot heavy blade. The pommel is a plain leather wrapped affair with no ornamentation. The last 4 inches of the blade taper to a point but the sheer weight of the weapon make it almost impossible to use this sword to stab anything at all. This is a ponderous weapon but one with the potential to deal substantial damage." /> 
  <value value="250" /> 
  <weight value="4" /> 
  <skill name="combat.melee.edged" wc="10" difficulty-to-use="40" /> 
  <skill name="combat.melee.pointed" wc="1" difficulty-to-use="60" not-in-combat="true" /> 
  </weapon>
  </lib>

 <<O>>  Difference Topic ObjectLibrary (r1.4 - 11 Feb 2003 - PumaN)

 <<O>>  Difference Topic ObjectLibrary (r1.3 - 11 Feb 2003 - PumaN)
Changed:
<
<

  1. centralizes the data of items, opposed to the current area-based localization
    1. test
>
>

  1. handles/stores the behaviour of data in items
Added:
>
>

  • next ones belongs in ObjectDatabase? / ObjectGenerator? ?
  1. centralizes the data of items, opposed to the current area-based localization
Changed:
<
<

Datatypes

  • importance
>
>

Datatypes

  • inheritance
    • Each object can bring in other parts, and thus become a combination of the parts
  • static
    • Exact data, should exist in bases only (in database?)
Added:
>
>

    • modifies data
  • importance
    • creates a new data seeing to the importance of other datas

Inheritance

Any object is defined by the modification from the parts it consists of, and does not (?) contain data of its own.

Static

Modifier

Importance

Object Types

Example: sword

  • base: weapon
    • type: sword
    • ability: swingable
    • part: blade, handle, hilt
    • balance:
      • importance: blade
      • importance: handle
      • importance: quality
Example: blade
  • base: part
    • type: blade
      • damagetype: sharp
        • importance: material
        • importance: quality
        • importance: damage
      • balance:
        • importance: quality
Added:
>
>

Example: Huffintot

  • base: history
    • type: Huffintot (object/data?)
    • modifier: name
    • modifier: design
    • modifier: durability
Example: (from ObjectDatabase??) the evil iron sword of Huffintot
  • base: sword
    • type: object
    • magic effect: evil
    • reverse the following to blade-material: iron?
    • material:
      • blade: iron
      • handle: iron
      • hilt: iron
    • history: Huffintot

 <<O>>  Difference Topic ObjectLibrary (r1.2 - 11 Feb 2003 - PumaN)
Changed:
<
<

The object library:

>
>

The object library:

Added:
>
>

    1. test
Changed:
<
<

  1. contains data about each item, making it possible to for example craft them
  2. should be able to generate items based to fit an area
>
>

  1. (contains data about each item, making it possible to for example craft them)
  2. should be able to generate items based to fit an area/theme

Datatypes

  • importance
  • modifier

 <<O>>  Difference Topic ObjectLibrary (r1.1 - 06 Feb 2003 - PumaN)
Added:
>
>

%META:TOPICINFO{author="PumaN" date="1044498840" format="1.0" version="1.1"}% %META:TOPICPARENT{name="WebHome"}%

Object Library

The need for the object library arises naturally out of some of the other systems we are planning. Mainly crafting and a dynamical world.

The object library:

  1. centralizes the data of items, opposed to the current area-based localization
  2. make us better able to alter the behaviour of each kind of item
  3. contains data about each item, making it possible to for example craft them
  4. should be able to generate items based to fit an area

Definitions:
object/items - These are not just weapons/armours, but monsters/trees/spells as well as buildings/terrains

-- PumaN - 06 Feb 2003


Topic ObjectLibrary . { View | Diffs | r1.26 | > | r1.25 | > | r1.24 | More }
Revision r1.1 - 06 Feb 2003 - 02:34 GMT - PumaN
Revision r1.26 - 22 Feb 2005 - 13:22 GMT - FreD
Copyright © 2001 by the contributing authors. All material on this collaboration tool is the property of the contributing authors.
Ideas, requests, problems regarding Tharsis? Send feedback.