Skip to content
Development
Skill

/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",

From plugin
m2ui
341 skill1 agent1 command

Claude Code

$ npx -y skills add martysama0134/m2ui-skill --skill m2ui --agent claude-code

SKILL.md

m2ui.SKILL.md
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`;

Read more
@martysama0134
Ships withm2ui

A skill for AI coding assistants that generates and modifies Metin2 client UI code.

341 skill1 agent
Get the whole plugin

Stars on GitHub

Momentum

stars in total
34
Star history of martysama0134/m2ui-skill on GitHub, a chart by star-history.com

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about m2ui.

Which coding agents can use m2ui?
m2ui installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.