Support target-scoped trauma mechanics

This commit is contained in:
JB
2026-07-27 22:20:52 -04:00
parent 7e78d75f85
commit 0b3be3587b
20 changed files with 1032 additions and 93 deletions
@@ -88,7 +88,7 @@
];
const mutations = [
{ syntax: 'ADD value TO pool', use: 'Increases state, respecting the pool maximum.' },
{ syntax: 'ADD value TO pool FOR EVENT TARGET', use: 'Increases one enemy’s target-scoped state, respecting the pool maximum.' },
{ syntax: 'SET value AS pool', use: 'Replaces the current pool value.' },
{ syntax: 'CONSUME value FROM pool', use: 'Spends available state without falling below the pool minimum.' },
{ syntax: 'CLEAR pool', use: 'Resets the selected state pool.' },
@@ -99,7 +99,7 @@
{ syntax: 'ON_EVENT', use: 'Applies against combat state as the event arrives.' },
{ syntax: 'AFTER_EVENT', use: 'Applies after branch mutations and resource costs.' },
{ syntax: 'ON_ENTER', use: 'Applies when tracked state enters an active range.' },
{ syntax: 'ON_EXIT', use: 'Applies when tracked state leaves an active range.' },
{ syntax: 'ON_EXIT', use: 'Applies when tracked state leaves an active range, using its final pre-exit value for stack thresholds and scaling.' },
{ syntax: 'WHILE_ACTIVE', use: 'Remains active while the referenced state satisfies its stack range.' }
];
@@ -155,6 +155,22 @@
'ON_EVENT: APPLY 2 CURRENT_HEALTH_PERCENT // Health cost',
'AFTER_EVENT: APPLY (0.6 * (1 + (EQUIPMENT.protocolTalentUpgrades / 5))) CURRENT_HEALTH_PERCENT USING CURRENT HEALTH // Additional damage'
];
const preciseTrauma = [
'MECHANIC PRECISE TRAUMA',
'STATE trauma [TARGET] 0..10; EXPIRES 1s AFTER WRITE',
'',
'WHEN WEAPON HIT // Body shot',
'IF EVENT.targetId EXISTS AND EVENT.values.headshot == false',
'ADD 1 TO trauma FOR EVENT TARGET',
'',
'WHEN WEAPON HIT // Headshot',
'IF EVENT.targetId EXISTS AND EVENT.values.headshot == true',
'ADD 2 TO trauma FOR EVENT TARGET',
'',
'WHEN SIMULATION TICK // Shared refreshed expiry',
'ON_EXIT: APPLY (1 * ATTRIBUTE[skill-damage-id]) FLAT DIRECT_DAMAGE PER STACK TO EVENT TARGET'
];
</script>
<svelte:head>
@@ -210,6 +226,13 @@
<article>
<div><strong>{event.label}</strong><code>{event.key}</code></div>
<p>{event.description}</p>
{#if event.fields?.length}
<ul aria-label={`${event.label} typed fields`}>
{#each event.fields as field}
<li><code>{field.path}</code><span>{field.label} · {field.type.toUpperCase()}</span></li>
{/each}
</ul>
{/if}
</article>
{/each}
</div>
@@ -318,7 +341,7 @@
</div>
<aside class="contract">
<strong>EXPIRY CONTRACT</strong>
<span>A pool can expire after its last write. A new stack refreshes that timer when the mechanic defines refresh-on-write behavior.</span>
<span>A pool can expire after its last write. Each write refreshes its timer. Target pools maintain independent values and timers for each bound enemy.</span>
</aside>
</section>
@@ -376,6 +399,10 @@
<section id="examples" class="reference-section examples-section">
<header><div><span>10</span><h3>WORKED MECHANICS</h3></div></header>
<div class="example-intro">
<div>
<h4>PRECISE TRAUMA</h4>
<p>Body shots add one target-bound stack and headshots add two. Each hit refreshes that enemy’s shared one-second expiry; the expiry deals one live Skill Damage value per final stack.</p>
</div>
<div>
<h4>SUPERIOR FIREPOWER</h4>
<p>Nine hits on one target add a Relentless stack. Each write refreshes the ten-second pool timer.</p>
@@ -386,6 +413,7 @@
</div>
</div>
<div class="example-scripts">
<PseudoScript title="PRECISE TRAUMA · GENERATED EXAMPLE" lines={preciseTrauma} readiness="READY" />
<PseudoScript title="SUPERIOR FIREPOWER · GENERATED EXAMPLE" lines={superiorFirepower} readiness="READY" />
<PseudoScript title="HAPPY SURVIVAL · GENERATED EXAMPLE" lines={happySurvival} readiness="REQUIRES ASSUMPTIONS" />
</div>
@@ -652,6 +680,25 @@
line-height: 1.45;
}
.event-registry ul {
display: grid;
gap: 4px;
margin: 2px 0 0;
padding: 0;
list-style: none;
}
.event-registry li {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
gap: 6px;
padding-top: 5px;
border-top: 1px solid var(--shd-border-soft);
color: var(--shd-text-muted);
font-size: var(--shd-type-telemetry);
}
.action-registry {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
@@ -937,7 +984,7 @@
.example-scripts {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 8px;
padding: 0 12px 12px;
}