Welcome, Guest. Please login or register.

Pages: [1]
Print
Author Topic: Ticket 306 (Stats Prototype)  (Read 2617 times)
Technomage
Admin
Community member

Posts: 80



View Profile
« on: February 08, 2011, 05:28:15 AM »

I went ahead and assigned ticket 306 (http://parpg-trac.cvsdude.com/parpg/ticket/306#comment:3) to myself, but I'd appreciate feedback from Taldor as I make progress on it.

Taldor and I brainstormed a while ago and came up with a basic implementation: http://parpg.pastebin.com/iWKXQdmQ. I figure this is a good place to start.
Logged

"There are more atoms in the period at the end of this sentence than you can count in a lifetime." Science is awesome.

Technomage
Admin
Community member

Posts: 80



View Profile
« Reply #1 on: February 11, 2011, 11:03:20 PM »

Status update: I've pretty much finished implementing the primary and secondary character statistics logic.

In my current prototype, character statistics (both primary and secondary) are defined in two parts: a class which defines attributes common to all statistics of that type (e.g. strength), and a class which contains the value of a type of statistic for a particular character. This relationship is shown in the attached UML diagram.

In the more concrete case of primary statistics, instances of the PrimaryCharacterStatistic class define a particular primary statistic type. Thus, the "strength" statistic is defined as:
Code:
strength_statistic = PrimaryCharacterStatistic(
    long_name='strength',
    short_name='ST',
    description='You know, muscle. Boom! Boom! Fiah Powah.',
)
While a character's strength statistic is given by:
Code:
character.statistics['strength'] = PrimaryStatisticValue(
    statistic_type = strength_statistic,
    value=50,
)

Secondary statistics work the same way, except they have a few additional attributes and methods which are used to calculate a display value (simply called 'value') used to display the secondary statistic value to the player, and a normalized value (on a scale of [0, 100]) used in calculations.

Notice that SecondaryStatisticValue does not allow the value attribute to be set through the constructor (value and normalized_value are read-only attributes as well) - the value is derived using the derive_value(normalized=True) method, which queries the character's primary statistics to calculate the current value. Consequently, SecondaryStatisticValue instances must be attached to the character they belong to and store a weak reference to that character.



Uploaded with ImageShack.us
Logged

"There are more atoms in the period at the end of this sentence than you can count in a lifetime." Science is awesome.

aspidites
Community member

Posts: 29


View Profile Email
« Reply #2 on: February 14, 2011, 08:21:03 AM »

While I understand that the function of the PrimaryStatisticValue class, I'm not certain I understand the purpose of PrimaryCharacterStatistic. Is this class's primary function purely aesthetic? Asked differently, is the point of the properties assigned to such a class only useful for the user interface, or is there some programmatic purpose for them?

Additionally, is there any particular reason that this is one class instead of two? In my mind, I'm trying to find out why the following wouldn't suffice:
Code:
character.statistics['strength'] = PrimaryStatistic(long_name='strength',
                                                    short_name='ST',
                                                    description='You know, muscle. Boom! Boom! Fiah Powah.',
                                                    value=50)

If the concern is boiler plate, then perhaps the following:
Code:
# in foo.py
class PrimaryStatistic(object):
    pass

strength = PrimaryStatistic(...)

# in bar.py
from foo import strength
character.statistics['strength'] = strength

Or if determined to adhere to inheritance:
Code:
# in foo.py
class PrimaryStatistic(object):
     # some abstract base class
     pass

class Strength(PrimaryStatistic):
    pass

# in bar.py
from foo import Strength
character.statistics['strength'] = Strength()

Now I could of course be missing the point of the PrimaryCharacterStatistic class all together. In either case, feedback to help me understand how these objects are to work in theory would be greatly appreciated. Thanks
Logged
Technomage
Admin
Community member

Posts: 80



View Profile
« Reply #3 on: February 15, 2011, 04:08:28 AM »

In this prototype a PrimaryCharacterStatistic or SecondaryCharacterStatistic instance defines a particular type of statistic, a sort of template which is then attached to a StatisticValue instance to give that StatisticValue instance a more concrete meaning.

There are a limited number of primary and secondary statistics: strength, health, endurance, melee damage, etc. Each type of statistic has certain common traits:  one or more names or identifiers, a description, and perhaps a minimum and maximum bounding value. All statistic values of a particular type (e.g. strength) attached to various characters have these attributes in common, even though the particular value of that statistic type attached to a particular character may vary. These concrete examples of primary and secondary skills are implemented as PrimaryCharacterStatistic and SecondaryCharacterStatistic instances.

If one were to map this implementation to an inheritance-based design as you suggest, then the attributes that the CharacterStatistic classes define would be class attributes, while the StatisticValue class would map to instance attributes. Although I originally intended to go this route, Taldor pointed out that it would be difficult to manage and extend the inheritance tree for so many statistic types. Instead, I went with Taldor's composition-based design which is much easier to script (new statistic types can be scripted in XML, for example).
Logged

"There are more atoms in the period at the end of this sentence than you can count in a lifetime." Science is awesome.

Pages: [1]
Print
Jump to: