Show the Derivation of Values (Savage): Difference between revisions

From HLKitWiki
Jump to navigationJump to search
No edit summary
No edit summary
Line 24: Line 24:
===Tracking of Adjustments===
===Tracking of Adjustments===


optional to use (can apply adjustments that aren't tracked, but generally a bad idea)
At this point, we could reload the data files and everything would continue to work as before. Although history tracking has been enabled for the "trtBonus" field, we can choose when to track adjustments and when not to do so. The tracking mechanism is optional, allowing us to apply adjustments that aren't tracked. This is important, because the same field may need to utilize history tracking for some things and not for others. This also makes it easy for us to integrate history tracking in a step-wise process instead of requiring us to do it all at once.


use of "modify" target reference
In order to track an adjustment within the history for a field, we need to utilize the "modify" target reference on the field. This target reference must be given an operator (e.g. "+" or "-"), a value, and a string that describes what the adjustment represents. Adding 2 to the "trtBonus" field for the "trCharisma" trait would look similar to the line of code below.


new macro (optionally include or exclude the "perform" statement)
<pre>
perform hero.child[trCharisma].field[trtBonus].modify[+,2,"The Reason"]
</pre>
 
Since we're going to be using this basic statement in lots of places, we might as well make it easy on ourselves. So we'll define a new script macro for this field that works similarly to the "traitbonus" script macro that we already use whenever modifying the value of a trait. Open the file "definition.def" and locate the various script macros. Now define a new macro that takes four parameters and resolves to the "modify" usage shown above. The new macro should look like the following.
 
<pre>
<scriptmacro
  name="traitadjust"
  param1="trait"
  param2="oper"
  param3="value"
  param4="text"
  result="hero.child[#trait].field[trtBonus].modify[#oper,#value,#text]"/>
</pre>
 
Since a macro is simply text that gets swapped in during compilation, we could also include the "perform " statement in the macro. If we do not include it, using the macro will look like the first example below. If we do include it, then our code will look like second example below. You are free to choose what works best for you, but we'll use the former approach as we continue this topic.
 
<pre>
perform #traitadjust[trCharisma,2,"The Reason"]
</pre>
 
<pre>
#traitadjust[trCharisma,2,"The Reason"]
</pre>


===Revise All Adjustments===
===Revise All Adjustments===
Line 42: Line 66:




The derived traits are shown on the Basics tab. However, these traits are influenced by a variety of factors.
The first thing we need to do is provide a place to accrue the derivation details for each derived trait. We can do this by defining a new field for the "Derived" component, which can be found in the file "traits.str". We'll name the new field "trtDerived" and make it a text field with adequate storage for multiple adjustments. This yields a field definition that looks like the one below.
<pre>
<field
  id="trtDerived"
  name="Derivation"
  type="derived"
  maxlength="200">
  </field>
</pre>
Since we're going to be modifying this field in a variety of places, we might as well make it easy on ourselves. So we'll define a new script macro for this field that works similarly to the "traitbonus" script macro that we already use whenever modifying the value of a derived trait. Open the file "definition.def" and locate the "traitbonus" script macro, then clone that macro. Edit the macro to have the name "traitderived" and operate on the "trtDerived" field, which is a text field. The new macro should look like the one shown below.
<pre>
<scriptmacro
  name="traitderived"
  param1="trait"
  result="hero.child[#trait].field[trtDerived].text"/>
</pre>


The next step is to initialize the field to something appropriate for each derived trait. This is easily accomplished by defining the field value within each thing. For example, we can set the initial derivation text for the Pace trait to something like "Base of 6" via the "fieldval" element, as shown below. This should be done for all derived traits within the file "thing_traits.dat".
The next step is to initialize the field to something appropriate for each derived trait. This is easily accomplished by defining the field value within each thing. For example, we can set the initial derivation text for the Pace trait to something like "Base of 6" via the "fieldval" element, as shown below. This should be done for all derived traits within the file "thing_traits.dat".

Revision as of 20:30, 13 January 2009

Context: HL Kit &#133; Authoring Examples &#133; Savage Worlds Walk-Through 

Overview

Within Savage Worlds, many traits are influenced by a variety of factors. When the user sees one of these traits on the screen, there will be times when the number just doesn't look right. Usually, this will be due to some effect being included that the user has overlooked but the data files are properly tracking. At times like this, it would be incredibly helpful to inform the user how the final trait value was actually calculated for the character, presenting each of the contributing influences so the user can see what he's overlooked. We'll take the time to add this information in a few key spots.

Built-In History Tracking

The first thing we need to do is provide a place to accrue the derivation details for each trait. Your first thought is probably to define a new text-based field where this information can be tracked, and that approach would definitely work. However, the Kit provides built-in handling for just this type of situation.

Fields that are value-based and derived can leverage history tracking that is wholly managed by HL. The tracking can take two different forms. The first is "best" tracking, which only tracks the largest adjustment applied to a given field and is ideally suited for situations where adjustments do not stack. The second is "stack" tracking, where each individual adjustment is tracked. Obviously, we'll want to use the second form and present a report to the user that shows all of the adjustments that were applied.

We can enable history tracking very easily by adding a new attribute to the field definition. Since all of the adjustments we want to track are applied to the "trtBonus" field of Traits, we'll add history tracking to that field. The modified field definition should look similar to the one shown below.

<field
  id="trtBonus"
  name="Bonus Value"
  type="derived"
  history="stack">
  </field>

Tracking of Adjustments

At this point, we could reload the data files and everything would continue to work as before. Although history tracking has been enabled for the "trtBonus" field, we can choose when to track adjustments and when not to do so. The tracking mechanism is optional, allowing us to apply adjustments that aren't tracked. This is important, because the same field may need to utilize history tracking for some things and not for others. This also makes it easy for us to integrate history tracking in a step-wise process instead of requiring us to do it all at once.

In order to track an adjustment within the history for a field, we need to utilize the "modify" target reference on the field. This target reference must be given an operator (e.g. "+" or "-"), a value, and a string that describes what the adjustment represents. Adding 2 to the "trtBonus" field for the "trCharisma" trait would look similar to the line of code below.

perform hero.child[trCharisma].field[trtBonus].modify[+,2,"The Reason"]

Since we're going to be using this basic statement in lots of places, we might as well make it easy on ourselves. So we'll define a new script macro for this field that works similarly to the "traitbonus" script macro that we already use whenever modifying the value of a trait. Open the file "definition.def" and locate the various script macros. Now define a new macro that takes four parameters and resolves to the "modify" usage shown above. The new macro should look like the following.

<scriptmacro
  name="traitadjust"
  param1="trait"
  param2="oper"
  param3="value"
  param4="text"
  result="hero.child[#trait].field[trtBonus].modify[#oper,#value,#text]"/>

Since a macro is simply text that gets swapped in during compilation, we could also include the "perform " statement in the macro. If we do not include it, using the macro will look like the first example below. If we do include it, then our code will look like second example below. You are free to choose what works best for you, but we'll use the former approach as we continue this topic.

perform #traitadjust[trCharisma,2,"The Reason"]
#traitadjust[trCharisma,2,"The Reason"]

Revise All Adjustments

setting the proper initial value via "fieldval"

using macro everywhere with proper annotation instead of "traitderived"

Showing the History Report

use "history" target reference within MouseInfo script



The next step is to initialize the field to something appropriate for each derived trait. This is easily accomplished by defining the field value within each thing. For example, we can set the initial derivation text for the Pace trait to something like "Base of 6" via the "fieldval" element, as shown below. This should be done for all derived traits within the file "thing_traits.dat".

<fieldval field="trtDerived" value="Base of 6"/>

Throughout the data files, there will be places where each derived field is modified in some way. In each of the locations, the derivation details must be logged at the same time the adjustment is applied. This is achieved by simply appending a suitable, brief description of the adjustment as text. For example, the "Berserk" edge applies a +2 bonus to the character's Toughness and a -2 penalty to the character's Parry. Once the derivation details are added, the new script should look like the one shown below.

if (field[abilActive].value = 0) then
  #traitbonus[trParry] -= 2
  #traitderived[trParry] &= ", Berserk -2"
  #traitroll[skFighting] += 2
  #traitbonus[trTough] += 2
  #traitderived[trTough] &= ", Berserk +2"
  endif

Go through the data files and locate all instances where the derived traits are modified. Every instance should be accompanied by a corresponding "#traitderived" macro that logs what adjustment was applied. Be sure to also track the effects of equipped weapons and shields on the Parry trait, as well as the effects of equipped armor on the Toughness trait.

For two of the derived traits, the final value depends on another trait that can also be modified by other effects. So we need to wait until the end of the evaluation cycle before applying the adjustment for the trait. This requires we define a new Eval script for each of the traits that properly appends the final adjustment description to the derivation field. The two traits that require this are the Parry and Toughness traits, which are based upon the Fighting skill and Vigor attribute, respectively. Putting it all together, the two Eval scripts below should handle things appropriately for these two traits.

<eval index="2" phase="Render" priority="10000"><![CDATA[
  if (hero.childexists[skFighting] <> 0) then
    field[trtDerived].text &= ", Half Fighting +" & #trait[skFighting]
    endif
  ]]></eval>

<eval index="2" phase="Render" priority="10000"><![CDATA[
  field[trtDerived].text &= ", Half Vigor +" & #trait[attrVig]
  ]]></eval>

The derivation explanation should now be getting properly synthesized for each trait, so all we need to do now is make it accessible to the user. Open the file "tab_basics.dat" and locate the "baTrtPick" template that is used to display the various derived traits. Within the template, the "details" portal shows the final value for the trait, and a MouseInfo script is defined that currently just outputs "???". Change the script to return the contents of the "trtDerived" field and the derivation details will be available to the user by simply moving the mouse over the value. The revised portal should look like the one shown below.

<portal
  id="details"
  style="lblLarge">
  <label>
    <labeltext><![CDATA[
      @text = field[trtDisplay].text
      ]]></labeltext>
    </label>
  <mouseinfo mousepos="middle+above"><![CDATA[
    @text = field[trtDerived].text
    ]]></mouseinfo>
  </portal>