Information Access
Context: HL Kit … Basic Concepts and Terminology … Scripting Language
Overview
The goal of writing a script is to retrieve and/or manipulate one or more facets of either an actor or a visual element. Consequently, your primary focus, as an author, will be on how to access information. The Kit uses an hierarchical structure for managing all the different objects. This section of the documentation outlines the basics of how to navigate the hierarchy and access the information you need.
Script Contexts and Transitions
Every script begins with an initial "context". The context depends entirely upon the script, but the context always refers to a specific object maintained by HL, such as a pick, an actor, or a layout. For example, an Eval Script begins with an initial context of the pick that the script will be executed upon. Similarly, a Position script for a layout begins with an initial context of the layout for which the contents need to be positioned on the screen.
When you are writing a script, you will often need to retrieve information from or apply changes to objects other than the initial context your script begins with. This is accomplished by performing a "transition" to the context of a connected object within the hierarchy, thereby establishing the new object as the new context. For example, you can transition from a pick context to the context of the container that contains the pick. Or you can transition from a pick context to the context of one of its fields.
Using context transitions, you can "travel" through the hierarchy of objects (within limits), seeking out the specific objects you need to manipulate via your scripts. The exact list of what context transitions are possible is entirely dependent on the script and the current context. The specific transitions available are outlined in the Kit Reference documentation.
IMPORTANT! The initial script context resets for each separate identifier used within a script - it does not persist. This makes it easy to have a single statement access multiple different contexts by transitioning in different directions from the same initial starting point.
NOTE! It is possible to transition to an invalid (i.e. non-existent) context. For example, a script might try to transition from a container to a pick that doesn't exist within that container. If that occurs and the non-existent context is then accessed (e.g. getting the name of the non-existent pick), a run-time error will be reported and the access will fail.
Script Targets
Once you have established the final context to operate upon, you need to identify the specific facet of the context to access or manipulate. This is referred to as a "target reference", or sometimes simply "target". For example, if you have a pick context, you must specify whether you are interested in its name, its tags, or something else.
The syntax for accessing a given target aspect will vary, depending on what the target is and what information is needed to uniquely identify the desired target. All of the different target references are defined in Kit Reference documentation.
Dot Notation
In order to access or manipulate a component, your script must specify both the intended context and the target. Scripts use an open-ended dot notation to convey this information and uniquely designate a "target identifier". A target identifier represents the combination of context and target reference, which should yield a specific piece of information to operate upon. You can use valid target identifiers anywhere within scripts that you would use a simple variable, allowing you to retrieve the current value of a target identifier or set that value.
The target identifier consists of a sequence of zero or more context references, each separated by a period ('.'), and finally followed by a singe target reference. In sequence, each context reference must specify a valid context transition from the previous context. The target reference must be valid for the final context established.
Examples
Let's look at a few examples of combining context transitions with target references into a useful target identifier. For the first example, we assume we're writing an Eval Script in which we need to access the calculated bonus conferred by the "strength" ability score for the hero. Since an Eval Script starts out in the context of a pick, we'll just go directly to the hero and drill down to get the value we need. From the hero, we transition to the pick that contains the "strength" ability score. Once we have the pick, we then transition to the "bonus" field. And finally we access the value of that field. In the end, the complete reference might look like the following:
hero.child[strength].field[bonus].value
What if our hero has a magic sword from which we need to extract information? In this situation, we need to drill down into the child gizmo and then into a pick belonging to that gizmo. Starting from the root hero again, we first access the pick that attaches the gizmo. From there, we transition to the gizmo, after which we can transition to the pick inside the gizmo. Once we have the pick context, we can get the field and access its value. The final result would look something like the following:
hero.child[magicsword].gizmo.child[attack].field[bonus].value
Now let's assume we have a script on a pick within the above gizmo that needs to access a field on a different pick within the same gizmo. Theoretically, we could bounce all the way out to the hero and drill down, but that approach won't work reliably if we have multiple magic swords on the hero. So the best approach is to move upwards to the container and then back down again into the desired pick. The process would look something like the following:
container.child[attack].field[bonus].value
The key thing to remember when writing scripts is to always know your initial context. From there, simply identify where you want to reference and then systematically transition, one step at a time. If you take things one step at a time, you'll be able to access the information you need and your scripts will work smoothly.
IMPORTANT! Within certain script contexts, all target references are treated as read-only, regardless of whether they are normally writable. Any attempts to modify the contents of a target reference that has been forced to be read-only will fail to either compile or work at run-time. For example, if a Position script for a visual element attempts to modify the contents of a pick, it will be forbidden. Any script for which this behavior occurs will specify it within the Kit Reference documentation.