Compare commits

...

2 Commits

Author SHA1 Message Date
4d325c8a44 more crap 2026-05-26 17:07:30 -04:00
f8fca90c6f More stuff 2026-05-26 16:59:10 -04:00
9 changed files with 100 additions and 18 deletions

View File

@@ -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,15 +46,26 @@
- 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 `&#32;`.
- 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
- [UE Wingman testing mindset](feedback_wingman_testing.md) — flag tool friction during game work sessions
- [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
- [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`

View 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.

View 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++.

View 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.

View 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.

View 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.

View File

@@ -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

View File

@@ -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")

View File

@@ -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
}