59 lines
3.1 KiB
Markdown
59 lines
3.1 KiB
Markdown
# 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.
|