EmbarkStudios / EmbarkStudios/UnrealClaudeFileHelper

Comprehensive analysis: accuracy, completeness, and reliability improvements

Open
#13 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
17
Forks
1
PR merge metrics
No merged PRs in 30d

Description

# Unreal Index — Comprehensive Analysis & Improvement Proposals

**Date:** 2026-02-07
**Index Size:** ~69,700 files across 9 projects (Discovery: 4,081, Engine: 24,830, EnginePlugins: 35,913, Shared: 1,473, Pioneer: 3,080, configs: 143)

This issue documents findings from an extensive evaluation of all 8 unreal-index MCP tools, with specific reproducible examples and prioritized improvement suggestions.

---

## P0 — Critical Issues

### 1. Grep searches far too few files (file coverage broken)

The `unreal_grep` tool consistently searches a tiny fraction of indexed files, making it unreliable for comprehensive usage searches.

**Repro examples:**

| Query | Project filter | Language | Files searched | Expected |
|-------|---------------|----------|---------------|----------|
| `TravelFailure` | Discovery | (all) | **1** | ~4,081 |
| `TravelFailure` | Shared | (all) | **0** | ~1,473 |
| `UPROPERTY.*EditAnywhere` | Discovery | angelscript | **3** | ~4,081 |
| `void BeginPlay` | Discovery | angelscript | **6** | ~4,081 |
| `TravelFailure` | (none) | (all) | 8 | ~69,700 |

It appears a pre-filtering optimization (trigram index?) is discarding the vast majority of files before the actual search runs. This makes grep unreliable for discovering all usages of a pattern, which forces fallback to filesystem grep and defeats the purpose of the index.

**Expected:** Grep should search ALL files matching the project/language filter, or at minimum report when pre-filtering excluded files.

### 2. FVector (and likely other core engine types) resolves to wrong file

Searching `FVector` with `project: Engine` returns:
```
TextureShareSDKUnrealEngineContainers.h (line 65, VirtualProduction program)
```

The real `FVector` is defined in `Runtime/Core/Public/Math/Vector.h` (via `UE_DECLARE_LWC_TYPE` macro). Because the index can't parse the macro-generated definition, it picks up a redefinition in an obscure program instead.

This affects the single most commonly-used struct in Unreal. Similar issues likely affect other macro-defined core types (`FRotator`, `FTransform`, `FQuat`, etc.).

**Expected:** Core math types should resolve to their canonical location, even if that requires special-casing or a priority/canonical flag.

---

## P1 — High Impact

### 3. `find_member` does not return function signatures

When searching for a function like `TakeDamage`, the result includes:
- Function name, containing type, line number, file path, specifiers

But does NOT include:
- Return type
- Parameter types and names
- Whether it's virtual/override
- Access modifier (public/private/protected)

This means every `find_member` call must be followed by a file read to understand the actual API. Adding signatures would eliminate ~50% of follow-up file reads for an AI coding assistant.

**Expected result format:**
```json
{
"name": "TakeDamage",
"signature": "void TakeDamage(float DamageAmount, FDamageEvent DamageEvent, AController EventInstigator, AActor DamageCauser)",
"returnType": "void",
"access": "public",
"isVirtual": true,
...
}
```

### 4. C++ base class members are not indexed

`GetPlayerState` with `containingType: APlayerController` returns **0 results**, because C++ class members are not in the member index (only the type definition is indexed).

This means the entire API surface of base classes (AActor, APlayerController, UActorComponent, UWidget, etc.) is invisible to member search. Since AngelScript classes inherit from these, this is a significant gap.

**Expected:** At minimum, index UFUNCTION/UPROPERTY-marked members in C++ headers, as these are the ones exposed to AngelScript.

---

## P2 — Medium Impact

### 5. Fuzzy scoring too permissive — low-relevance results are noise

Searching `EmbarkGameMode` with `fuzzy: true` returns results down to score 0.5, including:
- `FOnEmbarkGameplayEffectRemovedDelegate` (score 0.5) — shares no semantic relationship with "GameMode"
- `FEmbarkClientOnlineModelSyncGameSettingsCompleted` (score 0.7) — barely related

**Suggestion:** Default minimum score threshold of 0.7, or add a `minScore` parameter.

### 6. No asset class filter on `find_asset`

Can't filter to "only Materials" or "only Blueprints". Searching `M_Highlight` returns Materials mixed with DataAssets and Charms.

**Suggestion:** Add `assetClass` parameter (Blueprint, Material, DataAsset, Map, etc.)

### 7. No default project configuration

When working on Discovery, every unfiltered query returns Pioneer results that are almost never relevant. Must manually specify `project: Discovery` on every call.

**Suggestion:** Add a session-level `defaultProject` configuration, or at minimum rank the "home" project results higher.

### 8. `find_file` scoring doesn't differentiate exact vs partial matches

Searching `DiscoveryPlayerController` returns 4 files all with score 0.7:
- `DiscoveryPlayerController.as` (exact match — should be 1.0)
- `DiscoveryPlayerControllerBoot.as` (partial)
- `DiscoveryPlayerControllerAudioComponent.as` (partial)
- `DiscoveryPlayerControllerReferenceValidator.as` (partial)

**Expected:** Exact filename matches should score significantly higher than partial matches.

---

## P3 — Nice to Have

### 9. No `find_references` / "Find Usages" tool

There's no structured way to find all callers of a function or all references to a type. Grep is the fallback but is unreliable (see issue #1) and returns raw text, not structured references.

A dedicated `find_references(memberName, containingType)` that returns call sites with context would be very valuable.

### 10. `browse_module` lacks shallow mode

Browsing `Discovery.Discovery.GameMode` (524 files) returns a flat list of all types recursively. No way to see just the immediate directory contents or just file names.

**Suggestion:** Add `shallow: true` and `filesOnly: true` options.

### 11. `find_type` has no prefix-agnostic search

Searching `PlayerController` (without `A` prefix) with exact match finds nothing. Must know the exact Unreal prefix convention.

**Suggestion:** Auto-strip/auto-try `A`/`U`/`F`/`E` prefixes on exact match failure.

### 12. `find_children` could return depth and summary info

Currently returns a flat list. Would be useful to include:
- Inheritance depth (1 = direct child, 2 = grandchild)
- Summary mode: child count grouped by project

---

## What Works Great

For balance, these aspects are excellent:

- **Speed:** All operations return in <500ms. Speed is not an issue at all.
- **`find_children`:** Inheritance trees are accurate and complete. Best tool in the suite.
- **`find_type` exact match for AngelScript:** Fast, correct, single-result responses.
- **`find_member` with `containingType`:** Precise single-result lookups when you know the type.
- **`list_modules`:** Clean, informative, well-structured with file counts.
- **`find_asset`:** Returns useful metadata including parent class for Blueprints.
- **Config file indexing:** INI files being indexed under `DiscoveryConfig`/`EngineConfig` is very useful.

---

## Overall Assessment

| Tool | Accuracy | Completeness | Usability | Grade |
|------|----------|--------------|-----------|-------|
| find_type | 7/10 | 8/10 | 8/10 | **B+** |
| find_member | 6/10 | 5/10 | 7/10 | **C+** |
| find_children | 9/10 | 8/10 | 8/10 | **A-** |
| grep | 4/10 | 3/10 | 7/10 | **D+** |
| find_file | 8/10 | 9/10 | 7/10 | **B+** |
| browse_module | 7/10 | 7/10 | 5/10 | **B-** |
| list_modules | 9/10 | 9/10 | 9/10 | **A** |
| find_asset | 8/10 | 8/10 | 7/10 | **B** |

**Overall: B-** — Strong structural foundation with fast lookups, but grep reliability and missing signature information significantly limit practical usefulness for an AI coding assistant.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.