Creatures (Savage Worlds)

From HLKitWiki
Revision as of 17:24, 5 February 2009 by Rob (Talk | contribs) (Directly Defining Traits)

Jump to: navigation, search

Context: HL KitAuthoring Examples … Savage Worlds Walk-Through 

Overview

If we want to be big help for GMs, we need to allow GMs to do more than just create NPCs. We must also let them quickly create monsters and animals.

New Character Type

Since creatures are fully defined within the rulebook, there is no substantial customization to be done, and there are definitely no rules that govern construction of creatures. Consequently, the first thing we need to do is add support for a new character type - the creature.

We currently has a field that indicates whether the character is an NPC or not. Since we'll now have three types of character, we'll change the field for more generalized use. The "acIsNPC" field can be changed to an "acCharType" field, where the value of the field can be one of three possibilities. A "zero" indicates a normal PC, a "one" indicates an NPC, and a "two" indicates a creature. The new field will look like below.

<field
  id="acCharType"
  name="Character Type"
  type="user"
  defvalue="0">
  </field>

We have a tag that identifies an NPC, but we really need separate tags to indicate all three different character types. We'll assign the appropriate tag based on the field value. The new tags will be defined within the "Hero" tag group and should include the following.

<value id="PC"/>
<value id="Creature"/>

The existing Eval script that identifies and NPC and sets up appropriately can be readily adapted. Instead of just recognizing an NPC, the script can recognize all three different values within the "acCharType" field. Based on the field value, the appropriate tag can be assigned to the hero, plus any other customizing of the interface. For example, the "Journal" tab is of no use for a creature. We're also going to need to either overhaul the "Edges" tab to only show racial abilities or replace it with an alternate tab. We'll assume the latter for now, which results in the following revised Eval script on the "Actor" component.

~assign a tag to indicate we're a PC, NPC, or Creature, as appropriate
if (field[acCharType].value = 0) then
  perform hero.assign[Hero.PC]
elseif (field[acCharType].value = 1) then
  perform hero.assign[Hero.NPC]
else
  perform hero.assign[Hero.Creature]
  endif

~if this is a standard PC, there's nothing more to do
if (hero.tagis[Hero.PC] <> 0) then
  done
  endif

~hide components of the interface that don't apply for NPCs and/or Creatures
perform hero.assign[HideTab.advances]
if (hero.tagis[Hero.Creature] <> 0) then
  perform hero.assign[HideTab.edges]
  perform hero.assign[HideTab.journal]
  endif

~force the starting XP field to zero in case the user has modified it
trustme
field[acStartXP].value = 0

Integrate Into Configure Hero Form

Now that we've changed the field, we need to change the "Configure Hero" form to properly set the field. We currently have a checkbox to designate whether the character is an NPC. We need to replace this checkbox with a way to choose between the three options: PC, NPC, and creature.

The easiest way to do this is with a menu that consists of literal choices. That way, we don't have to go through the extra work of defining an assortment of "things" to represent each option. With a literal menu, we have complete control over the choices presented and the corresponding values associated with each choice. We just need to spell out the list of choices as part of the menu definition.

You'll find an example of using a menu like this on the "Personal" tab. It's the one for selecting the character's gender, with options for male and female. We can copy this menu and adapt it for our needs. We've already determined the meaning of the values 0-2 for the "acCharType" field, so all we need to do is define corresponding options. This results in a new menu portal that looks like below.

<portal
  id="chartype"
  style="menuNormal">
  <menu_literal
    field="acCharType">
      <choice value="0" display="Type: Player Character"/>
      <choice value="1" display="Type: NPC (Unlimited)"/>
      <choice value="2" display="Type: Creature"/>
    </menu_literal>
  </portal>

Once the portal is defined, we can easily integrate it into the Position script. We're replacing the "isnpc" portal, so we can swap out all references to that portal and use "chartype" instead. The only detail that differs between menus and checkboxes is that checkboxes are automatically sized to fit the text they contain, while menus are not. This means we have to specify the width of the portal to something appropriate. We must do this before we center the portal horizontally by adding the line of code below.

portal[chartype].width = width

Our new portal should now be ready to go, with the proper selections being presented and stored internally within the field. However, our behaviors aren't quite right yet. We need to control the visibility of various portals based on the character type. The wildcard checkbox should only be visible for non-creatures, while the starting cash and XP should only be visible for PCs. This requires changing the block of lines at the start of the script to be the following.

~determine whether the wildcard option is visible based on whether we're a creature
portal[iswild].visible = !hero.tagis[Hero.Creature]

~determine whether the starting cash is visible based on whether we're a pc
portal[cash].visible = hero.tagis[Hero.PC]
portal[lblcash].visible = portal[cash].visible

~determine whether the starting xp is visible based on if we're a pc
portal[xp].visible = hero.tagis[Hero.PC]
portal[lblxp].visible = portal[xp].visible

New Creature Component

We could adapt the existing "Race" component for use with creatures, but creatures behave quite differently from normal characters. As such, we should define a new component and component set for handling creatures. We'll use the id "Creature" for both, and we'll force the creature specification to be unique for every actor. This yields the following basic definitions, which we'll extend below.

<component
  id="Creature"
  name="Creature"
  autocompset="no">
  </component>

<compset
  id="Creature"
  forceunique="yes">
  <compref component="Creature"/>
  </compset>

Some creatures are wildcards, while others are not. Based on the way creatures are presented in the rulebook, the wildcard designation is fixed for each particular creature. We've already omitted the checkbox from the "Configure Hero" form, so we need a way to designate a creature as a wilcard or not within its definition.

We could easily use a field on the "Creature" component for this purpose. However, the best way to handle either-or conditions for users is to utilize a tag. If the tag is present, the condition exists, else it doesn't - clean and simple. So we'll define a new tag that can be specified on the creature and give it the "Wildcard" unique id. Since this tag will be user-defined as part of the thing definition, we'll define the tag within the "User" tag group. Any creature that should be behave as a wildcard must be assigned this tag.

Now we need to do something with the tag. The actual wildcard behavior is managed via the "acIsWild" field on the "Actor" component. So we need to translate the tag into an appropriate modification of the field. This can be accomplished via an Eval script on the "Creature" component. We simply set the field value based on the presence of the tag. The appropriate Eval script looks like the one below.

<eval index="1" phase="Initialize" priority="5000"><![CDATA[
  trustme
  herofield[acIsWild].value = tagis[User.Wildcard]
  ]]></eval>

We should also track the creature type on the actor, just like we track the race. We can achieved that by defining an identity tag on each creature and forwarding that tag to the hero. This entails the following additions.

<identity group="Creature"/>

<eval index="2" phase="Setup" priority="5000"><![CDATA[
  perform forward[Creature.?]
  ]]></eval>

We can now define creatures that don't do anything useful, but the framework is in place that we can build upon.

Selecting the Creature

Directly Defining Traits

General Approach

-tags instead of fields where possible for user ease

Defining Attributes

Defining Derived Traits

Defining Skills

Defining a Complete Creature

-change history tracking to "changes" to ignore values of zero

Tailoring the Interface

Separate Creature and Race Choosers

Resource Revisions

Basics and Skills Tabs

Omitting Non-Applicable Tabs

Safety Checks

Existence Tag Expressions

-existence tagexpr to auto-delete race/creature upon switch

Validation Rules

Allow User to Add Abilities

-tag to identify general abilities for re-use -allow user to specify facets of dynamic abilities that are needed (value/text)