There will be many situations where you want to add a pick to a container automatically. For example, you'll need to make sure that every actor starts out with all of the attributes possessed by characters. You'll also want to re-use abilities, so you'll need to have one thing automatically add another thing.
Within the Kit, this process is referred to as "bootstrapping". Correspondingly, when you add a thing to a container automatically, the resulting pick is referred to as a "bootstrapped" pick. There are a number of important implications associated with bootstrapping, which are discussed in the topics below.
Things Bootstrapping Other Things
You can bootstrap picks from a variety of situations. However, the most common situation will be when you have one thing bootstrap another. This will regularly occur when the game system has an assortment of abilities that are conferred from a variety of sources. For example, consider the "low-light vision" ability within the d20 System. This ability is conferred by multiple different races, certain magic weapons, etc. You're only going to want to define the ability once, after which you can have each race and weapon simply bootstrap the ability.
When a pick is bootstrapped by another pick, the pick that does the bootstrapping is referred to as the "root" pick. The root pick has complete control control of the bootstrapped pick. If the root pick is deleted, the bootstrapped pick is also deleted. If the root pick goes non-live, so does the bootstrapped pick. The bootstrapped pick still has its own independent existence, but that state is wholly dependent upon the root pick as well.
Situations Where You Can Bootstrap
In addition to things bootstrapping each other, there are a number of additional situations in which bootstrapping of things can be performed. These situations are outlined below. In each of these cases, the dependency relationships outlined above for things bootstrapping things do not apply.
- Things can be bootstrapped onto all actors when the actor is initially created.
- Things can be bootstrapped onto entities as part of the entity's definition. The bootstrapped picks are part of every gizmo created from that entity.
- Things can be bootstrapped onto entities when they are attached. The bootstrapped picks are only included on gizmos created by that thing.
- Things can be bootstrapped onto minions when they are attached. The bootstrapped picks are only included on minions created by that thing.
Bootstrapped Picks are Not Deletable
The topic name pretty much sums it. When a pick is bootstrapped into a container, only the source that performs the bootstrap has control over the pick's existence. Consequently, all bootstrapped picks of fundamentally not deletable. Any attempt to delete a bootstrapped pick will fail.
If you want to pre-select a pick into a table or chooser, and you want the user to be able to delete that selection, you need to use a different technique. Please refer to the section "Automatically Adding Picks to Actors".
Bootstrapping the Same Thing Multiple Times
At this point, you may be wondering what happens when the same thing is bootstrapped multiple times into a container. The answer depends on whether the thing is designated as being unique. If not, then separate, independent picks are always created, and their behaviors are not linked in any way. However, if the thing is designated as unique, then only one pick is ever added to a given container. This means that all of the bootstrap actions will actually reference the identical pick.
When the first bootstrap occurs, the new pick is created. Each subsequent bootstrap simply increases the reference count for the pick. As long as at least one of the sources for the bootstrap remains in existence, so will the bootstrapped pick. This is important when things bootstrap over things and those things are user-added. Consider the situation where both ThingA and ThingB bootstrap ThingZ. When the user added ThingA, ThingZ is bootstrapped. When the user adds ThingB, the reference count is increased. If ThingA is deleted, the reference count is decreased, but ThingZ still exists. When ThingB is deleted, the reference count goes to zero and ThingZ is finally deleted as well.
When multiple things bootstrap the same, unique thing, their effects are cumulative upon the new pick. If ThingA specifies an auto-tag for ThingZ, and ThingB specifies a different auto-tag for ThingZ, then both auto-tags are assigned to ThingZ. If only ThingA is added to the container, only its auto-tags are assigned, and the same holds for ThingB. However, if both things are added to the container, both auto-tags are assigned.
If multiple things bootstrap the same, unique thing, all of the conditions associated with the root picks must be handled in accordance with some sort of rules. For example, we'll assume ThingA and ThingB both bootstrap ThingZ, and both ThingA and ThingB have been added to the same container. Now we'll further assume that ThingA has a Live test that is currently failed. This means that ThingA is treated as not existing within the container, although ThingB has no dependency and therefore fully exists. So what happens with ThingZ?
To resolve situations like this, the Kit treats each root pick independently. If any one of the root picks for a bootstrapped pick is considered live, then the bootstrapped pick is also considered live. In the example above, this means that ThingZ would be treated as being live due to ThingB being live. The fact that ThingA is not live is irrelevant.
The Mechanics of Bootstrapping
The process of bootstrapping a thing is accomplished via the the "bootstrap" element. Since there are a variety of places where bootstrapping can be performed, this element is re-used throughout the Kit.
At a minimum, the "bootstrap" element requires you to specify the unique id of the specific thing to be added. You may also specify tags that will be automatically assigned to the pick when it is added.
The vast majority of bootstraps are simple. The bootstrap is always performed for the source context it is defined within. However, there are some situations where you want the bootstrap to only be applicable under certain circumstances. For example, a bootstrap definition on a component will be inherited by all things derived from that component. However, you may only want the bootstrap to be applied to most of those things, with some not having the bootstrap.
In these situations, a Condition tag expression may be specified.
phase and priority for condition test
-Bootstrap tagexprs are now properly handled for all picks
-Condition test is performed at the specified phase/priority -Condition test is ignored when specified on rulesets and entities -Condition test is performed against tags on the container
-Bootstraps can be defined for components
-Inherited by all things that derive from the component -Specify a "match" tagexpr that restricts which things the bootstrap is applied to
-The "live" test performed for a bootstrap provides the reference pick of the
bootstrap for use in testing field values within the tagexpr -All field value tests in the tagexpr are applied to the reference pick that chains to the pick whose live state is being updated -The author is responsible for ensuring field values are only tested for picks that actually have reference picks, since global bootstraps possess no reference pick and attempts to access missing fields will report an error
-If no 'match' test is present on component bootstraps, the bootstrap is now
applied. This is a change from the previous behaviour, where it was not applied.
-The "live" tag expression of bootstraps is special for gizmos and minions
-The "live" tagexpr normally uses the reference pick that attaches bootstrap, but gizmos and minions don't have a normal reference pick -Gizmos use the pick that attaches the gizmo as a special bootstrap reference -Minions use the anchor/master pick as a special bootstrap reference -Provides a suitable target for use of "fieldval" within bootstrap tagexpr
-The timing of all bootstrap condition tests is properly factored into the
determination of the "latest" condition timing for each thing -If a bootstrap condition test occurs latest than other condition tests for a given thing, the "latest" timing for that thing uses the new timing -Ensures that the final condition test is scheduled late enough to properly incorporate the effects of all bootstrap condition tests -Ensures that any scripts scheduled to be processed earlier than bootstrap condition tests are properly flagged as a conflict during compilation
-Condition tests are not allowed for bootstraps on entities and rulesets