So I’m working on a skill system for L5R and I’ve come across something of a conundrum. In L5R, characters are given ranks in various rings which in turn are informed by the ranks in their associated traits. For example: The Fire ring is formed of the Intelligence and Agility traits. Both ring and trait ranks are used in various rolls, abilities, and derived traits through out the system.
My first thought was to create collections for both traits and rings (with corresponding models for both) on the character, and a collection for traits on the ring model as well, but then it occurred to me that this might not be the most efficient way to do things. In fact is it even possible? I came up with the alternative of putting the trait collection directly on the ring model instead and simply creating a helper method that pulled those whenever I needed them.
Would love and appreciate some advice on which of these (or a third, as yet unconsidered approach) would be most efficient!
I could be missing something (having never played the new L5R) but I think all you need is a method on the character object.
Assuming you have a collection of traits, you can do:
class L5RTrait < Ohm::Model
attribute :rating
# I assume there are other things about a trait you need to store; otherwise a model is overkill
end
class Character
collection :l5r_traits, "AresMUSH::L5RTrait"
def l5r_trait(name)
# Finds a trait by name
end
def l5r_ring(name)
if (name == "Fire")
return l5r_trait("Intelligence").rating + l5r_trait("Agility").rating
else
...
end
end
end
Something like that anyway.
Side note tip - notice that I named the attributes and methods on the character object as l5r_xxx. That’s just to avoid collisions with other definitions that might try to use a name like “trait” or “skill” or whatever.
You know… That… Honestly had never occurred to me. I did a very quick pass through to make sure that there wasn’t something /I/ was missing too, but no I think that’d work. There’s no real reason why it has to be stored on the character.
In this case it’s 4E so I’d be using .min, but yeah…
Thanks! That’s much simpler.
And yeah, I’ve been absorbing every scrap of information on the AresMUSH site and examining your other skill system plugins for about a week. Glad to see I at least got the naming conventions correct!
Though at the same time, I think I might want to take a second pass at the models just to make sure nothing else is extraneous.
I’m not sure where you intended that method to live, but you have two options.
In the character class, in which case you don’t need the char parameter because you’ll be calling it like some_char_you_already_have.calc_l5r_ring('fire').
In the L5R module helper, in which case you’ll need to define it as def self.calc_l5r_ring(char, ring) and call it like L5R.calc_l5r_ring(some_char,'fire')
Also if l5r_traits is a collection of Ohm models, you’ll access the parts using t.name and t.value instead of the array versions t[:name]. What you have there would work if l5r_traits is a hash attribute as opposed to a separate model.
Both are totally valid ways of storing the traits; it really comes down to how much ancillary data is stored about the trait. For example in FS3 we have last XP spends, specializations, etc. It’s not just a name and a number. The more complex your data, the more likely you’ll want to store it as a model and not a hash.
Good catch! I knew about making that comparison twice (because I borked it once before), but yeah… 1:30 in the morning after a busy shift was not the time to be doing anything besides sleeping.
Yeah, sorry, it wasn’t meant as a code review. I just know how nefarious unexpected conditionals (that aren’t technically syntactically wrong) can be and so I just wanted to make sure it was known.