Adding skills & isac talent updates
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import type { AiMechanicAuthoringRequest } from '$lib/ai/mechanic-authoring';
|
||||
import { CONDITIONAL_MECHANIC_OUTCOME_CAPABILITIES } from '$lib/calculations/mechanic-editor';
|
||||
import { MECHANIC_COMBAT_REFERENCE_REGISTRY } from '$lib/calculations/mechanic';
|
||||
import type { AiMechanicAttribute } from './mechanic-authoring-context';
|
||||
|
||||
export const AI_MECHANIC_PROMPT_VERSION = 5;
|
||||
export const AI_MECHANIC_PROMPT_VERSION = 6;
|
||||
|
||||
const mechanicsGrammar = {
|
||||
version: 1,
|
||||
@@ -17,9 +18,9 @@ const mechanicsGrammar = {
|
||||
required: ['key', 'label', 'stateKind', 'scope', 'initial'],
|
||||
stateKind: ['flag', 'count', 'stack', 'duration', 'scalar', 'target_mark', 'resource'],
|
||||
scope: ['agent', 'target'],
|
||||
optional: ['min', 'max', 'bestCaseValue', 'expiresAfterSeconds'],
|
||||
optional: ['min', 'max', 'bestCaseValue', 'expiresAfterSeconds', 'expiresAfterSecondsVariants'],
|
||||
expirationSemantics:
|
||||
'expiresAfterSeconds is one timer per pool entity. Every write resets that entity timer, and expiry resets only that entity to the pool initial value.',
|
||||
'expiresAfterSeconds is one timer per pool entity. Use expiresAfterSecondsVariants instead when each source variant has a different duration; define every requested variant exactly once. Every write resets that entity timer, and expiry resets only that entity to the pool initial value.',
|
||||
targetScopeSemantics:
|
||||
'A target-scoped pool stores one independent value and expiry timer per resolved entity. Use mutation.entity event_target when a weapon-hit mechanic binds state to the enemy that was hit.'
|
||||
},
|
||||
@@ -43,11 +44,13 @@ const mechanicsGrammar = {
|
||||
mutationKinds: ['none', 'add', 'set', 'consume', 'derive', 'clear', 'transfer'],
|
||||
entitySelectors: ['agent', 'event_actor', 'event_target', 'event_field'],
|
||||
valueReferences: ['event', 'scenario', 'combat', 'equipment', 'attribute', 'reducer', 'pool'],
|
||||
numericExpressionOperators: ['add', 'subtract', 'multiply', 'divide', 'min', 'max', 'clamp'],
|
||||
combatReferences: MECHANIC_COMBAT_REFERENCE_REGISTRY,
|
||||
numericExpressionOperators: ['add', 'subtract', 'multiply', 'divide', 'min', 'max', 'clamp', 'floor'],
|
||||
referenceShapes: [
|
||||
{ ref: { source: 'event', path: 'values.distanceMeters' } },
|
||||
{ ref: { source: 'scenario', key: 'input-key' } },
|
||||
{ ref: { source: 'combat', path: 'currentHealth', timing: 'current' } },
|
||||
{ ref: { source: 'combat', path: 'currentHealthPercent', timing: 'current' } },
|
||||
{ ref: { source: 'equipment', path: 'protocolTalentUpgrades' } },
|
||||
{ ref: { source: 'attribute', attributeId: 'replace-with-an-exact-catalog-attribute-id' } },
|
||||
{ ref: { source: 'reducer' } },
|
||||
@@ -56,7 +59,8 @@ const mechanicsGrammar = {
|
||||
expressionShapes: [
|
||||
{ op: 'multiply', left: 3, right: { ref: { source: 'pool', pool: 'stacks' } } },
|
||||
{ op: 'min', left: { ref: { source: 'reducer' } }, right: 5 },
|
||||
{ op: 'clamp', value: { ref: { source: 'event', path: 'values.enemyCount' } }, min: 0, max: 5 }
|
||||
{ op: 'clamp', value: { ref: { source: 'event', path: 'values.enemyCount' } }, min: 0, max: 5 },
|
||||
{ op: 'floor', value: { op: 'divide', left: { ref: { source: 'event', path: 'values.distanceMeters' } }, right: 5 } }
|
||||
],
|
||||
predicateShapes: [
|
||||
{ kind: 'true' },
|
||||
@@ -339,6 +343,8 @@ export function buildAiMechanicAuthoringInput(input: {
|
||||
'Percent values use the numeric percentage shown in game, such as 3 for +3%, rather than 0.03.',
|
||||
'Live Attribute references must use {source:"attribute",attributeId:"<exact supplied catalog ID>"}. Never use an Attribute name or invent an ID.',
|
||||
'An Attribute whose catalog unit is % resolves to its displayed percentage number, such as 20 for 20%. Divide that reference by 100 when wording applies it as a percentage multiplier, such as 240 × 20%.',
|
||||
'combat.currentHealthPercent with timing:"current" resolves authoritative current Health divided by resolved maximum Health on a 0–100 scale. Use operator:"lt" for exact “below” wording.',
|
||||
'Health threshold bands must be mutually exclusive. For thresholds 25, 50, and 75, use <25, >=25 and <50, and >=50 and <75; exact threshold values enter the next weaker band.',
|
||||
'Continuous Health restoration is supported. Use kind:"restoration", resource:"health", delivery:"continuous", and a positive durationSeconds. The variant expression resolves the total restoration across that duration, not a per-second value. Do not replace continuous delivery with a periodic reducer.',
|
||||
'Each continuous-restoration activation creates an independent constant-rate stream. Overlapping streams add, and restoration above the resource maximum is lost when it occurs.',
|
||||
'A target-scoped pool owns an independent value and expiry timer for each entity. Bind hit-created target state with entity:{kind:"event_target"}; do not collapse different enemies into one Agent-scoped pool.',
|
||||
|
||||
Reference in New Issue
Block a user