Compare commits
2 Commits
493ae99d90
...
4d325c8a44
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d325c8a44 | |||
| f8fca90c6f |
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
## Coding Style Preferences
|
## Coding Style Preferences
|
||||||
|
|
||||||
- **NO STATIC FUNCTIONS in Unreal code.** Use class methods or namespace-scoped functions instead. This is a hard rule — the user has corrected this multiple times.
|
- **No FREE-FLOATING (file-scope) static functions in Unreal code.** Use class methods (incl. `static` member functions) or namespace-scoped functions instead. A `static` member function inside a class is fine — e.g. a Blueprint-callable factory. The rule is only against file-local `static` free functions. (Corrected 2026-05-26 after I misread this as banning all `static`.)
|
||||||
- Prefer in-class member initializers (`int x_ = 0;` in the header) over explicit initialization in constructor bodies. When touching constructors, migrate toward this style.
|
- Prefer in-class member initializers (`int x_ = 0;` in the header) over explicit initialization in constructor bodies. When touching constructors, migrate toward this style.
|
||||||
- Inline empty constructors/destructors in the header when possible.
|
- Inline empty constructors/destructors in the header when possible.
|
||||||
- Avoid ternary operator unless very concise (e.g., `x ? 1 : 0`). For longer expressions, use early-return `if` instead.
|
- Avoid ternary operator unless very concise (e.g., `x ? 1 : 0`). For longer expressions, use early-return `if` instead.
|
||||||
@@ -46,11 +46,18 @@
|
|||||||
- Blueprints in `/Game/Luprex/` use the `lx` prefix (e.g., `lxPlayerController`) and are loaded directly, not through the asset lookup system.
|
- Blueprints in `/Game/Luprex/` use the `lx` prefix (e.g., `lxPlayerController`) and are loaded directly, not through the asset lookup system.
|
||||||
- See `Source/Integration/AssetLookup.cpp` for the indexing logic.
|
- See `Source/Integration/AssetLookup.cpp` for the indexing logic.
|
||||||
|
|
||||||
## MCP / Blueprint Editing
|
## UE Wingman
|
||||||
|
|
||||||
- BlueprintMCP plugin is in `Plugins/BlueprintMCP/` (C++ plugin, editor-only). Listens on TCP port 9847.
|
- UE Wingman is a command-line tool (no longer an MCP server). Plugin lives in `Plugins/UEWingman/`; CLI is `ue-wingman` (on PATH at `/home/jyelon/bin/ue-wingman`).
|
||||||
- Python MCP bridge is `tools/mcp-bridge.py` (stdio transport, forwards to TCP port 9847).
|
- Invoke directly via Bash. Subcommands are CamelCase, e.g. `ue-wingman Graph_Dump <path> True`.
|
||||||
- Blueprint text exports go to `Saved/BlueprintExports/<PackageName>/` — includes both custom graph exports and Unreal's copy-format ASCII dump.
|
- Start by reading the manual: `ue-wingman Documentation_Manual`. Also useful: `Documentation_Commands` (concise list), `Documentation_Command <Name>` (detailed help for one command).
|
||||||
|
- Common commands: `Blueprint_Dump`, `Graph_Dump`, `Details_Dump`, `Details_Set`, `GraphNode_ShowMenu`, `GraphNode_ChooseMenu`, `Variables_Add`/`Modify`/`Remove`, `TypeName_Search`.
|
||||||
|
- Fetcher path syntax: `/Game/<Asset>,graph:<GraphName>,node:<NodeId>,pin:<PinName>` (also `widget:`, `component:`, `levelblueprint:`, `structprop:`). FNames in paths use periods for spaces (e.g. `graph:Handle.Invalid.Lua.Command`, not `HandleInvalidLuaCommand`). Other marks `\"'(),.:;<=>&` use HTML entity escapes like ` `.
|
||||||
|
- ue-wingman is much faster than the LLM — batch multiple commands with `;` instead of running one at a time.
|
||||||
|
|
||||||
|
## Project
|
||||||
|
|
||||||
|
- [Eris addinfo intentionally removed](project_eris_addinfo_removed.md) — `luaG_runerror` no longer prefixes `file:line:`; traceback machinery handles location info
|
||||||
|
|
||||||
## Feedback
|
## Feedback
|
||||||
|
|
||||||
@@ -58,3 +65,7 @@
|
|||||||
- [Use mv for file renames](feedback_rename_with_mv.md) — mv + targeted edits, don't rewrite from memory
|
- [Use mv for file renames](feedback_rename_with_mv.md) — mv + targeted edits, don't rewrite from memory
|
||||||
- [LLDB formatter style — let lldb do the math](feedback_lldb_formatter_style.md) — typed SBValues, no raw pointer/byte math in Python
|
- [LLDB formatter style — let lldb do the math](feedback_lldb_formatter_style.md) — typed SBValues, no raw pointer/byte math in Python
|
||||||
- [LLDB formatter style — no defensive IsValid checks](feedback_lldb_formatter_no_defensive_checks.md) — let invalid SBValues fail loudly; silent returns conceal bugs
|
- [LLDB formatter style — no defensive IsValid checks](feedback_lldb_formatter_no_defensive_checks.md) — let invalid SBValues fail loudly; silent returns conceal bugs
|
||||||
|
- [C++ never depends on Blueprint](feedback_cpp_no_bp_dependency.md) — construct widget trees in C++; don't reference WBP assets from C++
|
||||||
|
- [Prefer check() over silent-skip](feedback_check_over_silent_skip.md) — invariants use check(); silent continue/return hides bugs
|
||||||
|
- [Don't auto-build after every change](feedback_dont_auto_build.md) — only build when the user asks
|
||||||
|
- [Edit workspace template, not the generated file](feedback_workspace_template.md) — `Integration.code-workspace` is generated; edit `Integration.code-workspace.tpl.json`
|
||||||
17
claude/integration-memory/feedback_check_over_silent_skip.md
Normal file
17
claude/integration-memory/feedback_check_over_silent_skip.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
name: Prefer check() over silent-skip for invariants
|
||||||
|
description: In C++ code, when a condition is an invariant that should always hold (not a legitimate filter), use check() instead of a silent continue/return that hides the bug
|
||||||
|
type: feedback
|
||||||
|
originSessionId: a2780d4f-894b-402a-8101-324052832606
|
||||||
|
---
|
||||||
|
When writing C++ code in this project, if a condition represents an **invariant** (something that must always be true based on how the code is structured), use `check()` to assert it — do **not** silently `continue`/`return`/guard past it.
|
||||||
|
|
||||||
|
**Why:** Silent skips conceal bugs. If the invariant is ever violated, the code just mysteriously produces a shorter list, a missing widget, a zero count — with no signal that anything went wrong. `check()` fails loudly and makes the broken invariant visible and diagnosable. The user has articulated this as a general principle: "I am strongly against code that hides bugs by failing silently."
|
||||||
|
|
||||||
|
**How to apply:**
|
||||||
|
- **Invariant → `check()`**: something that must hold given how the code is wired AND a violation would propagate silently (stored in a container, passed to a function that tolerates null, absorbed by a later filter). Example: pushing a potentially-null pointer into a TSet or TArray — segfault won't happen until much later.
|
||||||
|
- **Invariant about to be dereferenced → nothing**: if the very next line dereferences the pointer, a null will segfault on its own. That IS a loud failure. Don't add a `check()` just for style — the segfault is the check. Also don't add checks for things that were *just constructed* and cannot be null in any realistic scenario ("we just built this array").
|
||||||
|
- **Legitimate filter → `if (...) continue;`**: a real business-logic condition that may or may not hold for different inputs. Example: filtering `Slots` to only those whose `Content` is a `UUserWidget` — other widget types are legitimate children, so skipping them is a filter, not hiding a bug.
|
||||||
|
- When in doubt, ask: "If this condition is false, is that a bug? AND will the bug propagate silently?" Only `check()` when BOTH are true.
|
||||||
|
|
||||||
|
Related: [LLDB formatter style — no defensive IsValid checks](feedback_lldb_formatter_no_defensive_checks.md) is the same principle applied specifically to lldb SBValue chains.
|
||||||
11
claude/integration-memory/feedback_cpp_no_bp_dependency.md
Normal file
11
claude/integration-memory/feedback_cpp_no_bp_dependency.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
name: C++ never depends on Blueprint, only the reverse
|
||||||
|
description: Never propose C++ code that loads/references Blueprint assets; dependency direction is strictly BP → C++
|
||||||
|
type: feedback
|
||||||
|
originSessionId: a2780d4f-894b-402a-8101-324052832606
|
||||||
|
---
|
||||||
|
C++ code in this project must never depend on Blueprint assets. Dependencies flow one way only: Blueprints may depend on C++, never the reverse.
|
||||||
|
|
||||||
|
**Why:** The user has stated this as a firm architectural principle. C++ that references BP assets (by soft class path, string, or otherwise) inverts the normal layering and creates fragile coupling to content.
|
||||||
|
|
||||||
|
**How to apply:** When suggesting UMG patterns, do not propose solutions that involve C++ doing `CreateWidget` on a WBP class, loading a WBP via `FSoftClassPath`, or otherwise reaching from C++ into `/Game/...` content. For UMG work initiated from C++, construct widget trees programmatically in C++ (override `RebuildWidget`, manipulate `WidgetTree` directly). Blueprint subclasses of C++ widget classes are fine — that's BP depending on C++.
|
||||||
14
claude/integration-memory/feedback_dont_auto_build.md
Normal file
14
claude/integration-memory/feedback_dont_auto_build.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
name: Don't build after every code change
|
||||||
|
description: Don't automatically run build.py after every edit; wait for the user to ask for a build
|
||||||
|
type: feedback
|
||||||
|
originSessionId: a2780d4f-894b-402a-8101-324052832606
|
||||||
|
---
|
||||||
|
Do not run `build.py` (or any build command) after every code change. The user will explicitly ask for a build when they want one.
|
||||||
|
|
||||||
|
**Why:** The user is iterating quickly and doesn't want to wait for builds between every small edit. Builds take ~10s and add noise to the conversation. The user will batch up several changes and ask for a build when they want to verify.
|
||||||
|
|
||||||
|
**How to apply:**
|
||||||
|
- Make code edits and report them. Stop there.
|
||||||
|
- Only run `build.py c++` when the user explicitly asks ("build please", "build", "verify it compiles", etc.).
|
||||||
|
- Don't proactively build after a rename, refactor, or other "obviously needs verification" change. Trust the user to ask if they want it.
|
||||||
11
claude/integration-memory/feedback_workspace_template.md
Normal file
11
claude/integration-memory/feedback_workspace_template.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
name: Edit workspace template, not the generated file
|
||||||
|
description: Integration.code-workspace is generated; edit Integration.code-workspace.tpl.json instead
|
||||||
|
type: feedback
|
||||||
|
originSessionId: b0f1e20f-9463-4d0f-aead-52a71412214a
|
||||||
|
---
|
||||||
|
`Integration.code-workspace` is a generated file. The source of truth is `Integration.code-workspace.tpl.json` at the project root.
|
||||||
|
|
||||||
|
**Why:** Edits to the generated `.code-workspace` get blown away the next time the workspace is regenerated, silently losing the change.
|
||||||
|
|
||||||
|
**How to apply:** Whenever a settings change needs to land in the VS Code workspace (e.g., `clangd.path`, `clangd.arguments`, file associations), edit `Integration.code-workspace.tpl.json`. Don't touch `Integration.code-workspace` directly.
|
||||||
14
claude/integration-memory/project_eris_addinfo_removed.md
Normal file
14
claude/integration-memory/project_eris_addinfo_removed.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
name: project-eris-addinfo-removed
|
||||||
|
description: "In this project's Eris fork, ldebug.c's addinfo() is intentionally commented out (luaG_runerror no longer prepends file:line: to error messages)."
|
||||||
|
metadata:
|
||||||
|
node_type: memory
|
||||||
|
type: project
|
||||||
|
originSessionId: bf905462-91dc-4dab-9f49-f76bf9ed0c8e
|
||||||
|
---
|
||||||
|
|
||||||
|
In `luprex/ext/eris-master/src/ldebug.c`, the `addinfo` function is commented out, and `luaG_runerror` no longer calls it. This means stock Lua's `"file:line: <msg>"` prefix is NOT added to runtime error messages.
|
||||||
|
|
||||||
|
**Why:** This project always appends a full traceback to errors via `traceback_pcall` / `traceback_coroutine` (in `luprex/cpp/core/traceback.cpp`). The traceback already shows file:line for every frame including the one that threw, so addinfo's prefix would be redundant.
|
||||||
|
|
||||||
|
**How to apply:** Don't "fix" the commented-out addinfo. If a runtime error message looks bare (no leading `file:line:`), that's expected — the traceback machinery is responsible for location info, not the message itself.
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
model = "gpt-5.4"
|
model = "gpt-5.4"
|
||||||
model_reasoning_effort = "medium"
|
model_reasoning_effort = "medium"
|
||||||
|
|
||||||
[features]
|
|
||||||
use_legacy_landlock = true
|
|
||||||
|
|
||||||
[sandbox_workspace_write]
|
[sandbox_workspace_write]
|
||||||
writable_roots = ["/home/jyelon/integration.UE"]
|
writable_roots = ["/home/jyelon/integration.UE"]
|
||||||
network_access = true
|
network_access = true
|
||||||
@@ -14,16 +11,10 @@ trust_level = "trusted"
|
|||||||
[projects."/home/jyelon/pacman"]
|
[projects."/home/jyelon/pacman"]
|
||||||
trust_level = "trusted"
|
trust_level = "trusted"
|
||||||
|
|
||||||
[mcp_servers.ue-wingman]
|
|
||||||
command = "python3"
|
|
||||||
args = ["/home/jyelon/integration/Plugins/UEWingman/ue-wingman-mcp.py"]
|
|
||||||
|
|
||||||
[mcp_servers.ue-wingman.tools.unreal]
|
|
||||||
approval_mode = "approve"
|
|
||||||
|
|
||||||
[notice.model_migrations]
|
[notice.model_migrations]
|
||||||
"gpt-5.3-codex" = "gpt-5.4"
|
"gpt-5.3-codex" = "gpt-5.4"
|
||||||
|
|
||||||
[tui.model_availability_nux]
|
[tui.model_availability_nux]
|
||||||
"gpt-5.5" = 2
|
"gpt-5.5" = 3
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,6 @@
|
|||||||
prefix_rule(pattern=["code"], decision="allow")
|
prefix_rule(pattern=["code"], decision="allow")
|
||||||
|
prefix_rule(pattern=["rg"], decision="allow")
|
||||||
|
prefix_rule(pattern=["sed", "-n"], decision="allow")
|
||||||
|
prefix_rule(pattern=["nl", "-ba", "Source/Integration/SlashCommand.cpp"], decision="allow")
|
||||||
|
prefix_rule(pattern=["nl", "-ba", "Source/Integration/SlashCommand.h"], decision="allow")
|
||||||
|
prefix_rule(pattern=["perl", "-0pi", "-e", "s/\\n\\tif \\(Token\\.Equals\\(Literal, ESearchCase::IgnoreCase\\)\\)\\n\\t\\{\\n\\t\\tKnownCommand = true;\\n\\t\\treturn ElxSuccessOrError::Success;\\n\\t\\}/\\n\\tif \\(Token\\.Equals\\(Literal, ESearchCase::IgnoreCase\\)\\)\\n\\t\\{\\n\\t\\treturn ElxSuccessOrError::Success;\\n\\t\\}/", "Source/Integration/SlashCommand.cpp"], decision="allow")
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"editor.hover.delay": 1000,
|
"editor.hover.delay": 1000,
|
||||||
"editor.hover.sticky": false,
|
"editor.hover.sticky": false,
|
||||||
"editor.fontFamily": "Cousine",
|
"editor.fontFamily": "Cousine",
|
||||||
"workbench.colorTheme": "Default Light Modern",
|
"workbench.colorTheme": "Light Modern",
|
||||||
"editor.autoClosingBrackets": "never",
|
"editor.autoClosingBrackets": "never",
|
||||||
"editor.autoClosingOvertype": "never",
|
"editor.autoClosingOvertype": "never",
|
||||||
"editor.autoClosingComments": "never",
|
"editor.autoClosingComments": "never",
|
||||||
@@ -27,5 +27,13 @@
|
|||||||
"editor.suggest.filterGraceful": false,
|
"editor.suggest.filterGraceful": false,
|
||||||
"extensions.ignoreRecommendations": true,
|
"extensions.ignoreRecommendations": true,
|
||||||
"diffEditor.renderSideBySide": false
|
"diffEditor.renderSideBySide": false
|
||||||
|
"editor.inlineSuggest.suppressSuggestions": true,
|
||||||
|
"editor.quickSuggestions": {
|
||||||
|
"comments": "off",
|
||||||
|
"strings": "off",
|
||||||
|
"other": "off"
|
||||||
|
},
|
||||||
|
"editor.parameterHints.enabled": false,
|
||||||
|
"editor.suggestOnTriggerCharacters": false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user