brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Use when creating, modifying, auditing, or debugging Metin2 client UI code (uiscript dicts, root ui*.py classes, locale entries) — user says "/m2ui", "create UI", "make a window", "add button to", provides a UI screenshot to replicate, asks to "check UI for bugs" / "diagnose",
Claude Code
$ npx -y skills add martysama0134/m2ui-skill --skill m2ui --agent claude-code
Codex
$ npx skills add martysama0134/m2ui-skill --skill m2ui -a codex -y
Cursor
$ npx skills add martysama0134/m2ui-skill --skill m2ui -a cursor -y
Gemini CLI
$ npx skills add martysama0134/m2ui-skill --skill m2ui -a gemini-cli -y
GitHub Copilot
$ npx skills add martysama0134/m2ui-skill --skill m2ui -a github-copilot -y
OpenCode
$ npx skills add martysama0134/m2ui-skill --skill m2ui -a opencode -y
Windsurf
$ npx skills add martysama0134/m2ui-skill --skill m2ui -a windsurf -y
name: m2ui
description: >
Use when creating, modifying, auditing, or debugging Metin2 client UI code
(uiscript dicts, root ui*.py classes, locale entries) — user says "/m2ui",
"create UI", "make a window", "add button to", provides a UI screenshot to
replicate, asks to "check UI for bugs" / "diagnose", or reports a visibly
broken window ("doesn't open", "click does nothing", "leaks").<SUBAGENT-STOP> Dispatched as a subagent with a specific task? Skip mode detection and execute the task directly — the parent agent already loaded m2ui context and picked the mode. </SUBAGENT-STOP>
Priority order:
1. **Explicit keyword**: args start with `screenshot`, `talk`, `script`, or `diagnose` → that mode 2. **Image attached** → screenshot mode 3. **Diagnose request**: args say "check", "audit", "review", "diagnose", "find bugs in" → diagnose mode 4. **Symptom report**: args contain a visible-bug phrase ("doesn't appear", "doesn't open", "doesn't work", "click does nothing", "X is broken", "looks broken", "leak", "crashes after", "stuck", "flickers") — even when a `.py` file is also referenced → load `reference/failure-atlas.md` FIRST, diagnose via the matching symptom entry, THEN script mode (if a code fix is needed) or talk mode 5. **File reference**: args name a `.py` file in `uiscript/` or `root/` → script mode 6. **Text description**: any other text → talk mode 7. **No args**: ask — "(a) Create from screenshot, (b) Describe a new UI, (c) Modify an existing file, (d) Diagnose for bugs" — then dispatch
Read the matching mode file from `modes/` adjacent to this SKILL.md (`screenshot.md`, `talk.md`, `script.md`, `diagnose.md`) and follow it.
**Mandatory floor (always load):**
1. `reference/mental-model.md` — ymir engine concepts; deprograms web/React assumptions 2. `reference/event-binding.md` — callback wrapping matrix
**Conditional load (only what the task needs):**
| Task | Load | |------|------| | New window from scratch | `reference/anchors/README.md` → walk its 2-step tree (see Anchor selection) | | Modifying an existing window | Skip anchors; load the existing files | | Widget you haven't used recently | `reference/widgets.md` — that widget's section | | Locale-heavy work (many new strings) | `reference/locale.md` | | C++ Python API (`net.X`, `player.X`, ...) not already in context | `reference/bindings.md` — grep for the function | | Patterns reminder (Initialize/Destroy, scrollbar wiring, ListBoxEx, integration template, lazy-load sub-windows, inner helper classes, 2D grids) | `reference/patterns.md` — relevant section | | User reports a visible symptom | `reference/failure-atlas.md` — matching symptom entry FIRST, before any anchor | | Visual style/sizing matters for a new window | `reference/visual-conventions.md` — pick archetype + chrome + palette before coding | | Wiring a window into the main interface | `reference/integration.md` (always — after every emission) | | Window has an OnUpdate body (animation / polling / fade / daily-event timing / movement queues / effect chains) | `reference/timer-patterns.md` |
**Anchor selection (new windows):** walk the 2-step decision tree in `reference/anchors/README.md` — pick exactly ONE primary archetype (the window's chrome; no exact match → closest; never skip this step), plus zero or more augmentors (`05-feature-gated`, `14-drag-and-drop`, `15-network-coupled-flow`, `16-tabbed-content`, `22-compare-tooltip`, `23-auto-hide-chrome`). Read the primary FIRST; augmentors layer on top and never override the primary's lifecycle/structure. Tie-breaker: match the window's CHROME, not its data — "tabbed inventory" = primary `08-inventory-equipment` + augmentor `16-tabbed-content`, NOT `16` alone. For `widgets.md`/`locale.md`/`bindings.md`/`patterns.md`, load only the section you need, not the whole file.
| Output | Path | |--------|------| | uiscript dicts | `pack/pack/uiscript/uiscript/` | | root UI classes | `pack/pack/root/` | | locale strings | auto-detect — see `reference/locale.md` |
All modes, all generated code. Reference files cite these by number — numbering 1-19 is frozen; new rules append.
1. **`@ui.WindowDestroy`** on every `Destroy(self)` method 2. **`Initialize()` or `__Initialize()`** sets all instance vars to `None`/defaults 3. **`Destroy()` calls `Initialize()`**; script-backed windows also `ClearDictionary()` 4. **`__del__`** calls `ui.ScriptWindow.__del__(self)` 5. <EXTREMELY-IMPORTANT> **Callback wrapping** — every callback that references `self` MUST use `ui.__mem_func__()`, `SAFE_SetEvent` (if fork provides it), or `lambda r=proxy(self): r.X()`. NEVER a bare bound method (`btn.SetEvent(self.OnClick)`) or self-capturing lambda (`lambda: self.OnClick()`) — both hold `self` alive past `Destroy` and leak. The single most common bug in community Metin2 code. Full matrix: `reference/event-binding.md`. </EXTREMELY-IMPORTANT> 6. **`Open()`/`Close()`** — `Open` calls `Show()`, `Close` calls `Hide()` 7. **`OnPressEscapeKey()`** returns `True` (always; not `False`) 8. **`OnMouseWheel()`** returns `True`/`False` based on whether it consumed the event 9. **No hardcoded strings** — all user text via `localeInfo.*` or `uiScriptLocale.*` 10. **`constInfo.intWithCommas()`** for large numbers 11. **`"not_pick"` flag** on decorative elements (lines, separators, background images) 12. **Z-order**: create widgets back-to-front (SetParent call order = render order) 13. **Parent bounds clip picking** — size parents to contain all interactive children 14. **Python 2.7** target — `//` for int division, `in` not `has_key()`, keep `xrange`. Full py2/py3 rules: `reference/patterns.md` Section 8 <EXTREMELY-IMPORTANT> 15. **Asset paths must exist** — verify every `d:/ymir work/ui/...` path under `D:\ymir work\ui\` via Glob before referencing it. New asset needed → emit `# TBD ASSET: <path> — needs creation`;
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.