一键导入
imgui-design
preferred imgui layout patterns
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
preferred imgui layout patterns
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Validate the unscience mod suite against a new upstream Kitten Space Agency (KSA) game build — the break-check playbook run when the game / its decompiled sources are bumped and you must decide what unscience needs fixed. Covers how to diff the CURRENT (new) vs PREVIOUS (old) game-assemblies trees, build-as-alarm (and the KSAFolder trap that fakes a catastrophic break), the string-reflection watchlist that fails silently at runtime, GLSL/byte-offset/render coupling the compiler cannot see, semantic drift with no symbol change, the known-broken baseline you must NOT re-report as new, and which scope/ + plans/ docs to update in lockstep. Use when asked to "check unscience against the new KSA build", "upgrade KSA", run the version-diff / break-check, or review a game update's impact. REQUIRES two KSA game-assemblies trees: CURRENT and PREVIOUS.
how to use fd cli tool
how to use genhttp effectively for http server
Execute git commit with conventional commit message analysis, intelligent staging, and message generation. Use when user asks to commit changes, create a git commit, or mentions "/commit". Supports: (1) Auto-detecting type and scope from changes, (2) Generating conventional commit messages from diff, (3) Interactive commit with optional type/scope/description overrides, (4) Intelligent file staging for logical grouping
details about the ksa game and how to add parts
details about how to implement a mod
| name | imgui-design |
| description | preferred imgui layout patterns |
These patterns are extracted from the KSA mod codebase and represent the preferred style for building ImGui UIs in submods.
Every submod's RenderContent() wraps its body with SubmodUI.BeginContentArea / EndContentArea from MeowSci.KsaAbstractions. This applies a consistent WindowPadding = float2(20f, 20f) and extra bottom padding. Always call this — never render content directly.
SubmodUI.BeginContentArea("##my_content");
// ... content ...
SubmodUI.EndContentArea();
All layout tables use NoPadOuterX so content stretches edge-to-edge with the window border (the window padding from BeginContentArea handles outer inset).
Apply CellPadding = float2(6f, 6f) before every layout table and pop after:
ImGui.PushStyleVar(ImGuiStyleVar.CellPadding, new float2(6f, 6f));
if (ImGui.BeginTable("##id", columns, flags))
{
// ...
ImGui.EndTable();
}
ImGui.PopStyleVar(); // CellPadding
Use for pairs of label+widget side by side (e.g. Columns/Rows, Spacing/Scale):
var flags = ImGuiTableFlags.SizingStretchSame | ImGuiTableFlags.NoPadOuterX;
if (ImGui.BeginTable("##params", 4, flags))
{
ImGui.TableNextRow();
ImGui.TableNextColumn(); ImGui.AlignTextToFramePadding(); ImGui.Text("Label A");
ImGui.TableNextColumn(); ImGui.SetNextItemWidth(-1); ImGui.DragFloat("##a", ref valA, ...);
ImGui.TableNextColumn(); ImGui.AlignTextToFramePadding(); ImGui.Text("Label B");
ImGui.TableNextColumn(); ImGui.SetNextItemWidth(-1); ImGui.DragFloat("##b", ref valB, ...);
ImGui.EndTable();
}
Use for rows where the label gets ¼ width and the widget gets ¾, matching the 4-column table's visual alignment:
var flags = ImGuiTableFlags.SizingStretchProp | ImGuiTableFlags.NoPadOuterX;
if (ImGui.BeginTable("##select", 2, flags))
{
ImGui.TableSetupColumn("##lbl", ImGuiTableColumnFlags.WidthStretch, 1f);
ImGui.TableSetupColumn("##widget", ImGuiTableColumnFlags.WidthStretch, 3f);
ImGui.TableNextRow();
ImGui.TableNextColumn(); ImGui.AlignTextToFramePadding(); ImGui.Text("Label");
ImGui.TableNextColumn(); ImGui.SetNextItemWidth(-1); /* widget */
ImGui.EndTable();
}
Use when rows need a label, a fill widget, and a fixed-width button group (e.g. con-man layout):
var flags = ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.NoPadOuterX;
if (ImGui.BeginTable("##form", 3, flags))
{
ImGui.TableSetupColumn("##lbl", ImGuiTableColumnFlags.WidthFixed, labelW);
ImGui.TableSetupColumn("##widget", ImGuiTableColumnFlags.WidthStretch);
ImGui.TableSetupColumn("##btns", ImGuiTableColumnFlags.WidthFixed, btnColW);
// ...
ImGui.EndTable();
}
Always call ImGui.AlignTextToFramePadding() immediately before any label text that sits in the same row as a widget, to vertically center it.
Use ImGui.Spacing() between logical groups. Use ImGui.SeparatorText("label") for named section dividers (e.g. between a creation form and a list of items).
(?) to the label when a tooltip is needed, then call ImGui.SetItemTooltip(...) immediately after.ImGuiTreeNodeFlags.DefaultOpen for primary/important sections.if (!ImGui.CollapsingHeader("My Section (?)", ImGuiTreeNodeFlags.DefaultOpen))
return;
ImGui.SetItemTooltip("Explanation of this section.");
When rendering a list of items where each has its own CollapsingHeader, put the content inside a bordered child window. The CollapsingHeader renders flush to the window edges (ignoring WindowPadding), so the child must be manually expanded to match and its cursor pulled left:
if (!ImGui.CollapsingHeader($"Item: {name}##id"))
return;
var wpadX = ImGui.GetStyle().WindowPadding.X;
float childW = ImGui.GetContentRegionAvail().X + wpadX * 2;
ImGui.SetCursorPosX(ImGui.GetCursorPosX() - wpadX);
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, new float2(20f, 10f)); // inner padding
ImGui.BeginChild($"child_{id}", new float2(childW, 0),
ImGuiChildFlags.Borders | ImGuiChildFlags.AutoResizeY | ImGuiChildFlags.AlwaysUseWindowPadding,
ImGuiWindowFlags.NoScrollbar);
ImGui.PopStyleVar(); // WindowPadding
// ... content ...
ImGui.Spacing();
ImGui.EndChild();
The WindowPadding push/pop must happen before BeginChild — ImGui captures it at Begin time.
" Apply ", " Delete ", " Create ", " Off ", " Rows ", etc.ImGui.PushStyleColor(ImGuiCol.Button, ImGui.GetColorU32(KSAColor.Xkcd.Scarlet));
ImGui.PushStyleColor(ImGuiCol.Text, ImGui.GetColorU32(KSAColor.Xkcd.PaleGrey));
if (ImGui.Button($" Destroy ##{id}"))
DoDestroy();
ImGui.PopStyleColor();
ImGui.PopStyleColor();
ImGui.SameLine(0, 8).ImGui.SameLine(0, 12) then ImGui.AlignTextToFramePadding() before the text.All combo dropdowns that may have many items follow this pattern:
if (ImGui.BeginCombo("##id", preview))
{
if (ImGui.IsWindowAppearing())
{
ImGui.SetKeyboardFocusHere();
_filter.Clear();
}
_filter.Draw("##filter", -1f);
for (int i = 0; i < items.Length; i++)
{
if (!_filter.PassFilter(items[i])) continue;
bool sel = _selectedIndex == i;
if (ImGui.Selectable(items[i], sel))
_selectedIndex = i;
if (sel) ImGui.SetItemDefaultFocus();
}
ImGui.EndCombo();
}
ImGui.TextColored(new float4(1f, 0.3f, 0.3f, 1f), message)ImGui.TextColored(new float4(0.4f, 1f, 0.4f, 1f), message)ImGui.TextDisabled(message)if (!string.IsNullOrEmpty(_message)) and add ImGui.Spacing() before.Wrap unavailable controls with the standard ImGui disable guard:
if (!canAct) ImGui.BeginDisabled();
if (ImGui.Button(" Act ##id")) DoAct();
if (!canAct) ImGui.EndDisabled();