design question:game skill system

Ian Kelly ian.g.kelly at gmail.com
Tue Oct 2 16:34:12 EDT 2012


On Tue, Oct 2, 2012 at 2:00 PM, Littlefield, Tyler <tyler at tysdomain.com> wrote:
> Hello all:
> I'm looking at a skill/perk system, where the player builds up his char by
> using perk points to add abilities.
> Each perk is under a category, and generally costs go up as you increase the
> perk.
> So I'm trying to figure something out; first, I'd really like the cost
> calculation and all of that to be dynamic, so that I don't have to write a
> calculateCost per object. I'd also like to be able to specify dependencies
> and say a level, as well as other factors before a player can obtain a perk
> and have them self documenting. The idea is that a player could do something
> like:
> data perk extended health
> and it would tell them they require health at 50 before they can purchase
> extended health, as well as the cost, the increase per level and the total
> overall cost.

What are the cost calculations based on?  If there are specific
formulas then you would need to store them somehow, possibly just as a
function to be called or string to be evaled, but if the security of
the perk database is of concern then you could engineer a more
sandboxed representation.  For dependencies, you can keep them in a
container.  An extended health perk might look something like:

cost_formula = "5 * level ** 2"
dependencies = {HEALTH: 50, PLAYER_LEVEL: 15}
benefits = {HEALTH: "7 * level"}

where HEALTH and PLAYER_LEVEL are just some arbitrary known constants.
 Your core perks library would then be responsible for looking this
information up, running the formulas, and performing whatever
calculations on it are needed.

> Finally, I'm curious how to store and calculate these. I thought about using
> a uid per perk, then storing something like: {uid:level} on the player, but
> means that I have to lookup the name somehow still in the main perk
> database, then use that uid to check if the player has it. Are there better
> ways of storing skills?

When you say uids, you mean UUIDs, right?  I'm not sure what advantage
there is in using abstracted unique identifiers for these.  Assuming
you have full control over what perks are added, you can ensure there
will be no name clashes, so why not just use the name or a name-based
tag to uniquely identify each perk?  Regardless of how you identify
them, though, your code is at some point going to have to go to the
database to look them up, so I would suggest you just go ahead and
write that code, and then you can add some caching later if it turns
out to be needed.

> I'm also thinking about calculation; currently the
> CalculateMaxHp method would have to add up all the possible perks for
> health, then add stats and all that. That could get really rough on
> performance if it's called often; would something like a cache work, where
> you have something like: {attribute:dirty}? So if I call CalculateHealth, it
> checks for the dirty flag, and if it doesn't exist just returns the previous
> max HP, but if the dirty flag is set, it recalculates? Then anything
> modifying health (level gains, perks, stat increases/etc) would just set the
> dirty flag and call calculate?

Sounds reasonable.  I wouldn't use a separate flag attribute, though.
When max HP becomes dirty, clear the cached value, and use the absence
of a cached value to inform your code that it needs to recalculate.



More information about the Python-list mailing list