claude-code-arcane 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +54 -6
- package/agents/game/ue-blueprint-specialist.md +125 -0
- package/agents/game/ue-gas-specialist.md +133 -0
- package/agents/game/ue-umg-specialist.md +131 -0
- package/dist/cli.js +5 -0
- package/docs/SKILLS-CATALOG.md +42 -3
- package/docs/USER-GUIDE.md +2 -2
- package/hooks/detect-unreal.sh +90 -0
- package/package.json +1 -1
- package/profiles/unreal-dev.yaml +97 -0
- package/rules/gamedev/unreal-code.md +125 -0
- package/skills/install-mcp/SKILL.md +135 -46
- package/skills/install-mcp/references/unreal-operations.md +55 -0
- package/skills/ue-actor-component-architecture/SKILL.md +509 -0
- package/skills/ue-actor-component-architecture/references/actor-lifecycle.md +301 -0
- package/skills/ue-actor-component-architecture/references/component-types.md +592 -0
- package/skills/ue-ai-navigation/SKILL.md +526 -0
- package/skills/ue-ai-navigation/references/behavior-tree-patterns.md +392 -0
- package/skills/ue-ai-navigation/references/behavior-tree-workflow.md +107 -0
- package/skills/ue-ai-navigation/references/custom-bttask.md +104 -0
- package/skills/ue-ai-navigation/references/eqs-reference.md +423 -0
- package/skills/ue-animation-system/SKILL.md +521 -0
- package/skills/ue-animation-system/references/anim-notify-reference.md +486 -0
- package/skills/ue-animation-system/references/locomotion-setup.md +550 -0
- package/skills/ue-async-threading/SKILL.md +433 -0
- package/skills/ue-async-threading/references/thread-safety-guide.md +213 -0
- package/skills/ue-async-threading/references/threading-patterns.md +345 -0
- package/skills/ue-audio-system/SKILL.md +527 -0
- package/skills/ue-audio-system/references/audio-setup-patterns.md +700 -0
- package/skills/ue-blueprints/SKILL.md +134 -0
- package/skills/ue-blueprints/references/communication.md +82 -0
- package/skills/ue-character-movement/SKILL.md +475 -0
- package/skills/ue-character-movement/references/cmc-extension-patterns.md +335 -0
- package/skills/ue-character-movement/references/movement-pipeline.md +189 -0
- package/skills/ue-cpp-foundations/SKILL.md +533 -0
- package/skills/ue-cpp-foundations/references/components-and-gc.md +107 -0
- package/skills/ue-cpp-foundations/references/container-patterns.md +544 -0
- package/skills/ue-cpp-foundations/references/delegate-patterns.md +497 -0
- package/skills/ue-cpp-foundations/references/gameplay-classes-cpp.md +136 -0
- package/skills/ue-cpp-foundations/references/property-specifiers.md +306 -0
- package/skills/ue-data-assets-tables/SKILL.md +527 -0
- package/skills/ue-data-assets-tables/references/asset-loading-patterns.md +306 -0
- package/skills/ue-data-assets-tables/references/data-driven-design.md +378 -0
- package/skills/ue-editor-tools/SKILL.md +523 -0
- package/skills/ue-editor-tools/references/detail-customization-patterns.md +395 -0
- package/skills/ue-editor-tools/references/editor-module-setup.md +480 -0
- package/skills/ue-game-features/SKILL.md +477 -0
- package/skills/ue-game-features/references/experience-system.md +222 -0
- package/skills/ue-game-features/references/game-feature-patterns.md +308 -0
- package/skills/ue-gameplay-abilities/SKILL.md +518 -0
- package/skills/ue-gameplay-abilities/references/ability-task-reference.md +391 -0
- package/skills/ue-gameplay-abilities/references/gameplay-effect-reference.md +397 -0
- package/skills/ue-gameplay-abilities/references/gas-setup-patterns.md +369 -0
- package/skills/ue-gameplay-framework/SKILL.md +466 -0
- package/skills/ue-gameplay-framework/references/framework-class-map.md +243 -0
- package/skills/ue-input-system/SKILL.md +394 -0
- package/skills/ue-input-system/references/cpp-setup.md +131 -0
- package/skills/ue-input-system/references/enhanced-input-workflow.md +117 -0
- package/skills/ue-input-system/references/input-action-reference.md +731 -0
- package/skills/ue-mass-entity/SKILL.md +476 -0
- package/skills/ue-mass-entity/references/mass-entity-patterns.md +319 -0
- package/skills/ue-mass-entity/references/mass-fragment-reference.md +119 -0
- package/skills/ue-materials-rendering/SKILL.md +526 -0
- package/skills/ue-materials-rendering/references/material-parameter-reference.md +216 -0
- package/skills/ue-materials-rendering/references/post-process-settings.md +383 -0
- package/skills/ue-module-build-system/SKILL.md +487 -0
- package/skills/ue-module-build-system/references/build-cs-reference.md +418 -0
- package/skills/ue-module-build-system/references/common-build-errors.md +381 -0
- package/skills/ue-naming-conventions/SKILL.md +142 -0
- package/skills/ue-naming-conventions/references/asset-name-modifiers.md +233 -0
- package/skills/ue-naming-conventions/references/content-structure.md +83 -0
- package/skills/ue-networking-replication/SKILL.md +452 -0
- package/skills/ue-networking-replication/references/replication-patterns.md +526 -0
- package/skills/ue-networking-replication/references/rpc-decision-guide.md +393 -0
- package/skills/ue-niagara-effects/SKILL.md +531 -0
- package/skills/ue-niagara-effects/references/niagara-data-interfaces.md +491 -0
- package/skills/ue-niagara-effects/references/niagara-parameter-types.md +153 -0
- package/skills/ue-niagara-effects/references/niagara-workflow.md +115 -0
- package/skills/ue-packaging/SKILL.md +116 -0
- package/skills/ue-physics-collision/SKILL.md +423 -0
- package/skills/ue-physics-collision/references/collision-channel-setup.md +218 -0
- package/skills/ue-physics-collision/references/trace-patterns.md +499 -0
- package/skills/ue-procedural-generation/SKILL.md +505 -0
- package/skills/ue-procedural-generation/references/pcg-node-reference.md +381 -0
- package/skills/ue-procedural-generation/references/procedural-mesh-patterns.md +940 -0
- package/skills/ue-project-context/SKILL.md +305 -0
- package/skills/ue-sequencer-cinematics/SKILL.md +506 -0
- package/skills/ue-sequencer-cinematics/references/sequencer-patterns.md +629 -0
- package/skills/ue-serialization-savegames/SKILL.md +524 -0
- package/skills/ue-serialization-savegames/references/save-system-architecture.md +705 -0
- package/skills/ue-state-trees/SKILL.md +489 -0
- package/skills/ue-state-trees/references/state-tree-mass-integration.md +184 -0
- package/skills/ue-state-trees/references/state-tree-patterns.md +321 -0
- package/skills/ue-testing-debugging/SKILL.md +520 -0
- package/skills/ue-testing-debugging/references/automation-test-patterns.md +387 -0
- package/skills/ue-testing-debugging/references/profiling-commands.md +357 -0
- package/skills/ue-ui-umg-slate/SKILL.md +431 -0
- package/skills/ue-ui-umg-slate/references/common-ui-setup.md +484 -0
- package/skills/ue-ui-umg-slate/references/widget-types.md +487 -0
- package/skills/ue-world-level-streaming/SKILL.md +518 -0
- package/skills/ue-world-level-streaming/references/streaming-patterns.md +414 -0
- package/templates/gamedev/unreal-project-context.md +107 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# SessionStart hook: inject a short note identifying the session as operating inside
|
|
3
|
+
# an Unreal Engine project, so Claude defaults to UE conventions and reaches for the
|
|
4
|
+
# ue-* skills. Walks upward from $PWD so sessions started in a subdirectory
|
|
5
|
+
# (Source/, Content/, Plugins/, ...) are still detected.
|
|
6
|
+
#
|
|
7
|
+
# Adapted from EpicGames/unreal-engine-skills-for-claude-code-plugin (MIT).
|
|
8
|
+
# Opt-in debug logging: set CLAUDE_UE_HOOK_DEBUG to any non-empty value.
|
|
9
|
+
set +e
|
|
10
|
+
|
|
11
|
+
debug() {
|
|
12
|
+
[[ -n "$CLAUDE_UE_HOOK_DEBUG" ]] && echo "detect-unreal.sh: $*" >&2
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
is_project_root() {
|
|
16
|
+
# Reliable top-level markers only. A bare `Engine` directory is NOT a marker: the
|
|
17
|
+
# Unreal source tree contains an `Engine` module at Engine/Source/Runtime/Engine,
|
|
18
|
+
# so walking up from a Runtime module would otherwise short-circuit at
|
|
19
|
+
# Source/Runtime and mis-identify it as the root.
|
|
20
|
+
local directory="$1"
|
|
21
|
+
[[ -f "$directory/GenerateProjectFiles.bat" ]] && return 0
|
|
22
|
+
[[ -f "$directory/GenerateProjectFiles.sh" ]] && return 0
|
|
23
|
+
[[ -f "$directory/GenerateProjectFiles.command" ]] && return 0
|
|
24
|
+
for candidate in "$directory"/*.uproject; do
|
|
25
|
+
[[ -e "$candidate" ]] && return 0
|
|
26
|
+
done
|
|
27
|
+
return 1
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
find_project_root() {
|
|
31
|
+
local directory="$1"
|
|
32
|
+
while [[ -n "$directory" ]]; do
|
|
33
|
+
if is_project_root "$directory"; then
|
|
34
|
+
echo "$directory"
|
|
35
|
+
return 0
|
|
36
|
+
fi
|
|
37
|
+
local parent
|
|
38
|
+
parent="$(dirname "$directory")"
|
|
39
|
+
[[ "$parent" == "$directory" ]] && break
|
|
40
|
+
directory="$parent"
|
|
41
|
+
done
|
|
42
|
+
return 1
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
main() {
|
|
46
|
+
local project_root
|
|
47
|
+
project_root="$(find_project_root "$PWD")"
|
|
48
|
+
if [[ -z "$project_root" ]]; then
|
|
49
|
+
debug "no Unreal Engine project marker found walking up from $PWD"
|
|
50
|
+
return 0
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
local project_type="game"
|
|
54
|
+
[[ -d "$project_root/Engine" ]] && project_type="engine"
|
|
55
|
+
|
|
56
|
+
local uproject_filename=""
|
|
57
|
+
for candidate in "$project_root"/*.uproject; do
|
|
58
|
+
if [[ -e "$candidate" ]]; then
|
|
59
|
+
uproject_filename="$(basename "$candidate")"
|
|
60
|
+
break
|
|
61
|
+
fi
|
|
62
|
+
done
|
|
63
|
+
|
|
64
|
+
debug "project root: $project_root (type=$project_type, uproject=$uproject_filename)"
|
|
65
|
+
|
|
66
|
+
local context="This working directory is an Unreal Engine project."
|
|
67
|
+
if [[ "$project_type" == "engine" ]]; then
|
|
68
|
+
context="$context It is an Engine source tree."
|
|
69
|
+
elif [[ -n "$uproject_filename" ]]; then
|
|
70
|
+
context="$context The project is \`$uproject_filename\`."
|
|
71
|
+
fi
|
|
72
|
+
context="$context Prefer Unreal Engine conventions (C++/UObject patterns, Slate, UHT reflection) when suggesting code."
|
|
73
|
+
context="$context Arcane ships ue-* skills for this stack; run /ue-project-context first if docs/unreal/project-context.md does not exist yet."
|
|
74
|
+
context="$context Unreal ships its own MCP server as engine plugins; run /install-mcp to enable and connect it."
|
|
75
|
+
|
|
76
|
+
if [[ -f "$project_root/.mcp.json" ]]; then
|
|
77
|
+
context="$context An \`.mcp.json\` is already present at the project root."
|
|
78
|
+
else
|
|
79
|
+
context="$context No \`.mcp.json\` is present yet. Run \`ModelContextProtocol.GenerateClientConfig ClaudeCode\` in the editor console to generate one."
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
# JSON-escape the dynamic content: backslash first, then double quote.
|
|
83
|
+
local escaped="${context//\\/\\\\}"
|
|
84
|
+
escaped="${escaped//\"/\\\"}"
|
|
85
|
+
|
|
86
|
+
printf '{"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"%s"}}\n' "$escaped"
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
main 2>/dev/null
|
|
90
|
+
exit 0
|
package/package.json
CHANGED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
name: unreal-dev
|
|
2
|
+
description: "Programador Unreal Engine 5 — C++, Blueprints, GAS, replication, rendering, naming conventions, build y editor MCP"
|
|
3
|
+
type: base
|
|
4
|
+
|
|
5
|
+
skills:
|
|
6
|
+
# Foundation — read this first, every other ue-* skill depends on it
|
|
7
|
+
- ue-project-context
|
|
8
|
+
- ue-naming-conventions
|
|
9
|
+
# C++ & architecture
|
|
10
|
+
- ue-cpp-foundations
|
|
11
|
+
- ue-actor-component-architecture
|
|
12
|
+
- ue-gameplay-framework
|
|
13
|
+
- ue-module-build-system
|
|
14
|
+
- ue-async-threading
|
|
15
|
+
# Blueprints
|
|
16
|
+
- ue-blueprints
|
|
17
|
+
# Gameplay systems
|
|
18
|
+
- ue-gameplay-abilities
|
|
19
|
+
- ue-character-movement
|
|
20
|
+
- ue-animation-system
|
|
21
|
+
- ue-physics-collision
|
|
22
|
+
- ue-game-features
|
|
23
|
+
- ue-networking-replication
|
|
24
|
+
# AI & behaviour
|
|
25
|
+
- ue-ai-navigation
|
|
26
|
+
- ue-state-trees
|
|
27
|
+
- ue-mass-entity
|
|
28
|
+
# Rendering & VFX
|
|
29
|
+
- ue-materials-rendering
|
|
30
|
+
- ue-niagara-effects
|
|
31
|
+
# Audio & cinematics
|
|
32
|
+
- ue-audio-system
|
|
33
|
+
- ue-sequencer-cinematics
|
|
34
|
+
# World & data
|
|
35
|
+
- ue-world-level-streaming
|
|
36
|
+
- ue-procedural-generation
|
|
37
|
+
- ue-data-assets-tables
|
|
38
|
+
- ue-serialization-savegames
|
|
39
|
+
# UI & input
|
|
40
|
+
- ue-ui-umg-slate
|
|
41
|
+
- ue-input-system
|
|
42
|
+
# Tooling, build & QA
|
|
43
|
+
- ue-editor-tools
|
|
44
|
+
- ue-testing-debugging
|
|
45
|
+
- ue-packaging
|
|
46
|
+
# Cross-engine, reused from the shared library
|
|
47
|
+
# Unreal ships its own MCP as engine plugins; install-mcp only enables and connects it.
|
|
48
|
+
- install-mcp
|
|
49
|
+
- test-setup
|
|
50
|
+
- perf-profile
|
|
51
|
+
- optimize
|
|
52
|
+
- deps-audit
|
|
53
|
+
- env-sync
|
|
54
|
+
- security-audit
|
|
55
|
+
- release-checklist
|
|
56
|
+
- patch-notes
|
|
57
|
+
- onboard
|
|
58
|
+
- map-systems
|
|
59
|
+
- game-audit
|
|
60
|
+
- audit-game
|
|
61
|
+
- asset-audit
|
|
62
|
+
- accessibility
|
|
63
|
+
- balance-check
|
|
64
|
+
- consistency-check
|
|
65
|
+
- doc-gdd
|
|
66
|
+
- playtest-report
|
|
67
|
+
|
|
68
|
+
rules:
|
|
69
|
+
universal:
|
|
70
|
+
[]
|
|
71
|
+
gamedev:
|
|
72
|
+
- unreal-code
|
|
73
|
+
- gameplay-code
|
|
74
|
+
- engine-code
|
|
75
|
+
- shader-code
|
|
76
|
+
- network-code
|
|
77
|
+
- ui-code
|
|
78
|
+
- ai-code
|
|
79
|
+
|
|
80
|
+
agents:
|
|
81
|
+
- game
|
|
82
|
+
|
|
83
|
+
permissions:
|
|
84
|
+
allow:
|
|
85
|
+
- "Bash(*RunUAT*)"
|
|
86
|
+
- "Bash(*UnrealBuildTool*)"
|
|
87
|
+
- "Bash(*UnrealEditor-Cmd*)"
|
|
88
|
+
- "Bash(*GenerateProjectFiles*)"
|
|
89
|
+
- "Glob(Source/**)"
|
|
90
|
+
- "Glob(Plugins/**)"
|
|
91
|
+
- "Grep(Source/**)"
|
|
92
|
+
deny:
|
|
93
|
+
- "Write(Content/**)"
|
|
94
|
+
- "Edit(Content/**)"
|
|
95
|
+
- "Write(Binaries/**)"
|
|
96
|
+
- "Write(Intermediate/**)"
|
|
97
|
+
- "Write(DerivedDataCache/**)"
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
paths:
|
|
3
|
+
- "Source/**"
|
|
4
|
+
- "Plugins/**/Source/**"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Unreal Engine C++ Rules
|
|
8
|
+
|
|
9
|
+
- Every UObject reference held by another UObject must be a `TObjectPtr<>` marked `UPROPERTY()` — an unmarked pointer is invisible to the GC and becomes a dangling pointer
|
|
10
|
+
- Never `new`/`delete` a UObject — use `NewObject<>()` or `CreateDefaultSubobject<>()`; use `TSharedPtr`/`TUniquePtr`/`TWeakPtr` only for non-UObject types
|
|
11
|
+
- Follow engine naming: `U` for UObject, `A` for AActor, `F` for structs, `E` for enums, `I` for interfaces, `T` for templates
|
|
12
|
+
- Restrict every identifier to `[A-Za-z0-9_]` — no whitespace, no symbols, no Unicode. This applies to type names, asset references and paths alike; non-ASCII identifiers break cooking, batch tools and source control in ways that surface far from the cause
|
|
13
|
+
- Use `FName` for identifiers and lookups, `FText` for anything shown to a player, `FString` only for manipulation — never build display strings by concatenating `FString` for localized UI
|
|
14
|
+
- Use `TArray`/`TMap`/`TSet`, not STL containers, in any reflected or engine-facing code
|
|
15
|
+
- `Tick` is opt-in, not default: disable it (`PrimaryActorTick.bCanEverTick = false`) and use timers, delegates or events instead. Ticking work multiplied across instances is a measured cost, not an assumption
|
|
16
|
+
- ZERO allocations in hot paths (tick, animation, physics, rendering) — pre-allocate, pool and reuse
|
|
17
|
+
- Always call `Super::` in overridden engine functions (`BeginPlay`, `EndPlay`, `Tick`, `GetLifetimeReplicatedProps`, `PostInitializeComponents`)
|
|
18
|
+
- Every replicated `UPROPERTY(Replicated)` must appear in `GetLifetimeReplicatedProps` with a `DOREPLIFETIME` entry, and every Server RPC must validate its input — never trust the client
|
|
19
|
+
- Use soft references (`TSoftObjectPtr`, `TSoftClassPtr`) plus the Asset Manager for assets that are not always needed; a hard reference pulls the whole asset tree into memory
|
|
20
|
+
- No synchronous load of large assets on the game thread during gameplay — use `StreamableManager` / async loading
|
|
21
|
+
- UObject access happens on the game thread only; async completion paths must handle their owner being destroyed mid-flight
|
|
22
|
+
- Editor-only code lives in an editor module or behind `WITH_EDITOR`, and never ships in a runtime target
|
|
23
|
+
- Profile with Unreal Insights and `stat` commands before AND after every optimization — document the measured numbers
|
|
24
|
+
- Blueprint Nativization was removed in UE5; never propose it as an optimization
|
|
25
|
+
|
|
26
|
+
## Examples
|
|
27
|
+
|
|
28
|
+
**Correct** (GC-visible reference, no tick, validated RPC):
|
|
29
|
+
|
|
30
|
+
```cpp
|
|
31
|
+
UCLASS()
|
|
32
|
+
class AGate : public AActor
|
|
33
|
+
{
|
|
34
|
+
GENERATED_BODY()
|
|
35
|
+
|
|
36
|
+
public:
|
|
37
|
+
AGate()
|
|
38
|
+
{
|
|
39
|
+
PrimaryActorTick.bCanEverTick = false; // event-driven, nothing to tick
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
protected:
|
|
43
|
+
virtual void BeginPlay() override
|
|
44
|
+
{
|
|
45
|
+
Super::BeginPlay(); // never skip Super
|
|
46
|
+
OnActorBeginOverlap.AddDynamic(this, &AGate::HandleOverlap);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
UFUNCTION(Server, Reliable, WithValidation)
|
|
50
|
+
void ServerRequestOpen();
|
|
51
|
+
|
|
52
|
+
private:
|
|
53
|
+
// TObjectPtr + UPROPERTY: the GC can see and keep this alive.
|
|
54
|
+
UPROPERTY(VisibleAnywhere)
|
|
55
|
+
TObjectPtr<UStaticMeshComponent> Frame;
|
|
56
|
+
|
|
57
|
+
// Soft reference: the VFX only loads when the gate actually opens.
|
|
58
|
+
UPROPERTY(EditDefaultsOnly)
|
|
59
|
+
TSoftObjectPtr<UNiagaraSystem> OpenEffect;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
bool AGate::ServerRequestOpen_Validate()
|
|
63
|
+
{
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
void AGate::ServerRequestOpen_Implementation()
|
|
68
|
+
{
|
|
69
|
+
// Server re-checks authority and state; the client's word is not enough.
|
|
70
|
+
if (!HasAuthority() || bIsLocked)
|
|
71
|
+
{
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
OpenInternal();
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Incorrect** (invisible to GC, needless tick, trusted client, hot-path allocation):
|
|
79
|
+
|
|
80
|
+
```cpp
|
|
81
|
+
UCLASS()
|
|
82
|
+
class AGate : public AActor
|
|
83
|
+
{
|
|
84
|
+
GENERATED_BODY()
|
|
85
|
+
|
|
86
|
+
// VIOLATION: raw pointer with no UPROPERTY — GC cannot see it, this will dangle
|
|
87
|
+
UStaticMeshComponent* Frame;
|
|
88
|
+
|
|
89
|
+
// VIOLATION: hard reference, loads the VFX and its dependencies with this actor
|
|
90
|
+
UPROPERTY()
|
|
91
|
+
UNiagaraSystem* OpenEffect;
|
|
92
|
+
|
|
93
|
+
virtual void BeginPlay() override
|
|
94
|
+
{
|
|
95
|
+
// VIOLATION: missing Super::BeginPlay()
|
|
96
|
+
Frame = new UStaticMeshComponent(); // VIOLATION: never new a UObject
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
virtual void Tick(float DeltaTime) override
|
|
100
|
+
{
|
|
101
|
+
// VIOLATION: allocates every frame
|
|
102
|
+
TArray<AActor*> Nearby;
|
|
103
|
+
UGameplayStatics::GetAllActorsOfClass(GetWorld(), APawn::StaticClass(), Nearby);
|
|
104
|
+
|
|
105
|
+
// VIOLATION: string comparison in a hot path — use FName or a tag
|
|
106
|
+
for (AActor* A : Nearby)
|
|
107
|
+
{
|
|
108
|
+
if (A->GetName() == TEXT("BP_Player_C_0"))
|
|
109
|
+
{
|
|
110
|
+
OpenInternal();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
UFUNCTION(Server, Unreliable)
|
|
116
|
+
void ServerRequestOpen(bool bClientSaysUnlocked)
|
|
117
|
+
{
|
|
118
|
+
// VIOLATION: trusts a client-supplied authority decision
|
|
119
|
+
if (bClientSaysUnlocked)
|
|
120
|
+
{
|
|
121
|
+
OpenInternal();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
```
|
|
@@ -1,45 +1,60 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: install-mcp
|
|
3
|
-
description: "
|
|
3
|
+
description: "Conecta Claude Code con el MCP del engine: Unity (package UPM CoplayDev) o Unreal (plugins del engine). Detecta, registra y verifica. Usar para: mcp unity, mcp unreal, setup MCP del editor."
|
|
4
4
|
category: "gamedev"
|
|
5
|
-
argument-hint: "[--secondary] [project-path]"
|
|
5
|
+
argument-hint: "[unity | unreal] [--secondary] [project-path]"
|
|
6
6
|
user-invocable: true
|
|
7
7
|
allowed-tools: Read, Glob, Grep, Bash, Write, Edit
|
|
8
8
|
---
|
|
9
|
-
# install-mcp —
|
|
9
|
+
# install-mcp — Engine MCP Setup
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Conecta Claude Code con el editor del engine via MCP. Los dos engines difieren en algo importante:
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
| | Unity | Unreal |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| **De donde viene el MCP** | Package de terceros (CoplayDev) | **Plugins propios del engine** (`ModelContextProtocol` + `AllToolsets`) |
|
|
16
|
+
| **Se suma algo al proyecto** | Si — package UPM en `Packages/manifest.json` | **No** — ya viene con el engine, solo se habilita |
|
|
17
|
+
| **Que hace este skill** | Instalar + registrar + verificar | Habilitar + conectar + verificar |
|
|
15
18
|
|
|
16
|
-
>
|
|
19
|
+
> En Unreal **no hay nada que instalar**. El server y los toolsets son plugins del engine; el trabajo es habilitarlos en el `.uproject`, prender auto-start y generar el `.mcp.json`. No agregues packages ni plugins de terceros.
|
|
17
20
|
|
|
18
21
|
## Input
|
|
19
22
|
|
|
20
|
-
- `
|
|
21
|
-
-
|
|
23
|
+
- `unity` | `unreal` (opcional): fuerza el engine. Sin argumento, se autodetecta.
|
|
24
|
+
- `project-path` (opcional): raiz del proyecto. Default: directorio actual.
|
|
25
|
+
- `--secondary` (opcional, **solo Unity**): ademas del primario, instala el package CoderGamester.
|
|
22
26
|
|
|
23
27
|
---
|
|
24
28
|
|
|
25
|
-
##
|
|
29
|
+
## Phase 1: Detectar el engine
|
|
26
30
|
|
|
27
|
-
|
|
31
|
+
Desde `project-path` (o cwd), buscar marcadores:
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
| Marcador | Engine |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `Packages/manifest.json` + `ProjectSettings/ProjectVersion.txt` | Unity |
|
|
36
|
+
| `*.uproject` (o `GenerateProjectFiles.*` en un source tree) | Unreal |
|
|
32
37
|
|
|
33
|
-
Si
|
|
38
|
+
- Si el argumento explicito contradice los marcadores, **avisar y preguntar** antes de seguir.
|
|
39
|
+
- Si no hay marcadores, **abortar**: "No parece un proyecto Unity ni Unreal. Pasa la ruta con `/install-mcp [unity|unreal] <project-path>`."
|
|
40
|
+
- Si aparecen ambos, preguntar cual.
|
|
34
41
|
|
|
35
|
-
|
|
42
|
+
Confirmar el engine detectado y la ruta antes de tocar archivos.
|
|
36
43
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Phase 2A: Unity — instalar y registrar
|
|
47
|
+
|
|
48
|
+
### 1. Verificar prerrequisitos
|
|
49
|
+
|
|
50
|
+
`uv --version` y `uvx --version` (server del primario). Si falta `uv`, **no abortar**: avisar, dar el comando y seguir editando el manifest.
|
|
51
|
+
|
|
52
|
+
- Windows: `winget install astral-sh.uv`
|
|
53
|
+
- alternativa: `pipx install uv`
|
|
54
|
+
|
|
55
|
+
Solo con `--secondary`: `node --version`. Si falta, avisar (el server CoderGamester no podra correr).
|
|
41
56
|
|
|
42
|
-
###
|
|
57
|
+
### 2. Agregar el package UPM
|
|
43
58
|
|
|
44
59
|
Leer `Packages/manifest.json`. Dentro de `"dependencies"`, agregar **solo si la key no existe** (idempotente — nunca duplicar):
|
|
45
60
|
|
|
@@ -47,61 +62,135 @@ Leer `Packages/manifest.json`. Dentro de `"dependencies"`, agregar **solo si la
|
|
|
47
62
|
"com.coplaydev.unity-mcp": "https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#main"
|
|
48
63
|
```
|
|
49
64
|
|
|
50
|
-
Con `--secondary`, agregar
|
|
65
|
+
Con `--secondary`, agregar tambien:
|
|
51
66
|
|
|
52
67
|
```json
|
|
53
68
|
"com.gamelovers.mcp-unity": "https://github.com/CoderGamester/mcp-unity.git"
|
|
54
69
|
```
|
|
55
70
|
|
|
56
|
-
Usar `Edit` puntual sobre el bloque `dependencies` preservando el JSON
|
|
71
|
+
Usar `Edit` puntual sobre el bloque `dependencies` preservando el JSON valido (indentacion, comas). Si la key ya estaba, reportar "ya presente, sin cambios".
|
|
57
72
|
|
|
58
|
-
> **Antes de escribir**, mostrar el diff propuesto sobre `manifest.json` (y el `.mcp.json` del paso
|
|
73
|
+
> **Antes de escribir**, mostrar el diff propuesto sobre `manifest.json` (y el `.mcp.json` del paso 3B si aplica) y pedir aprobacion al usuario. No editar sin confirmacion.
|
|
59
74
|
|
|
60
|
-
###
|
|
61
|
-
|
|
62
|
-
Dos caminos, en orden de preferencia:
|
|
75
|
+
### 3. Registrar el server en Claude Code
|
|
63
76
|
|
|
64
77
|
**A. Recomendado (auto-config desde Unity).** Instruir al usuario:
|
|
65
|
-
1. Abrir el proyecto en Unity (
|
|
78
|
+
1. Abrir el proyecto en Unity (importara el package nuevo).
|
|
66
79
|
2. `Window → MCP for Unity`.
|
|
67
|
-
3.
|
|
80
|
+
3. Usar el boton de auto-configuracion para **Claude Code** — instala el server `uv` y registra el cliente.
|
|
68
81
|
|
|
69
|
-
**B. Fallback manual.**
|
|
82
|
+
**B. Fallback manual.** Registrar el transport HTTP de CoplayDev:
|
|
70
83
|
|
|
71
84
|
```bash
|
|
72
85
|
claude mcp add --transport http unity-mcp http://127.0.0.1:8080
|
|
73
86
|
```
|
|
74
87
|
|
|
75
|
-
|
|
76
|
-
|
|
88
|
+
> El server solo responde con Unity abierto y `MCP for Unity` activo. Registrar el cliente no levanta el server.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Phase 2B: Unreal — habilitar y conectar
|
|
93
|
+
|
|
94
|
+
Nada se instala. Tres pasos, en orden. **No edites el `.uproject` sin confirmar la ruta con el usuario.**
|
|
95
|
+
|
|
96
|
+
### 1. Habilitar los plugins del engine en el `.uproject`
|
|
97
|
+
|
|
98
|
+
Dos plugins, ambos requeridos. `ModelContextProtocol` es el server y el transport; `AllToolsets` provee las tools. Con solo `ModelContextProtocol` el server arranca pero **no expone ninguna tool**.
|
|
99
|
+
|
|
100
|
+
En el array `Plugins` del `.uproject`, asegurar las dos entradas:
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{ "Name": "ModelContextProtocol", "Enabled": true },
|
|
104
|
+
{ "Name": "AllToolsets", "Enabled": true }
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Si el array no existe, crearlo. Si alguna entrada esta en `"Enabled": false`, pasarla a `true`. Mostrar el diff y pedir aprobacion antes de escribir.
|
|
108
|
+
|
|
109
|
+
`AllToolsets` es un agregador editor-only con `EnabledByDefault` apagado, asi que hay que habilitarlo explicitamente. Para exponer solo un subconjunto, habilitar los plugins de toolset puntuales en lugar de `AllToolsets`.
|
|
110
|
+
|
|
111
|
+
### 2. Prender auto-start
|
|
77
112
|
|
|
78
|
-
|
|
113
|
+
Por default el server queda detenido. Para arrancarlo a mano en una sesion: `ModelContextProtocol.StartServer` desde la consola del editor.
|
|
79
114
|
|
|
80
|
-
|
|
115
|
+
Para que arranque en cada launch, agregar al config per-user del editor:
|
|
81
116
|
|
|
82
|
-
|
|
117
|
+
`<Project>/Saved/Config/<Platform>Editor/EditorPerProjectUserSettings.ini`
|
|
118
|
+
|
|
119
|
+
```ini
|
|
120
|
+
[/Script/ModelContextProtocolEngine.ModelContextProtocolSettings]
|
|
121
|
+
bAutoStartServer=True
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Es per-user y no va a source control. Overrides opcionales si el default choca con otro servicio local:
|
|
125
|
+
|
|
126
|
+
```ini
|
|
127
|
+
ServerPortNumber=8000
|
|
128
|
+
ServerUrlPath=/mcp
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Alternativa por command line: `-ModelContextProtocolStartServer` (y `-ModelContextProtocolPort=<port>`). Preferir el `.ini` porque persiste.
|
|
132
|
+
|
|
133
|
+
### 3. Generar el `.mcp.json`
|
|
134
|
+
|
|
135
|
+
El editor no lo escribe solo.
|
|
136
|
+
|
|
137
|
+
**Con el editor corriendo (preferido):** `ModelContextProtocol.GenerateClientConfig ClaudeCode` en la consola (o `All` para todos los clientes soportados). Re-correrlo mergea sobre el JSON existente, asi que es seguro despues de cambiar puerto o path.
|
|
138
|
+
|
|
139
|
+
El destino depende del tipo de build:
|
|
140
|
+
- **Source build** (el repo contiene `Engine/`): se escribe en la raiz del workspace, al lado de `Engine/` — **no** junto al `.uproject`.
|
|
141
|
+
- **Installed/launcher build**: se escribe junto al `.uproject`.
|
|
142
|
+
|
|
143
|
+
**Sin lanzar el editor**, escribir a mano en la ubicacion que corresponda:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"mcpServers": {
|
|
148
|
+
"unreal-mcp": {
|
|
149
|
+
"type": "http",
|
|
150
|
+
"url": "http://127.0.0.1:8000/mcp"
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Ajustar la URL si se override el puerto o el path en el paso 2.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Phase 3: Verificar
|
|
83
161
|
|
|
84
162
|
```bash
|
|
85
163
|
claude mcp list
|
|
86
164
|
```
|
|
87
165
|
|
|
88
|
-
Reportar si
|
|
166
|
+
Reportar si el server aparece **conectado** (`unity-mcp` o `unreal-mcp` segun el engine). En Unreal, dos senales extra: el Output Log muestra mensajes de arranque del MCP, y `list_toolsets` responde.
|
|
89
167
|
|
|
90
|
-
|
|
168
|
+
**Si NO esta conectado, avisar explicitamente** y aclarar que las operaciones de engine (scenes, assets, blueprints, prefabs, UI wiring) NO se aplicaron — no asumir exito.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Phase 4: Resumen
|
|
91
173
|
|
|
92
174
|
Reportar:
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
175
|
+
- Engine detectado y ruta del proyecto.
|
|
176
|
+
- **Unity:** que keys se agregaron a `manifest.json` (o si ya estaban).
|
|
177
|
+
- **Unreal:** que plugins se habilitaron en el `.uproject`, si se prendio auto-start, y donde quedo el `.mcp.json`.
|
|
178
|
+
- Estado del registro y resultado de `claude mcp list`.
|
|
179
|
+
- Proximo paso manual, si queda alguno.
|
|
97
180
|
|
|
98
181
|
**Verdict:**
|
|
99
|
-
- **READY** —
|
|
100
|
-
- **PENDING** —
|
|
101
|
-
- **BLOCKED** — falta un prerrequisito (`uv` ausente) o no es un proyecto
|
|
182
|
+
- **READY** — server registrado y conectado en `claude mcp list`.
|
|
183
|
+
- **PENDING** — config lista, pero falta abrir el editor para que el server conecte (Unity: `Window → MCP for Unity`; Unreal: lanzar el editor con auto-start, o `ModelContextProtocol.StartServer`). Avisar que las operaciones de engine aun NO estan disponibles.
|
|
184
|
+
- **BLOCKED** — falta un prerrequisito (`uv` ausente en Unity), el `.uproject` no se pudo editar, o no es un proyecto valido. Indicar el fix.
|
|
102
185
|
|
|
103
|
-
|
|
186
|
+
## Next Steps
|
|
187
|
+
|
|
188
|
+
- **Unity:** `/unity-game-architecture` o `/scaffold-unity` para trabajar el proyecto
|
|
189
|
+
- **Unreal:** `/ue-project-context` primero (el resto de los `ue-*` lo leen), despues `/ue-cpp-foundations` o `/ue-blueprints`
|
|
190
|
+
- Si el server no conecta, ver el troubleshooting de la referencia del engine que corresponda
|
|
104
191
|
|
|
105
192
|
---
|
|
106
193
|
|
|
107
|
-
> → Read references/manual-setup.md for
|
|
194
|
+
> → Read references/manual-setup.md for el flujo manual de Unity (`Window → MCP for Unity`), troubleshooting (uv no encontrado, puerto 8080 ocupado, MCP no conecta) y la variante secundaria CoderGamester
|
|
195
|
+
|
|
196
|
+
> → Read references/unreal-operations.md for los console commands de Unreal (`StartServer`, `StopServer`, `RefreshTools`, `GenerateClientConfig`), el modo tool-search y la matriz de troubleshooting (puerto ocupado, toolset faltante, tool calls que cuelgan)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Unreal MCP — Console Commands, Settings, Recovery
|
|
2
|
+
|
|
3
|
+
> Adapted from the `unreal-mcp` skill in [EpicGames/unreal-engine-skills-for-claude-code-plugin](https://github.com/EpicGames/unreal-engine-skills-for-claude-code-plugin) (MIT). References to the upstream `setup.md` were remapped to Phase 2B of this skill.
|
|
4
|
+
|
|
5
|
+
Read this when something is misbehaving with the Unreal MCP server (tools missing, port collision, stale tool registry), or when you need a non-default configuration.
|
|
6
|
+
|
|
7
|
+
Remember: the server and toolsets are **engine plugins**. Nothing here installs anything into the project — it enables, restarts and reconfigures what the engine already ships.
|
|
8
|
+
|
|
9
|
+
## Console commands
|
|
10
|
+
|
|
11
|
+
Run these from the Unreal Editor console (`~`).
|
|
12
|
+
|
|
13
|
+
| Command | Use it for |
|
|
14
|
+
|---------|------------|
|
|
15
|
+
| `ModelContextProtocol.StartServer [port]` | Start the MCP server. Pass a port to override the default (e.g. when 8000 is in use). |
|
|
16
|
+
| `ModelContextProtocol.StopServer` | Stop the server. Useful if the registry is in a bad state and you want a clean restart. |
|
|
17
|
+
| `ModelContextProtocol.RefreshTools` | Re-register every toolset. Run this after enabling a new toolset plugin. |
|
|
18
|
+
| `ModelContextProtocol.GenerateClientConfig <client>` | Regenerate the per-client config file. Args: `ClaudeCode`, `Cursor`, `VSCode`, `Gemini`, `Codex`, `All`. |
|
|
19
|
+
|
|
20
|
+
Codex is the exception for config generation: it uses TOML and the writer refuses to overwrite an existing `.codex/config.toml`. Edit that one by hand if it already exists.
|
|
21
|
+
|
|
22
|
+
## Tool-search mode
|
|
23
|
+
|
|
24
|
+
`tools/list` has two modes, controlled by the `bEnableToolSearch` UPROPERTY on `UModelContextProtocolSettings` (default `true`):
|
|
25
|
+
|
|
26
|
+
- **`True`** (default): `tools/list` returns only `list_toolsets`, `describe_toolset`, `call_tool`. Toolset tools are dispatched server-side through `call_tool` and stay out of the prompt; the catalog never changes mid-session, so the prompt cache stays warm.
|
|
27
|
+
- **`False`**: every toolset tool is registered as a native MCP tool at startup, with schemas visible upfront.
|
|
28
|
+
|
|
29
|
+
Override in the same `.ini` used for `bAutoStartServer` (see Phase 2B):
|
|
30
|
+
|
|
31
|
+
```ini
|
|
32
|
+
[/Script/ModelContextProtocolEngine.ModelContextProtocolSettings]
|
|
33
|
+
bEnableToolSearch=False
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Troubleshooting matrix
|
|
37
|
+
|
|
38
|
+
| Symptom | What to do |
|
|
39
|
+
|---------|------------|
|
|
40
|
+
| `unreal-mcp` not in `claude mcp list` / `/mcp`, or `list_toolsets` errors | The editor isn't running, or the server isn't started. Launch the editor and run `ModelContextProtocol.StartServer`, or enable `bAutoStartServer` per Phase 2B. Then check the Output Log for startup errors. |
|
|
41
|
+
| Editor logs "Failed to listen on port" | Another process holds the default port. Change `ServerPortNumber` in the per-user `EditorPerProjectUserSettings.ini`, or pass `-ModelContextProtocolPort=<port>` on the next launch. Restart the editor, then re-run `ModelContextProtocol.GenerateClientConfig ClaudeCode` to refresh `.mcp.json`. |
|
|
42
|
+
| A toolset you expect (e.g. `NiagaraTools`) is missing | Run `ModelContextProtocol.RefreshTools`. If still missing, that toolset's plugin may not be enabled in the `.uproject` — check there. Remember `AllToolsets` is the aggregator and is off by default. |
|
|
43
|
+
| Tool calls hang or return errors | The editor may be busy compiling, loading a level, or in PIE. Wait and retry. For long compiles, prefer `LiveCodingToolset.CompileLiveCoding`, which returns when the compile actually finishes. |
|
|
44
|
+
| `AIAssistantToolset.GetDockedContext` returns empty | The Claude Code tab must be docked inside an asset editor (Blueprint, Material, etc.) to provide docked context. Undocked, that tool has nothing to report. |
|
|
45
|
+
| Sequential tool calls collide | Tool calls execute on the game thread. Don't issue them in parallel, even when they look independent. Serialize them. |
|
|
46
|
+
|
|
47
|
+
## Safety notes when driving the editor
|
|
48
|
+
|
|
49
|
+
These matter because every MCP call mutates live editor state on the game thread:
|
|
50
|
+
|
|
51
|
+
- **Save before and after** any bulk change. MCP edits are not always undoable, especially across compilation boundaries.
|
|
52
|
+
- **Wait for compilation** to finish before issuing further calls.
|
|
53
|
+
- **Never parallelize** tool calls.
|
|
54
|
+
- **Read every result.** Many tools return a status that flips between success and failure without raising. Treat anything that isn't an explicit success as a stop.
|
|
55
|
+
- **Mind PIE.** Editor-only tools, asset creation in particular, behave differently while Play-in-Editor is active.
|