Skip to content

Commit 38d3e87

Browse files
committed
add skills
1 parent f37f8c7 commit 38d3e87

6 files changed

Lines changed: 580 additions & 0 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
name: ceres
3+
description: Practical handbook for extending Ceres Flow in Unity projects. Use when Codex needs to add or review Ceres Flow containers, ImplementableEvent or ExecutableEvent events, ExecutableFunction APIs, ExecutableFunctionLibrary classes, custom Flow nodes, generic nodes, port-array nodes, or diagnose Ceres source generator, ILPP, linker, or hot reload issues.
4+
---
5+
6+
# Ceres
7+
8+
Use this skill when working with Ceres Flow extension code in a Unity project.
9+
Prefer existing Ceres package patterns over inventing new graph infrastructure.
10+
11+
## First Steps
12+
13+
1. Locate the Ceres package before making decisions. Common locations:
14+
- `Packages/Ceres`
15+
- `Packages/com.kurisu.ceres`
16+
- a Unity package listed as `com.kurisu.ceres`
17+
2. Read the relevant Ceres source or docs near the user's task. Useful package docs usually live in `Documentation~/docs`.
18+
3. Choose one path below and load only the matching reference file.
19+
20+
## Extension Paths
21+
22+
- **Containers and code generation**: Read `references/containers-and-codegen.md` when creating or modifying Flow containers, graph assets, runtime objects, ScriptableObject containers, or `[GenerateFlow]` classes.
23+
- **Events and executable functions**: Read `references/events-and-functions.md` when exposing C# APIs to Flow, adding `[ImplementableEvent]`, creating custom `[ExecutableEvent]` event types, or writing `ExecutableFunctionLibrary` classes.
24+
- **Custom nodes**: Read `references/custom-nodes.md` when implementing a custom node, generic node, port-array node, port metadata, or custom node behavior.
25+
- **Troubleshooting**: Read `references/troubleshooting.md` when generated code, ILPP event injection, function discovery, type preservation, hot reload, or Ceres editor search behavior is wrong.
26+
27+
## Working Rules
28+
29+
- Do not change Ceres package internals for ordinary user extension work. Add extension code in the user's Unity project unless the user explicitly asks to modify Ceres itself.
30+
- Keep Ceres Flow APIs in runtime assemblies and editor-only helpers in editor assemblies.
31+
- Prefer `FlowGraphObject`, `FlowGraphAsset`, `FlowGraphInstanceObject`, and `FlowGraphScriptableObject` before designing custom containers.
32+
- Prefer `[ExecutableFunction]` and `ExecutableFunctionLibrary` for exposing C# methods. Use custom nodes only when the behavior needs state, custom execution flow, async control, dynamic ports, or editor-specific node shape.
33+
- Do not teach or implement programmatic graph/blueprint creation from this skill unless the user explicitly asks for it; if asked, inspect the current Ceres source first because there is no single stable public GraphBuilder facade.
34+
- Validate with Unity compilation or the most local available compile/test signal, and inspect generated warnings when source generation or ILPP is involved.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
interface:
2+
display_name: "Ceres"
3+
short_description: "Guide Ceres Flow extension work in Unity"
4+
default_prompt: "Use $ceres to add a Ceres Flow extension following the package's event, function, and node patterns."
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Ceres Containers And Code Generation
2+
3+
Use this reference when adding or modifying Ceres Flow containers or generated container implementations.
4+
5+
## Container Decision Guide
6+
7+
- Use `FlowGraphObject` for normal scene `MonoBehaviour` gameplay logic with graph data stored on the component.
8+
- Use `FlowGraphAsset` when one graph asset should be reused by multiple runtime instances. Set `runtimeType` so the editor knows what `Self`, properties, and implementable events should target.
9+
- Use `FlowGraphInstanceObject` for a scene object that executes a referenced `FlowGraphAsset`.
10+
- Use `FlowGraphScriptableObject` when the logic asset should own and execute its own graph, such as skills, states, buffs, dialogue, or other asset-driven behavior.
11+
- Create a custom `[GenerateFlow] partial` class only when the built-in containers do not fit the runtime ownership model.
12+
13+
## Core Interfaces
14+
15+
- `IFlowGraphContainer` owns persistent graph data:
16+
- `FlowGraph GetFlowGraph()`
17+
- `FlowGraphData GetFlowGraphData()`
18+
- `void SetGraphData(CeresGraphData graphData)`
19+
- `UObject Object`
20+
- `IFlowGraphRuntime` owns the runtime graph instance:
21+
- `UObject Object`
22+
- `FlowGraph Graph`
23+
- `FlowGraphObjectBase` caches a runtime `FlowGraph`, compiles it on first `Graph` access, and disposes it through `ReleaseGraph()`.
24+
25+
## GenerateFlow
26+
27+
`[GenerateFlow]` tells `Ceres.SourceGenerator` to generate container/runtime boilerplate for a `partial` class.
28+
29+
```csharp
30+
using Ceres.Graph.Flow.Annotations;
31+
using UnityEngine;
32+
33+
[GenerateFlow(GenerateImplementation = true, GenerateRuntime = true)]
34+
public partial class MyFlowRuntime : MonoBehaviour
35+
{
36+
}
37+
```
38+
39+
Generation flags:
40+
41+
- `GenerateImplementation = true`: generate serialized `FlowGraphData graphData`, `Object`, `GetFlowGraph()`, `GetFlowGraphData()`, `SetGraphData()`, and protected `GetGraphData()`.
42+
- `GenerateRuntime = true`: generate runtime `Graph` cache, compile-on-first-access, and `ReleaseGraph()`.
43+
44+
Built-in patterns:
45+
46+
- `FlowGraphScriptableObjectBase`: generated container implementation only.
47+
- `FlowGraphScriptableObject`: generated runtime only, inheriting the container implementation from the base class.
48+
- `FlowGraphObject`: generated container implementation; runtime caching is handled by `FlowGraphObjectBase`.
49+
50+
## Source Generator Constraints
51+
52+
- The class must be `partial`.
53+
- The class must have a base type in the declaration for the generator receiver to pick it up.
54+
- Prefer normal namespace declarations. If behavior seems missing, inspect generated output and generator logs before assuming the C# code is wrong.
55+
- The project assembly must reference Ceres; generators skip assemblies that do not reference the Ceres assembly.
56+
57+
## Runtime Lifecycle
58+
59+
Use this pattern when manually compiling a runtime graph:
60+
61+
```csharp
62+
using var context = FlowGraphCompilationContext.GetPooled();
63+
using var compiler = CeresGraphCompiler.GetPooled(graph, context);
64+
graph.Compile(compiler);
65+
```
66+
67+
Do not mutate persistent `FlowGraphData` during play mode unless the workflow explicitly supports hot reload. In editor mode, clone graph data before creating instances when persistent data must stay untouched.
68+
69+
## Useful Package Files
70+
71+
- `Runtime/Flow/FlowGraphObject.cs`
72+
- `Runtime/Flow/FlowGraphAsset.cs`
73+
- `Runtime/Flow/FlowGraphInstanceObject.cs`
74+
- `Runtime/Flow/FlowGraphScriptableObject.cs`
75+
- `Runtime/Flow/Annotations/GenerateFlowAttribute.cs`
76+
- `Runtime/SourceGenerators/Source~/Ceres.SourceGenerator/Generators/FlowGraphGenerator.cs`
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
# Ceres Custom Nodes
2+
3+
Use this reference when writing custom Flow nodes, generic nodes, dynamic port nodes, or port behavior.
4+
5+
## Choose A Base Class
6+
7+
- Use `FlowNode` for simple synchronous nodes. Override `LocalExecute(ExecutionContext)`. Flow continues through the default `exec` port.
8+
- Use `ForwardNode` when the node is in a forward chain but needs async work or custom continuation.
9+
- Use `ExecutableNode` when the node needs full execution control or should run only in dependency path.
10+
11+
Minimal synchronous node:
12+
13+
```csharp
14+
using System;
15+
using Ceres.Annotations;
16+
using Ceres.Graph;
17+
using Ceres.Graph.Flow;
18+
19+
[Serializable]
20+
[CeresGroup("Gameplay")]
21+
[CeresLabel("Add Score")]
22+
public class FlowNode_AddScore : FlowNode
23+
{
24+
[InputPort, CeresLabel("Amount")]
25+
public CeresPort<int> amount = new(1);
26+
27+
protected override void LocalExecute(ExecutionContext executionContext)
28+
{
29+
// Apply score.
30+
}
31+
}
32+
```
33+
34+
Async/custom continuation node:
35+
36+
```csharp
37+
using System;
38+
using Ceres.Annotations;
39+
using Ceres.Graph;
40+
using Ceres.Graph.Flow;
41+
using Cysharp.Threading.Tasks;
42+
43+
[Serializable]
44+
[CeresGroup("Utilities")]
45+
[CeresLabel("Delay")]
46+
public class FlowNode_Delay : ForwardNode
47+
{
48+
[InputPort]
49+
public CeresPort<float> seconds = new(1f);
50+
51+
[OutputPort(false), CeresLabel("")]
52+
public NodePort exec;
53+
54+
protected override async UniTask Execute(ExecutionContext executionContext)
55+
{
56+
await UniTask.Delay(TimeSpan.FromSeconds(seconds.Value),
57+
cancellationToken: executionContext.Context.GetCancellationTokenOnDestroy());
58+
executionContext.SetNext(exec.GetT<ExecutableNode>());
59+
}
60+
}
61+
```
62+
63+
## Ports
64+
65+
- Use `[InputPort] public CeresPort<T> name` for data inputs.
66+
- Use `[OutputPort] public CeresPort<T> name` for data outputs.
67+
- Use `[OutputPort(false)] public NodePort exec` for execution outputs.
68+
- Use `NodePort.GetT<ExecutableNode>()` to resolve the connected next node at runtime.
69+
- Give default values by constructing ports, such as `new CeresPort<float>(1f)`.
70+
- Use `[HideInGraphEditor]` for internal fields or connection-only ports.
71+
- Use `[CeresLabel]` to make port and node labels readable.
72+
- Use `[NodeInfo]` for tooltips.
73+
74+
## Execution Path Metadata
75+
76+
Use dependency path only for nodes that produce values without relying on forward order.
77+
78+
```csharp
79+
[CeresMetadata("style = ConstNode", "path = Dependency")]
80+
public class FlowNode_ReadValue : ExecutableNode
81+
{
82+
}
83+
```
84+
85+
Forward path is the default and should be used for side effects, control flow, async work, and Unity object mutation.
86+
87+
## Port Arrays
88+
89+
Use `IReadOnlyPortArrayNode` for fixed dynamic arrays and `IPortArrayNode` when the editor can resize them.
90+
Only one port array is supported per node type.
91+
92+
```csharp
93+
using System;
94+
using Ceres.Annotations;
95+
using Ceres.Graph;
96+
using Ceres.Graph.Flow;
97+
using Cysharp.Threading.Tasks;
98+
using UnityEngine;
99+
100+
[Serializable]
101+
[CeresGroup("Flow Control")]
102+
[CeresLabel("Sequence")]
103+
[CeresMetadata("style = ForwardNode")]
104+
public class FlowNode_SequenceLike : ForwardNode, ISerializationCallbackReceiver, IPortArrayNode
105+
{
106+
[OutputPort(false), CeresLabel("Then"), CeresMetadata("DefaultLength = 2")]
107+
public NodePort[] outputs;
108+
109+
[HideInGraphEditor]
110+
public int outputCount;
111+
112+
protected override async UniTask Execute(ExecutionContext executionContext)
113+
{
114+
foreach (var output in outputs)
115+
{
116+
var next = output.GetT<ExecutableNode>();
117+
if (next != null)
118+
await executionContext.Forward(next);
119+
}
120+
}
121+
122+
public void OnBeforeSerialize() { }
123+
124+
public void OnAfterDeserialize()
125+
{
126+
outputs = new NodePort[outputCount];
127+
for (var i = 0; i < outputCount; i++)
128+
outputs[i] = new NodePort();
129+
}
130+
131+
public int GetPortArrayLength() => outputCount;
132+
public string GetPortArrayFieldName() => nameof(outputs);
133+
public void SetPortArrayLength(int newLength) => outputCount = newLength;
134+
}
135+
```
136+
137+
## Generic Nodes
138+
139+
Generic nodes need two classes:
140+
141+
- Runtime node: `FlowNode_NameT<T...>`
142+
- Template class: `FlowNode_NameT_Template : GenericNodeTemplate`
143+
144+
The template name must match `{node type name without arity}_Template`.
145+
146+
```csharp
147+
using System;
148+
using System.Linq;
149+
using Ceres.Annotations;
150+
using Ceres.Graph;
151+
using Ceres.Graph.Flow;
152+
using Ceres.Utilities;
153+
using Cysharp.Threading.Tasks;
154+
155+
[Serializable]
156+
[CeresGroup("Utilities")]
157+
[CeresLabel("Cast to {0}")]
158+
public class FlowNode_CastLikeT<TFrom, TTo> : ForwardNode where TTo : TFrom
159+
{
160+
[InputPort, HideInGraphEditor]
161+
public CeresPort<TFrom> source;
162+
163+
[OutputPort]
164+
public CeresPort<TTo> result;
165+
166+
[OutputPort(false), CeresLabel("")]
167+
public NodePort exec;
168+
169+
protected override UniTask Execute(ExecutionContext executionContext)
170+
{
171+
result.Value = (TTo)source.Value;
172+
executionContext.SetNext(exec.GetT<ExecutableNode>());
173+
return UniTask.CompletedTask;
174+
}
175+
}
176+
177+
public class FlowNode_CastLikeT_Template : GenericNodeTemplate
178+
{
179+
public override bool RequirePort() => true;
180+
181+
public override Type[] GetGenericArguments(Type portValueType, Type selectArgumentType)
182+
{
183+
return new[] { portValueType, selectArgumentType };
184+
}
185+
186+
public override Type[] GetAvailableArguments(Type portValueType)
187+
{
188+
return CeresPort.GetAssignedPortValueTypes()
189+
.Where(type => type.IsAssignableTo(portValueType) && type != portValueType)
190+
.ToArray();
191+
}
192+
}
193+
```
194+
195+
Template guidance:
196+
197+
- Return `true` from `RequirePort()` when type arguments depend on a dragged port.
198+
- Return selectable types from `GetAvailableArguments`.
199+
- Return generic arguments in the same order as the node type parameters.
200+
- Cache expensive type lists in static fields.
201+
202+
## Metadata And Search
203+
204+
- `[CeresGroup("Group/Subgroup")]` controls search grouping.
205+
- `[CeresLabel("Display")]` controls node, function, and port display text.
206+
- `[CeresMetadata("style = ConstNode")]` controls editor style classes.
207+
- `[RequirePort(typeof(SomeType))]` hides a node unless it is created from a compatible dragged port.
208+
- `[HideInGraphEditor]` hides serialized fields from property UI.
209+
210+
## Useful Package Files
211+
212+
- `Documentation~/docs/flow_custom_node.md`
213+
- `Documentation~/docs/flow_generic_node.md`
214+
- `Documentation~/docs/flow_advanced.md`
215+
- `Runtime/Core/Models/Graph/Nodes/CeresNode.cs`
216+
- `Runtime/Core/Models/Graph/Nodes/GenericNodeTemplate.cs`
217+
- `Runtime/Core/Models/Graph/Nodes/PortArrayNodeReflection.cs`
218+
- `Runtime/Core/Models/Graph/Ports/CeresPort.cs`
219+
- `Runtime/Flow/Models/Nodes/Core/ExecutableNode.cs`

0 commit comments

Comments
 (0)