Compare commits
2 Commits
493ae99d90
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d325c8a44 | |||
| f8fca90c6f |
@@ -17,7 +17,7 @@
|
||||
|
||||
## 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.
|
||||
- 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.
|
||||
@@ -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.
|
||||
- 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.
|
||||
- Python MCP bridge is `tools/mcp-bridge.py` (stdio transport, forwards to TCP port 9847).
|
||||
- Blueprint text exports go to `Saved/BlueprintExports/<PackageName>/` — includes both custom graph exports and Unreal's copy-format ASCII dump.
|
||||
- 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`).
|
||||
- Invoke directly via Bash. Subcommands are CamelCase, e.g. `ue-wingman Graph_Dump <path> True`.
|
||||
- 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
|
||||
|
||||
@@ -58,3 +65,7 @@
|
||||
- [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 — 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_reasoning_effort = "medium"
|
||||
|
||||
[features]
|
||||
use_legacy_landlock = true
|
||||
|
||||
[sandbox_workspace_write]
|
||||
writable_roots = ["/home/jyelon/integration.UE"]
|
||||
network_access = true
|
||||
@@ -14,16 +11,10 @@ trust_level = "trusted"
|
||||
[projects."/home/jyelon/pacman"]
|
||||
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]
|
||||
"gpt-5.3-codex" = "gpt-5.4"
|
||||
|
||||
[tui.model_availability_nux]
|
||||
"gpt-5.5" = 2
|
||||
"gpt-5.5" = 3
|
||||
|
||||
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
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.sticky": false,
|
||||
"editor.fontFamily": "Cousine",
|
||||
"workbench.colorTheme": "Default Light Modern",
|
||||
"workbench.colorTheme": "Light Modern",
|
||||
"editor.autoClosingBrackets": "never",
|
||||
"editor.autoClosingOvertype": "never",
|
||||
"editor.autoClosingComments": "never",
|
||||
@@ -27,5 +27,13 @@
|
||||
"editor.suggest.filterGraceful": false,
|
||||
"extensions.ignoreRecommendations": true,
|
||||
"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