/m2ui
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",
$ npx -y skills add martysama0134/m2ui-skill --skill m2ui --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/m2ui
Context preview
The summary Claude sees to decide when to auto-load this skill.
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",
SKILL.md
m2ui.SKILL.mdname: 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")./m2ui — Metin2 UI Generator
<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>
Mode Detection
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.
Before Generating Any Code
**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 Targets
| Output | Path | |--------|------| | uiscript dicts | `pack/pack/uiscript/uiscript/` | | root UI classes | `pack/pack/root/` | | locale strings | auto-detect — see `reference/locale.md` |
Critical Rules
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`;
Read more
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")./m2ui — Metin2 UI Generator
<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>
Mode Detection
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.
Before Generating Any Code
**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 Targets
| Output | Path | |--------|------| | uiscript dicts | `pack/pack/uiscript/uiscript/` | | root UI classes | `pack/pack/root/` | | locale strings | auto-detect — see `reference/locale.md` |
Critical Rules
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`;
A skill for AI coding assistants that generates and modifies Metin2 client UI code.

