feat: add source-owned combat mechanic programs

This commit is contained in:
JB
2026-07-27 13:35:00 -04:00
parent 5a67b252aa
commit 4eb754e7c8
62 changed files with 14815 additions and 905 deletions
+216 -49
View File
@@ -713,7 +713,7 @@ augmentation cell communicates that this talent advances to Tier II.
The exotic talent is owned by exactly one exotic weapon and is authored inline
inside that weapon editor, never selected from a shared global pool. Its
engineered sub-panel includes the talent name, shared description template,
Tier I/II previews, reusable triggers, and paired effect values. The Talent
Tier I/II previews, and the shared source-owned mechanic program editor. The Talent
Registry may display an owned exotic talent for discovery, but routes editing
back to its weapon rather than opening the shared-talent editor.
@@ -816,9 +816,9 @@ the base until five upgrades show exactly twice the base effect.
Diamonds are both a progression preview and an explicit numeric state; expose
their upgrade number and `aria-pressed` state rather than relying on fill color.
Protocol talents own their effects but reuse the global stat and trigger
registries. Shared secondary values do not scale with the individual protocol’s
level. Store only the unique primary and talent base values, and derive their
Protocol Talents own their mechanic programs and reuse the global Attribute
registry. Shared secondary values do not scale with the individual protocol’s
level. Store only the unique primary and Talent base values, and derive their
progression consistently in calculation and display code.
### ISAC editor lifecycle
@@ -835,16 +835,16 @@ text is operationally useful. Use compact wrapping description cells rather
than replacing meaningful data with a generic “configured” label; retain an
explicit textual missing state when a tier has no rendered description.
Talent mechanics are structured metadata, not free-form prose. Present optional
cooldown, duration, and maximum-stack inputs together in a compact three-column
mechanics strip that collapses to one column on narrow screens. Description
templates use numbered expressions (`{1}`, `{2}`) for tiered attribute effects
and named expressions (`{duration}`, `{max_stacks}`) for shared mechanics.
Named expressions are valid only when their corresponding value is defined.
Cooldown is never embedded in the description: render it consistently as
`Talent Cooldown: [value] seconds` beneath the talent identity or description.
Do not imply an absent mechanic with a zero value; show no cooldown line and
leave optional editor fields explicitly marked as not defined.
Talent mechanics are structured metadata, not free-form prose. Author
cooldowns on event branches, durations and maximum stacks on state pools, and
tier values on outcomes through `MechanicProgramEditor`. Description templates
use numbered expressions (`{1}`, `{2}`) for ordered outcomes and named
expressions (`{duration}`, `{max_stacks}`) for defined pool mechanics. Named
expressions are valid only when their corresponding value exists. Cooldown is
never embedded in the description: render it consistently as `Talent
Cooldown: [value] seconds` beneath the talent identity or description. Do not
imply an absent mechanic with a zero value; omit the cooldown line when no
branch defines one.
### Registry pagination
@@ -916,8 +916,8 @@ bookmarkable, and expose the selected state with both orange emphasis and
`aria-current`. Cards require pointer, hover, focus-visible, pressed, and
textually identifiable active states. Every card explicitly says `FILTER →`
or `SELECTED`; do not rely on KPI-card styling alone to communicate that the
metrics are controls. Counts describe the full search scope,
not merely the visible page. Replace aggregate facts that cannot filter the
metrics are controls. Counts describe the full search scope and never only the
visible page. Replace aggregate facts that cannot filter the
affected registry with actionable subsets.
### Registry row interaction
@@ -963,8 +963,8 @@ Show contributor access banners only on Data Management modules. Show the
data-mode controls and language from User Operations, System Oversight, and
System Configuration because their permissions govern access independently.
Read-only mode is an inspection surface: hide add controls, row edit actions,
mutation forms, and editors opened through URL state. Do not merely dim or
disable them. Registry navigation, KPI filters, pagination, search, evidence,
mutation forms, and editors opened through URL state. Dimming or disabling
those controls is insufficient. Registry navigation, KPI filters, pagination, search, evidence,
and other non-mutating inspection controls remain visible and interactive.
The ISAC command-status cluster includes system state, access state, the themed
@@ -1293,8 +1293,8 @@ The primary `name` field in each ISAC data editor is a 46-pixel header-level
input with larger, heavier text. It gives long registries a consistent first
reading point while keeping secondary metadata compact.
`SearchableAssignment` is the standard relationship picker for long attribute,
talent, trigger, and compatibility lists. Multiple mode manages additive sets;
`SearchableAssignment` is the standard relationship picker for long Attribute,
Talent, event, and compatibility lists. Multiple mode manages additive sets;
single mode presents the same searchable selected/result treatment for one
relationship. Prefer these modes over native selects once a source registry is
large enough that scanning a dropdown is inefficient. The selected record,
@@ -1397,10 +1397,11 @@ such as the single-exotic-weapon rule are explained rather than hidden.
Numeric instance values display their authoritative minimum and maximum beside
the field and clamp to that range on completion. Always-on item rolls, fixed
bonuses, inherited profiles, enabled augments, and activated set bonuses feed
the live totals immediately. Trigger-dependent talents remain explicitly
`CONDITIONAL` until the user enables `TRIGGER ACTIVE`; only then may their
effects enter combined totals. This textual distinction must remain clear
without relying on color.
the live totals immediately. Conditional mechanics state their calculation
mode and readiness. Maximum Potential uses their best-case state; Custom
Scenario uses the source-defined advanced assumptions saved with the loadout.
Exclude a mechanic that lacks a required assumption and label it `REQUIRES
ASSUMPTIONS`. This distinction must remain clear without relying on color.
### Pending ISAC registry records
@@ -1844,23 +1845,165 @@ positive whole-number quantities for Rank 2. Rank 3 uses the yellow High-end
Omega treatment and exactly one component. Color is supporting hierarchy;
quality names and quantities always remain visible.
### Conditional combat modeling
### Source-owned mechanic program editor
ISAC authors define a combat effect once per Specialization and attach it to
one or more tree-node ranks. Each rank attachment owns its hit trigger, stack
duration, stack limit, and Attribute modifiers. Keep the lifecycle rules in a
compact fact rail: trigger counters reset after a proc, each stack gain refreshes
the timer, and expiry clears the complete stack. The shared definition provides
one effect name and description to every attached rank.
Use `MechanicProgramEditor` for every calculation-ready standard or exotic
Talent, OS Protocol Talent, Skill Chip Talent, and Specialization tree-rank
effect. The program stays inside its owning source editor and contribution
payload. Do not create a standalone Trigger registry, Trigger assignment
control, or shared Trigger lifecycle.
Use `--shd-model-surface` and `--shd-model-border` for conditional mechanics,
Each source supplies the value columns required by its progression:
- Standard and exotic Talents show Tier I and Tier II.
- OS Protocol Talents show a base value and may scale an outcome through the
protocol's zero-to-five upgrade expression.
- Skill Chip Talents show minimum and maximum values.
- Specialization tree ranks show the rank's base value.
The editor is one layered control surface. Start with a compact program heading
and the explicit `READY`, `REQUIRES ASSUMPTIONS`, or `CAPTURED ONLY` state.
Follow it with Builder Controls, Recipe Starter, State Pools, ordered event
branches, ordered outcomes, and the generated read-only script. Use connected
panels and restrained borders to preserve the hierarchy; do not present the
typed graph as an undifferentiated form.
The direct-event picker reads the 19 normalized events from the code-defined
event registry. Use searchable single-assignment because the vocabulary exceeds
the compact segmented-choice limit. Each branch presents its event, match
policy and parameters, optional cooldown, state mutations, and outcomes.
Recipe-generated predicates and weights remain visible in the generated
script. State rows expose label, agent or target scope, initial value, bounds,
best-case value, and optional expiry. Outcome rows expose kind, target scope,
Attribute or resource when applicable, value basis, state scaling, phase, and
every source-specific value column. The Value Model control supports static
values, event fields, reducer output, source-defined scenario controls, and OS
Protocol upgrade scaling where the source permits it.
Action Family recipes are optional authoring starters. Present the recipe
catalog as a searchable assignment with only the parameters required by the
selected family. `ADD RECIPE BRANCH` copies typed branches into the current
source program, where authors may edit its exposed branch, state, and outcome
controls. The recipe label records provenance only. `REPLACE PROGRAM` requires
an inline confirmation that states all existing branches will be discarded.
Builder Controls define source-specific advanced scenario assumptions. Authors
choose toggle, slider, or numeric input and provide a label, Agent guidance,
default value, best-case value, and numeric bounds when applicable. Group these
controls behind the builder's advanced scenario surface. Maximum Potential
uses best-case values. Custom Scenario uses saved Agent values. A required
cadence or environmental value with no supplied assumption keeps the mechanic
out of the calculation and displays `REQUIRES ASSUMPTIONS`; the editor and
runtime never invent a cadence.
Use `--shd-model-surface` and `--shd-model-border` for mechanic programs,
calculation revisions, and field calibration. The blue information rail marks
modeled behavior. Orange remains reserved for selection and activation. Every
effect card names its trigger, duration, maximum stacks, and value per stack in
text so the mechanic remains clear without color.
modeled behavior. Orange remains reserved for selection and activation. Name
events, branches, state, cooldowns, durations, stack limits, outcomes, phases,
and per-stack values in text so the model remains legible without color.
The loadout builder gives each unlocked conditional effect three calculation
modes:
At narrow widths, stack panels, branch controls, state rows, variant columns,
and outcomes without changing their order. Keep add, remove, replace, and help
controls at least 44 pixels tall. Every disclosure and confirmation exposes
its state to assistive technology. Focus remains in the active field when the
generated script refreshes, and reduced-motion preferences remove expansion
and replacement transitions.
#### Generated mechanic script
The shared `PseudoScript` component gives authors and builders a readable
transcription of the typed mechanic or combat calculation. The typed event,
predicate, reducer, state-pool, outcome, and calculation-stage data remain
authoritative. The interface generates the script from that data; authors do
not edit or execute the displayed text.
Render generated script on `--shd-model-surface` with
`--shd-model-border`, a blue information rail, restrained green syntax
keywords, line numbers, and the shared monospaced typeface. Give the panel an
explicit `GENERATED SCRIPT · READ ONLY` label and show its calculation
readiness in text. Reserve orange for adjacent actions and selected controls.
Do not style the panel as an editable textarea or show a caret, resize handle,
or save action.
Use semantic code content inside the panel. Treat line numbers as structural
decoration and ensure assistive technology reads each statement once. Preserve
indentation and keep type at the telemetry floor. Long statements may wrap at
token boundaries or use horizontal scrolling on narrow widths. Keep the panel
within its parent grid with `min-width: 0`. Script regeneration must not move
focus or announce the complete script after each field change. Place validation
and readiness messages beside the panel with ordinary status semantics.
Use the shared `MechanicLanguageHelp` control wherever an author can configure
mechanics or calculation stages. The compact `SCRIPT REFERENCE` button opens a
native help dialog with syntax, event, timing, state, and outcome references.
Long registry-level references may use a labeled disclosure with the same
content. The help trigger remains near the generated preview so authors do not
need to leave the editor to interpret it. Point every full-reference action to
`/isac/mechanic-reference`, with a stable section anchor when the source has a
specific topic. Do not point full-reference actions to collapsed same-page
anchors.
Help triggers and disclosure summaries use native button semantics,
focus-visible treatment, and explicit expanded or dialog state. Opening a
dialog moves focus to its close control; Escape and the close action dismiss
it and return focus to the trigger. On mobile, the dialog fits the viewport,
scrolls its body, and keeps its close action available. Reduced-motion
preferences remove dialog and disclosure transitions. Syntax color and motion
never carry meaning without text.
#### Mechanic reference surface
`/isac/mechanic-reference` is the dedicated read surface for the mechanic and
combat-calculation languages. It contains no mutation controls. Give the page a
compact section index beside the reference body and keep that index sticky when
the available width and viewport height support it. Assign a stable heading
anchor to each major section so editor dialogs can link to the relevant
definition.
Present bounded syntax, state, phase, outcome, and calculation-stage
vocabularies as connected reference matrices with shared borders and aligned
columns. Generate the 19-event registry and Action Family recipe catalog from
code-defined metadata so the reference matches the available editor controls.
Explain that events are runtime contracts and recipes only seed editable source
branches. Pair complex mechanics with a worked `PseudoScript` example. Keep
labels and descriptions visible; color, abbreviations, and script keywords
cannot carry the explanation alone.
Include a live-searchable Attribute variable glossary sourced from the active
ISAC Attribute registry. Search matches Attribute names, stored descriptions,
types, categories, calculation types, units, source ranges, and caps. Display
each stored Attribute description verbatim. Show type, category, calculation
type, unit, applicable Gear, Weapon, and Skill Chip ranges, and optional cap as
supporting metadata. Mark a missing description as `DOCUMENTATION NEEDED` and
link authorized authors to the Attribute record; do not generate substitute
copy. Search operates on the full active glossary before any result limit and
keeps its visible label, clear action, keyboard focus, and textual result count.
Section-index links and anchored headings use visible keyboard focus. In-page
navigation must place the target below the application header. At narrow
widths, move the index into document flow above the content and stack reference
sections in one column. Allow connected matrices to scroll within their own
boundaries, and prevent horizontal page overflow. Reduced-motion preferences
remove smooth anchor scrolling and sticky-state transitions.
#### Builder calculation modes
The loadout builder places one required two-option `SegmentedChoice` above
combat assumptions. The persisted `maximum` and `custom` values use these
visible labels:
- `MAXIMUM POTENTIAL` calculates a configured ceiling. It applies conditional
effects at peak state and treats selected abilities as firing on cooldown
against their maximum configured target count.
- `CUSTOM SCENARIO` exposes encounter assumptions and source-defined advanced
controls for a player-defined scenario.
New loadouts select `MAXIMUM POTENTIAL`. The interface labels Maximum results
as a modeled ceiling so players do not read them as typical encounter
performance. Maximum hides granular assumption fields without deleting their
saved values. Returning to Custom restores those values.
Custom mode gives each unlocked conditional effect three state controls:
- `OFF` excludes the effect.
- `PEAK` applies its configured maximum stacks.
@@ -1868,17 +2011,27 @@ modes:
reload time, hit rate, firing activity, and encounter duration.
Users may override encounter assumptions on one effect without changing the
global combat profile. The effect card shows the applied stack state beside the
mode. On mobile, assumption fields and effect controls stack into full-width
44-pixel targets.
global Custom profile. Open the advanced scenario surface to show only the
toggle, slider, and numeric controls defined by that effect's owning source.
The effect card shows uptime, activation count, and applied stack state beside
the mode. A mechanic that needs an undefined cadence or another missing
scenario input displays `REQUIRES ASSUMPTIONS`; the builder withholds its
calculated contribution until the author or player supplies that input.
Maximum and Custom use radio semantics, an explicit selected label, keyboard
arrow navigation, and the standard orange selected rail. Results repeat the
active calculation mode in text. On mobile, the global mode control and Custom
assumption fields stack into full-width targets of at least 44 pixels.
Mode changes use the standard pressed feedback; reduced-motion preferences
remove transitions without hiding the state change.
Combat result panels show normal, critical, headshot, and critical-headshot
values with burst, sustained, and encounter DPS. Conditional stack telemetry
lists the mode, average and peak stacks, ending stacks, buildup time, and
maintained state that produced the result. A result with missing equipment,
Attribute bindings, rules, or assumptions displays `INSUFFICIENT DATA` and a
concrete remediation list. The interface withholds combat numbers until it has
the required inputs.
lists the mode, uptime, activations, average and peak stacks, ending stacks,
buildup time, and maintained state. A result with missing equipment, Attribute
bindings, rules, or assumptions displays `INSUFFICIENT DATA` and a concrete
remediation list. The interface withholds combat numbers until it has the
required inputs.
### Specialization loadout composer
@@ -1893,10 +2046,16 @@ ranks remain visible with their lock state. The builder permits a row after the
user buys every available Rank 1 and Rank 2 in preceding rows and enforces the
49-point limit. Cost telemetry lists Credits and components beside each rank.
Saved loadouts store focus, node ranks, nine Skill Chips, effect modes, and
combat assumptions. The builder accepts only the current complete structure.
Invalid local drafts are discarded; invalid server records are unavailable and
removed through a backed-up database migration.
Each ability panel exposes one compact activation control: Off, On Cooldown, or
Custom Rate. Custom Rate adds uses per minute. Every enabled
ability has its own target count. Skill result cards show the ability name,
activation count, single-target DPS, total-target DPS, and a combined summary.
They state that Skills can critically hit and multi-shot but cannot headshot.
Saved loadouts store focus, node ranks, nine Skill Chips, conditional modes,
encounter assumptions, and per-ability activation profiles. The builder accepts
only the current complete structure. Invalid local drafts are discarded;
invalid server records are removed through a backed-up database migration.
### Calculation revision controls
@@ -1906,6 +2065,14 @@ requires `calculation.publish`, an explicit review state, and a confirmation
that saved builds will recalculate. Successful activation closes the
confirmation surface and records the revision in the audit history.
Keep weapon and Skill Attribute profiles in separate compact registries inside
the same revision editor. A Skill profile shows the Attribute, one of the
bounded Skill stages, Add or Multiply, and its weight. Use searchable
assignment for the ten-stage vocabulary and a segmented control for the
two-value operator. Reject duplicate Attribute and stage pairs. Revision
cloning, proposal review, publication evidence, and audit snapshots must
include both profile registries.
Calibration cases pair a loadout snapshot with measured hit and timing values.
Ready cases require the four hit values, magazine time, and reload time.
Assisted suggestions create a draft revision for review and leave activation