Skip to content

@modoki/engine / index / UIBinding

Variable: UIBinding

const UIBinding: Trait<{ highlightColor: number; highlightComponent: string; highlightProperty: string; highlightTarget: string; highlightTextColor: number; highlightValue: string; inputBinding: string; textBinding: string; visibleBinding: string; visibleOp: string; visibleValue: string; }>

UIBinding — connects UI content to Zustand store fields.

Covers text templating, two-way input, state-driven VISIBILITY, and a small "active highlight" rule. Visibility: the authored UIElement.isVisible is still the base source of truth; a visibleBinding (below) can ADDITIONALLY hide the element from a store field (both must be true), and — like a button's UIAction kind:'set' — it's a play-time effect that never reaches disk (the editor ignores it so bound elements stay authorable).

Active highlight reads the SOURCE OF TRUTH directly (no mirrored store flag): the element renders with highlightColor as its background whenever the live value of highlightComponent.highlightProperty on the entity referenced by highlightTarget (a guid) string-equals highlightValue. The canonical use is a clip-selector button that lights up while its clip is the one currently playing — highlightTarget→the animated entity, component SkeletalAnimator, property clip, value this button's clip name. Disabled when highlightColor < 0 (the default).

⚠️ REPAINT INVARIANT (the watched value must dirty the UI): the highlight re-resolves only when the UI tree rebuilds, which happens on a UI dirty signal — i.e. when the watched trait is written through setTrait/writeTraitField (these call markUIDirty) or by a UIAction kind:'set' binding. If a SYSTEM mutates the watched value via a raw entity.set/updateEach (the per-frame ECS write path, which deliberately bypasses the dirty system for performance), the highlight will NOT update until some other UI change dirties the tree. The canonical clip-selector is safe because the clip is changed via a set binding. To highlight a value a game system drives directly, that writer must call markUIDirty() after the write. (Locked by uiTreeHighlight.test.ts "does NOT re-resolve … without a dirty signal".)

Built with Modoki.