-
Notifications
You must be signed in to change notification settings - Fork 25
Description
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:
conditioncan be child of:modifier,modifierGroup,conditionGroup.repeatcan be child of:modifier,modifierGroup.constraintcan be child of:selectionEntry,selectionEntryGroup,entryLink,forceEntry,categoryLinkinforceEntry,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.childIdaka Filter By - which of the candidate entries/values do we actually process.value- reference value that the query result is compared with.comparison-conditionandconstraintuses it to compare the result with a referencevalue.- 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 (
scopehas to be Roster,filteris unused).
Special cases:
forcesfield allows only the followingscopevalues:force,roster, specific force entry.- Cost Limit field allows only
scope=roster. Thefieldis then formatted likelimit::{type-id}where{type-id}is the ID of the Cost Type.
Scope
Scope can be one of:
self- restrictedparentancestor- restrictedprimary-category- restrictedforcerosterprimary-catalogue- specific selection, category, or force entry
Special cases:
selfis not allowed inconstraints.ancestorandprimary-categoryare only allowed withcomparisonof(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 thescopeare returned.- EntryType (unit/model/upgrade) - all elements in the
scopewith specified EntryKind (type) are returned. - a Category Entry - all elements in the
scopewith specified category linked are returned. - a Force Entry - all elements in the
scopethat are instance of that entry. - any Selection Entry - all elements in the
scopethat are instance of that entry.
Special cases:
childId/filterinconstraintis disabled. It is implicitly the constraint's parent entry.- complete reference of what is allowed when: Documenting Querying in BattleScribe #45 (comment)
Value
- in
repeatused to divide query result into "buckets", and for each such bucket there are N repetitions of the modifier applied (N isrepeatsvalue in BS XML). repeatrequires a positivevalue.- in
constraintused to compare usingcomparisonoperator. - in
conditionused to compare usingcomparisonoperator. If it's ainstance-ofkind of operator, thevalueis 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
repeathas none.conditionhas all numeric comparison operators and two special ones (instance-of):(not-)equal togreater/less than (or equal)(not-)instance of.
constrainthasmin(greater than or equal) andmax(less than or equal).
Special cases:
- when
scopeisancestororprimary-category,comparisonmust be(not)instance-of, thus those scopes are not available forconstraintandrepeat. (not-)instance-ofvalue ofcomparisonis a special case inconditionqueries: there's nofielddefined,scopedefines the checked entry, andchildId/filterdefines the type/entry thescopeshould be "instance of". Whenfilteris:any(anything) - it's a noop, always satisfied.- EntryType (unit/model/upgrade) - the
scopeshould have that type. - a Category Entry - the
scopeshould have that category linked. - a Force Entry - the
scopeshould be instance of that entry. - any Selection Entry - the
scopeshould 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
constrainthascomparisondefined differently: it hastypeofminormax- those are equivalent togreater than or equalandless than or equalvalues oftypeincondition.valuecan be negative forconstraintandcondition. Details: Documenting Querying in BattleScribe #45 (comment)repeathas nocomparison(type), but instead declares a number of repetitions per multiplications of referencevaluein query result ((result / value) * repeats).constraintofmaxvalue 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 it0 - 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?