skills/n2c-context-gatherer/SKILL.md
Gather project context for C++ code generation including include paths, base class signatures, and API patterns. Sub-agent of n2c-orchestrator.
npx skillsauth add sipherxyz/universal-ue-skills n2c-context-gathererInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill reads project-specific values from skills.config.json at the repository root.
If not found, auto-detect using ue-detect-engine skill or prompt the user.
Gathers verified include paths, base class signatures, and API patterns from the project.
{
"jsonPath": "{project.root}/Saved/NodeToCode/Export/GA_Jump.json",
"metadata": {
"baseClass": "USipherGameplayAbilityRuntime",
"referencedTypes": ["FSipherAbilityData_Animation", "PlayerCombatAttributeSet"]
}
}
Success:
{
"success": true,
"includeMap": {
"USipherGameplayAbilityRuntime": "GameplayAbilities/SipherGameplayAbilityRuntime.h",
"FSipherAbilityData_Animation": "GameplayAbilities/AbilityData/SipherAbilityData_Animation.h",
"PlayerCombatAttributeSet": "Core/ASC/AttributeSet/PlayerCombatAttributeSet.h"
},
"baseClassContext": {
"className": "USipherGameplayAbilityRuntime",
"headerPath": "GameplayAbilities/SipherGameplayAbilityRuntime.h",
"fullHeaderPath": "{project.root}/Source/S2/Public/GameplayAbilities/SipherGameplayAbilityRuntime.h",
"virtualMethods": [
{
"name": "K2_OverrideRuntimeData_Implementation",
"signature": "virtual bool K2_OverrideRuntimeData_Implementation(TInstancedStruct<FSipherGenericAbilityData>& OverridenData)",
"returnType": "bool",
"isConst": false
},
{
"name": "ActivateAbility",
"signature": "virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override",
"returnType": "void",
"isConst": false
}
],
"memberVariables": ["AnimationData", "AbilityData"]
},
"apiPatterns": {
"UAITask_MoveTo": "Use OnMoveTaskFinished.AddUObject (public), NOT OnMoveFinished.AddDynamic (protected)",
"AbilityWaitDelay": "Use UAbilityTask_WaitDelay::WaitDelay, NOT UGameplayTask_WaitDelay",
"TSoftObjectPtr": "Call .LoadSynchronous() when assigning to raw pointer",
"AttributeGetter": "Use 2-param version returning float, NOT 3-param with out reference"
},
"namingConventions": {
"actorPrefix": "ASipher",
"componentPrefix": "USipher",
"structPrefix": "FSipher",
"enumPrefix": "ESipher"
},
"potentialConflicts": ["AnimationData", "AbilityData"]
}
Failure:
{
"success": false,
"errorCode": "BASE_CLASS_NOT_FOUND",
"errorMessage": "Could not find header for USipherGameplayAbilityRuntime",
"searchedPaths": ["Source/S2/Public", "Plugins/..."]
}
| Code | Description |
|------|-------------|
| BASE_CLASS_NOT_FOUND | Cannot locate base class header |
| TYPE_NOT_FOUND | Referenced type not in project |
| AMBIGUOUS_TYPE | Multiple headers define same type |
| PARSE_ERROR | Cannot parse header file |
Search these locations in order:
1. Source/S2/Public/**/*.h
2. Source/S2/Private/**/*.h
3. Plugins/Sipher*/Source/*/Public/**/*.h
4. Plugins/Sipher*/Source/*/Private/**/*.h
5. Plugins/Frameworks/*/Source/*/Public/**/*.h
6. Plugins/Frameworks/*/Source/*/Private/**/*.h
From metadata, collect all types to resolve:
types_to_resolve = set()
# Add base class
types_to_resolve.add(metadata.baseClass)
# Add all referenced types
for type_name in metadata.referencedTypes:
types_to_resolve.add(type_name)
# Clean type names (remove prefixes/suffixes)
# "SKEL_USipherGameplayAbility_C" -> "USipherGameplayAbility"
For each type, search for its header:
# Search pattern for class declaration
grep -r "class\s+\w*_API\s+{ClassName}\s*:" Source/S2/Public --include="*.h" -l
grep -r "class\s+{ClassName}\s*:" Source/S2/Public --include="*.h" -l
# Search pattern for struct declaration
grep -r "struct\s+\w*_API\s+{ClassName}" Source/S2/Public --include="*.h" -l
grep -r "struct\s+{ClassName}" Source/S2/Public --include="*.h" -l
# Also search plugins
grep -r "class.*{ClassName}" Plugins/Sipher*/Source/*/Public --include="*.h" -l
grep -r "class.*{ClassName}" Plugins/Frameworks/*/Source/*/Public --include="*.h" -l
Build include map:
include_map = {}
for type_name in types_to_resolve:
header_path = find_header(type_name)
if header_path:
# Convert absolute path to relative include path
# {project.root}/Source/S2/Public/Core/ASC/SipherASC.h -> Core/ASC/SipherASC.h
relative_path = make_relative(header_path, "Source/S2/Public/")
include_map[type_name] = relative_path
else:
# Mark as not found
include_map[type_name] = None
Read the base class header and extract virtual methods:
# Find base class header
BASE_HEADER=$(grep -r "class.*{BaseClassName}.*:" Source/S2/Public Plugins/Sipher*/Source/*/Public Plugins/Frameworks/*/Source/*/Public --include="*.h" -l | head -1)
Parse header for virtual methods:
# Read header content
header_content = read_file(base_header_path)
# Extract virtual method declarations
# Pattern: virtual {return_type} {method_name}({params}) [const] [override] [= 0];
virtual_pattern = r'virtual\s+(\w+[\w\s\*\&<>,]*)\s+(\w+)\s*\(([^)]*)\)\s*(const)?\s*(override)?\s*(=\s*0)?'
virtual_methods = []
for match in re.finditer(virtual_pattern, header_content):
return_type = match.group(1).strip()
method_name = match.group(2)
params = match.group(3)
is_const = bool(match.group(4))
virtual_methods.append({
"name": method_name,
"signature": match.group(0).rstrip(';'),
"returnType": return_type,
"isConst": is_const
})
Extract member variables (to detect shadowing):
# Pattern: UPROPERTY(...) {type} {name};
# or plain: {type} {name};
member_pattern = r'(?:UPROPERTY[^)]*\))?\s*(\w+[\w\s\*\&<>,]*)\s+(\w+)\s*[;=]'
member_variables = []
for match in re.finditer(member_pattern, header_content):
var_name = match.group(2)
if var_name not in ['GENERATED_BODY', 'public', 'private', 'protected']:
member_variables.append(var_name)
Check for known UE5.7 patterns in the codebase:
# Check UAITask_MoveTo delegate pattern
grep -r "OnMoveTaskFinished" Plugins/Frameworks/SipherAIScalableFramework --include="*.h" --include="*.cpp" | head -3
grep -r "OnMoveFinished" Plugins/Frameworks/SipherAIScalableFramework --include="*.h" --include="*.cpp" | head -3
# Check AbilityTask_WaitDelay usage
grep -r "UAbilityTask_WaitDelay" Source/S2 Plugins/Sipher* --include="*.cpp" | head -3
# Check TSoftObjectPtr loading pattern
grep -r "\.LoadSynchronous()" Source/S2 Plugins/Sipher* --include="*.cpp" | head -3
# Check attribute getter pattern
grep -r "GetCharacterAttributeValue" Source/S2/Public/BFL --include="*.h" -A2 | head -5
Build API patterns based on findings:
api_patterns = {}
if found_OnMoveTaskFinished and not_found_OnMoveFinished_public:
api_patterns["UAITask_MoveTo"] = "Use OnMoveTaskFinished.AddUObject (public), NOT OnMoveFinished.AddDynamic (protected)"
if found_UAbilityTask_WaitDelay:
api_patterns["AbilityWaitDelay"] = "Use UAbilityTask_WaitDelay::WaitDelay, NOT UGameplayTask_WaitDelay"
# Always include these known patterns
api_patterns["TSoftObjectPtr"] = "Call .LoadSynchronous() when assigning to raw pointer"
api_patterns["K2Functions"] = "Use native functions (SetActorLocation), NOT K2_ wrappers (K2_SetActorLocation)"
Compare member variables with common local variable names:
potential_conflicts = []
common_local_names = ["AnimationData", "AbilityData", "CombatData", "CharacterData", "TargetData"]
for member in member_variables:
if member in common_local_names:
potential_conflicts.append(member)
{
"success": true,
"includeMap": { ... },
"baseClassContext": {
"className": "USipherGameplayAbilityRuntime",
"headerPath": "GameplayAbilities/SipherGameplayAbilityRuntime.h",
"fullHeaderPath": "{project.root}/Source/S2/Public/GameplayAbilities/SipherGameplayAbilityRuntime.h",
"virtualMethods": [ ... ],
"memberVariables": ["AnimationData", "AbilityData"]
},
"apiPatterns": { ... },
"namingConventions": {
"actorPrefix": "ASipher",
"componentPrefix": "USipher",
"structPrefix": "FSipher",
"enumPrefix": "ESipher"
},
"potentialConflicts": ["AnimationData"]
}
If a type cannot be found in project source:
{
"includeMap": {
"UGameplayAbility": {
"external": true,
"module": "GameplayAbilities",
"include": "Abilities/GameplayAbility.h"
}
}
}
development
This skill should be used when implementing features in isolation using git worktrees. Triggers on "create worktree", "isolated workspace", "parallel development", or when starting implementation that should not affect main workspace.
testing
Manage VFX team issues on GitHub Projects - timeline scheduling, status updates, member commit checks, bulk assign. Use when managing VFX team project board, adding issues to timeline, checking member progress, or bulk-updating issue fields.
tools
Generate C++ validation rules from JSON definitions. Use when team updates ValidationRules.json or asks to add/modify validation rules.
development
Check codebase for Microsoft Xbox XR (Xbox Requirements) compliance issues. Scans for account picker, cloud saves, achievements, Quick Resume, and Xbox certification requirements. Use before console submission or when preparing for Microsoft certification. Triggers on "XR", "Xbox certification", "Microsoft compliance", "Xbox cert", "Xbox requirements", "GDK compliance".