# General UE5 Conventions and Practices

## C++ conventions
- Macros: UCLASS, UPROPERTY, UFUNCTION, GENERATED_BODY() — always present on UObject types
- Naming: PascalCase for classes/functions, bBoolName for booleans; no m-prefix (not UE style)
- Forward-declare in .h, include in .cpp. Use PCH (CoreMinimal.h in .h)
- GC safety: raw UObject* in local scope OK; member pointers MUST be UPROPERTY
- Threading: game logic on Game Thread only. HTTP/IO callbacks → AsyncTask(ENamedThreads::GameThread,...)

## Asset naming conventions (Prefix_BaseName_Variant)
ALWAYS use the correct prefix when creating assets:
  BP_       Blueprint                    ABP_      Animation Blueprint
  M_        Material                     MI_       Material Instance
  S_        Static Mesh                  SK_       Skeletal Mesh
  T_        Texture                      WBP_      Widget Blueprint
  PS_       Particle System (Cascade)    NS_       Niagara System
  DT_       Data Table                   DA_       Data Asset
  BPI_      Blueprint Interface          BPFL_     Blueprint Function Library
  A_        Animation Sequence           AM_       Animation Montage
  BS_       Blend Space                  AO_       Aim Offset
  BT_       Behavior Tree                BB_       Blackboard
  AIC_      AI Controller               EQS_      Environment Query
  GE_       Gameplay Effect              GA_       Gameplay Ability
  GC_       Gameplay Cue                 IMC_      Input Mapping Context
  IA_       Input Action                 PP_       Post Process Material
Texture suffixes: _D (Diffuse) _N (Normal) _R (Roughness) _M (Metallic) _E (Emissive) _O (AO) _A (Alpha)
Folder structure: PascalCase only, no spaces or special characters in any path.

## C++ edit workflow
1. `read_file` to understand the file before editing
2. `edit_file` (targeted) or `write_file` for new files
3. `live_coding_compile` or `hot_reload` after every C++ change
4. `compile_and_check(asset_path)` after any Blueprint asset change — errors returned inline

## Blueprint workflow (via execute_python)
All Blueprint operations use `execute_python` with `import unreal`:
1. Check if asset exists (discover the method via `query_ue_api`)
2. Load: `unreal.load_asset(path)`
3. Modify via Python API
4. Compile the blueprint (discover via `query_ue_api`)
5. Save the asset (discover via `query_ue_api`)
6. ALWAYS print() results to confirm success

## Codebase search
The project is indexed automatically on editor startup (BM25, no API key needed).
Use `semantic_search` to locate code BEFORE reading random files:
  `semantic_search('GetPlayerHealth')` — finds by C++ identifier (camelCase-aware)
  `semantic_search('damage gameplay effect')` — finds by concept
If index is empty: call `index_project_for_search` once (< 30 s, no API key needed).

## Engine API reflection (via execute_python)
Before creating Blueprint graphs or C++ referencing engine types, USE `execute_python`
to get EXACT names, types, and signatures via Python reflection. NEVER guess function names or pin names.
  `cls = unreal.find_class('Character'); [f.get_name() for f in cls.get_all_functions() if 'Jump' in f.get_name()]`
  `unreal.find_function('PrintString')` — find owning class
  `enum = unreal.find_enum('EMovementMode'); [enum.get_name_by_index(i) for i in range(enum.num_enums())]`

## FORBIDDEN Python calls
- **NEVER call `open_editor_for_asset()` or `open_editor_for_assets()`** — crashes the editor
  with FMRUList null dereference in automated context. Opening asset editors is unnecessary:
  all asset modifications are done directly via Python API (set_editor_property, SCS, WidgetTree, etc.)
- **NEVER use `open()` with relative file paths** — use absolute paths or write to Saved/UND/.
  The Python working directory is NOT the project root during automated execution.

## CRITICAL — Efficiency: batch execute_python calls
Each execute_python call costs a turn. A simple Blueprint component should take 3-5 turns, NOT 20-30.
**Batch rules:**
- Create the BP + ALL variables + compile in ONE execute_python call
- Create ALL function graphs + add ALL params/returns in ONE call
- Build nodes for 2-3 functions per call (wire all pins within each function)
- Final compile + save + verify in ONE call
**Anti-pattern:** one variable per call, one function per call, one node per call → wastes 20+ turns
**Target:** 5-10 turns for a complete Blueprint component with 3-5 functions

## CRITICAL — Verify BEFORE attempting completion
After building Blueprint graphs:
1. Compile: `compile_blueprint(bp)` + `save_asset()`
2. **Validate graphs** (catches logical errors that compile misses):
```python
problems = unreal.UNDBlueprintHelpers.validate_blueprint_graphs(bp)
for p in problems: print(p)
if not problems: print('VALIDATION PASSED')
```
3. If problems found → fix them, then re-validate until empty.
4. Then `compile_and_check` to confirm zero compilation errors.
**NEVER call attempt_completion while validate_blueprint_graphs() reports problems.**

## Rules
- Minimal targeted changes — never rewrite more than necessary
- Prefer editing existing files over creating new ones
- ALWAYS verify results with print() — never assume success
