添加 claude code game studios 到项目

This commit is contained in:
panw
2026-05-15 14:52:29 +08:00
parent dff559462d
commit a16fe4bff7
415 changed files with 78609 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
# Agent Test Spec: godot-csharp-specialist
## Agent Summary
Domain: C# patterns in Godot 4, .NET idioms applied to Godot, [Export] attribute usage, signal delegates, and async/await patterns.
Does NOT own: GDScript code (gdscript-specialist), GDExtension C/C++ bindings (gdextension-specialist).
Model tier: Sonnet (default).
No gate IDs assigned.
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references C# in Godot 4 / .NET patterns / signal delegates)
- [ ] `allowed-tools:` list includes Read, Write, Edit, Bash, Glob, Grep
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition does not claim authority over GDScript or GDExtension code
---
## Test Cases
### Case 1: In-domain request — appropriate output
**Input:** "Create an export property for enemy health with validation that clamps it between 1 and 1000."
**Expected behavior:**
- Produces a C# property with `[Export]` attribute
- Uses a backing field with a property getter/setter that clamps the value in the setter
- Does NOT use a raw `[Export]` public field without validation
- Follows Godot 4 C# naming conventions (PascalCase for properties, fields private with underscore prefix)
- Includes XML doc comment on the property per coding standards
### Case 2: Out-of-domain request — redirects correctly
**Input:** "Rewrite this enemy health system in GDScript."
**Expected behavior:**
- Does NOT produce GDScript code
- Explicitly states that GDScript authoring belongs to `godot-gdscript-specialist`
- Redirects the request to `godot-gdscript-specialist`
- May note that the C# interface can be described so the gdscript-specialist knows the expected API shape
### Case 3: Async signal awaiting
**Input:** "Wait for an animation to finish before transitioning game state using C# async."
**Expected behavior:**
- Produces a proper `async Task` pattern using `ToSignal()` to await a Godot signal
- Uses `await ToSignal(animationPlayer, AnimationPlayer.SignalName.AnimationFinished)`
- Does NOT use `Thread.Sleep()` or `Task.Delay()` as a polling substitute
- Notes that the calling method must be `async` and that fire-and-forget `async void` is only acceptable for event handlers
- Handles cancellation or timeout if the animation could fail to fire
### Case 4: Threading model conflict
**Input:** "This C# code accesses a Godot Node from a background Task thread to update its position."
**Expected behavior:**
- Flags this as a race condition risk: Godot nodes are not thread-safe and must only be accessed from the main thread
- Does NOT approve or implement the multi-threaded node access pattern
- Provides the correct pattern: use `CallDeferred()`, `Callable.From().CallDeferred()`, or marshal back to the main thread via a thread-safe queue
- Explains the distinction between Godot's main thread requirement and .NET's thread-agnostic types
### Case 5: Context pass — Godot 4.6 API correctness
**Input:** Engine version context: Godot 4.6. Request: "Connect a signal using the new typed signal delegate pattern."
**Expected behavior:**
- Produces C# signal connection using the typed delegate pattern introduced in Godot 4 C# (`+=` operator on typed signal)
- Checks the 4.6 context to confirm no breaking changes to the signal delegate API in 4.4, 4.5, or 4.6
- Does NOT use the old string-based `Connect("signal_name", callable)` pattern (deprecated in Godot 4 C#)
- Produces code compatible with the project's pinned 4.6 version as documented in VERSION.md
---
## Protocol Compliance
- [ ] Stays within declared domain (C# in Godot 4 — patterns, exports, signals, async)
- [ ] Redirects GDScript requests to godot-gdscript-specialist
- [ ] Redirects GDExtension requests to godot-gdextension-specialist
- [ ] Returns C# code following Godot 4 conventions (not Unity MonoBehaviour patterns)
- [ ] Flags multi-threaded Godot node access as unsafe and provides the correct pattern
- [ ] Uses typed signal delegates — not deprecated string-based Connect() calls
- [ ] Checks engine version reference for API changes before producing code
---
## Coverage Notes
- Export property with validation (Case 1) should have a unit test verifying the clamp behavior
- Threading conflict (Case 4) is safety-critical: the agent must identify and fix this without prompting
- Async signal (Case 3) verifies the agent applies .NET idioms correctly within Godot's single-thread constraint

View File

@@ -0,0 +1,86 @@
# Agent Test Spec: godot-gdextension-specialist
## Agent Summary
Domain: GDExtension API, godot-cpp C++ bindings, godot-rust bindings, native library integration, and native performance optimization.
Does NOT own: GDScript code (gdscript-specialist), shader code (godot-shader-specialist).
Model tier: Sonnet (default).
No gate IDs assigned.
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references GDExtension / godot-cpp / native bindings)
- [ ] `allowed-tools:` list includes Read, Write, Edit, Bash, Glob, Grep
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition does not claim authority over GDScript or shader authoring
---
## Test Cases
### Case 1: In-domain request — appropriate output
**Input:** "Expose a C++ rigid-body physics simulation library to GDScript via GDExtension."
**Expected behavior:**
- Produces a GDExtension binding pattern using godot-cpp:
- Class inheriting from `godot::Object` or an appropriate Godot base class
- `GDCLASS` macro registration
- `_bind_methods()` implementation exposing the physics API to GDScript
- `GDExtension` entry point (`gdextension_init`) setup
- Notes the `.gdextension` manifest file format required
- Does NOT produce the GDScript usage code (that belongs to gdscript-specialist)
### Case 2: Out-of-domain redirect
**Input:** "Write the GDScript that calls the physics simulation from Case 1."
**Expected behavior:**
- Does NOT produce GDScript code
- Explicitly states that GDScript authoring belongs to `godot-gdscript-specialist`
- Redirects to `godot-gdscript-specialist`
- May describe the API surface the GDScript should call (method names, parameter types) as a handoff spec
### Case 3: ABI compatibility risk — minor version update
**Input:** "We're upgrading from Godot 4.5 to 4.6. Will our existing GDExtension still work?"
**Expected behavior:**
- Flags the ABI compatibility concern: GDExtension binaries may not be ABI-compatible across minor versions
- Directs to check the 4.5→4.6 migration guide for GDExtension API changes
- Recommends recompiling the extension against the 4.6 godot-cpp headers rather than assuming binary compatibility
- Notes that the `.gdextension` manifest may need a `compatibility_minimum` version update
- Provides the recompilation checklist
### Case 4: Memory management — RAII for Godot objects
**Input:** "How should we manage the lifecycle of Godot objects created inside C++ GDExtension code?"
**Expected behavior:**
- Produces the RAII-based lifecycle pattern for Godot objects in GDExtension:
- `Ref<T>` for reference-counted objects (auto-released when Ref goes out of scope)
- `memnew()` / `memdelete()` for non-reference-counted objects
- Warning: do NOT use `new`/`delete` for Godot objects — undefined behavior
- Notes object ownership rules: who is responsible for freeing a node added to the scene tree
- Provides a concrete example managing a `CollisionShape3D` created in C++
### Case 5: Context pass — Godot 4.6 GDExtension API check
**Input:** Engine version context: Godot 4.6 (upgrading from 4.5). Request: "Check if any GDExtension APIs changed from 4.5 to 4.6."
**Expected behavior:**
- References the 4.5→4.6 migration guide from the VERSION.md verified sources list
- Reports on any documented GDExtension API changes in the 4.6 release
- If no breaking changes are documented for GDExtension in 4.6, states that explicitly with the caveat to verify against the official changelog
- Flags the D3D12 default on Windows (4.6 change) as potentially relevant for GDExtension rendering code
- Provides a checklist of what to verify after upgrading
---
## Protocol Compliance
- [ ] Stays within declared domain (GDExtension, godot-cpp, godot-rust, native bindings)
- [ ] Redirects GDScript authoring to godot-gdscript-specialist
- [ ] Redirects shader authoring to godot-shader-specialist
- [ ] Returns structured output (binding patterns, RAII examples, ABI checklists)
- [ ] Flags ABI compatibility risks on minor version upgrades — never assumes binary compatibility
- [ ] Uses Godot-specific memory management (`memnew`/`memdelete`, `Ref<T>`) not raw C++ new/delete
- [ ] Checks engine version reference for GDExtension API changes before confirming compatibility
---
## Coverage Notes
- Binding pattern (Case 1) should include a smoke test verifying the extension loads and the method is callable from GDScript
- ABI risk (Case 3) is a critical escalation path — the agent must not approve shipping an unverified extension binary
- Memory management (Case 4) verifies the agent applies Godot-specific patterns, not generic C++ RAII

View File

@@ -0,0 +1,82 @@
# Agent Test Spec: godot-gdscript-specialist
## Agent Summary
Domain: GDScript static typing, design patterns in GDScript, signal architecture, coroutine/await patterns, and GDScript performance.
Does NOT own: shader code (godot-shader-specialist), GDExtension bindings (godot-gdextension-specialist).
Model tier: Sonnet (default).
No gate IDs assigned.
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references GDScript / static typing / signals / coroutines)
- [ ] `allowed-tools:` list includes Read, Write, Edit, Bash, Glob, Grep
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition does not claim authority over shader code or GDExtension
---
## Test Cases
### Case 1: In-domain request — appropriate output
**Input:** "Review this GDScript file for type annotation coverage."
**Expected behavior:**
- Reads the provided GDScript file
- Flags every variable, parameter, and return type that is missing a static type annotation
- Produces a list of specific line-by-line findings: `var speed = 5.0``var speed: float = 5.0`
- Notes the performance and tooling benefits of static typing in Godot 4
- Does NOT rewrite the entire file unprompted — produces a findings list for the developer to apply
### Case 2: Out-of-domain request — redirects correctly
**Input:** "Write a vertex shader to distort the mesh in world space."
**Expected behavior:**
- Does NOT produce shader code in GDScript or in Godot's shading language
- Explicitly states that shader authoring belongs to `godot-shader-specialist`
- Redirects the request to `godot-shader-specialist`
- May note that the GDScript side (passing uniforms to a shader, setting shader parameters) is within its domain
### Case 3: Async loading with coroutines
**Input:** "Load a scene asynchronously and wait for it to finish before spawning it."
**Expected behavior:**
- Produces an `await` + `ResourceLoader.load_threaded_request` pattern for Godot 4
- Uses static typing throughout (`var scene: PackedScene`)
- Handles the completion check with `ResourceLoader.load_threaded_get_status()`
- Notes error handling for failed loads
- Does NOT use deprecated Godot 3 `yield()` syntax
### Case 4: Performance issue — typed array recommendation
**Input:** "The entity update loop is slow; it iterates an untyped Array of 1,000 nodes every frame."
**Expected behavior:**
- Identifies that an untyped `Array` foregoes compiler optimization in GDScript
- Recommends converting to a typed array (`Array[Node]` or the specific type) to enable JIT hints
- Notes that if this is still insufficient, escalates the hot path to C# migration recommendation
- Produces the typed array refactor as the immediate fix
- Does NOT recommend migrating the entire codebase to C# without profiling evidence
### Case 5: Context pass — Godot 4.6 with post-cutoff features
**Input:** Engine version context provided: Godot 4.6. Request: "Create an abstract base class for all enemy types using @abstract."
**Expected behavior:**
- Identifies `@abstract` as a Godot 4.5+ feature (post-cutoff)
- Notes this in the output: feature introduced in 4.5, verified against VERSION.md migration notes
- Produces the GDScript class using `@abstract` with correct syntax as documented in migration notes
- Marks the output as requiring verification against the official 4.5 release notes due to post-cutoff status
- Uses static typing for all method signatures in the abstract class
---
## Protocol Compliance
- [ ] Stays within declared domain (GDScript — typing, patterns, signals, coroutines, performance)
- [ ] Redirects shader requests to godot-shader-specialist
- [ ] Redirects GDExtension requests to godot-gdextension-specialist
- [ ] Returns structured GDScript output with full static typing
- [ ] Uses Godot 4 API only — no deprecated Godot 3 patterns (yield, connect with strings, etc.)
- [ ] Flags post-cutoff features (4.4, 4.5, 4.6) and marks them as requiring doc verification
---
## Coverage Notes
- Type annotation review (Case 1) output is suitable as a code review checklist
- Async loading (Case 3) should produce testable code verifiable with a unit test in `tests/unit/`
- Post-cutoff @abstract (Case 5) confirms the agent flags version uncertainty rather than silently using unverified APIs

View File

@@ -0,0 +1,84 @@
# Agent Test Spec: godot-shader-specialist
## Agent Summary
Domain: Godot shading language (GLSL-derivative), visual shaders (VisualShader graph), material setup, particle shaders, and post-processing effects.
Does NOT own: gameplay code, art style direction.
Model tier: Sonnet (default).
No gate IDs assigned.
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references Godot shading language / materials / post-processing)
- [ ] `allowed-tools:` list includes Read, Write, Edit, Glob, Grep
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition references `docs/engine-reference/godot/VERSION.md` as the authoritative source for Godot shader API changes
---
## Test Cases
### Case 1: In-domain request — appropriate output
**Input:** "Write a dissolve effect shader for enemy death in Godot."
**Expected behavior:**
- Produces valid Godot shading language code (not HLSL, not GLSL directly)
- Uses `shader_type spatial;` or `canvas_item` as appropriate
- Defines `uniform float dissolve_amount : hint_range(0.0, 1.0);`
- Samples a noise texture to determine per-pixel dissolve threshold
- Uses `discard;` for pixels below the threshold
- Optionally adds an edge glow using emission near the dissolve boundary
- Code is syntactically correct for Godot's shading language
### Case 2: HLSL redirect
**Input:** "Write an HLSL compute shader for this dissolve effect."
**Expected behavior:**
- Does NOT produce HLSL code
- Clearly states: "Godot does not use HLSL directly; it uses its own shading language (a GLSL derivative)"
- Translates the HLSL intent to the equivalent Godot shader approach
- Notes that RenderingDevice compute shaders are available in Godot 4 but are a low-level API and flags it appropriately if that was the intent
### Case 3: Post-cutoff API change — texture sampling (Godot 4.4)
**Input:** "Use `texture()` with a sampler2D to sample the noise texture in the shader."
**Expected behavior:**
- Checks the version reference: Godot 4.4 changed texture sampler type declarations
- Flags the potential API change: `sampler2D` syntax and `texture()` call behavior may differ from pre-4.4
- Provides the correct syntax for the project's pinned version (4.6) as documented in migration notes
- Does NOT use pre-4.4 texture sampling syntax without flagging the version risk
### Case 4: Fragment shader LOD strategy
**Input:** "The fragment shader for the water surface has 8 texture samples and is causing GPU bottlenecks on mid-range hardware."
**Expected behavior:**
- Identifies the per-fragment texture sample count as the primary cost driver
- Proposes an LOD strategy:
- Reduce sample count at distance (distance-based shader variant or LOD level)
- Pre-bake some texture combinations offline
- Use lower-resolution noise textures for distant samples
- Provides the shader code modification implementing the LOD approach
- Does NOT change gameplay behavior of the water system
### Case 5: Context pass — Godot 4.6 glow rework
**Input:** Engine version context: Godot 4.6. Request: "Add a bloom/glow post-processing effect to the scene."
**Expected behavior:**
- References the VERSION.md note: Godot 4.6 includes a glow rework
- Produces glow configuration guidance using the 4.6 WorldEnvironment approach, not the pre-4.6 API
- Explicitly notes which properties or parameters changed in the 4.6 glow rework
- Flags any properties that the LLM's training data may have incorrect information about due to the post-cutoff timing
---
## Protocol Compliance
- [ ] Stays within declared domain (Godot shading language, materials, VFX shaders, post-processing)
- [ ] Redirects gameplay code requests to gameplay-programmer
- [ ] Produces valid Godot shading language — never HLSL or raw GLSL without a Godot wrapper
- [ ] Checks engine version reference for post-cutoff shader API changes (4.4 texture types, 4.6 glow rework)
- [ ] Returns structured output (shader code with uniforms documented, LOD strategies with performance rationale)
- [ ] Flags any post-cutoff API usage as requiring verification
---
## Coverage Notes
- Dissolve shader (Case 1) should be paired with a visual test screenshot in `production/qa/evidence/`
- Texture API flag (Case 3) confirms the agent checks VERSION.md before using APIs that changed post-4.3
- Glow rework (Case 5) is a Godot 4.6-specific test — verifies the agent applies the most recent migration notes

View File

@@ -0,0 +1,82 @@
# Agent Test Spec: godot-specialist
## Agent Summary
Domain: Godot-specific patterns, node/scene architecture, signals, resources, and GDScript vs C# vs GDExtension decisions.
Does NOT own: actual code authoring in a specific language (delegates to language sub-specialists).
Model tier: Sonnet (default).
No gate IDs assigned.
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references Godot architecture / node patterns / engine decisions)
- [ ] `allowed-tools:` list includes Read, Write, Edit, Bash, Glob, Grep
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition references `docs/engine-reference/godot/VERSION.md` as the authoritative API source
---
## Test Cases
### Case 1: In-domain request — appropriate output
**Input:** "When should I use signals vs. direct method calls in Godot?"
**Expected behavior:**
- Produces a pattern decision guide with rationale:
- Signals: decoupled communication, parent-to-child ignorance, event-driven UI updates, one-to-many notification
- Direct calls: tightly-coupled systems where the caller needs a return value, or performance-critical hot paths
- Provides concrete examples of each pattern in the project's context
- Does NOT produce raw code for both patterns — refers to gdscript-specialist or csharp-specialist for implementation
- Notes the "no upward signals" convention (child does not call parent methods directly — uses signals instead)
### Case 2: Wrong-engine redirect
**Input:** "Write a MonoBehaviour that runs on Start() and subscribes to a UnityEvent."
**Expected behavior:**
- Does NOT produce Unity MonoBehaviour code
- Clearly identifies that this is a Unity pattern, not a Godot pattern
- Provides the Godot equivalent: a Node script using `_ready()` instead of `Start()`, and Godot signals instead of UnityEvent
- Confirms the project is Godot-based and redirects the conceptual mapping
### Case 3: Post-cutoff API risk
**Input:** "Use the new Godot 4.5 @abstract annotation to define an abstract base class."
**Expected behavior:**
- Identifies that `@abstract` is a post-cutoff feature (introduced in Godot 4.5, after LLM knowledge cutoff)
- Flags the version risk: LLM knowledge of this annotation may be incomplete or incorrect
- Directs the user to verify against `docs/engine-reference/godot/VERSION.md` and the official 4.5 migration guide
- Provides best-effort guidance based on the migration notes in the version reference while clearly marking it as unverified
### Case 4: Language selection for a hot path
**Input:** "The physics query loop runs every frame for 500 objects. Should we use GDScript or C# for this?"
**Expected behavior:**
- Provides a balanced analysis:
- GDScript: simpler, team familiar, but slower for tight loops
- C#: faster for CPU-intensive loops, requires .NET runtime, team needs C# knowledge
- Does NOT make the final decision unilaterally
- Defers the decision to `lead-programmer` with the analysis as input
- Notes that GDExtension (C++) is a third option for extreme performance cases and recommends escalating if C# is insufficient
### Case 5: Context pass — engine version 4.6
**Input:** Engine version context provided: Godot 4.6, Jolt as default physics. Request: "Set up a RigidBody3D for the player character."
**Expected behavior:**
- Reads the 4.6 context and applies the Jolt-default knowledge (from VERSION.md migration notes)
- Recommends RigidBody3D configuration choices that are Jolt-compatible (e.g., notes any GodotPhysics-specific settings that behave differently under Jolt)
- References the 4.6 migration note about Jolt becoming default rather than relying on LLM training data alone
- Flags any RigidBody3D properties that changed behavior between GodotPhysics and Jolt
---
## Protocol Compliance
- [ ] Stays within declared domain (Godot architecture decisions, node/scene patterns, language selection)
- [ ] Redirects language-specific implementation to godot-gdscript-specialist or godot-csharp-specialist
- [ ] Returns structured findings (decision trees, pattern recommendations with rationale)
- [ ] Treats `docs/engine-reference/godot/VERSION.md` as authoritative over LLM training data
- [ ] Flags post-cutoff API usage (4.4, 4.5, 4.6) with verification requirements
- [ ] Defers language-selection decisions to lead-programmer when trade-offs exist
---
## Coverage Notes
- Signal vs. direct call guide (Case 1) should be written to `docs/architecture/` as a reusable pattern doc
- Post-cutoff flag (Case 3) confirms the agent does not confidently use APIs it cannot verify
- Engine version case (Case 5) verifies the agent applies migration notes from the version reference, not assumptions

View File

@@ -0,0 +1,87 @@
# Agent Test Spec: unity-addressables-specialist
## Agent Summary
Domain: Addressable Asset System — groups, async loading/unloading, handle lifecycle management, memory budgeting, content catalogs, and remote content delivery.
Does NOT own: rendering systems (engine-programmer), game logic that uses the loaded assets (gameplay-programmer).
Model tier: Sonnet (default).
No gate IDs assigned.
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references Addressables / asset loading / content catalogs / remote delivery)
- [ ] `allowed-tools:` list includes Read, Write, Edit, Bash, Glob, Grep
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition does not claim authority over rendering systems or gameplay using the loaded assets
---
## Test Cases
### Case 1: In-domain request — appropriate output
**Input:** "Load a character texture asynchronously and release it when the character is destroyed."
**Expected behavior:**
- Produces the `Addressables.LoadAssetAsync<Texture2D>()` call pattern
- Stores the returned `AsyncOperationHandle<Texture2D>` in the requesting object
- On character destruction (`OnDestroy()`), calls `Addressables.Release(handle)` with the stored handle
- Does NOT use `Resources.Load()` as the loading mechanism
- Notes that releasing with a null or uninitialized handle causes errors — includes a validity check
- Notes the difference between releasing the handle vs. releasing the asset (handle release is correct)
### Case 2: Out-of-domain redirect
**Input:** "Implement the rendering system that applies the loaded texture to the character mesh."
**Expected behavior:**
- Does NOT produce rendering or mesh material assignment code
- Explicitly states that rendering system implementation belongs to `engine-programmer`
- Redirects the request to `engine-programmer`
- May describe the asset type and API surface it will provide (e.g., `Texture2D` reference once the handle completes) as a handoff spec
### Case 3: Memory leak — un-released handle
**Input:** "Memory usage keeps climbing after each level load. We use Addressables to load level assets."
**Expected behavior:**
- Diagnoses the likely cause: `AsyncOperationHandle` objects not being released after use
- Identifies the handle leak pattern: loading assets into a local variable, losing reference, never calling `Addressables.Release()`
- Produces an auditing approach: search for all `LoadAssetAsync` / `LoadSceneAsync` calls and verify matching `Release()` calls
- Provides a corrected pattern using a tracked handle list (`List<AsyncOperationHandle>`) with a `ReleaseAll()` cleanup method
- Does NOT assume the leak is elsewhere without evidence
### Case 4: Remote content delivery — catalog versioning
**Input:** "We need to support downloadable content updates without requiring a full app re-install."
**Expected behavior:**
- Produces the remote catalog update pattern:
- `Addressables.CheckForCatalogUpdates()` on startup
- `Addressables.UpdateCatalogs()` for detected updates
- `Addressables.DownloadDependenciesAsync()` to pre-warm the updated content
- Notes catalog hash checking for change detection
- Addresses the edge case: what happens if a player starts a session, the catalog updates mid-session — defines behavior (complete current session on old catalog, reload on next launch)
- Does NOT design the server-side CDN infrastructure (defers to devops-engineer)
### Case 5: Context pass — platform memory constraints
**Input:** Platform context: Nintendo Switch target, 4GB RAM, practical asset memory ceiling 512MB. Request: "Design the Addressables loading strategy for a large open-world level."
**Expected behavior:**
- References the 512MB memory ceiling from the provided context
- Designs a streaming strategy:
- Divide the world into addressable zones loaded/unloaded based on player proximity
- Defines a memory budget per active zone (e.g., 128MB, max 4 zones active)
- Specifies async pre-load trigger distance and unload distance (hysteresis)
- Notes Switch-specific constraints: slower load times from SD card, recommend pre-warming adjacent zones
- Does NOT produce a loading strategy that would exceed the stated 512MB ceiling without flagging it
---
## Protocol Compliance
- [ ] Stays within declared domain (Addressables loading, handle lifecycle, memory, catalogs, remote delivery)
- [ ] Redirects rendering and gameplay asset-use code to engine-programmer and gameplay-programmer
- [ ] Returns structured output (loading patterns, handle lifecycle code, streaming zone designs)
- [ ] Always pairs `LoadAssetAsync` with a corresponding `Release()` — flags handle leaks as a memory bug
- [ ] Designs loading strategies against provided memory ceilings
- [ ] Does not design CDN/server infrastructure — defers to devops-engineer for server side
---
## Coverage Notes
- Handle lifecycle (Case 1) must include a test verifying memory is reclaimed after release
- Handle leak diagnosis (Case 3) should produce a findings report suitable for a bug ticket
- Platform memory case (Case 5) verifies the agent applies hard constraints from context, not default assumptions

View File

@@ -0,0 +1,87 @@
# Agent Test Spec: unity-dots-specialist
## Agent Summary
Domain: ECS architecture (IComponentData, ISystem, SystemAPI), Jobs system (IJob, IJobEntity, Burst), Burst compiler constraints, DOTS gameplay systems, and hybrid renderer.
Does NOT own: MonoBehaviour gameplay code (gameplay-programmer), UI implementation (unity-ui-specialist).
Model tier: Sonnet (default).
No gate IDs assigned.
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references ECS / Jobs / Burst / IComponentData)
- [ ] `allowed-tools:` list includes Read, Write, Edit, Bash, Glob, Grep
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition does not claim authority over MonoBehaviour gameplay or UI systems
---
## Test Cases
### Case 1: In-domain request — appropriate output
**Input:** "Convert the player movement system to ECS."
**Expected behavior:**
- Produces:
- `PlayerMovementData : IComponentData` struct with velocity, speed, and input vector fields
- `PlayerMovementSystem : ISystem` with `OnUpdate()` using `SystemAPI.Query<>` or `IJobEntity`
- Bakes the player's initial state from an authoring MonoBehaviour via `IBaker`
- Uses `RefRW<LocalTransform>` for position updates (not deprecated `Translation`)
- Marks the job `[BurstCompile]` and notes what must be unmanaged for Burst compatibility
- Does NOT modify the input polling system — reads from an existing `PlayerInputData` component
### Case 2: MonoBehaviour push-back
**Input:** "Just use MonoBehaviour for the player movement — it's simpler."
**Expected behavior:**
- Acknowledges the simplicity argument
- Explains the DOTS trade-off: more setup upfront, but the ECS/Burst approach provides the performance characteristics documented in the project's ADR or requirements
- Does NOT implement a MonoBehaviour version if the project has committed to DOTS
- If no commitment exists, flags the architecture decision to `lead-programmer` / `technical-director` for resolution
- Does not make the MonoBehaviour vs. DOTS decision unilaterally
### Case 3: Burst-incompatible managed memory
**Input:** "This Burst job accesses a `List<EnemyData>` to find the nearest enemy."
**Expected behavior:**
- Flags `List<T>` as a managed type that is incompatible with Burst compilation
- Does NOT approve the Burst job with managed memory access
- Provides the correct replacement: `NativeArray<EnemyData>`, `NativeList<EnemyData>`, or `NativeHashMap<>` depending on the use case
- Notes that `NativeArray` must be disposed explicitly or via `[DeallocateOnJobCompletion]`
- Produces the corrected job using unmanaged native containers
### Case 4: Hybrid access — DOTS system needs MonoBehaviour data
**Input:** "The DOTS movement system needs to read the camera transform managed by a MonoBehaviour CameraController."
**Expected behavior:**
- Identifies this as a hybrid access scenario
- Provides the correct hybrid pattern: store the camera transform in a singleton `IComponentData` (updated from the MonoBehaviour side each frame via `EntityManager.SetComponentData`)
- Alternatively suggests the `CompanionComponent` / managed component approach
- Does NOT access the MonoBehaviour from inside a Burst job — flags that as unsafe
- Provides the bridge code on both the MonoBehaviour side (writing to ECS) and the DOTS system side (reading from ECS)
### Case 5: Context pass — performance targets
**Input:** Technical preferences from context: 60fps target, max 2ms CPU script budget per frame. Request: "Design the ECS chunk layout for 10,000 enemy entities."
**Expected behavior:**
- References the 2ms CPU budget explicitly in the design rationale
- Designs the `IComponentData` chunk layout for cache efficiency:
- Groups frequently-queried together components in the same archetype
- Separates rarely-used data into separate components to keep hot data compact
- Estimates entity iteration time against the 2ms budget
- Provides memory layout analysis (bytes per entity, entities per chunk at 16KB chunk size)
- Does NOT design a layout that will obviously exceed the stated 2ms budget without flagging it
---
## Protocol Compliance
- [ ] Stays within declared domain (ECS, Jobs, Burst, DOTS gameplay systems)
- [ ] Redirects MonoBehaviour-only gameplay to gameplay-programmer
- [ ] Returns structured output (IComponentData structs, ISystem implementations, IBaker authoring classes)
- [ ] Flags managed memory access in Burst jobs as a compile error and provides unmanaged alternatives
- [ ] Provides hybrid access patterns when DOTS systems need to interact with MonoBehaviour systems
- [ ] Designs chunk layouts against provided performance budgets
---
## Coverage Notes
- ECS conversion (Case 1) must include a unit test using the ECS test framework (`World`, `EntityManager`)
- Burst incompatibility (Case 3) is safety-critical — the agent must catch this before the code is written
- Chunk layout (Case 5) verifies the agent applies quantitative performance reasoning to architecture decisions

View File

@@ -0,0 +1,83 @@
# Agent Test Spec: unity-shader-specialist
## Agent Summary
Domain: Unity Shader Graph, custom HLSL, VFX Graph, URP/HDRP pipeline customization, and post-processing effects.
Does NOT own: gameplay code, art style direction.
Model tier: Sonnet (default).
No gate IDs assigned.
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references Shader Graph / HLSL / VFX Graph / URP / HDRP)
- [ ] `allowed-tools:` list includes Read, Write, Edit, Glob, Grep
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition does not claim authority over gameplay code or art direction
---
## Test Cases
### Case 1: In-domain request — appropriate output
**Input:** "Create an outline effect for characters using Shader Graph in URP."
**Expected behavior:**
- Produces a Shader Graph node setup description:
- Inverted hull method: Scale Normal → Vertex offset in vertex stage, Cull Front
- OR screen-space post-process outline using depth/normal edge detection
- Recommends the appropriate method based on URP capabilities (inverted hull for URP compatibility, post-process for HDRP)
- Notes URP limitations: no geometry shader support (rules out geometry-shader outline approach)
- Does NOT produce HDRP-specific nodes without confirming the render pipeline
### Case 2: Out-of-domain redirect
**Input:** "Implement the character health bar UI in code."
**Expected behavior:**
- Does NOT produce UI implementation code
- Explicitly states that UI implementation belongs to `ui-programmer` (or `unity-ui-specialist`)
- Redirects the request appropriately
- May note that a shader-based fill effect for a health bar (e.g., a dissolve/fill gradient) is within its domain if the visual effect itself is shader-driven
### Case 3: HDRP custom pass for outline
**Input:** "We're on HDRP and want the outline as a post-process effect."
**Expected behavior:**
- Produces the HDRP `CustomPassVolume` pattern:
- C# class inheriting `CustomPass`
- `Execute()` method using `CoreUtils.SetRenderTarget()` and a full-screen shader blit
- Depth/normal buffer sampling for edge detection
- Notes that CustomPass requires HDRP package and does not work in URP
- Confirms the project is on HDRP before providing HDRP-specific code
### Case 4: VFX Graph performance — GPU event batching
**Input:** "The explosion VFX Graph has 10,000 particles per event and spawning 20 simultaneous explosions is causing GPU frame spikes."
**Expected behavior:**
- Identifies GPU particle spawn as the cost driver (200,000 simultaneous particles)
- Proposes GPU event batching: spawn events deferred over multiple frames, stagger initialization
- Recommends a particle budget cap per active explosion (e.g., 3,000 per explosion, queue excess)
- Notes the VFX Graph Event Batcher pattern and Output Event API for cross-frame distribution
- Does NOT change the gameplay event system — proposes a VFX-side budgeting solution
### Case 5: Context pass — render pipeline (URP or HDRP)
**Input:** Project context: URP render pipeline, Unity 2022.3. Request: "Add depth of field post-processing."
**Expected behavior:**
- Uses URP Volume framework: `DepthOfField` Volume Override component
- Does NOT use HDRP Volume components (e.g., HDRP's `DepthOfField` with different parameter names)
- Notes URP-specific DOF limitations vs HDRP (e.g., Bokeh quality differences)
- Produces C# Volume profile setup code compatible with Unity 2022.3 URP package version
---
## Protocol Compliance
- [ ] Stays within declared domain (Shader Graph, HLSL, VFX Graph, URP/HDRP customization)
- [ ] Redirects gameplay and UI code to appropriate agents
- [ ] Returns structured output (node graph descriptions, HLSL code, CustomPass patterns)
- [ ] Distinguishes between URP and HDRP approaches — never cross-contaminates pipeline-specific APIs
- [ ] Flags geometry shader approaches as URP-incompatible when relevant
- [ ] Produces VFX optimizations that do not change gameplay behavior
---
## Coverage Notes
- Outline effect (Case 1) should be paired with a visual screenshot test in `production/qa/evidence/`
- HDRP CustomPass (Case 3) confirms the agent produces the correct Unity pattern, not a generic post-process approach
- Pipeline separation (Case 5) verifies the agent never assumes the render pipeline without context

View File

@@ -0,0 +1,83 @@
# Agent Test Spec: unity-specialist
## Agent Summary
Domain: Unity-specific architecture patterns, MonoBehaviour vs DOTS decisions, and subsystem selection (Addressables, New Input System, UI Toolkit, Cinemachine, etc.).
Does NOT own: language-specific deep dives (delegates to unity-dots-specialist, unity-ui-specialist, etc.).
Model tier: Sonnet (default).
No gate IDs assigned.
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references Unity patterns / MonoBehaviour / subsystem decisions)
- [ ] `allowed-tools:` list includes Read, Write, Edit, Bash, Glob, Grep
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition acknowledges the sub-specialist routing table (DOTS, UI, Shader, Addressables)
---
## Test Cases
### Case 1: In-domain request — appropriate output
**Input:** "Should I use MonoBehaviour or ScriptableObject for storing enemy configuration data?"
**Expected behavior:**
- Produces a pattern decision tree covering:
- MonoBehaviour: for runtime behavior, needs to be attached to a GameObject, has Update() lifecycle
- ScriptableObject: for pure data/configuration, exists as an asset, shared across instances, no scene dependency
- Recommends ScriptableObject for enemy configuration data (stateless, reusable, designer-friendly)
- Notes that MonoBehaviour can reference the ScriptableObject for runtime use
- Provides a concrete example of what the ScriptableObject class definition looks like (does not produce full code — refers to engine-programmer or gameplay-programmer for implementation)
### Case 2: Wrong-engine redirect
**Input:** "Set up a Node scene tree with signals for this enemy system."
**Expected behavior:**
- Does NOT produce Godot Node/signal code
- Identifies this as a Godot pattern
- States that in Unity the equivalent is GameObject hierarchy + UnityEvent or C# events
- Maps the concepts: Godot Node → Unity MonoBehaviour, Godot Signal → C# event / UnityEvent
- Confirms the project is Unity-based before proceeding
### Case 3: Unity version API flag
**Input:** "Use the new Unity 6 GPU resident drawer for batch rendering."
**Expected behavior:**
- Identifies the Unity 6 feature (GPU Resident Drawer)
- Flags that this API may not be available in earlier Unity versions
- Asks for or checks the project's Unity version before providing implementation guidance
- Directs to verify against official Unity 6 documentation
- Does NOT assume the project is on Unity 6 without confirmation
### Case 4: DOTS vs. MonoBehaviour conflict
**Input:** "The combat system uses MonoBehaviour for state management, but we want to add a DOTS-based projectile system. Can they coexist?"
**Expected behavior:**
- Recognizes this as a hybrid architecture scenario
- Explains the hybrid approach: MonoBehaviour can interface with DOTS via SystemAPI, IComponentData, and managed components
- Notes the performance and complexity trade-offs of mixing the two patterns
- Recommends escalating the architecture decision to `lead-programmer` or `technical-director`
- Defers to `unity-dots-specialist` for the DOTS-side implementation details
### Case 5: Context pass — Unity version
**Input:** Project context provided: Unity 2023.3 LTS. Request: "Configure the new Input System for this project."
**Expected behavior:**
- Applies Unity 2023.3 LTS context: uses the New Input System (com.unity.inputsystem) package
- Does NOT produce legacy Input Manager code (`Input.GetKeyDown()`, `Input.GetAxis()`)
- Notes any 2023.3-specific Input System behaviors or package version constraints
- References the project version to confirm Burst/Jobs compatibility if the Input System interacts with DOTS
---
## Protocol Compliance
- [ ] Stays within declared domain (Unity architecture decisions, pattern selection, subsystem routing)
- [ ] Redirects Godot patterns to appropriate Godot specialists or flags them as wrong-engine
- [ ] Redirects DOTS implementation to unity-dots-specialist
- [ ] Redirects UI implementation to unity-ui-specialist
- [ ] Flags Unity version-gated APIs and requires version confirmation before suggesting them
- [ ] Returns structured pattern decision guides, not freeform opinions
---
## Coverage Notes
- MonoBehaviour vs. ScriptableObject (Case 1) should be documented as an ADR if it results in a project-level decision
- Version flag (Case 3) confirms the agent does not assume the latest Unity version without context
- DOTS hybrid (Case 4) verifies the agent escalates architecture conflicts rather than resolving them unilaterally

View File

@@ -0,0 +1,81 @@
# Agent Test Spec: unity-ui-specialist
## Agent Summary
Domain: Unity UI Toolkit (UXML/USS), UGUI (Canvas), data binding, runtime UI performance, and UI input event handling.
Does NOT own: UX flow design (ux-designer), visual art style (art-director).
Model tier: Sonnet (default).
No gate IDs assigned.
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references UI Toolkit / UGUI / Canvas / data binding)
- [ ] `allowed-tools:` list includes Read, Write, Edit, Bash, Glob, Grep
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition does not claim authority over UX flow design or visual art direction
---
## Test Cases
### Case 1: In-domain request — appropriate output
**Input:** "Implement an inventory UI screen using Unity UI Toolkit."
**Expected behavior:**
- Produces a UXML document defining the inventory panel structure (ListView, item templates, detail panel)
- Produces USS styles for the inventory layout and item states (default, hover, selected)
- Provides C# code binding the inventory data model to the UI via `INotifyValueChanged` or `IBindable`
- Uses `ListView` with `makeItem` / `bindItem` callbacks for the scrollable item list
- Does NOT produce the UX flow design — implements from a provided spec
### Case 2: Out-of-domain redirect
**Input:** "Design the UX flow for the inventory — what happens when the player equips vs. drops an item."
**Expected behavior:**
- Does NOT produce UX flow design
- Explicitly states that interaction flow design belongs to `ux-designer`
- Redirects the request to `ux-designer`
- Notes it will implement whatever flow the ux-designer specifies
### Case 3: UI Toolkit data binding for dynamic list
**Input:** "The inventory list needs to update in real time as items are added or removed from the player's bag."
**Expected behavior:**
- Produces the `ListView` pattern with a bound `ObservableList<T>` or event-driven refresh approach
- Uses `ListView.Rebuild()` or `ListView.RefreshItems()` on the backing collection change event
- Notes the performance considerations for large lists (virtualization via `makeItem`/`bindItem` pattern)
- Does NOT use `QuerySelector` loops to update individual elements as a list refresh strategy — flags that as a performance antipattern
### Case 4: Canvas performance — overdraw
**Input:** "The main menu canvas is causing GPU overdraw warnings; there are many overlapping panels."
**Expected behavior:**
- Identifies overdraw causes: multiple stacked canvases, full-screen overlay panels not culled when inactive
- Recommends:
- Separate canvases for world-space, screen-space-overlay, and screen-space-camera layers
- Disable/deactivate panels instead of setting alpha to 0 (invisible alpha-0 panels still draw)
- Canvas Group + alpha for fade effects, not individual Image alpha
- Notes UI Toolkit alternative if the project is in a migration position
### Case 5: Context pass — Unity version
**Input:** Project context: Unity 2022.3 LTS. Request: "Implement the settings panel with data binding."
**Expected behavior:**
- Uses UI Toolkit with the 2022.3 LTS version of the runtime binding system
- Notes that Unity 2022.3 introduced runtime data binding (as opposed to editor-only binding in earlier versions)
- Does NOT use the Unity 6 enhanced binding API features if they are not available in 2022.3
- Produces code compatible with the stated Unity version, with version-specific API notes
---
## Protocol Compliance
- [ ] Stays within declared domain (UI Toolkit, UGUI, data binding, UI performance)
- [ ] Redirects UX flow design to ux-designer
- [ ] Returns structured output (UXML, USS, C# binding code)
- [ ] Uses the correct Unity UI framework version for the project's Unity version
- [ ] Flags Canvas overdraw as a performance antipattern and provides specific remediation
- [ ] Does not use alpha-0 as a hide/show pattern — uses SetActive() or VisualElement.style.display
---
## Coverage Notes
- Inventory UI (Case 1) should have a manual walkthrough doc in `production/qa/evidence/`
- Dynamic list binding (Case 3) should have an integration test or automated interaction test
- Canvas overdraw (Case 4) verifies the agent knows the correct Unity UI performance patterns

View File

@@ -0,0 +1,80 @@
# Agent Test Spec: ue-blueprint-specialist
## Agent Summary
- **Domain**: Blueprint architecture, the Blueprint/C++ boundary, Blueprint graph quality, Blueprint performance optimization, Blueprint Function Library design
- **Does NOT own**: C++ implementation (engine-programmer or gameplay-programmer), art assets or shaders, UI/UX flow design (ux-designer)
- **Model tier**: Sonnet
- **Gate IDs**: None; defers to unreal-specialist or lead-programmer for cross-domain rulings
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references Blueprint architecture and optimization)
- [ ] `allowed-tools:` list matches the agent's role (Read for Blueprint project files; no server or deployment tools)
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition does not claim authority over C++ implementation decisions
---
## Test Cases
### Case 1: In-domain request — Blueprint graph performance review
**Input**: "Review our AI behavior Blueprint. It has tick-based logic running every frame that checks line-of-sight for 30 NPCs simultaneously."
**Expected behavior**:
- Identifies tick-heavy logic as a performance problem
- Recommends switching from EventTick to event-driven patterns (perception system events, timers, or polling on a reduced interval)
- Flags the per-NPC cost of simultaneous line-of-sight checks
- Suggests alternatives: AIPerception component events, staggered tick groups, or moving the system to C++ if Blueprint overhead is measured to be significant
- Output is structured: problem identified, impact estimated, alternatives listed
### Case 2: Out-of-domain request — C++ implementation
**Input**: "Write the C++ implementation for this ability cooldown system."
**Expected behavior**:
- Does not produce C++ implementation code
- Provides the Blueprint equivalent of the cooldown logic (e.g., using a Timeline or GameplayEffect if GAS is in use)
- States clearly: "C++ implementation is handled by engine-programmer or gameplay-programmer; I can show the Blueprint approach or describe the boundary where Blueprint calls into C++"
- Optionally notes when the cooldown complexity warrants a C++ backend
### Case 3: Domain boundary — unsafe raw pointer access in Blueprint
**Input**: "Our Blueprint calls GetOwner() and then immediately accesses a component on the result without checking if it's valid."
**Expected behavior**:
- Flags this as a runtime crash risk: GetOwner() can return null in some lifecycle states
- Provides the correct Blueprint pattern: IsValid() node before any property/component access
- Notes that Blueprint's null checks are not optional on Actor-derived references
- Does NOT silently fix the code without explaining why the original was unsafe
### Case 4: Blueprint graph complexity — readiness for Function Library refactor
**Input**: "Our main GameMode Blueprint has 600+ nodes in a single graph with duplicated damage calculation logic in 8 places."
**Expected behavior**:
- Diagnoses this as a maintainability and testability problem
- Recommends extracting duplicated logic into a Blueprint Function Library (BFL)
- Describes how to structure the BFL: pure functions for calculations, static calls from any Blueprint
- Notes that if the damage logic is performance-sensitive or shared with C++, it may be a candidate for migration to unreal-specialist review
- Output is a concrete refactor plan, not a vague recommendation
### Case 5: Context pass — Blueprint complexity budget
**Input context**: Project conventions specify a maximum of 100 nodes per Blueprint event graph before a mandatory Function Library extraction.
**Input**: "Here is our inventory Blueprint graph [150 nodes shown]. Is it ready to ship?"
**Expected behavior**:
- References the stated 150-node count against the 100-node budget from project conventions
- Flags the graph as exceeding the complexity threshold
- Does NOT approve it as-is
- Produces a list of candidate subgraphs for Function Library extraction to bring the main graph within budget
---
## Protocol Compliance
- [ ] Stays within declared domain (Blueprint architecture, performance, graph quality)
- [ ] Redirects C++ implementation requests to engine-programmer or gameplay-programmer
- [ ] Returns structured findings (problem/impact/alternatives format) rather than freeform opinions
- [ ] Enforces Blueprint safety patterns (null checks, IsValid) proactively
- [ ] References project conventions when evaluating graph complexity
---
## Coverage Notes
- Case 3 (null pointer safety) is a safety-critical test — this is a common source of shipping crashes
- Case 5 requires that project conventions include a stated node budget; if none is configured, the agent should note the absence and recommend setting one
- No automated runner; review manually or via `/skill-test`

View File

@@ -0,0 +1,81 @@
# Agent Test Spec: ue-gas-specialist
## Agent Summary
- **Domain**: Gameplay Ability System (GAS) — abilities (UGameplayAbility), gameplay effects (UGameplayEffect), attribute sets (UAttributeSet), gameplay tags, ability tasks (UAbilityTask), ability specs (FGameplayAbilitySpec), GAS prediction and latency compensation
- **Does NOT own**: UI display of ability state (ue-umg-specialist), net replication of GAS data beyond built-in GAS prediction (ue-replication-specialist), art or VFX for ability feedback (vfx-artist)
- **Model tier**: Sonnet
- **Gate IDs**: None; defers cross-domain calls to the appropriate specialist
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references GAS, abilities, GameplayEffects, AttributeSets)
- [ ] `allowed-tools:` list matches the agent's role (Read/Write for GAS source files; no deployment or server tools)
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition does not claim authority over UI implementation or low-level net serialization
---
## Test Cases
### Case 1: In-domain request — dash ability with cooldown
**Input**: "Implement a dash ability that moves the player forward 500 units and has a 1.5 second cooldown."
**Expected behavior**:
- Produces a GAS AbilitySpec structure or outline: UGameplayAbility subclass with ActivateAbility logic, an AbilityTask for movement (e.g., AbilityTask_ApplyRootMotionMoveToForce or custom root motion), and a UGameplayEffect for the cooldown
- Cooldown GameplayEffect uses Duration policy with the 1.5s duration and a GameplayTag to block re-activation
- Tags clearly named following a hierarchy convention (e.g., Ability.Dash, Cooldown.Ability.Dash)
- Output includes both the ability class outline and the GameplayEffect definition
### Case 2: Out-of-domain request — GAS state replication
**Input**: "How do I replicate the player's ability cooldown state to all clients so the UI updates correctly?"
**Expected behavior**:
- Clarifies that GAS has built-in replication for AbilitySpecs and GameplayEffects via the AbilitySystemComponent's replication mode
- Explains the three ASC replication modes (Full, Mixed, Minimal) and when to use each
- For custom replication needs beyond GAS built-ins, explicitly states: "For custom net serialization of GAS data, coordinate with ue-replication-specialist"
- Does NOT attempt to write custom replication code outside GAS's own systems without flagging the domain boundary
### Case 3: Domain boundary — incorrect GameplayTag hierarchy
**Input**: "We have an ability that applies a tag called 'Stunned' and another that checks for 'Status.Stunned'. They're not matching."
**Expected behavior**:
- Identifies the root cause: tag names must be exact or use hierarchical matching via TagContainer queries
- Flags the naming inconsistency: 'Stunned' is a root-level tag; 'Status.Stunned' is a child tag under 'Status' — these are different tags
- Recommends a project tag naming convention: all status effects under Status.*, all abilities under Ability.*
- Provides the fix: either rename the applied tag to 'Status.Stunned' or update the query to match 'Stunned'
- Notes where tag definitions should live (DefaultGameplayTags.ini or a DataTable)
### Case 4: Conflict — attribute set conflict between two abilities
**Input**: "Our Shield ability and our Armor ability both modify a 'DefenseValue' attribute. They're stacking in ways that aren't intended — after both are active, defense goes well above maximum."
**Expected behavior**:
- Identifies this as a GameplayEffect stacking and magnitude calculation problem
- Proposes a resolution using Execution Calculations (UGameplayEffectExecutionCalculation) or Modifier Aggregators to cap the combined result
- Alternatively recommends using Gameplay Effect Stacking policies (Aggregate, None) to prevent unintended additive stacking
- Produces a concrete resolution: either an Execution Calculation class outline or a change to the Modifier Op (Override instead of Additive for the cap)
- Does NOT propose removing one of the abilities as the solution
### Case 5: Context pass — designing against an existing attribute set
**Input context**: Project has an existing AttributeSet with attributes: Health, MaxHealth, Stamina, MaxStamina, Defense, AttackPower.
**Input**: "Design a Berserker ability that increases AttackPower by 50% when Health drops below 30%."
**Expected behavior**:
- Uses the existing Health, MaxHealth, and AttackPower attributes — does NOT invent new attributes
- Designs a Passive GameplayAbility (or triggered Effect) that fires on Health change, checks Health/MaxHealth ratio via a GameplayEffectExecutionCalculation or Attribute-Based magnitude
- Uses a Gameplay Cue or Gameplay Tag to track the Berserker active state
- References the actual attribute names from the provided AttributeSet (AttackPower, not "Damage" or "Strength")
---
## Protocol Compliance
- [ ] Stays within declared domain (GAS: abilities, effects, attributes, tags, ability tasks)
- [ ] Redirects custom replication requests to ue-replication-specialist with clear explanation of boundary
- [ ] Returns structured findings (ability outline + GameplayEffect definition) rather than vague descriptions
- [ ] Enforces tag hierarchy naming conventions proactively
- [ ] Uses only attributes and tags present in the provided context; does not invent new ones without noting it
---
## Coverage Notes
- Case 3 (tag hierarchy) is a frequent source of subtle bugs; test whenever tag naming conventions change
- Case 4 requires knowledge of GAS stacking policies — verify this case if the GAS integration depth changes
- Case 5 is the most important context-awareness test; failing it means the agent ignores project state
- No automated runner; review manually or via `/skill-test`

View File

@@ -0,0 +1,82 @@
# Agent Test Spec: ue-replication-specialist
## Agent Summary
- **Domain**: Property replication (UPROPERTY Replicated/ReplicatedUsing), RPCs (Server/Client/NetMulticast), client prediction and reconciliation, net relevancy and always-relevant settings, net serialization (FArchive/NetSerialize), bandwidth optimization and replication frequency tuning
- **Does NOT own**: Gameplay logic being replicated (gameplay-programmer), server infrastructure and hosting (devops-engineer), GAS-specific prediction (ue-gas-specialist handles GAS net prediction)
- **Model tier**: Sonnet
- **Gate IDs**: None; escalates security-relevant replication concerns to lead-programmer
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references replication, RPCs, client prediction, bandwidth)
- [ ] `allowed-tools:` list matches the agent's role (Read/Write for C++ and Blueprint source files; no infrastructure or deployment tools)
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition does not claim authority over server infrastructure, game server architecture, or gameplay logic correctness
---
## Test Cases
### Case 1: In-domain request — replicated player health with client prediction
**Input**: "Set up replicated player health that clients can predict locally (e.g., when taking self-inflicted damage) and have corrected by the server."
**Expected behavior**:
- Produces a UPROPERTY(ReplicatedUsing=OnRep_Health) declaration in the appropriate Character or AttributeSet class
- Describes the OnRep_Health function: apply visual/audio feedback, reconcile predicted value with server-authoritative value
- Explains the client prediction pattern: local client applies tentative damage immediately, server authoritative value arrives via OnRep and corrects any discrepancy
- Notes that if GAS is in use, the built-in GAS prediction handles this — recommend coordinating with ue-gas-specialist
- Output is a concrete code structure (property declaration + OnRep outline), not a conceptual description only
### Case 2: Out-of-domain request — game server architecture
**Input**: "Design our game server infrastructure — how many dedicated servers we need, regional deployment, and matchmaking architecture."
**Expected behavior**:
- Does not produce server infrastructure architecture, hosting recommendations, or matchmaking design
- States clearly: "Server infrastructure and deployment architecture is owned by devops-engineer; I handle the Unreal replication layer within a running game session"
- Does not conflate in-game replication with server hosting concerns
### Case 3: Domain boundary — RPC without server authority validation
**Input**: "We have a Server RPC called ServerSpendCurrency that deducts in-game currency. The client calls it and the server just deducts without checking anything."
**Expected behavior**:
- Flags this as a critical security vulnerability: unvalidated server RPCs are exploitable by cheaters sending arbitrary RPC calls
- Provides the required fix: server-side validation before the deduct — check that the player actually has the currency, verify the transaction is valid, reject and log if not
- Uses the pattern: `if (!HasAuthority()) return;` guard plus explicit state validation before mutation
- Notes this should be reviewed by lead-programmer given the economy implications
- Does NOT produce the "fixed" code without explaining why the original was dangerous
### Case 4: Bandwidth optimization — high-frequency movement replication
**Input**: "Our player movement is replicated using a Vector3 position every tick. With 32 players, we're exceeding our bandwidth budget."
**Expected behavior**:
- Identifies tick-rate replication of full-precision Vector3 as bandwidth-expensive
- Proposes quantized replication: use FVector_NetQuantize or FVector_NetQuantize100 instead of raw FVector to reduce bytes per update
- Recommends reducing replication frequency via SetNetUpdateFrequency() for non-owning clients
- Notes that Unreal's built-in Character Movement Component already has optimized movement replication — recommends using or extending it rather than rolling a custom system
- Produces a concrete bandwidth estimate comparison if possible, or explains the tradeoff
### Case 5: Context pass — designing within a network budget
**Input context**: Project network budget is 64 KB/s per player, with 32 players = 2 MB/s total server outbound. Current movement replication already uses 40 KB/s per player.
**Input**: "We want to add real-time inventory replication so all clients can see other players' equipment changes immediately."
**Expected behavior**:
- Acknowledges the existing 40 KB/s movement cost leaves only 24 KB/s for everything else per player
- Does NOT design a naive full-inventory replication approach (would exceed budget)
- Recommends a delta-only or event-driven approach: replicate only changed slots rather than the full inventory array
- Uses FGameplayItemSlot or equivalent with ReplicatedUsing to trigger targeted updates
- Explicitly states the proposed approach's bandwidth estimate relative to the remaining 24 KB/s budget
---
## Protocol Compliance
- [ ] Stays within declared domain (property replication, RPCs, client prediction, bandwidth)
- [ ] Redirects server infrastructure requests to devops-engineer without producing infrastructure design
- [ ] Flags unvalidated server RPCs as security issues and recommends lead-programmer review
- [ ] Returns structured findings (property declarations, bandwidth estimates, optimization options) not freeform advice
- [ ] Uses project-provided bandwidth budget numbers when evaluating replication design choices
---
## Coverage Notes
- Case 3 (RPC security) is a shipping-critical test — unvalidated RPCs are a top-ten multiplayer exploit vector
- Case 5 is the most important context-awareness test; agent must use actual budget numbers, not generic advice
- Case 1 GAS branch: if GAS is configured, agent should detect it and defer to ue-gas-specialist for GAS-managed attributes
- No automated runner; review manually or via `/skill-test`

View File

@@ -0,0 +1,79 @@
# Agent Test Spec: ue-umg-specialist
## Agent Summary
- **Domain**: UMG widget hierarchy design, data binding patterns, CommonUI input routing and action tags, widget styling (WidgetStyle assets), UI optimization (widget pooling, ListView, invalidation)
- **Does NOT own**: UX flow and screen navigation design (ux-designer), gameplay logic (gameplay-programmer), backend data sources (game code), server communication
- **Model tier**: Sonnet
- **Gate IDs**: None; defers UX flow decisions to ux-designer
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references UMG, widget hierarchy, CommonUI)
- [ ] `allowed-tools:` list matches the agent's role (Read/Write for UI assets and Blueprint files; no server or gameplay source tools)
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition does not claim authority over UX flow, navigation architecture, or gameplay data logic
---
## Test Cases
### Case 1: In-domain request — inventory widget with data binding
**Input**: "Create an inventory widget that shows a grid of item slots. Each slot should display item icon, quantity, and rarity color. It needs to update when the inventory changes."
**Expected behavior**:
- Produces a UMG widget structure: a parent WBP_Inventory containing a UniformGridPanel or TileView, with a child WBP_InventorySlot widget per item
- Describes data binding approach: either Event Dispatchers on an Inventory Component triggering a refresh, or a ListView with a UObject item data class implementing IUserObjectListEntry
- Specifies how rarity color is driven: a WidgetStyle asset or a data table lookup, not hardcoded color values
- Output includes the widget hierarchy, binding pattern, and the refresh trigger mechanism
### Case 2: Out-of-domain request — UX flow design
**Input**: "Design the full navigation flow for our inventory system — how the player opens it, transitions to character stats, and exits to the pause menu."
**Expected behavior**:
- Does not produce a navigation flow or screen transition architecture
- States clearly: "Navigation flow and screen transition design is owned by ux-designer; I can implement the UMG widget structure once the flow is defined"
- Does not make UX decisions (back button behavior, transition animations, modal vs. fullscreen) without a UX spec
### Case 3: Domain boundary — CommonUI input action mismatch
**Input**: "Our inventory widget isn't responding to the controller Back button. We're using CommonUI."
**Expected behavior**:
- Identifies the likely cause: the widget's Back input action tag does not match the project's registered CommonUI InputAction data asset
- Explains the CommonUI input routing model: widgets declare input actions via `CommonUI_InputAction` tags; the CommonActivatableWidget handles routing
- Provides the fix: verify that the widget's Back action tag matches the registered tag in the project's CommonUI input action data table
- Distinguishes this from a hardware input binding issue (which would be Enhanced Input territory)
### Case 4: Widget performance issue — many widget instances per frame
**Input**: "Our leaderboard widget creates 500 individual WBP_LeaderboardRow instances at once. The game hitches for 300ms when opening the leaderboard."
**Expected behavior**:
- Identifies the root cause: 500 widget instantiations in a single frame causes a construction hitch
- Recommends switching to ListView or TileView with virtualization — only visible rows are constructed
- Explains the IUserObjectListEntry interface requirement for ListView data objects
- If ListView is not appropriate, recommends pooling: pre-instantiate a fixed number of rows and recycle them with new data
- Output is a concrete recommendation with the specific UMG component to use, not a vague "optimize it"
### Case 5: Context pass — CommonUI setup already configured
**Input context**: Project uses CommonUI with the following registered InputAction tags: UI.Action.Confirm, UI.Action.Back, UI.Action.Pause, UI.Action.Secondary.
**Input**: "Add a 'Sort Inventory' button to the inventory widget that works with CommonUI."
**Expected behavior**:
- Uses UI.Action.Secondary (or recommends registering a new tag like UI.Action.Sort if Secondary is already allocated)
- Does NOT invent a new InputAction tag without noting that it must be registered in the CommonUI data table
- Does NOT use a non-CommonUI input binding approach (e.g., raw key press in Event Graph) when CommonUI is the established pattern
- References the provided tag list explicitly in the recommendation
---
## Protocol Compliance
- [ ] Stays within declared domain (UMG structure, data binding, CommonUI, widget performance)
- [ ] Redirects UX flow and navigation design requests to ux-designer
- [ ] Returns structured findings (widget hierarchy + binding pattern) rather than freeform opinions
- [ ] Uses existing CommonUI InputAction tags from context; does not invent new ones without flagging registration requirement
- [ ] Recommends virtualized lists (ListView/TileView) before widget pooling for large collections
---
## Coverage Notes
- Case 3 (CommonUI input routing) requires project to have CommonUI configured; test is skipped if project does not use CommonUI
- Case 4 (performance) is a high-impact failure mode — 300ms hitches are shipping-blocking; prioritize this test case
- Case 5 is the most important context-awareness test for UI pipeline consistency
- No automated runner; review manually or via `/skill-test`

View File

@@ -0,0 +1,80 @@
# Agent Test Spec: unreal-specialist
## Agent Summary
- **Domain**: Unreal Engine patterns and architecture — Blueprint vs C++ decisions, UE subsystems (GAS, Enhanced Input, Niagara), UE project structure, plugin integration, and engine-level configuration
- **Does NOT own**: Art style and visual direction (art-director), server infrastructure and deployment (devops-engineer), UI/UX flow design (ux-designer)
- **Model tier**: Sonnet
- **Gate IDs**: None; defers gate verdicts to technical-director
---
## Static Assertions (Structural)
- [ ] `description:` field is present and domain-specific (references Unreal Engine)
- [ ] `allowed-tools:` list matches the agent's role (Read, Write for UE project files; no deployment tools)
- [ ] Model tier is Sonnet (default for specialists)
- [ ] Agent definition does not claim authority outside its declared domain (no art, no server infra)
---
## Test Cases
### Case 1: In-domain request — Blueprint vs C++ decision criteria
**Input**: "Should I implement our combo attack system in Blueprint or C++?"
**Expected behavior**:
- Provides structured decision criteria: complexity, reuse frequency, team skill, and performance requirements
- Recommends C++ for systems called every frame or shared across 5+ ability types
- Recommends Blueprint for designer-tunable values and one-off logic
- Does NOT render a final verdict without knowing project context — asks clarifying questions if context is absent
- Output is structured (criteria table or bullet list), not a freeform opinion
### Case 2: Out-of-domain request — Unity C# code
**Input**: "Write me a C# MonoBehaviour that handles player health and fires a Unity event on death."
**Expected behavior**:
- Does not produce Unity C# code
- States clearly: "This project uses Unreal Engine; the Unity equivalent would be an Actor Component in UE C++ or a Blueprint Actor Component"
- Optionally offers to provide the UE equivalent if requested
- Does not redirect to a Unity specialist (none exists in the framework)
### Case 3: Domain boundary — UE5.4 API requirement
**Input**: "I need to use the new Motion Matching API introduced in UE5.4."
**Expected behavior**:
- Flags that UE5.4 is a specific version with potentially limited LLM training coverage
- Recommends cross-referencing official Unreal docs or the project's engine-reference directory before trusting any API suggestions
- Provides best-effort API guidance with explicit uncertainty markers (e.g., "Verify this against UE5.4 release notes")
- Does NOT silently produce stale or incorrect API signatures without a caveat
### Case 4: Conflict — Blueprint spaghetti in a core system
**Input**: "Our replication logic is entirely in a deeply nested Blueprint event graph with 300+ nodes and no functions. It's becoming unmaintainable."
**Expected behavior**:
- Identifies this as a Blueprint architecture problem, not a minor style issue
- Recommends migrating core replication logic to C++ ActorComponent or GameplayAbility system
- Notes the coordination required: changes to replication architecture must involve lead-programmer
- Does NOT unilaterally declare "migrate to C++" without surfacing the scope of the refactor to the user
- Produces a concrete migration recommendation, not a vague suggestion
### Case 5: Context pass — version-appropriate API suggestions
**Input context**: Project engine-reference file states Unreal Engine 5.3.
**Input**: "How do I set up Enhanced Input actions for a new character?"
**Expected behavior**:
- Uses UE5.3-era Enhanced Input API (InputMappingContext, UEnhancedInputComponent::BindAction)
- Does NOT reference APIs introduced after UE5.3 without flagging them as potentially unavailable
- References the project's stated engine version in its response
- Provides concrete, version-anchored code or Blueprint node names
---
## Protocol Compliance
- [ ] Stays within declared domain (Unreal patterns, Blueprint/C++, UE subsystems)
- [ ] Redirects Unity or other-engine requests without producing wrong-engine code
- [ ] Returns structured findings (criteria tables, decision trees, migration plans) rather than freeform opinions
- [ ] Flags version uncertainty explicitly before producing API suggestions
- [ ] Coordinates with lead-programmer for architecture-scale refactors rather than deciding unilaterally
---
## Coverage Notes
- No automated runner exists for agent behavior tests — these are reviewed manually or via `/skill-test`
- Version-awareness (Case 3, Case 5) is the highest-risk failure mode for this agent; test regularly when engine version changes
- Case 4 integration with lead-programmer is a coordination test, not a technical correctness test