feat(ui): AttrCombobox declare vs. consume semantics

Attr-string fields in the Custom Modifier Editor now differentiate
between declare-sites (seed-attribute.attr) and consume-sites
(add-to-attribute.attr, multiply-attribute.attr, add-aura.targetAttr,
absorb-damage-with-attribute.attr):

- Consume-sites hide the illustrative 'User-defined examples' group
  (ArmorPlates/BloodStacks/ManaPool) because those names are fiction
  unless something seeds them.
- Consume-sites surface a new 'Seeded in this descriptor' group
  populated from seed-attribute primitives elsewhere in the current
  tree (including inside trigger children via childPrimitives).
- Badge states: emerald 'seeded' when the typed value matches an
  in-tree seed; red 'not seeded' when it's a non-schema name with no
  backing seed; amber 'user-defined' only in declare-mode for
  off-catalog names.

Declare-mode behaviour is unchanged — inventing ShieldCharges there
still works without warnings.
This commit is contained in:
Joey Yakimowich-Payne 2026-04-21 13:07:27 -06:00
commit 8605a22530
No known key found for this signature in database
5 changed files with 349 additions and 25 deletions

View file

@ -55,9 +55,26 @@ suggestions:
ManaPool. Illustrative names matching the recipes; invent your own.
The combobox is **free-form** — type any name and hit Enter to accept it,
even if it isn't in the list. Typed values not in the catalog get a small
`user-defined` badge so you know you're outside the schema. Numeric-context
primitives (add, multiply, aura, absorb) rank numeric suggestions first.
even if it isn't in the list. Numeric-context primitives (add, multiply,
aura, absorb) rank numeric suggestions first.
**Declare vs. consume sites.** The combobox distinguishes between
primitives that *declare* a new attribute and primitives that *consume* an
existing one:
- **`seed-attribute.attr`** is a **declare-site** — any name is fine,
including inventing brand new counters. The illustrative "User-defined
examples" group is surfaced for inspiration. Typed values outside both
the schema and the examples catalog carry an amber `user-defined` badge.
- **`add-to-attribute.attr`**, **`multiply-attribute.attr`**,
**`absorb-damage-with-attribute.attr`**, and **`add-aura.targetAttr`**
are **consume-sites** — they read an attribute that must already exist.
The illustrative examples group is **hidden** because those names are
fiction until something seeds them. Instead, a "Seeded in this
descriptor" group surfaces attrs that `seed-attribute` primitives
elsewhere in the current tree actually declare. Typed names that
aren't built-in and aren't seeded carry a red `not seeded` warning;
names that are seeded carry an emerald `seeded` confirmation.
---