Skip to content

Commit 5c2661e

Browse files
committed
Update docs with CustomParameters input
1 parent 7782c5b commit 5c2661e

5 files changed

Lines changed: 120 additions & 2 deletions

File tree

docs/statescript/nodes/action/execute-cue-node.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Executes one or more one-shot cues (`CuesManager.ExecuteCue`) on one or more tar
3030
| 2 | Magnitude | `int` | Optional. Cue magnitude. |
3131
| 3 | Normalized Magnitude | `float` | Optional. Cue magnitude normalized to 0–1. |
3232
| 4 | Source | `IForgeEntity` | Optional. The source entity carried in the cue parameters. |
33+
| 5 | Custom Parameters | `Dictionary<StringKey, object>` | Optional. Custom parameter bag built by an `ICueCustomParametersProvider` (see [CueCustomParametersResolver](../../resolvers/cue-custom-parameters-resolver.md)). |
3334

3435
This node has no output variables, cues are addressed entirely by tag.
3536

@@ -38,7 +39,7 @@ This node has no output variables, cues are addressed entirely by tag.
3839
1. The node resolves the **Cue Tags** input as a single `Tag` or an array of tags.
3940
2. It resolves the **Target** input as a single `IForgeEntity` or an array of entities.
4041
3. It fires every cue tag on every target, forming a full `cueTag[] x target[]` matrix. Each cue is executed through that target's `IForgeEntity.CuesManager`.
41-
4. The optional **Magnitude**, **Normalized Magnitude**, and **Source** inputs are resolved once and shared across the matrix. When all three are unbound, the cues are executed with `null` parameters; otherwise a `CueParameters` is built from the resolved values (unbound fields default to `0` / `0` / `null`).
42+
4. The optional **Magnitude**, **Normalized Magnitude**, **Source**, and **Custom Parameters** inputs are resolved once and shared across the matrix. When all are unbound, the cues are executed with `null` parameters; otherwise a `CueParameters` is built from the resolved values (unbound fields default to `0` / `0` / `null` / `null`).
4243
5. The output port emits after all cues are fired.
4344

4445
## Usage
@@ -64,3 +65,4 @@ executeCue.BindInput(ExecuteCueNode.MagnitudeInput, "magnitude");
6465
- [Action Nodes Overview](README.md)
6566
- [UpdateCueNode](update-cue-node.md)
6667
- [CueNode](../state/cue-node.md)
68+
- [CueCustomParametersResolver](../../resolvers/cue-custom-parameters-resolver.md)

docs/statescript/nodes/action/update-cue-node.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Updates one or more already-active cues (`CuesManager.UpdateCue`) on one or more
3030
| 2 | Magnitude | `int` | Optional. Cue magnitude. |
3131
| 3 | Normalized Magnitude | `float` | Optional. Cue magnitude normalized to 0–1. |
3232
| 4 | Source | `IForgeEntity` | Optional. The source entity carried in the cue parameters. |
33+
| 5 | Custom Parameters | `Dictionary<StringKey, object>` | Optional. Custom parameter bag built by an `ICueCustomParametersProvider` (see [CueCustomParametersResolver](../../resolvers/cue-custom-parameters-resolver.md)). |
3334

3435
This node has no output variables, cues are addressed entirely by tag.
3536

@@ -55,3 +56,4 @@ updateCue.BindInput(UpdateCueNode.MagnitudeInput, "charge");
5556
- [Action Nodes Overview](README.md)
5657
- [ExecuteCueNode](execute-cue-node.md)
5758
- [CueNode](../state/cue-node.md)
59+
- [CueCustomParametersResolver](../../resolvers/cue-custom-parameters-resolver.md)

docs/statescript/nodes/state/cue-node.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ Applies one or more persistent cues (`CuesManager.ApplyCue`) on activation and r
3535
| 2 | Magnitude | `int` | Optional. Cue magnitude for the apply. |
3636
| 3 | Normalized Magnitude | `float` | Optional. Cue magnitude normalized to 0–1. |
3737
| 4 | Source | `IForgeEntity` | Optional. The source entity carried in the cue parameters. |
38+
| 5 | Custom Parameters | `Dictionary<StringKey, object>` | Optional. Custom parameter bag built by an `ICueCustomParametersProvider` (see [CueCustomParametersResolver](../../resolvers/cue-custom-parameters-resolver.md)). |
3839

3940
This node has no output variables, cues are addressed entirely by tag.
4041

4142
## Behavior
4243

43-
1. On activation, the node resolves the **Cue Tags** and **Target** inputs (single or array each) and applies every cue tag to every target, the full `cueTag[] x target[]` matrix, through each target's `IForgeEntity.CuesManager`. The optional **Magnitude** / **Normalized Magnitude** / **Source** inputs are resolved once and shared (`null` parameters when all are unbound).
44+
1. On activation, the node resolves the **Cue Tags** and **Target** inputs (single or array each) and applies every cue tag to every target, the full `cueTag[] x target[]` matrix, through each target's `IForgeEntity.CuesManager`. The optional **Magnitude** / **Normalized Magnitude** / **Source** / **Custom Parameters** inputs are resolved once and shared (`null` parameters when all are unbound).
4445
2. The exact cue/target pairs applied on activation are recorded in `CueNodeContext`.
4546
3. The node has **no timer**: it stays active until deactivated externally. It is typically placed as a subgraph of another state node so it lives for that state's duration.
4647
4. On deactivation, the node removes exactly the recorded cue/target pairs. Whether the removal is an interruption is derived from how the node was deactivated: a natural shutdown (parent subgraph ending or `GraphProcessor.StopGraph`) passes `interrupted: false`, while a deactivation forced through the **Abort** port passes `interrupted: true`. No interrupt input is needed.
@@ -63,3 +64,4 @@ Place the node as a subgraph of another state node so it lives for that state's
6364
- [State Nodes Overview](README.md)
6465
- [ExecuteCueNode](../action/execute-cue-node.md)
6566
- [UpdateCueNode](../action/update-cue-node.md)
67+
- [CueCustomParametersResolver](../../resolvers/cue-custom-parameters-resolver.md)

docs/statescript/resolvers/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ These resolvers provide effect instances and application context to nodes such a
3838

3939
---
4040

41+
## Cue Resolvers
42+
43+
These resolvers author the optional inputs of the cue nodes (`ExecuteCueNode`, `UpdateCueNode`, `CueNode`).
44+
45+
| Resolver | Output Type | Description |
46+
|----------|-------------|-------------|
47+
| [CueCustomParametersResolver](cue-custom-parameters-resolver.md) | `Dictionary<StringKey, object>` | Produces the `CueParameters.CustomParameters` bag for a cue via an `ICueCustomParametersProvider`. |
48+
49+
---
50+
4151
## Entity Resolvers
4252

4353
Entity resolvers are typed object-backed resolvers used by APIs such as `AttributeResolver` and `TagQueryResolver`. They do
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# CueCustomParametersResolver
2+
3+
> **Type:** `Gamesmiths.Forge.Statescript.Properties.CueCustomParametersResolver`
4+
> **Output Type:** `Dictionary<StringKey, object>`
5+
6+
Produces the custom parameter bag attached to a cue's `CueParameters.CustomParameters` when a graph fires a cue. It delegates to an `ICueCustomParametersProvider`, which builds a dictionary keyed by `StringKey` from the current graph state. Bind it to the optional **Custom Parameters** input of [ExecuteCueNode](../nodes/action/execute-cue-node.md), [UpdateCueNode](../nodes/action/update-cue-node.md), and [CueNode](../nodes/state/cue-node.md).
7+
8+
A cue handler then reads the values back by key from the `CueParameters` it receives. This is the cue-side analog of [EffectContextDataResolver](effect-context-data-resolver.md): instead of producing an `EffectApplicationContext` for the effect pipeline, it produces the parameter dictionary the cue handler consumes.
9+
10+
## Constructor
11+
12+
```csharp
13+
new CueCustomParametersResolver(provider)
14+
```
15+
16+
| Parameter | Type | Description |
17+
|-----------|------|-------------|
18+
| provider | `ICueCustomParametersProvider` | The provider that builds the custom parameter bag from the graph state. |
19+
20+
## Defining a provider
21+
22+
Derive from `CueCustomParametersProvider` and override `CreateCustomParameters`. Return a `Dictionary<StringKey, object>` whose keys are whatever your cue handler reads back.
23+
24+
```csharp
25+
public sealed class DamageCueParametersProvider : CueCustomParametersProvider
26+
{
27+
public override Dictionary<StringKey, object> CreateCustomParameters(
28+
GraphContext graphContext,
29+
CueCustomParameterInputs inputs)
30+
{
31+
graphContext.TryResolve("damage", out int damage);
32+
graphContext.TryResolve("isCritical", out bool isCritical);
33+
34+
return new Dictionary<StringKey, object>
35+
{
36+
["damage"] = damage,
37+
["isCritical"] = isCritical,
38+
};
39+
}
40+
}
41+
```
42+
43+
The same keys are then available in the cue handler:
44+
45+
```csharp
46+
public void OnExecute(IForgeEntity? target, CueParameters? parameters)
47+
{
48+
if (parameters?.CustomParameters is { } custom && custom.TryGetValue("damage", out object? damage))
49+
{
50+
var amount = (int)damage;
51+
// ...
52+
}
53+
}
54+
```
55+
56+
## Declaring authored inputs
57+
58+
Instead of reading values from named graph variables, a provider can declare **inputs** that the graph editor renders as nested resolvers directly on the node's Custom Parameters section. Override `Inputs` and read the resolved values from the `CueCustomParameterInputs` bag:
59+
60+
```csharp
61+
public sealed class StrengthCueParametersProvider : CueCustomParametersProvider
62+
{
63+
public override IReadOnlyList<CueCustomParameterInput> Inputs =>
64+
[new CueCustomParameterInput("Strength", typeof(int))];
65+
66+
public override Dictionary<StringKey, object> CreateCustomParameters(
67+
GraphContext graphContext,
68+
CueCustomParameterInputs inputs)
69+
{
70+
return new Dictionary<StringKey, object> { ["strength"] = inputs.Get<int>("Strength") };
71+
}
72+
}
73+
```
74+
75+
Each declared input renders its own resolver dropdown (constant, variable, activation data, math, ...) in the editor, so a designer can author the value without touching graph variables. `CueCustomParameterInputs.Get<T>` reads the resolved value (`default` when no resolver is bound); declared input value types must be supported by `Variant128`. The same `Name` is used both as the editor label and as the key passed to `Get<T>`. A provider that needs object-lane values (entities, tags) is not limited by this: it can read them directly from `graphContext` and box them into the bag.
76+
77+
## Behavior
78+
79+
- On each resolve, calls `provider.CreateCustomParameters(graphContext, inputs)`, which builds a fresh dictionary. Declared inputs are resolved lazily from the bag as the provider reads them.
80+
- The node resolves the bag once per execution and shares the same dictionary across the whole `cueTag[] x target[]` matrix, attaching it to the `CueParameters.CustomParameters` of every fired cue.
81+
- When the **Custom Parameters** input is unbound, cues fire without custom parameters (the dictionary is `null`).
82+
83+
## Usage
84+
85+
```csharp
86+
graph.VariableDefinitions.DefineObjectProperty(
87+
"damageParams",
88+
new CueCustomParametersResolver(new DamageCueParametersProvider()));
89+
90+
var executeCue = new ExecuteCueNode();
91+
executeCue.BindInput(ExecuteCueNode.CueTagInput, "hitCue");
92+
executeCue.BindInput(ExecuteCueNode.TargetInput, "target");
93+
executeCue.BindInput(ExecuteCueNode.CustomParametersInput, "damageParams");
94+
```
95+
96+
## See Also
97+
98+
- [Resolvers Overview](README.md)
99+
- [EffectContextDataResolver](effect-context-data-resolver.md)
100+
- [ExecuteCueNode](../nodes/action/execute-cue-node.md)
101+
- [UpdateCueNode](../nodes/action/update-cue-node.md)
102+
- [CueNode](../nodes/state/cue-node.md)

0 commit comments

Comments
 (0)