First step in redesigning lua widgets

This commit is contained in:
2026-04-09 14:43:11 -04:00
parent 6be07679d2
commit 3b6207f7a1
6 changed files with 62 additions and 73 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,38 @@
# Best Practices for UE Wingman
UE Wingman is useful when you need the *live* Unreal blueprint graph, especially when text exports are missing or stale. Keep the investigation narrow and work in this order:
1. Start with `Blueprint_Dump` on the asset.
2. Then use `Graph_Dump` on only the graphs you need.
3. Inspect child widgets or helper blueprints separately.
4. Use C++ source only to confirm the surrounding native handoff.
## Practical Tips
- Use exact asset paths, like `/Game/Widgets/WB_Hotkeys`.
- For graph paths, include the graph name exactly as Wingman reports it.
- Expect parameter names to be strict; check the automatic documentation if a command fails.
- Prefer structural questions over broad ones. Ask for one asset, one graph, or one dispatcher at a time.
- Use Wingman to confirm what the blueprint *actually does*, not what the docs say it should do.
## What Wingman Is Good At
- Finding widget trees.
- Showing event graphs and function graphs.
- Tracing blueprint-to-blueprint or blueprint-to-Lua handoff points.
- Confirming which variables a widget stores and reads.
## What Wingman Is Not Good At
- Replacing source code browsing for C++.
- Explaining large graphs all at once.
- Tolerating vague paths or loosely named assets.
## Recommended Workflow
1. Dump the blueprint.
2. Dump the relevant graphs.
3. Trace the data flow node by node.
4. Cross-check the native C++ only where the blueprint calls into engine code.
This keeps the context small and makes the result easier to trust.

View File

@@ -1,57 +0,0 @@
# Comment Formatting Standards
## Line Width
Wrap comments at approximately 60 columns. Code and function signatures are not wrapped.
## Comment Style
Use C++ style (`//`) for all comments. Use `/** */` only for UENUM/UPROPERTY values that should appear as tooltips in the blueprint editor.
## Section Banners
Each class, struct, or enum gets a banner block. The banner line is 60 characters of slashes. The banner names the type and gives a brief description.
```cpp
////////////////////////////////////////////////////////////
//
// FlxExampleClass
//
// Brief description of what this class does.
//
////////////////////////////////////////////////////////////
```
## Header File Banners
Ideally, we'd like to have documentation about what a header
file is for. This would be a banner block at the top of the
header file, before the pragma once. If you're claude code,
and there is no documentation yet, generate a little, but
mark it "DOCUMENTATION GENERATED BY CLAUDE."
## Member Comments
Comments on member variables and functions use `//` followed by a blank `//` line:
```cpp
// Brief description of what this does.
//
void DoSomething();
```
## UFUNCTION Spacing
UFUNCTION-decorated members should be followed by a single blank line to visually separate them from the next member:
```cpp
// Get the value.
//
UFUNCTION(BlueprintCallable)
int32 GetValue() const;
// Set the value.
//
UFUNCTION(BlueprintCallable)
void SetValue(int32 Val);
```

View File

@@ -23,10 +23,9 @@
-- At this point, if you were to pprint(keys), the output would -- At this point, if you were to pprint(keys), the output would
-- look like this: -- look like this:
-- --
-- { "hotkeys", "X", "Light Oven", "A", "Add Fuel" } -- { "X", "Light Oven", "A", "Add Fuel" }
-- --
-- The first array element is always the word "hotkeys". Notice -- Notice that a hotkeylist doesn't store the closures, they are
-- also that a hotkeylist doesn't store the closures, they are
-- silently ignored. The resulting array is in a format that can -- silently ignored. The resulting array is in a format that can
-- be returned directly to Unreal. -- be returned directly to Unreal.
-- --
@@ -58,7 +57,7 @@ makeclass("hotkeylist")
makeclass("hotkeypress") makeclass("hotkeypress")
function hotkeylist.create() function hotkeylist.create()
local result = { "hotkeys" } local result = {}
setmetatable(result, hotkeylist) setmetatable(result, hotkeylist)
return result return result
end end
@@ -79,4 +78,3 @@ function hotkeypress.add(self, key, action, closure)
self.closure = closure self.closure = closure
end end
end end

View File

@@ -55,13 +55,9 @@ function engio.getlookat()
end end
-- if the class has a function 'lookhotkeys', then the correct -- if the class has a function 'lookhotkeys', then the correct
-- look-at widget is 'hotkeys'. We're going to automatically -- look-at widget is 'hotkeys'.
-- generate the correct response.
if class.lookhotkeys ~= nil then if class.lookhotkeys ~= nil then
local keys = hotkeylist.create() return "hotkeys"
class.lookhotkeys(keys)
setmetatable(keys, nil)
return keys
end end
-- otherwise, if the class has a function 'getlookat', use that. -- otherwise, if the class has a function 'getlookat', use that.
@@ -73,6 +69,20 @@ function engio.getlookat()
return "" return ""
end end
function engio.gethotkeys()
local class = tangible.getclass(place)
-- if the tangible doesn't have a 'lookhotkeys' function, do nothing
if class == nil or class.lookhotkeys == nil then
return {}
end
local keys = hotkeylist.create()
class.lookhotkeys(keys)
setmetatable(keys, nil)
return keys
end
function engio.presshotkey(action) function engio.presshotkey(action)
local class = tangible.getclass(place) local class = tangible.getclass(place)
@@ -94,4 +104,4 @@ function jp3()
tangible.animate{tan=actor, anim={action="play", seq="jump"}} tangible.animate{tan=actor, anim={action="play", seq="jump"}}
tangible.animate{tan=actor, anim={action="play", seq="jump"}} tangible.animate{tan=actor, anim={action="play", seq="jump"}}
end end