Skip to content

Documenting Querying in BattleScribe #45

@amis92

Description

@amis92

We need to document queries: what are legal combinations, how do they work, what are the results.

BS Nodes

The elements in BattleScribe that use queries are: condition, constraint, repeat.

These elements appear as children in other BattleScribe elements:

  • condition can be child of: modifier, modifierGroup, conditionGroup.
  • repeat can be child of: modifier, modifierGroup.
  • constraint can be child of: selectionEntry, selectionEntryGroup, entryLink, forceEntry, categoryLink in forceEntry, categoryEntry.

It's important to list all elements that can contain modifiers, since then they can also contain conditions and repeats within those modifiers. modifier can be child of:

  • all those that can have constraint (see list above)
  • profile, rule, infoGroup, infoLink.

Query components

The elements of a query are:

  • field - what is the counted value.
  • scope - where (in what subtree) are the values counted.
  • childId aka Filter By - which of the candidate entries/values do we actually process.
  • value - reference value that the query result is compared with.
  • comparison - condition and constraint uses it to compare the result with a reference value.
  • additional options: shared, value-is-percentage, include-child-selections, include-child-forces, round-up.

Known options

Field

Allowed values for a field in a Query:

  • selections - count the selections.
  • forces - count the forces.
  • specific Cost - sum cost values of the given Cost Type, looking at elements returned by the query.
  • specific Cost Limit - use roster limit of the given Cost Type (scope has to be Roster, filter is unused).

Special cases:

  • forces field allows only the following scope values: force, roster, specific force entry.
  • Cost Limit field allows only scope=roster. The field is then formatted like limit::{type-id} where {type-id} is the ID of the Cost Type.

Scope

Scope can be one of:

  • self - restricted
  • parent
  • ancestor - restricted
  • primary-category - restricted
  • force
  • roster
  • primary-catalogue
  • specific selection, category, or force entry

Special cases:

  • self is not allowed in constraints.
  • ancestor and primary-category are only allowed with comparison of (not)instance-of.
  • specific entries allowed:
    • any Category Entry
    • any Force Entry (including nested ones)
    • any Selection Entry that is ancestor of the querying constraint/modifier

Filter

Filter can be one of:

  • any (Anything) - noop.
  • unit/model/upgrade (Unit/Model/Upgrade) - all elements with specified EntryKind (type) are returned.
  • specific selection, category, or force entry

When filter has specified value:

  • any (anything) - all elements in the scope are returned.
  • EntryType (unit/model/upgrade) - all elements in the scope with specified EntryKind (type) are returned.
  • a Category Entry - all elements in the scope with specified category linked are returned.
  • a Force Entry - all elements in the scope that are instance of that entry.
  • any Selection Entry - all elements in the scope that are instance of that entry.

Special cases:

Value

  • in repeat used to divide query result into "buckets", and for each such bucket there are N repetitions of the modifier applied (N is repeats value in BS XML).
  • repeat requires a positive value.
  • in constraint used to compare using comparison operator.
  • in condition used to compare using comparison operator. If it's a instance-of kind of operator, the value is unused.

Generally, negative values work as expected. The exception here is a -1 value for a type=max constraint - in that case, it is interpreted as "infinity" or "no limit". Further modifications of the value (e.g. by Modifiers) are calculated as normal, e.g. when a constraint of -1 is modifed to increase value by 1, now the maximum is 0 so the selections are not allowed. Any other negative value (e.g. -2) is treated normally (no special behavior).

Comparison

  • repeat has none.
  • condition has all numeric comparison operators and two special ones (instance-of):
    • (not-)equal to
    • greater/less than (or equal)
    • (not-)instance of.
  • constraint has min (greater than or equal) and max (less than or equal).

Special cases:

  • when scope is ancestor or primary-category, comparison must be (not)instance-of, thus those scopes are not available for constraint and repeat.
  • (not-)instance-of value of comparison is a special case in condition queries: there's no field defined, scope defines the checked entry, and childId/filter defines the type/entry the scope should be "instance of". When filter is:
    • any (anything) - it's a noop, always satisfied.
    • EntryType (unit/model/upgrade) - the scope should have that type.
    • a Category Entry - the scope should have that category linked.
    • a Force Entry - the scope should be instance of that entry.
    • any Selection Entry - the scope should be instance of that entry.

Options

shared - the query should sum up all instances of childId/filter in scope, disregarding the selection path. BS author explainer. ❓ When is this option allowed in Data Editor UI?

value-is-percentage - the value should be interpreted as percentage, and is limited to the range [0; 100].

include-child-selections - the scope includes selection subtrees (recursive/all descendants).

include-child-forces - the scope includes force subtrees (recursive/all descendants).

round-up - used in repeat calculations, rounds the division of result by value up, instead of down as is by default.

Loose notes

  • constraint has comparison defined differently: it has type of min or max - those are equivalent to greater than or equal and less than or equal values of type in condition.
  • value can be negative for constraint and condition. Details: Documenting Querying in BattleScribe #45 (comment)
  • repeat has no comparison (type), but instead declares a number of repetitions per multiplications of reference value in query result ((result / value) * repeats).
  • constraint of max value has an interesting quirk. When an entry has a constraint of type=min scope=parent value=0, the entry is hidden in Roster Editor, as it's not allowed to be selected. As expected, using a Modifier to Set that constraint's value to -1 makes this entry selectable (unlimited) and it's correctly shown in Roster Editor. However, when using a Modifier to Decrease the value by 1 (making it 0 - 1 = -1 - unlimited), the Roster Editor does not show the entry (incorrectly?), as that entry is unlimited due to the new value of max constraint.

❓ What are other unobvious interactions?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions