# SHD Talent Entry Reference ## Canonical surfaces - Talent editor: `src/routes/isac/talents/+page.svelte` - Talent action and validation: `src/routes/isac/talents/+page.server.ts` - Mechanic editor: `src/lib/components/isac/MechanicProgramEditor.svelte` - Mechanic draft types: `src/lib/calculations/mechanic-editor.ts` - Mechanic runtime and validation: `src/lib/calculations/mechanic.ts` - Mechanic persistence: `src/lib/server/conditional-effects.ts` - Supported recipes: `src/lib/calculations/mechanic-recipes.ts` - Attribute registry and actions: `src/routes/isac/attributes/` - Icon validation and persistence: `src/lib/server/game-data-icons.ts` Treat these files as the current authority. Inspect them before acting when fields or behavior may have changed. When a pictured mechanic is not representable, add the smallest reusable runtime capability and its validation, persistence, editor controls, migration, reference entry, and tests before entering the talent. A missing runtime feature is an implementation task, not a reason by itself to leave a talent under assumptions. ## Request path Prefer a direct authenticated request to the SvelteKit talent action over editor interaction: - Load or inspect `/isac/talents` to obtain current registry data and confirm the authenticated session. - Construct `FormData` from the current contract in `+page.svelte` and `+page.server.ts`. - Include the icon as the `icon` file part and the complete mechanic program as serialized `conditionalRule`. - Submit one `POST` request to `/isac/talents?/saveTalent` with an accepted SvelteKit action response type. - Parse the action result, then query the registry and audit surfaces for readback. Do not treat the action path as a public, version-stable REST API. Re-check the route implementation when it changes. Do not insert into the embedded database or call persistence utilities directly. ## Talent form The user-facing categories are: - `Weapon Talent 1` - `Weapon Talent 2` - `Backpack` - `Body Armor` Talent descriptions use one shared template. Number tier-varying outcomes as `{1}`, `{2}`, and so on in reading order. The action derives Tier I and Tier II descriptions from each outcome's variant values. ## Mechanic entry Use the `health_threshold_bands` recipe for non-stacking current-health ranges. Enter thresholds from strongest to weakest in the editor and assign one outcome to each band. Verify exact boundary behavior after saving. For the Spirited example: - Base name: `Spirited` - Tier I: 9% below 75% Health; 12% below 50%; 15% below 25% - Tier II: 12.60% below 75% Health; 16.80% below 50%; 21% below 25% - Shared template: `Grants +{1} Damage Reduction while below 75% Health. Grants +{2} Damage Reduction while below 50% Health. Grants +{3} Damage Reduction while below 25% Health.` - Attribute: `Damage Reduction`, unit `%` - Scope: self - Phase: while active - Basis: flat percentage points - Bands: `[50,75)`, `[25,50)`, and `[0,25)`; no effect at or above 75% Confirm that `Damage Reduction` already exists before creating it. Confirm the category/slot with the user before saving.