The Savage Worlds game system emphasizes the use of allies. As such, our data files should provide for the creation and management of allies associated with the characters.
Setting Up Ally Support
Allies are essentially independent characters that are children of the main characters. The Kit provides a framework for handling such characters very easily via the "minion" mechanism. Minions work very similarly to gizmos. They are attached to a character via a thing, and the minion is automatically added to the character whenever a pick based on that thing is added. Deleting the pick also deletes the minion. The parent character of a minion is referred to as the "master".
Just about any "thing" can have a minion attached. However, we want to be able to readily identify the picks that add our allies from other picks. We'll define a new component and component set to accomplish this. We'll assign the component a unique id of "Ally" and have it automatically define a component set with the same id, since we don't need to re-use any other special behaviors.
It would also be useful to let the user enter some arbitrary notes about each ally that can be used to readily identify them. For this, we'll include a field on the component where we can store those details. This results in a component set that looks like below, which we can add to the file "miscellaneous.str".
<component id="Ally" name="Ally"> <!-- Brief summary of ally for display in the list of allies --> <field id="alySummary" name="Summary" type="user" maxlength="100"> </field> </component>
Defining the Minion
We can now define a thing based on our new component set. We can add the thing to the file "thing_miscellaneous.dat". The only item of note about this thing is that the the minion will be attached by it.
Associating a minion with a thing is accomplished via the "minion" child element. Each minion needs to be assigned a unique id, which makes it possible to identify different minions when multiple types of minions are added to a character. We'll only have one type of minion, but we need to assign a unique id anyway.
The other important facet of our minion is that we want it to inherit all of the settings associated with the master character. For example, if the master has only the "Futuristic" time period selected, then we want to assume that the minion has the same behaviors. This is achieved via the "isinherit" attribute within the "minion" element.
Putting this all together, we end up with a thing definition that looks like the following.
<thing id="mscAlly" name="Ally" compset="Ally"> <minion id="ally" isinherit="yes"> </minion> </thing>
We now need to figure out how to let users add and manage allies. We could add allies to an existing tab, but none of them really seem appropriate. There also is a space consideration, as many of our tabs are already quite packed with information. Since we only have a rather small number of tabs, it would be quite reasonable to add another tab for tracking allies.
When adding our tab, we'll want something very simple. We'll have a single table on the tab where the user can add and access allies. The "Skills" tab is very similar, so we'll copy the file "tab_skills.dat" as "tab_allies.dat" and then adapt the file to our needs.
The first thing we need to do is revise the table portal at the top. All allies will be attached to the character via the same "mscAlly" thing that we defined above. Consequently, we need to utilize an "auto" table that automatically adds a new pick based on a specific thing instead of prompting the user to select a thing. This requires that we specify the thing id to be used. We also need to utilize a custom template for showing the contents of each ally. The resulting portal should look like the one shown below.
<portal id="alAllies" style="tblNormal"> <table_auto component="Ally" showtemplate="alPick" autothing="mscAlly"> <headertitle><![CDATA[ @text = "Allies Associated with Character" ]]></headertitle> <additem><![CDATA[ @text = "Add a New Ally to the Character" ]]></additem> </table_auto> </portal>
For the moment, we'll keep the template very simple. We'll start with just the name of the pick, plus the standard info and delete portals. We'll come back in a moment to refine the template and make it more useful. This yields a template like the one below.
<template id="alPick" name="Ally Pick" compset="Ally" marginhorz="3" marginvert="2"> <portal id="name" style="lblNormal" showinvalid="yes"> <label field="name"> </label> </portal> <portal id="info" style="actInfo"> <action action="info"> </action> <mouseinfo/> </portal> <portal id="delete" style="actDelete" tiptext="Click to delete this item"> <action action="delete"> </action> </portal> <position><![CDATA[ ~set up our height based on the tallest portal height = portal[info].height ~if this is a "sizing" calculation, we're done if (issizing <> 0) then done endif ~position our tallest portal at the top and center other portals vertically portal[info].top = 0 perform portal[name].centervert perform portal[delete].centervert ~position the delete and info portals on the far right perform portal[delete].alignedge[right,0] perform portal[info].alignrel[rtol,delete,-8] ~position the name on the left portal[name].left = 0 ]]></position>
minions automatically have a way to access the master via the static form