@aeonsparx/pi-unreal 0.0.0-stage → 1.1.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 +89 -0
- package/LICENSE +21 -0
- package/README.md +199 -2
- package/docs/internals.md +245 -0
- package/extensions/unreal/index.ts +696 -0
- package/extensions/unreal/lib/cache.ts +190 -0
- package/extensions/unreal/lib/compiledb.ts +491 -0
- package/extensions/unreal/lib/descriptors.ts +631 -0
- package/extensions/unreal/lib/engine-resolver.ts +443 -0
- package/extensions/unreal/lib/pi-tools.ts +452 -0
- package/extensions/unreal/lib/plugin-resolver.ts +305 -0
- package/extensions/unreal/lib/query.ts +272 -0
- package/extensions/unreal/lib/registry.ts +208 -0
- package/extensions/unreal/lib/scan.ts +510 -0
- package/extensions/unreal/lib/store.ts +1490 -0
- package/extensions/unreal/lib/tools.ts +1074 -0
- package/extensions/unreal/lib/ubt.ts +380 -0
- package/extensions/unreal/lib/util.ts +210 -0
- package/package.json +60 -4
- package/prompts/unreal-context.md +36 -0
- package/skills/ue-engine-resolution/SKILL.md +129 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ue-engine-resolution
|
|
3
|
+
description: Resolve which Unreal Engine installation a .uproject actually uses, and read .uproject/.uplugin facts from engine-authored schemas. Use when an engine path, version, plugin availability, or descriptor field must be established as fact, before UE builds, plugin edits, or any "which engine version is this?" question.
|
|
4
|
+
compatibility: Windows-first (registry via pwsh); resolver core is platform-neutral.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Unreal Engine resolution
|
|
8
|
+
|
|
9
|
+
Never infer an engine root from a directory name, a `UE_*` folder, or an environment variable alone.
|
|
10
|
+
Resolve it, then quote the resolved value.
|
|
11
|
+
|
|
12
|
+
## Order of truth
|
|
13
|
+
|
|
14
|
+
1. Run `unreal_resolve_engine` (or `/unreal`) first. It reports `engineRoot`, `identifier`,
|
|
15
|
+
`Build.version`, source rank, and — on failure — the rejected candidates with reasons.
|
|
16
|
+
2. Only after a resolution exists should a build command, a `.Build.cs` read, or an
|
|
17
|
+
engine-source lookup name a concrete engine path.
|
|
18
|
+
|
|
19
|
+
Resolution mirrors the engine's own algorithm
|
|
20
|
+
(`Engine/Source/Developer/DesktopPlatform/Private/DesktopPlatformBase.cpp:459-511`, UE 5.8):
|
|
21
|
+
|
|
22
|
+
| Association in `.uproject` | Meaning | Engine source of truth |
|
|
23
|
+
| --- | --- | --- |
|
|
24
|
+
| `5.8` | installed (Launcher) build | `HKLM:\SOFTWARE\EpicGames\Unreal Engine\5.8` → `InstalledDirectory`, plus `<installDirDefault>\UE_5.8` |
|
|
25
|
+
| `{GUID}` | source build | `HKCU:\SOFTWARE\Epic Games\Unreal Engine\Builds` → root path |
|
|
26
|
+
| engine-root **path** | explicit pin, bypasses registration | validated as `<root>/Engine/Binaries` + `<root>/Engine/Build` |
|
|
27
|
+
| **empty** | project is inside an engine tree | walk up 12 levels for `Engine/Config/BaseEngine.ini` |
|
|
28
|
+
|
|
29
|
+
An association that matches more than one valid root is reported **ambiguous** — the engine
|
|
30
|
+
refuses to pick, so neither should the agent. Pass `engineRootHint` to disambiguate.
|
|
31
|
+
|
|
32
|
+
## Machine-local facts that are not inferable
|
|
33
|
+
|
|
34
|
+
- `HKLM` registers UE 4.0 … 5.7. **UE 5.8 has no registry key**: it is found by scanning
|
|
35
|
+
`C:/Program Files/Epic Games` for `UE_*`, or by `$env:UNREAL_ENGINE`, which points at it.
|
|
36
|
+
- 5.5 and 5.6 registry entries point at directories that do not exist. A registry hit is a
|
|
37
|
+
**candidate**, never a conclusion — every candidate is validated
|
|
38
|
+
(`Engine/Binaries` + `Engine/Build` + `Engine/Build/Build.version` major.minor match)
|
|
39
|
+
before it can be reported.
|
|
40
|
+
- `D:/UnrealEngine/Source` is a source build (5.7.4) registered under a GUID in `HKCU`.
|
|
41
|
+
|
|
42
|
+
## Descriptor fields: read them from the parser, not from memory
|
|
43
|
+
|
|
44
|
+
Field names, host types, and loading phases come from the engine's own serializers, not from
|
|
45
|
+
blog posts. `unreal_project_inspect` / `unreal_plugin_inspect` report the engine's names:
|
|
46
|
+
|
|
47
|
+
- `.uproject` → `Engine/Source/Runtime/Projects/Private/ProjectDescriptor.cpp:100-225`
|
|
48
|
+
- `.uplugin` → `Engine/Source/Runtime/Projects/Private/PluginDescriptor.cpp:263-409`
|
|
49
|
+
- module entries → `Engine/Source/Runtime/Projects/Private/ModuleDescriptor.cpp`
|
|
50
|
+
(`Type` is **required**; `EHostType::FromString` → `Max` → descriptor load fails)
|
|
51
|
+
- plugin references → `Engine/Source/Runtime/Projects/Private/PluginReferenceDescriptor.cpp:130-180`
|
|
52
|
+
(`Enabled` is **required**; a reference without it is rejected)
|
|
53
|
+
|
|
54
|
+
Host types (`EHostType::ToString`) and phases (`ELoadingPhase`) are enumerated by the parser;
|
|
55
|
+
an unrecognized value is reported with the engine's own failure text. Do not "fix" a descriptor
|
|
56
|
+
by inventing a key name — fix it to the key the engine reads.
|
|
57
|
+
|
|
58
|
+
`.uplugin` has **no** `Enabled` key. Enablement is `EnabledByDefault`
|
|
59
|
+
(`PluginManager.cpp:421-431`) plus the project's `"Enabled": true` reference.
|
|
60
|
+
|
|
61
|
+
## Plugin availability
|
|
62
|
+
|
|
63
|
+
`unreal_project_inspect` resolves every reference against an index built in
|
|
64
|
+
UnrealBuildTool's discovery order (`Engine/Source/Programs/UnrealBuildTool/System/Plugins.cs:322`):
|
|
65
|
+
Engine → Project (`Plugins/`) → Mod (`Mods/`) → `AdditionalPluginDirectories`, with later scans
|
|
66
|
+
shadowing earlier ones on name collision. Use the reported status (`resolved`, `missing`,
|
|
67
|
+
`disabled`, `version-warning`, `shadowed`, `no-modules`) instead of assuming a plugin is
|
|
68
|
+
available. `Binaries/`, `Intermediate/`, `Saved/`, and `ThirdParty/` are never scanned.
|
|
69
|
+
|
|
70
|
+
Two facts are separate and both matter, and the report keeps them apart:
|
|
71
|
+
|
|
72
|
+
- **Reference status**: `Mover: resolved ← Engine · modules Mover(Runtime), MoverCVDData(Runtime),
|
|
73
|
+
MoverEditor(UncookedOnly)`. The modules are what the reference buys; "resolved" alone never said
|
|
74
|
+
which C++ exists.
|
|
75
|
+
- **Availability without a reference**: engine plugins with `EnabledByDefault: true` load even when
|
|
76
|
+
the `.uproject` does not list them, and a module can be inside the target's link graph without the
|
|
77
|
+
plugin being referenced. `unreal_context` with `module: "PhysicsControl"` reports the graph check,
|
|
78
|
+
the module directory, the declared `Type`, and the `.uproject` status as separate lines — "the
|
|
79
|
+
project lacks plugin X" is not "module X is unavailable", and not "X does not exist".
|
|
80
|
+
|
|
81
|
+
## After resolution: where declarations and build context come from
|
|
82
|
+
|
|
83
|
+
`unreal_resolve_engine` answers *which engine*. The rest of the navigation questions are answered
|
|
84
|
+
by the index tools, and they use the resolved root — a wrong engine root means a wrong index:
|
|
85
|
+
|
|
86
|
+
- `unreal_symbol` — declaration site + owning module for a type, function, `UPROPERTY`, delegate.
|
|
87
|
+
Engine scope is opt-in (`scope: "engine"`). Its roots are `Engine/Source/<area>` **plus the plugin
|
|
88
|
+
roots the `.uproject` enables** — in an installed engine most gameplay types ship as plugins
|
|
89
|
+
(`Mover`, `PoseSearch`, `SmartObjects`, `BlendStack`, `StateTree`, `GameplayAbilities`), so an
|
|
90
|
+
index of `Engine/Source/Runtime` alone reports 0 rows for `UMoverComponent`. Plugins the project
|
|
91
|
+
does not reference are opt-in too: `engineAreas: ["Plugins"]` (every `Engine/Plugins` source,
|
|
92
|
+
~2.8× the `Runtime` scan) or `engineAreas: ["Plugins/Animation/PhysicsControl"]` (one plugin).
|
|
93
|
+
- **A 0-row answer is about the roots scanned, not about the engine.** It prints the index keys, the
|
|
94
|
+
root kinds (`279 engine-source root(s), 62 engine-plugin root(s)`) and the next call. Run
|
|
95
|
+
`unreal_index` with `action: "status"` before trusting a 0: an index key encodes its root set, so
|
|
96
|
+
an index you did not build is not what was searched.
|
|
97
|
+
- `unreal_index` with `action: "headers"` — "does this header exist in this engine version?" A
|
|
98
|
+
path-only index (no content read, seconds, ~38 000 header paths on a UE 5.8 install): exact path,
|
|
99
|
+
owning module, owning plugin, `EnabledByDefault`, `.uproject` reference. Invented names return
|
|
100
|
+
*not a file path* plus the closest real **file** names — a file name is not a type, and a token
|
|
101
|
+
match is not proof of existence. Never built implicitly.
|
|
102
|
+
- `unreal_context` — include paths, C++ standard, compiler, the real `WITH_*` defines read from
|
|
103
|
+
`Definitions.<Module>.h`, and the module's public/private dependency lists. Scope is derived from
|
|
104
|
+
path shape, so `Engine/Plugins/.../Public/X.h` is searched as engine scope, and a miss answers the
|
|
105
|
+
path question separately from the symbol question.
|
|
106
|
+
- `unreal_index` — build/refresh/patch/status, `moduleRefs` for the dependency graph, and the
|
|
107
|
+
UnrealBuildTool `-Mode=Query` cache underneath.
|
|
108
|
+
|
|
109
|
+
No compiler, no IDE database, nothing written inside the project: the index lives in
|
|
110
|
+
`~/.pi/agent/unreal-cache` (`$PI_UNREAL_CACHE_DIR`). clangd stays the authority for references,
|
|
111
|
+
overrides, and diagnostics — see `ue-symbol-navigation` in a UE project's `.agents/skills/`. An
|
|
112
|
+
empty clangd answer is **evidence**: on an installed engine the compile database has no engine
|
|
113
|
+
translation units, so "clangd found nothing in engine code" describes the setup, not a defect to
|
|
114
|
+
route around.
|
|
115
|
+
|
|
116
|
+
The boundary this package does not cross: it answers C++ **declaration, module, include-path and
|
|
117
|
+
dependency** facts. Asset questions — UENUM index order, UStruct field types, UCLASS/CDO instance
|
|
118
|
+
values, component lists, parent chains, Blueprint graphs — need the `unreal-engine` editor MCP with
|
|
119
|
+
the editor running. A C++ scan cannot see them; ask a scan only what a scan can answer.
|
|
120
|
+
|
|
121
|
+
## Conventions this package enforces
|
|
122
|
+
|
|
123
|
+
- `.uasset` and `.umap` are cooked binary — author them in the running editor, never by editing
|
|
124
|
+
bytes. The gate blocks such writes.
|
|
125
|
+
- Newly compiled C++ does not load into a running editor: close the editor, then build with
|
|
126
|
+
`UnrealEngine-BuildProjectEditor`. The gate warns when `UnrealEditor*` is running during a C++ edit.
|
|
127
|
+
- Never run `clang-format` on `*.cs`: it applies the C# language rule and can empty the file
|
|
128
|
+
(verified on `Source/Lp.Target.cs`). The gate blocks such commands. Format C++ with
|
|
129
|
+
`Script/Dev/Format-Cpp.ps1`.
|