Difference between revisions of "Adding Edges (Savage)"
Latest revision as of 21:13, 17 December 2008
With the mechanics for edges in place, we now need to get them implemented. We'll keep them all together as a group by creating a new "thing_edges.dat" file where they will be added. All of the reminders outlined for hindrances also apply to edges, and the following sections discuss a few key edges to highlight important facets of their implementation.
We'll start with the simple "Combat Reflexes" edge. This edge is of type "Combat" and has a minimum rank of "Seasoned" (or one), so we assign the tag and set the field value accordingly. The result is shown below.
<thing id="edgComRefs" name="Combat Reflexes" compset="Edge" isunique="yes" description="Description goes here"> <fieldval field="edgMinRank" value="1"/> <tag group="EdgeType" tag="Combat"/> </thing>
Next up is the "Berserk" edge, which demonstrates the handling of user-activated behaviors. The fact that there is a user-activated behavior is controlled by assigning the "User.Activation" tag. We use an Eval script to assign the behaviors, wrapping them within a test of the activated ability state. This edge also demonstrates the need to carefully distinguish between using the "#traitbonus" and "#traitroll" macros. The net result is the definition below.
<thing id="edgBerserk" name="Berserk" compset="Edge" isunique="yes" description="Description goes here"> <fieldval field="edgMinRank" value="0"/> <tag group="EdgeType" tag="Background"/> <tag group="User" tag="Activation"/> <eval index="1" phase="PreTraits" priority="5000"> <before name="Calc trtFinal"/><![CDATA[ if (field[abilActive].value = 0) then #traitbonus[trParry] -= 2 #traitbonus[trTough] += 2 #traitroll[skFighting] += 2 endif ]]></eval> </thing>
Each arcane background is granted via an edge. That means that each arcane background thing must automatically add all of the proper logic for managing that arcane background. One thing can automatically add any number of chained things by use of the "bootstrap" mechanism within the Kit, so our edge will bootstrap the logic for the arcane background. The "Magic" background below demonstrates this.
<thing id="edgArcMag" name="Arcane Background: Magic" compset="Edge" isunique="yes" description="Description goes here"> <fieldval field="edgMinRank" value="0"/> <tag group="EdgeType" tag="Background"/> <bootstrap thing="arcMagic"/> </thing>
Numerous edges possess pre-requisites on different traits, such as requiring a Strength attribute of d8 or higher, or needing a Fighting skill of d10 or higher. Each edge needs to implement these pre-requisites individually, but the structure and behavior is always the same. We use the "Sweep" edge as an example to show how this works below.
<thing id="edgSweep" name="Sweep" compset="Edge" isunique="yes" description="Description goes here"> <fieldval field="edgMinRank" value="0"/> <tag group="EdgeType" tag="Combat"/> <exprreq message="Strength d8 required."><![CDATA[ #trait[attrStr] >= 4 ]]></exprreq> <exprreq message="Fighting d8 required."><![CDATA[ #traitfound[skFighting] >= 4 ]]></exprreq> </thing>
Note that each separate requirement is implemented as a distinct pre-requisite instead of merging them into a single test. While this is not required, it is a highly recommended approach. The advantage of doing this is that HL can readily report each individual requirement that is not satisfied, providing greater detail to the user about what is wrong and needs to be fixed.
Pre-Requisites on Other Edges
There are quite a few edges that are boosted versions of other edges. They can only be taken when the lesser version of the edge has already been taken. For example, the "Improved Arcane Resistance" edge can only be taken if the "Arcane Resistance" edge has already been taken. So we need to setup appropriate pre-requisites on the presence of other edges. This can be handled easily via use of the "pickreq" element. The implementation of "Improved Arcane Resistance" shown below demonstrates how this is done.
<thing id="edgArcRes2" name="Improved Arcane Resistance" compset="Edge" isunique="yes" description="Description goes here"> <fieldval field="edgMinRank" value="0"/> <tag group="EdgeType" tag="Background"/> <pickreq thing="edgArcRes"/> </thing>
A small number of edges employ very specialized pre-requisites. This entails using the generalized "prereq" element and a Validate script to perform the appropriate tests. An example of this is the "Power Surge" edge, which requires the character to possess an arcane skill with a rating of d10 or higher. The implementation of this edge is shown below.
<thing id="edgPwrSurg" name="Power Surge" compset="Edge" isunique="yes" description="Description goes here"> <fieldval field="rnkMinRank" value="1"/> <fieldval field="edgIsWild" value="1"/> <tag group="EdgeType" tag="Wildcard"/> <prereq iserror="yes" message="Arcane Skill of d10 required."> <validate><![CDATA[ ~go through all arcane skills and check for d10 foreach pick in hero where "component.Skill & Arcane.?" if (eachpick.field[trtFinal].value >= 5) then @valid = 1 done endif nexteach altthing.linkvalid = 0 ]]></validate> </prereq> </thing>
Deferring Complex Special Cases
There will be times when you run into special cases that you want to implement correctly but that will require a non-trivial amount of extra work. In those cases, the best strategy is to figure out a suitable interim solution and plan to implement a "proper" solution once everything else is in place. There are two shining examples of this among the edges of Savage Worlds.
The first is the "Scholar" edge, which requires the user to select two "Knowledge" skills at d8 or higher and confers a "+2" bonus to each of the selected skills. Allowing the user to make the selections requires that edges support two separate menus from which the user can select one skill each. The presented list of skills must be filtered to only show the existing "Knowledge" skills, and it should ideally only include skills with a d8 rating or higher. This represents a fair amount of work to implement, so we're going to defer adding this until later. For the time being, we'll setup the "Scholar" edge to simply require that at least two "Knowledge" exist at d8 or higher. We'll also leave it up to the user to add two suitable permanent adjustments to apply the appropriate bonuses to the desired skills. While this solution is a bit clunky, it allows the user to achieve the desired result without requiring lots of extra development work - a perfect interim solution when you're trying to get your initial set of files operational.
The second example of complexity that is best deferred is the "Professional" edge, along with its siblings "Expert" and "Master". Each of these requires that the user select a trait that is at a d12 rating, with that trait being granted a "+1" bonus. Just like the "Scholar" edge, a menu is needed that properly filters the list of traits shown to those that qualify and from which the user can make the selection. As an interim solution, these three edges can simply verify that at least one trait is at a d12 rating and the user can add a permanent adjustment to apply the bonus to the appropriate trait.
Acknowledging Our Limitations
There is one edge that we simply can't implement with 100% completeness, unless we want to inconvenience the user. The "Gadgeteer" edge requires that the character have at least two "Knowledge" skills at a d6 or higher, and those skills must be scientific in nature. The problem is that the user is free to type in whatever he wants for the domain of the skill, so we have no way to determine whether a particular skill is scientific or not. In situations like this, we are forced to either add some contrived mechanism to get the information we need or defer the details to the user. Deferring to the user is almost always the best path to choose. With "Gadgeteer", we can verify that there are at least two "Knowledge" skills at a d6 or higher, but we must leave it up to the user to verify that both of them are truly scientific in focus.