[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71BFPHTSZTM4QT1AB3XQSFM":3,"skill-same:01M71BFPHTSZTM4QT1AB3XQSFM":97},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":58,"commitSha":59,"skillDirectory":60,"forksCount":61,"repositoryHtmlUrl":62,"repositoryHomepageUrl":63,"ownerHtmlUrl":64,"ownerBlogUrl":6,"ownerDescription":65,"updatedAt":66,"install":67,"resources":80},"01M71BFPHTSZTM4QT1AB3XQSFM","unikit-architecture",null,"Generate, update or reorganize the architecture guidelines of a game project. Scans the project structure and tech stack, then writes .unikit\u002FARCHITECTURE.md — a root with the module map and the global dependency rules — and, when the file grows, topic files in .unikit\u002Farchitecture\u002F that agents load only when the work matches them. Modes: generate (no file yet), update (rescan and add what is missing, removing nothing), optimise (split a large file into a root and topics), chosen by a keyword or from the request in plain words. Name a specific pattern or let it auto-detect. Use when the user wants to define, document, update or slim down the project architecture, e.g. \"generate architecture\", \"update the architecture document\", \"the architecture file is too big\", \"split ARCHITECTURE.md\", or mentions module structure, module boundaries, project organization, or dependency rules.","NintendaDev\u002Funikit-ai","NintendaDev","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F181320258?v=4","01M71BFH8JJ6EBGRXBWRZK894Y","Dmitrii Vasilev","01M71BFH9T4K66TTBFNV1ZWFN5",22,"MIT","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-architecture\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"architecture","unikit architecture","module","modes","generate architecture","guidelines","tech","edit","write","read","update","generate","project structure","stack","structure","text","auto","files","auto-detect","project","2026-11-10 10:12:30",false,"---\nname: unikit-architecture\ndescription: >-\n  Generate, update or reorganize the architecture guidelines of a game project. Scans the\n  project structure and tech stack, then writes .unikit\u002FARCHITECTURE.md — a root with the\n  module map and the global dependency rules — and, when the file grows, topic files in\n  .unikit\u002Farchitecture\u002F that agents load only when the work matches them. Modes: generate\n  (no file yet), update (rescan and add what is missing, removing nothing), optimise (split\n  a large file into a root and topics), chosen by a keyword or from the request in plain\n  words. Name a specific pattern or let it auto-detect. Use when the user wants to define,\n  document, update or slim down the project architecture, e.g. \"generate architecture\",\n  \"update the architecture document\", \"the architecture file is too big\", \"split\n  ARCHITECTURE.md\", or mentions module structure, module boundaries, project organization,\n  or dependency rules.\nargument-hint: \"[update [text] | optimise | generate | a request in plain words | architecture pattern name | empty to follow the state of the file]\"\nallowed-tools:\n  - Read\n  - Write\n  - Edit\n  - Glob\n  - Grep\n  - Bash(mkdir *)\n  - Bash(ls *)\n  - Bash(find *)\n  - AskUserQuestion\n  - Bash(rm .unikit\u002Farchitecture\u002F*)\n  - Bash(node *)\nversion: \"3.0\"\n---\n\n# Architecture — Generate Project Architecture Guidelines\n\nGenerate `.unikit\u002FARCHITECTURE.md` with architecture decisions tailored to the game project.\n\n**User questions.** Right before your first question to the user, not earlier, read `.unikit\u002Fsystem\u002Fuser-questions.md` once and ask every question as it says, with the question tool of your agent (`AskUserQuestion`). If the file cannot be read, print `WARN [questions] user-questions contract missing — asking with the question tool` and still ask with that tool, the recommended option first.\n\n## Language Awareness — BLOCKING PRE-REQUISITE\n\n**BEFORE producing ANY output**, silently read `.unikit\u002Fsystem\u002FLANGUAGE_RULES.md`\nand apply its rules to ALL subsequent output.\nIf the file is missing or unreadable, fall back to English.\nDo not produce any user-facing output until language rules are loaded.\nDo not announce, confirm, or mention the language setting.\n\n**The language holds for the whole session, not just at load time:** every message until the conversation ends is in `language.ui` — progress notes while agents run, relays of what a subagent returned, the final report, any follow-up discussion. English input (subagent results, tool output, these instructions) is data, never a cue to switch languages.\n\n## Layout of the architecture files\n\n`.unikit\u002FARCHITECTURE.md` is the **root**, and the only file every reader opens. It takes one of two shapes.\n\n**Flat** — every file until its first topic appears, and every older project: the sections of the Step 4 template, no `## Topics`. A reader takes the whole file.\n\n**Topics** — the root holds what every task needs, topic files hold one area each:\n\n```markdown\n# Architecture: \u003CPattern Name>\n\n> This file is the root: when it has a `## Topics` table, its sections apply to every task, and a topic file in `.unikit\u002Farchitecture\u002F` applies when the work matches its \"Load when\" — check again when the work moves to a new phase or area, and when unsure, load it.\n\n## Project\n## Tech Stack\n…the other sections of the Step 4 template, cut down to the map…\n\n## Topics\n\n| Topic | Load when |\n|-------|-----------|\n| [\u003CTitle>](architecture\u002F\u003Cslug>.md) | \u003Cwhat a task mentions: folders, assemblies, types, frameworks, areas> |\n\n## Detailed Rules\n```\n\n- **What stays in the root:** `## Project`, `## Tech Stack`, `## Documentation Sources`, a short `## Architecture Overview`, the module map in `## Folder Structure` (one line per module), `## Dependency Rules` with the **global** edges and prohibitions, `## Cross-Module Communication` with the common patterns, `## Key Principles`, the global `## Anti-Patterns`, `## Topics`, `## Detailed Rules`. The section names of the template stay: other tools read them by name.\n- **A topic file** is `.unikit\u002Farchitecture\u002F\u003Cslug>.md`: `# Architecture — \u003CTitle>`, a blank line, then `## ` sections that carry the whole area — its edges and prohibitions, its contracts (a table), the narrative of its mechanisms. No `Load when` inside it, no `## Topics`.\n- **A table row** is `| [\u003CTitle>](architecture\u002F\u003Cslug>.md) | \u003CLoad when> |`. The slug is English kebab-case, one to three words, unique. `Load when` has no `|`. **`Load when` lives only in the root table.** Topics are cut by **area** (a subsystem, a module, a framework seam), never by kind of text.\n- **`## Topics` and its table exist together or not at all**; the section stands directly above `## Detailed Rules` (last when there is none). The header quote under the title is written whenever the root has a table and removed when it has none.\n- **Where a prohibition lives.** One that touches more than one area stays in the root (`## Dependency Rules`, `## Anti-Patterns`); one that touches a single area may live in its topic. When unsure, the root.\n- **Priority.** The root and its topics are one level (number 2 of `RULES_INDEX.md`). Inside its own area a topic wins over a root section it contradicts.\n- **The `flat` marker** is the line `\u003C!-- unikit:architecture-layout flat -->`, directly under the root's `# Architecture:` line. It records the user's refusal of the topic layout and means nothing to readers. There is no marker for the topic layout: the `## Topics` table is the sign.\n- **Anchors** — `## Topics`, the header row `| Topic | Load when |`, the marker, the slugs, the `# Architecture — ` prefix and the header quote — are English, and so is the rest of the document and of every topic file: architecture documentation always stays in English (LANGUAGE_RULES).\n- **Not to be confused:** `.unikit\u002Farchitecture\u002F` holds these topic files; `.unikit\u002Fcode\u002Farchitecture\u002F` holds maps a user's own skills may write. This skill reads and writes only the first.\n\n## Modes\n\nThe mode comes from the user's request together with the state of the file (below), in this order: **(1) an explicit parameter, (2) the intent of free text, (3) the state.** Both ways stay: the parameter is the stable, deterministic interface (other skills and scripts rely on it — `unikit-rules` prune hands a block over as `update \u003Cblock>`), free text is for people. **The request** is `$ARGUMENTS`; when that is empty or only a pattern name, it is the message that started this run, which is how the mode is found when the skill was picked by its description with no arguments. Free text may be in any language: read its intent, do not match words, so \"the architecture file is too big\", \"slim it down\" and `optimise` all mean the same thing. **Announce the mode first:** the announcement is the run's very first output, before Step 0 (a clarifying question, when rule 3 or 4 below needs one, comes first and the announcement follows the answer); mode names stay English, the sentence is in `language.ui`.\n\n```\n1. Parameter — checked first, never interpreted:\n   ├── the whole argument is `optimise` \u002F `optimize` (any letter case)  → Mode C\n   ├── the first word is `update` (the rest of the line is read as the request, see rule 1)  → Mode B\n   └── the whole argument is `generate`  → Mode A\n2. Otherwise the intent of the request, free text in any language:\n   ├── reorganize, optimise, slim down, shorten, split into topics, \"the file is too big\"  → Mode C: reorganize into a root and topics\n   ├── update, refresh, bring in line with the code, add what is missing, record this fact or block  → Mode B: update\n   └── generate, create, write, set up the architecture document  → Mode A: generate\n3. No parameter and no intent (an empty request, a pattern name, a question about the architecture)\n   → by the state of .unikit\u002FARCHITECTURE.md: `empty` → Mode A, any other → Mode B — a pattern name is a hint, never an order to regenerate\n```\n\n**Rules of the intent.**\n1. A request that carries a fact or a block to record (\"module X may not depend on Y\", or the text `unikit-rules` hands over) is Mode B whether it came as `update \u003Cblock>` or as free text, and that text is the block (`mode-update.md`, U.4); the text after the word `update` that only describes the wish (\"the architecture, we added a module\") is a request, not a block.\n2. Two intents in one request run in the order given — Mode B before Mode C when both are named, because Mode C restructures what Mode B just wrote.\n3. A request that reads as update or as reorganize (\"tidy up the architecture\") is asked once, with the question tool of your agent (`AskUserQuestion`): `Update` (recommended) \u002F `Reorganize into topics`. It is never guessed.\n4. A generate intent — or the `generate` parameter — on a file that has content is asked once, with the same tool: `Update instead` (recommended) \u002F `Rewrite from scratch`. Rewriting replaces what is written — the only path of this skill that removes anything — and it runs only on that answer.\n5. `update` on an `empty` file prints `INFO [architecture] update: no file — generating` and runs Mode A; `optimise` on an `empty` file prints `INFO [architecture] optimise: no architecture document — nothing to do` and stops.\n6. Whatever the wording or the parameter, Mode C writes nothing before the user confirms its preview.\n\n| Mode | Announcement | Runs |\n|------|--------------|------|\n| A: generate | `generate: I'll scan the project and write .unikit\u002FARCHITECTURE.md.` | Steps 0–6 below |\n| B: update | `update: I'll rescan the project and add what is missing to .unikit\u002FARCHITECTURE.md; nothing already written is removed.` | Steps 0–2, then read `{{skills_dir}}\u002F{{self_name}}\u002Freferences\u002Fmode-update.md` and follow it; Steps 3–4 do not run |\n| C: optimise | `optimise: I'll sort .unikit\u002FARCHITECTURE.md into a root and topic files and show you the proposed layout before writing anything.` | read `{{skills_dir}}\u002F{{self_name}}\u002Freferences\u002Fmode-optimise.md` and follow it; Steps 0–4 and 6 do not run, Step 5 (the `AGENTS.md` row) runs when that file says so |\n\n**The state** is decided by the file's content, checked in this order, the first match wins:\n\n| State | Sign |\n|-------|------|\n| `topics` | a line `## Topics` followed by the table header row `Topic` \u002F `Load when` |\n| `flat` | the marker line |\n| `empty` | no file, or a file without a single line that starts with `## ` |\n| `legacy` | anything else: content, but neither the table nor the marker |\n\nDrift is reported, never fixed silently: a row whose file is missing → `WARN [architecture] topic table: \u003Cslug> is listed, .unikit\u002Farchitecture\u002F\u003Cslug>.md does not exist`; a file in `.unikit\u002Farchitecture\u002F` no row lists → `WARN [architecture] topic table: .unikit\u002Farchitecture\u002F\u003Cfile> is not listed under ## Topics — no reader loads it`; marker and table together → `WARN [architecture] layout: flat marker ignored — the file already has a ## Topics table`. A `flat` file is never offered the reorganization again; only `optimise` reorganizes it, and removes the marker when it does.\n\n## Workflow\n\nDetermine the mode first (`## Modes`) and print its announcement as the run's first output; Steps 0–2 are shared.\n\n### Step 0: Load Engine Rules\n\nRead `{{skills_dir}}\u002F{{self_name}}\u002Freferences\u002FENGINE_RULES.md`. This file is installed by `unikit-ai init`\nbased on the user's engine choice and contains engine-specific paths, scan targets, framework lists,\nand pattern indicators. Use it for all engine-specific details in subsequent steps.\n\nIf the file is missing, inform the user: \"Engine rules not found. Please run `unikit-ai init` to configure your project.\"\n\n### Step 1: Load Existing Context\n\n**Read `.unikit\u002FDESCRIPTION.md`** if it exists — project specification, tech stack, constraints.\nThis gives you the baseline understanding of what technologies are in play before scanning.\n\n**Read `.unikit\u002Fmemory\u002Fcode\u002FRULES_INDEX.md`** if it exists — it contains the index of framework-specific\nrule files that the project already uses. This tells you which frameworks and patterns are in play.\nDo NOT read the individual rule files — only the index to understand what's covered.\n\n**Read `.unikit\u002FRULES.md`** if it exists — naming conventions, class structure, DI rules. **Rule topics:** its `## Topics` table names the topic files in `.unikit\u002Frules\u002F`; open one only when the architecture work at hand touches its `Load when`.\nExtract key conventions but do NOT duplicate them into ARCHITECTURE.md — reference the file instead.\n\n**Read the root `.unikit\u002FARCHITECTURE.md`** if it exists — its state (see `## Modes`) decides the mode. **Architecture topics:** open a topic file only when the work at hand places or checks a fact in its area (Mode B), or when `optimise` reads them all.\n\n**Read `.unikit\u002Fskill-context\u002Funikit-architecture\u002FSKILL.md`** if it exists — project-specific rules accumulated by `\u002Funikit-evolve`. Treat as overrides: skill-context wins over general rules on conflict.\n\n\u003C!-- unikit:extension-point:bootstrap -->\n\n### Step 2: Scan the Project\n\nScan the project to discover the actual tech stack. This is the most important step —\narchitecture documentation must reflect reality, not assumptions.\n\nUse `ENGINE_RULES.md` file (loaded in Step 0) to determine:\n- Which directories to scan and what to look for in each\n- Which file extensions indicate project scripts\n- How to discover module boundaries (assembly definitions, build files, folder conventions)\n- Which DI\u002FIoC frameworks to look for\n- Which architectural pattern indicators to check\n\n#### 2.1 Scan Directories\n\nScan the directories listed in `ENGINE_RULES.md` under \"Scan Targets\".\nFor each discovered directory, run `ls` to get subfolder names — this reveals the real building blocks.\n\n#### 2.2 Scan Module Boundaries\n\nFind module boundary definition files as specified in `ENGINE_RULES.md` (e.g., assembly definitions,\nbuild files, or folder-based conventions). Read a representative sample to understand:\n- Module boundaries and namespace conventions\n- Dependency directions between modules\n- Which modules reference which frameworks\n\n#### 2.3 Detect DI\u002FIoC Framework\n\nLook for DI framework indicators listed in `ENGINE_RULES.md`.\nNot all engines have standard DI — if none is detected, note \"manual DI or none\".\n\n#### 2.4 Detect Key Patterns\n\nLook for architectural pattern indicators. These patterns are largely engine-agnostic:\n\n- Files with `View`, `ViewModel`, `Presenter`, `Model` suffixes — reveals MV* pattern\n- `Controller` suffixes — may indicate MVC or GRASP controllers\n- Folders named `ECS`, `Systems`, `Components`, `Entities` — may indicate ECS\n- `SignalBus`, `EventBus`, `MessageBus` — event system\n- `SaveSerializer`, `SaveData`, `SaveManager` — save system pattern\n- DI installer\u002Fmodule files — as specified in `ENGINE_RULES.md`\n\n### Step 3: Ask About Architecture (if needed)\n\nMode A only. In Mode B a named pattern is a hint for the rescan, nothing more.\n\n**If `$ARGUMENTS` specifies an architecture pattern** (e.g., `\u002Funikit-architecture modular-monolith`):\n- Use that pattern directly, skip to Step 4\n\n**If the project already has code and patterns are detectable from Step 2:**\n- Summarize what you found and confirm with the user\n\n**If the project is new or patterns are unclear**, print the message below as plain markdown first, then ask its last question with the question tool of your agent (`AskUserQuestion`): the options are the pattern the scan and the Quick Decision Guide point to (recommended), one or two other likely patterns from the list, and `Document what I found as-is`; the user writes any other pattern or a combination in the free-text answer:\n\n```\nBased on the project scan, I found:\n- [discovered modules\u002Fframeworks\u002Fpatterns]\n\nWhich architectural patterns do you plan to use?\n\nCommon game architecture patterns:\n1. Modular Monolith — independent modules with enforced boundaries, single deployment\n2. Feature-based — code organized by feature (Player\u002F, Inventory\u002F, Combat\u002F)\n3. Layered — horizontal layers (Domain → Application → Presentation)\n4. MVC \u002F MVP \u002F MVVM — Model-View separation (specify which variant)\n5. ECS — Entity Component System for data-oriented design\n6. Component-based — engine's native component architecture without extra layers\n\nYou can combine patterns (e.g., \"Modular Monolith + MVVM for UI\").\n```\n\n### Step 4: Generate .unikit\u002FARCHITECTURE.md\n\n```bash\nmkdir -p .unikit\n```\n\nGenerate `.unikit\u002FARCHITECTURE.md` using the template below. Every section must be adapted\nto what was actually discovered in Step 2 — never use placeholder or generic content.\n\n---\n\n**ARCHITECTURE.md Template:**\n\n```markdown\n# Architecture: [Pattern Name]\n\n## Project\n\n[1 sentence: what this project is, target platforms]\n\n## Tech Stack\n\n| Category | Technology |\n|----------|-----------|\n| Engine | [engine name + version \u002F primary language \u002F render pipeline] |\n| DI | [DI framework name or \"None\"] |\n| [category] | [technology] |\n...\n\nInclude only technologies actually found during scanning. Each row must correspond\nto a real framework, module, or asset discovered in the project.\n\n## Documentation Sources\n\nWhen you need up-to-date API docs for these libraries:\n\n[List each major library with its documentation lookup method.\nIf context7 MCP is available, specify \"use context7\" with the search query.\nIf docs are bundled locally, point to the path.]\n\n## Architecture Overview\n\n[2-3 paragraphs explaining the chosen architecture pattern and why it fits this project.\nIf the pattern was detected from existing code, describe what you found.\nIf it was chosen by the user, explain the rationale.]\n\n## Folder Structure\n\n```\n[Project root]\u002F\n├── [scripts directory]\u002F    [describe organization principle]\n│   ├── [folder]\u002F           [purpose]\n│   └── ...\n├── [modules directory]\u002F    [describe module boundaries]\n│   ├── [Module1]\u002F          [purpose]\n│   └── ...\n├── [plugins directory]\u002F    [third-party frameworks]\n└── [assets directory]\u002F     [store assets]\n```\n\nDescribe the actual folder structure found in the project, not an ideal one.\n\n## Dependency Rules\n\n[What depends on what. Use the actual module\u002Ffolder names from the project.]\n\n- ✅ [allowed dependency direction with real names]\n- ❌ [forbidden dependency direction with real names]\n\n## Module Boundary Strategy\n\n[Describe how the project partitions the codebase into modules. Include:\n- What mechanism enforces boundaries (assembly definitions, build files, folder conventions)\n- Naming convention for modules\n- How modules expose their public API\n- Test module conventions]\n\n## Cross-Module Communication\n\n[How modules communicate. Describe ONLY patterns that actually exist in the project.\nCommon patterns: DI interfaces, event\u002Fsignal bus, reactive properties, direct references.\nFor each pattern, specify which module or framework provides it.]\n\n## Key Principles\n\n[3-5 principles derived from the project's actual conventions. Examples:]\n1. [Principle from the codebase]\n2. ...\n\n## Anti-Patterns\n\n- ❌ [What NOT to do — derived from actual project conventions]\n- ❌ ...\n\n## Detailed Rules\n\nFor framework-specific rules, coding conventions, and implementation details see:\n\n- **`.unikit\u002FRULES.md`** — [brief description of what's there; when it has a `## Topics` table, name its topic files in `.unikit\u002Frules\u002F`]\n- **`.unikit\u002Fmemory\u002Fcode\u002FRULES_INDEX.md`** — index of all framework-specific rule files\n- **`.unikit\u002Farchitecture\u002F`** — topic files, listed in `## Topics` (only when the file has topics)\n```\n\n---\n\n**Rules for generation:**\n\n- Every technology, module, and pattern mentioned must have been found during scanning\n- Use code examples in the project's primary language that match the project's actual style\n- Folder structure must extend what already exists, not replace it\n- If custom modules were found (SignalBus, EventBus, SaveSystem, etc.), document their role\n  in the architecture explicitly — they are first-class architectural elements\n- The \"Detailed Rules\" section MUST reference `.unikit\u002Fmemory\u002Fcode\u002FRULES_INDEX.md` — that file\n  is the single source of truth for which rule files exist and when to load them\n- Do NOT duplicate content from RULES.md or memory\u002Fcode\u002FRULES_INDEX.md —\n  reference them and describe what each contains in one line\n- **Topics at generation.** Write one root. A subsystem for which the scan found more than one table row of structure — its own edges and prohibitions, a contract catalogue, or a mechanism that needs a paragraph — becomes a topic file (shape: `## Layout of the architecture files`) listed in `## Topics`; everything that fits one line stays in the root. A project with no such subsystem gets the flat shape: no `## Topics`, no header quote.\n- Keep the root concise — it's a map, not a manual. What explains how one area works lives in that area's topic file, or in `docs\u002F`, not in the root.\n\n### Step 5: Update AGENTS.md\n\nIf `AGENTS.md` exists in the project root, add or update the `.unikit\u002FARCHITECTURE.md` entry\nin the \"AI Context Files\" table (or equivalent section):\n\n```\n| .unikit\u002FARCHITECTURE.md | Architecture decisions and guidelines |\n```\n\nWhen the file has topics, the row reads `| .unikit\u002FARCHITECTURE.md | Architecture decisions and guidelines; topic files in .unikit\u002Farchitecture\u002F load when their \"Load when\" matches |`. Modes B and C run this step too whenever the file has topics when they finish, or has just lost its last one: the row is checked every time, so a regenerated `AGENTS.md` gets the topic note back.\n\nIf the entry already exists, verify it's accurate. If `AGENTS.md` doesn't exist, skip this step silently.\n\n### Step 6: Confirm\n\n```\n✅ Architecture document generated!\n\nEngine: [detected engine]\nPattern: [chosen pattern]\nFile: .unikit\u002FARCHITECTURE.md\nTopics: [N topic files in .unikit\u002Farchitecture\u002F | none — flat]\n\nDiscovered:\n- [N] modules in [modules directory]\n- [N] plugins\u002Faddons in [plugins directory]\n- [N] third-party assets\u002Fpackages\n- [N] module boundary definitions\n\nKey architectural decisions:\n- [decision 1]\n- [decision 2]\n- [decision 3]\n\nThe document references .unikit\u002Fmemory\u002Fcode\u002FRULES_INDEX.md for detailed framework rules\nand .unikit\u002FRULES.md for coding conventions.\n```\n\n## Knowledge Base\n\nReference material for architecture evaluation. This content informs recommendations —\nit is NOT output directly.\n\n### Architecture Decision Matrix\n\n| Factor | Component-Based | Layered | Feature-Based | Modular Monolith | MVC\u002FMVP\u002FMVVM | ECS |\n|--------|----------------|---------|---------------|-------------------|--------------|-----|\n| Project size | Small | Small-Medium | Medium-Large | Medium-Large | Any with UI | Performance-critical |\n| Team size | 1-3 | 1-5 | 3-15 | 5-20 | Any | 3-15 |\n| Domain complexity | Low | Low-Medium | Medium-High | High | Medium (UI-focused) | Low-Medium |\n| Code reuse across projects | Low | Low | Medium | High | Medium | High |\n| Initial velocity | ✅ Fast | ✅ Fast | Medium | Medium | Medium | ❌ Slow |\n| Refactoring cost | ❌ High | Medium | Medium | ✅ Low | Medium | Medium |\n\n### Quick Decision Guide\n\n```\nGame jam \u002F prototype? → Component-based (engine-native)\nSimple mobile game, solo dev? → Layered or Feature-based\nMedium project, clear features? → Feature-based\nMultiple reusable systems across projects? → Modular Monolith\nUI-heavy game (simulator, strategy, RPG)? → Modular Monolith + MVVM\u002FMVP for UI\nPerformance-critical (thousands of entities)? → ECS\nUnclear yet? → Start with Feature-based, refactor when patterns emerge\n```\n\n### Pattern Details\n\n#### Component-Based (Engine-Native)\nThe default architecture of most game engines — entities composed of reusable components.\nGood for small projects and prototypes. Scales poorly without additional structure.\nSee `ENGINE_RULES.md` for the specific component model.\n\n#### Layered Architecture\nHorizontal layers: Presentation (Views, UI) → Logic (Services, Controllers) → Data (Models, Persistence).\nEach layer depends only on the layer below. Simple but can lead to \"god service\" classes.\n\n#### Feature-Based Organization\nCode organized by game feature: `Player\u002F`, `Inventory\u002F`, `Combat\u002F`, `UI\u002F`.\nEach feature folder contains all its scripts. Good balance of simplicity and organization.\n\n#### Modular Monolith\nIndependent modules with enforced boundaries. Each module has its own namespace, tests, and public API.\nModules communicate through interfaces and DI. High reusability across projects.\nWorks best when combined with a DI\u002FIoC framework.\nSee `ENGINE_RULES.md` for how module boundaries are enforced in each engine.\n\n**Typical module structure:**\n```\nModules\u002F\n├── ModuleName\u002F\n│   ├── Scripts\u002F        (or src\u002F, Source\u002F)\n│   │   ├── Public\u002F     # Interfaces, DTOs exposed to other modules\n│   │   └── Internal\u002F   # Implementation details\n│   ├── Tests\u002F\n│   └── [boundary file] # .asmdef, BUILD, module.json, etc.\n```\n\n#### MVC \u002F MVP \u002F MVVM\nModel-View separation patterns. Choose based on UI complexity:\n- **MVC** — Controller mediates between Model and View. Simplest, good for basic UI.\n- **MVP** — Presenter replaces Controller, owns View reference. Better testability.\n- **MVVM** — ViewModel exposes bindable properties, View subscribes. Best for data-driven UI.\n  Requires a binding framework — see `ENGINE_RULES.md` for available options.\n\nThese patterns typically apply to the UI\u002Fpresentation layer and combine with another\npattern for overall project organization.\n\n#### ECS (Entity Component System)\nData-oriented design: Components are pure data, Systems process components in bulk.\nMaximum performance through cache-friendly memory layout.\nSteep learning curve, best for specific performance-critical scenarios.\nSee `ENGINE_RULES.md` for engine-specific ECS implementations.\n\n### Module Boundary Best Practices\n\n- Each module gets its own boundary definition — this enforces dependency rules at compile\u002Fbuild time\n- Test modules reference the module they test + test framework\n- Avoid circular dependencies — if two modules need each other, extract a shared interface module\n- Root project code can reference all modules, but modules should not reference project code\n- Use visibility modifiers to control what's accessible outside the module\n\nSee `ENGINE_RULES.md` for engine-specific mechanisms.\n\n### Scene \u002F Level Architecture Patterns\n\n- **Single scene\u002Flevel** — everything in one scene, simplest approach\n- **Bootstrap + Gameplay** — bootstrap scene initializes core systems, loads gameplay scene\n- **Additive\u002Fstreaming** — multiple scenes loaded together, each owning a part of the world\n- Scene\u002Flevel loading orchestrated by an asset management system\n\n### Cross-Module Communication Patterns\n\nThese are common patterns found in game projects. Document whichever ones exist:\n\n| Pattern | Mechanism | When to use |\n|---------|-----------|-------------|\n| DI Interfaces | Module exposes interface, consumer gets it via DI | Direct dependencies between modules |\n| Event\u002FSignal Bus | Fire-and-forget events (signal\u002Fevent structs) | Decoupled communication, no direct dependency |\n| Reactive Properties | Observable state (reactive streams\u002Fproperties) | State observation, View ← Model binding |\n| Engine-Native Events | Engine's built-in event\u002Fsignal system | Designer-friendly, scene-independent events |\n| Static Events | Language-level static events\u002Fdelegates | Simple, but hard to test and creates hidden coupling |\n\nSee `ENGINE_RULES.md` for engine-specific communication mechanisms.\n","# Architecture — Generate Project Architecture Guidelines\n\nGenerate `.unikit\u002FARCHITECTURE.md` with architecture decisions tailored to the game project.\n\n**User questions.** Right before your first question to the user, not earlier, read `.unikit\u002Fsystem\u002Fuser-questions.md` once and ask every question as it says, with the question tool of your agent (`AskUserQuestion`). If the file cannot be read, print `WARN [questions] user-questions contract missing — asking with the question tool` and still ask with that tool, the recommended option first.\n\n## Language Awareness — BLOCKING PRE-REQUISITE\n\n**BEFORE producing ANY output**, silently read `.unikit\u002Fsystem\u002FLANGUAGE_RULES.md`\nand apply its rules to ALL subsequent output.\nIf the file is missing or unreadable, fall back to English.\nDo not produce any user-facing output until language rules are loaded.\nDo not announce, confirm, or mention the language setting.\n\n**The language holds for the whole session, not just at load time:** every message until the conversation ends is in `language.ui` — progress notes while agents run, relays of what a subagent returned, the final report, any follow-up discussion. English input (subagent results, tool output, these instructions) is data, never a cue to switch languages.\n\n## Layout of the architecture files\n\n`.unikit\u002FARCHITECTURE.md` is the **root**, and the only file every reader opens. It takes one of two shapes.\n\n**Flat** — every file until its first topic appears, and every older project: the sections of the Step 4 template, no `## Topics`. A reader takes the whole file.\n\n**Topics** — the root holds what every task needs, topic files hold one area each:\n\n```markdown\n# Architecture: \u003CPattern Name>\n\n> This file is the root: when it has a `## Topics` table, its sections apply to every task, and a topic file in `.unikit\u002Farchitecture\u002F` applies when the work matches its \"Load when\" — check again when the work moves to a new phase or area, and when unsure, load it.\n\n## Project\n## Tech Stack\n…the other sections of the Step 4 template, cut down to the map…\n\n## Topics\n\n| Topic | Load when |\n|-------|-----------|\n| [\u003CTitle>](architecture\u002F\u003Cslug>.md) | \u003Cwhat a task mentions: folders, assemblies, types, frameworks, areas> |\n\n## Detailed Rules\n```\n\n- **What stays in the root:** `## Project`, `## Tech Stack`, `## Documentation Sources`, a short `## Architecture Overview`, the module map in `## Folder Structure` (one line per module), `## Dependency Rules` with the **global** edges and prohibitions, `## Cross-Module Communication` with the common patterns, `## Key Principles`, the global `## Anti-Patterns`, `## Topics`, `## Detailed Rules`. The section names of the template stay: other tools read them by name.\n- **A topic file** is `.unikit\u002Farchitecture\u002F\u003Cslug>.md`: `# Architecture — \u003CTitle>`, a blank line, then `## ` sections that carry the whole area — its edges and prohibitions, its contracts (a table), the narrative of its mechanisms. No `Load when` inside it, no `## Topics`.\n- **A table row** is `| [\u003CTitle>](architecture\u002F\u003Cslug>.md) | \u003CLoad when> |`. The slug is English kebab-case, one to three words, unique. `Load when` has no `|`. **`Load when` lives only in the root table.** Topics are cut by **area** (a subsystem, a module, a framework seam), never by kind of text.\n- **`## Topics` and its table exist together or not at all**; the section stands directly above `## Detailed Rules` (last when there is none). The header quote under the title is written whenever the root has a table and removed when it has none.\n- **Where a prohibition lives.** One that touches more than one area stays in the root (`## Dependency Rules`, `## Anti-Patterns`); one that touches a single area may live in its topic. When unsure, the root.\n- **Priority.** The root and its topics are one level (number 2 of `RULES_INDEX.md`). Inside its own area a topic wins over a root section it contradicts.\n- **The `flat` marker** is the line `\u003C!-- unikit:architecture-layout flat -->`, directly under the root's `# Architecture:` line. It records the user's refusal of the topic layout and means nothing to readers. There is no marker for the topic layout: the `## Topics` table is the sign.\n- **Anchors** — `## Topics`, the header row `| Topic | Load when |`, the marker, the slugs, the `# Architecture — ` prefix and the header quote — are English, and so is the rest of the document and of every topic file: architecture documentation always stays in English (LANGUAGE_RULES).\n- **Not to be confused:** `.unikit\u002Farchitecture\u002F` holds these topic files; `.unikit\u002Fcode\u002Farchitecture\u002F` holds maps a user's own skills may write. This skill reads and writes only the first.\n\n## Modes\n\nThe mode comes from the user's request together with the state of the file (below), in this order: **(1) an explicit parameter, (2) the intent of free text, (3) the state.** Both ways stay: the parameter is the stable, deterministic interface (other skills and scripts rely on it — `unikit-rules` prune hands a block over as `update \u003Cblock>`), free text is for people. **The request** is `$ARGUMENTS`; when that is empty or only a pattern name, it is the message that started this run, which is how the mode is found when the skill was picked by its description with no arguments. Free text may be in any language: read its intent, do not match words, so \"the architecture file is too big\", \"slim it down\" and `optimise` all mean the same thing. **Announce the mode first:** the announcement is the run's very first output, before Step 0 (a clarifying question, when rule 3 or 4 below needs one, comes first and the announcement follows the answer); mode names stay English, the sentence is in `language.ui`.\n\n```\n1. Parameter — checked first, never interpreted:\n   ├── the whole argument is `optimise` \u002F `optimize` (any letter case)  → Mode C\n   ├── the first word is `update` (the rest of the line is read as the request, see rule 1)  → Mode B\n   └── the whole argument is `generate`  → Mode A\n2. Otherwise the intent of the request, free text in any language:\n   ├── reorganize, optimise, slim down, shorten, split into topics, \"the file is too big\"  → Mode C: reorganize into a root and topics\n   ├── update, refresh, bring in line with the code, add what is missing, record this fact or block  → Mode B: update\n   └── generate, create, write, set up the architecture document  → Mode A: generate\n3. No parameter and no intent (an empty request, a pattern name, a question about the architecture)\n   → by the state of .unikit\u002FARCHITECTURE.md: `empty` → Mode A, any other → Mode B — a pattern name is a hint, never an order to regenerate\n```\n\n**Rules of the intent.**\n1. A request that carries a fact or a block to record (\"module X may not depend on Y\", or the text `unikit-rules` hands over) is Mode B whether it came as `update \u003Cblock>` or as free text, and that text is the block (`mode-update.md`, U.4); the text after the word `update` that only describes the wish (\"the architecture, we added a module\") is a request, not a block.\n2. Two intents in one request run in the order given — Mode B before Mode C when both are named, because Mode C restructures what Mode B just wrote.\n3. A request that reads as update or as reorganize (\"tidy up the architecture\") is asked once, with the question tool of your agent (`AskUserQuestion`): `Update` (recommended) \u002F `Reorganize into topics`. It is never guessed.\n4. A generate intent — or the `generate` parameter — on a file that has content is asked once, with the same tool: `Update instead` (recommended) \u002F `Rewrite from scratch`. Rewriting replaces what is written — the only path of this skill that removes anything — and it runs only on that answer.\n5. `update` on an `empty` file prints `INFO [architecture] update: no file — generating` and runs Mode A; `optimise` on an `empty` file prints `INFO [architecture] optimise: no architecture document — nothing to do` and stops.\n6. Whatever the wording or the parameter, Mode C writes nothing before the user confirms its preview.\n\n| Mode | Announcement | Runs |\n|------|--------------|------|\n| A: generate | `generate: I'll scan the project and write .unikit\u002FARCHITECTURE.md.` | Steps 0–6 below |\n| B: update | `update: I'll rescan the project and add what is missing to .unikit\u002FARCHITECTURE.md; nothing already written is removed.` | Steps 0–2, then read `{{skills_dir}}\u002F{{self_name}}\u002Freferences\u002Fmode-update.md` and follow it; Steps 3–4 do not run |\n| C: optimise | `optimise: I'll sort .unikit\u002FARCHITECTURE.md into a root and topic files and show you the proposed layout before writing anything.` | read `{{skills_dir}}\u002F{{self_name}}\u002Freferences\u002Fmode-optimise.md` and follow it; Steps 0–4 and 6 do not run, Step 5 (the `AGENTS.md` row) runs when that file says so |\n\n**The state** is decided by the file's content, checked in this order, the first match wins:\n\n| State | Sign |\n|-------|------|\n| `topics` | a line `## Topics` followed by the table header row `Topic` \u002F `Load when` |\n| `flat` | the marker line |\n| `empty` | no file, or a file without a single line that starts with `## ` |\n| `legacy` | anything else: content, but neither the table nor the marker |\n\nDrift is reported, never fixed silently: a row whose file is missing → `WARN [architecture] topic table: \u003Cslug> is listed, .unikit\u002Farchitecture\u002F\u003Cslug>.md does not exist`; a file in `.unikit\u002Farchitecture\u002F` no row lists → `WARN [architecture] topic table: .unikit\u002Farchitecture\u002F\u003Cfile> is not listed under ## Topics — no reader loads it`; marker and table together → `WARN [architecture] layout: flat marker ignored — the file already has a ## Topics table`. A `flat` file is never offered the reorganization again; only `optimise` reorganizes it, and removes the marker when it does.\n\n## Workflow\n\nDetermine the mode first (`## Modes`) and print its announcement as the run's first output; Steps 0–2 are shared.\n\n### Step 0: Load Engine Rules\n\nRead `{{skills_dir}}\u002F{{self_name}}\u002Freferences\u002FENGINE_RULES.md`. This file is installed by `unikit-ai init`\nbased on the user's engine choice and contains engine-specific paths, scan targets, framework lists,\nand pattern indicators. Use it for all engine-specific details in subsequent steps.\n\nIf the file is missing, inform the user: \"Engine rules not found. Please run `unikit-ai init` to configure your project.\"\n\n### Step 1: Load Existing Context\n\n**Read `.unikit\u002FDESCRIPTION.md`** if it exists — project specification, tech stack, constraints.\nThis gives you the baseline understanding of what technologies are in play before scanning.\n\n**Read `.unikit\u002Fmemory\u002Fcode\u002FRULES_INDEX.md`** if it exists — it contains the index of framework-specific\nrule files that the project already uses. This tells you which frameworks and patterns are in play.\nDo NOT read the individual rule files — only the index to understand what's covered.\n\n**Read `.unikit\u002FRULES.md`** if it exists — naming conventions, class structure, DI rules. **Rule topics:** its `## Topics` table names the topic files in `.unikit\u002Frules\u002F`; open one only when the architecture work at hand touches its `Load when`.\nExtract key conventions but do NOT duplicate them into ARCHITECTURE.md — reference the file instead.\n\n**Read the root `.unikit\u002FARCHITECTURE.md`** if it exists — its state (see `## Modes`) decides the mode. **Architecture topics:** open a topic file only when the work at hand places or checks a fact in its area (Mode B), or when `optimise` reads them all.\n\n**Read `.unikit\u002Fskill-context\u002Funikit-architecture\u002FSKILL.md`** if it exists — project-specific rules accumulated by `\u002Funikit-evolve`. Treat as overrides: skill-context wins over general rules on conflict.\n\n\u003C!-- unikit:extension-point:bootstrap -->\n\n### Step 2: Scan the Project\n\nScan the project to discover the actual tech stack. This is the most important step —\narchitecture documentation must reflect reality, not assumptions.\n\nUse `ENGINE_RULES.md` file (loaded in Step 0) to determine:\n- Which directories to scan and what to look for in each\n- Which file extensions indicate project scripts\n- How to discover module boundaries (assembly definitions, build files, folder conventions)\n- Which DI\u002FIoC frameworks to look for\n- Which architectural pattern indicators to check\n\n#### 2.1 Scan Directories\n\nScan the directories listed in `ENGINE_RULES.md` under \"Scan Targets\".\nFor each discovered directory, run `ls` to get subfolder names — this reveals the real building blocks.\n\n#### 2.2 Scan Module Boundaries\n\nFind module boundary definition files as specified in `ENGINE_RULES.md` (e.g., assembly definitions,\nbuild files, or folder-based conventions). Read a representative sample to understand:\n- Module boundaries and namespace conventions\n- Dependency directions between modules\n- Which modules reference which frameworks\n\n#### 2.3 Detect DI\u002FIoC Framework\n\nLook for DI framework indicators listed in `ENGINE_RULES.md`.\nNot all engines have standard DI — if none is detected, note \"manual DI or none\".\n\n#### 2.4 Detect Key Patterns\n\nLook for architectural pattern indicators. These patterns are largely engine-agnostic:\n\n- Files with `View`, `ViewModel`, `Presenter`, `Model` suffixes — reveals MV* pattern\n- `Controller` suffixes — may indicate MVC or GRASP controllers\n- Folders named `ECS`, `Systems`, `Components`, `Entities` — may indicate ECS\n- `SignalBus`, `EventBus`, `MessageBus` — event system\n- `SaveSerializer`, `SaveData`, `SaveManager` — save system pattern\n- DI installer\u002Fmodule files — as specified in `ENGINE_RULES.md`\n\n### Step 3: Ask About Architecture (if needed)\n\nMode A only. In Mode B a named pattern is a hint for the rescan, nothing more.\n\n**If `$ARGUMENTS` specifies an architecture pattern** (e.g., `\u002Funikit-architecture modular-monolith`):\n- Use that pattern directly, skip to Step 4\n\n**If the project already has code and patterns are detectable from Step 2:**\n- Summarize what you found and confirm with the user\n\n**If the project is new or patterns are unclear**, print the message below as plain markdown first, then ask its last question with the question tool of your agent (`AskUserQuestion`): the options are the pattern the scan and the Quick Decision Guide point to (recommended), one or two other likely patterns from the list, and `Document what I found as-is`; the user writes any other pattern or a combination in the free-text answer:\n\n```\nBased on the project scan, I found:\n- [discovered modules\u002Fframeworks\u002Fpatterns]\n\nWhich architectural patterns do you plan to use?\n\nCommon game architecture patterns:\n1. Modular Monolith — independent modules with enforced boundaries, single deployment\n2. Feature-based — code organized by feature (Player\u002F, Inventory\u002F, Combat\u002F)\n3. Layered — horizontal layers (Domain → Application → Presentation)\n4. MVC \u002F MVP \u002F MVVM — Model-View separation (specify which variant)\n5. ECS — Entity Component System for data-oriented design\n6. Component-based — engine's native component architecture without extra layers\n\nYou can combine patterns (e.g., \"Modular Monolith + MVVM for UI\").\n```\n\n### Step 4: Generate .unikit\u002FARCHITECTURE.md\n\n```bash\nmkdir -p .unikit\n```\n\nGenerate `.unikit\u002FARCHITECTURE.md` using the template below. Every section must be adapted\nto what was actually discovered in Step 2 — never use placeholder or generic content.\n\n---\n\n**ARCHITECTURE.md Template:**\n\n```markdown\n# Architecture: [Pattern Name]\n\n## Project\n\n[1 sentence: what this project is, target platforms]\n\n## Tech Stack\n\n| Category | Technology |\n|----------|-----------|\n| Engine | [engine name + version \u002F primary language \u002F render pipeline] |\n| DI | [DI framework name or \"None\"] |\n| [category] | [technology] |\n...\n\nInclude only technologies actually found during scanning. Each row must correspond\nto a real framework, module, or asset discovered in the project.\n\n## Documentation Sources\n\nWhen you need up-to-date API docs for these libraries:\n\n[List each major library with its documentation lookup method.\nIf context7 MCP is available, specify \"use context7\" with the search query.\nIf docs are bundled locally, point to the path.]\n\n## Architecture Overview\n\n[2-3 paragraphs explaining the chosen architecture pattern and why it fits this project.\nIf the pattern was detected from existing code, describe what you found.\nIf it was chosen by the user, explain the rationale.]\n\n## Folder Structure\n\n```\n[Project root]\u002F\n├── [scripts directory]\u002F    [describe organization principle]\n│   ├── [folder]\u002F           [purpose]\n│   └── ...\n├── [modules directory]\u002F    [describe module boundaries]\n│   ├── [Module1]\u002F          [purpose]\n│   └── ...\n├── [plugins directory]\u002F    [third-party frameworks]\n└── [assets directory]\u002F     [store assets]\n```\n\nDescribe the actual folder structure found in the project, not an ideal one.\n\n## Dependency Rules\n\n[What depends on what. Use the actual module\u002Ffolder names from the project.]\n\n- ✅ [allowed dependency direction with real names]\n- ❌ [forbidden dependency direction with real names]\n\n## Module Boundary Strategy\n\n[Describe how the project partitions the codebase into modules. Include:\n- What mechanism enforces boundaries (assembly definitions, build files, folder conventions)\n- Naming convention for modules\n- How modules expose their public API\n- Test module conventions]\n\n## Cross-Module Communication\n\n[How modules communicate. Describe ONLY patterns that actually exist in the project.\nCommon patterns: DI interfaces, event\u002Fsignal bus, reactive properties, direct references.\nFor each pattern, specify which module or framework provides it.]\n\n## Key Principles\n\n[3-5 principles derived from the project's actual conventions. Examples:]\n1. [Principle from the codebase]\n2. ...\n\n## Anti-Patterns\n\n- ❌ [What NOT to do — derived from actual project conventions]\n- ❌ ...\n\n## Detailed Rules\n\nFor framework-specific rules, coding conventions, and implementation details see:\n\n- **`.unikit\u002FRULES.md`** — [brief description of what's there; when it has a `## Topics` table, name its topic files in `.unikit\u002Frules\u002F`]\n- **`.unikit\u002Fmemory\u002Fcode\u002FRULES_INDEX.md`** — index of all framework-specific rule files\n- **`.unikit\u002Farchitecture\u002F`** — topic files, listed in `## Topics` (only when the file has topics)\n```\n\n---\n\n**Rules for generation:**\n\n- Every technology, module, and pattern mentioned must have been found during scanning\n- Use code examples in the project's primary language that match the project's actual style\n- Folder structure must extend what already exists, not replace it\n- If custom modules were found (SignalBus, EventBus, SaveSystem, etc.), document their role\n  in the architecture explicitly — they are first-class architectural elements\n- The \"Detailed Rules\" section MUST reference `.unikit\u002Fmemory\u002Fcode\u002FRULES_INDEX.md` — that file\n  is the single source of truth for which rule files exist and when to load them\n- Do NOT duplicate content from RULES.md or memory\u002Fcode\u002FRULES_INDEX.md —\n  reference them and describe what each contains in one line\n- **Topics at generation.** Write one root. A subsystem for which the scan found more than one table row of structure — its own edges and prohibitions, a contract catalogue, or a mechanism that needs a paragraph — becomes a topic file (shape: `## Layout of the architecture files`) listed in `## Topics`; everything that fits one line stays in the root. A project with no such subsystem gets the flat shape: no `## Topics`, no header quote.\n- Keep the root concise — it's a map, not a manual. What explains how one area works lives in that area's topic file, or in `docs\u002F`, not in the root.\n\n### Step 5: Update AGENTS.md\n\nIf `AGENTS.md` exists in the project root, add or update the `.unikit\u002FARCHITECTURE.md` entry\nin the \"AI Context Files\" table (or equivalent section):\n\n```\n| .unikit\u002FARCHITECTURE.md | Architecture decisions and guidelines |\n```\n\nWhen the file has topics, the row reads `| .unikit\u002FARCHITECTURE.md | Architecture decisions and guidelines; topic files in .unikit\u002Farchitecture\u002F load when their \"Load when\" matches |`. Modes B and C run this step too whenever the file has topics when they finish, or has just lost its last one: the row is checked every time, so a regenerated `AGENTS.md` gets the topic note back.\n\nIf the entry already exists, verify it's accurate. If `AGENTS.md` doesn't exist, skip this step silently.\n\n### Step 6: Confirm\n\n```\n✅ Architecture document generated!\n\nEngine: [detected engine]\nPattern: [chosen pattern]\nFile: .unikit\u002FARCHITECTURE.md\nTopics: [N topic files in .unikit\u002Farchitecture\u002F | none — flat]\n\nDiscovered:\n- [N] modules in [modules directory]\n- [N] plugins\u002Faddons in [plugins directory]\n- [N] third-party assets\u002Fpackages\n- [N] module boundary definitions\n\nKey architectural decisions:\n- [decision 1]\n- [decision 2]\n- [decision 3]\n\nThe document references .unikit\u002Fmemory\u002Fcode\u002FRULES_INDEX.md for detailed framework rules\nand .unikit\u002FRULES.md for coding conventions.\n```\n\n## Knowledge Base\n\nReference material for architecture evaluation. This content informs recommendations —\nit is NOT output directly.\n\n### Architecture Decision Matrix\n\n| Factor | Component-Based | Layered | Feature-Based | Modular Monolith | MVC\u002FMVP\u002FMVVM | ECS |\n|--------|----------------|---------|---------------|-------------------|--------------|-----|\n| Project size | Small | Small-Medium | Medium-Large | Medium-Large | Any with UI | Performance-critical |\n| Team size | 1-3 | 1-5 | 3-15 | 5-20 | Any | 3-15 |\n| Domain complexity | Low | Low-Medium | Medium-High | High | Medium (UI-focused) | Low-Medium |\n| Code reuse across projects | Low | Low | Medium | High | Medium | High |\n| Initial velocity | ✅ Fast | ✅ Fast | Medium | Medium | Medium | ❌ Slow |\n| Refactoring cost | ❌ High | Medium | Medium | ✅ Low | Medium | Medium |\n\n### Quick Decision Guide\n\n```\nGame jam \u002F prototype? → Component-based (engine-native)\nSimple mobile game, solo dev? → Layered or Feature-based\nMedium project, clear features? → Feature-based\nMultiple reusable systems across projects? → Modular Monolith\nUI-heavy game (simulator, strategy, RPG)? → Modular Monolith + MVVM\u002FMVP for UI\nPerformance-critical (thousands of entities)? → ECS\nUnclear yet? → Start with Feature-based, refactor when patterns emerge\n```\n\n### Pattern Details\n\n#### Component-Based (Engine-Native)\nThe default architecture of most game engines — entities composed of reusable components.\nGood for small projects and prototypes. Scales poorly without additional structure.\nSee `ENGINE_RULES.md` for the specific component model.\n\n#### Layered Architecture\nHorizontal layers: Presentation (Views, UI) → Logic (Services, Controllers) → Data (Models, Persistence).\nEach layer depends only on the layer below. Simple but can lead to \"god service\" classes.\n\n#### Feature-Based Organization\nCode organized by game feature: `Player\u002F`, `Inventory\u002F`, `Combat\u002F`, `UI\u002F`.\nEach feature folder contains all its scripts. Good balance of simplicity and organization.\n\n#### Modular Monolith\nIndependent modules with enforced boundaries. Each module has its own namespace, tests, and public API.\nModules communicate through interfaces and DI. High reusability across projects.\nWorks best when combined with a DI\u002FIoC framework.\nSee `ENGINE_RULES.md` for how module boundaries are enforced in each engine.\n\n**Typical module structure:**\n```\nModules\u002F\n├── ModuleName\u002F\n│   ├── Scripts\u002F        (or src\u002F, Source\u002F)\n│   │   ├── Public\u002F     # Interfaces, DTOs exposed to other modules\n│   │   └── Internal\u002F   # Implementation details\n│   ├── Tests\u002F\n│   └── [boundary file] # .asmdef, BUILD, module.json, etc.\n```\n\n#### MVC \u002F MVP \u002F MVVM\nModel-View separation patterns. Choose based on UI complexity:\n- **MVC** — Controller mediates between Model and View. Simplest, good for basic UI.\n- **MVP** — Presenter replaces Controller, owns View reference. Better testability.\n- **MVVM** — ViewModel exposes bindable properties, View subscribes. Best for data-driven UI.\n  Requires a binding framework — see `ENGINE_RULES.md` for available options.\n\nThese patterns typically apply to the UI\u002Fpresentation layer and combine with another\npattern for overall project organization.\n\n#### ECS (Entity Component System)\nData-oriented design: Components are pure data, Systems process components in bulk.\nMaximum performance through cache-friendly memory layout.\nSteep learning curve, best for specific performance-critical scenarios.\nSee `ENGINE_RULES.md` for engine-specific ECS implementations.\n\n### Module Boundary Best Practices\n\n- Each module gets its own boundary definition — this enforces dependency rules at compile\u002Fbuild time\n- Test modules reference the module they test + test framework\n- Avoid circular dependencies — if two modules need each other, extract a shared interface module\n- Root project code can reference all modules, but modules should not reference project code\n- Use visibility modifiers to control what's accessible outside the module\n\nSee `ENGINE_RULES.md` for engine-specific mechanisms.\n\n### Scene \u002F Level Architecture Patterns\n\n- **Single scene\u002Flevel** — everything in one scene, simplest approach\n- **Bootstrap + Gameplay** — bootstrap scene initializes core systems, loads gameplay scene\n- **Additive\u002Fstreaming** — multiple scenes loaded together, each owning a part of the world\n- Scene\u002Flevel loading orchestrated by an asset management system\n\n### Cross-Module Communication Patterns\n\nThese are common patterns found in game projects. Document whichever ones exist:\n\n| Pattern | Mechanism | When to use |\n|---------|-----------|-------------|\n| DI Interfaces | Module exposes interface, consumer gets it via DI | Direct dependencies between modules |\n| Event\u002FSignal Bus | Fire-and-forget events (signal\u002Fevent structs) | Decoupled communication, no direct dependency |\n| Reactive Properties | Observable state (reactive streams\u002Fproperties) | State observation, View ← Model binding |\n| Engine-Native Events | Engine's built-in event\u002Fsignal system | Designer-friendly, scene-independent events |\n| Static Events | Language-level static events\u002Fdelegates | Simple, but hard to test and creates hidden coupling |\n\nSee `ENGINE_RULES.md` for engine-specific communication mechanisms.\n",{"name":5,"version":44,"description":7,"allowed-tools":45,"argument-hint":57},"3.0",[46,47,48,49,50,51,52,53,54,55,56],"Read","Write","Edit","Glob","Grep","Bash(mkdir *)","Bash(ls *)","Bash(find *)","AskUserQuestion","Bash(rm .unikit\u002Farchitecture\u002F*)","Bash(node *)","[update [text] | optimise | generate | a request in plain words | architecture pattern name | empty to follow the state of the file]","main","ae3c6dfffd26d9b45b9d96d71ba2c122c50b67ae","skills\u002Funikit-architecture",1,"https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai","https:\u002F\u002Funikit.nintenda.dev","https:\u002F\u002Fgithub.com\u002FNintendaDev","Unity Developer. Building games and UniKit AI","2026-11-08 15:05:51",{"source":8,"skillName":5,"commands":68,"prompt":78,"zipAvailable":79},[69,72,75],{"tool":70,"command":71},"npx","npx skills add NintendaDev\u002Funikit-ai --skill unikit-architecture",{"tool":73,"command":74},"bunx","bunx skills add NintendaDev\u002Funikit-ai --skill unikit-architecture",{"tool":76,"command":77},"pnpm","pnpm dlx skills add NintendaDev\u002Funikit-ai --skill unikit-architecture","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-architecture\u002FSKILL.md",true,[81,87,91],{"path":82,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":85,"sourceHtmlUrl":86},"references\u002Fmode-optimise.md","REFERENCE","参考文档",10640,"https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-architecture\u002Freferences\u002Fmode-optimise.md",{"path":88,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":89,"sourceHtmlUrl":90},"references\u002Fmode-update.md",4630,"https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-architecture\u002Freferences\u002Fmode-update.md",{"path":92,"resourceType":93,"resourceTypeDesc":94,"sizeBytes":95,"sourceHtmlUrl":96},"scripts\u002Farchitecture-layout.mjs","SCRIPT","脚本",29536,"https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-architecture\u002Fscripts\u002Farchitecture-layout.mjs",[98,121,146,168,187,212],{"skillNo":99,"name":100,"nameZh":6,"description":101,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":102,"categories":103,"keywords":109,"publishedAt":39},"01M71BQ00EXGX51PPCDY7VG334","unikit","Initialize the UniKit framework in a project. Scans the current project to detect the engine and real tech stack, then generates the base framework documents that give AI agents context about the project — the resolved project description, the architecture doc, AGENTS.md, and the user-editable .unikit\u002Fconfig.yaml. This is the one-time, whole-project setup run before any other unikit skill. Use whenever the user wants to initialize, set up, or onboard the framework, e.g. \"initialize unikit\", \"init the framework\", \"set up unikit\", \"set up the project\", \"configure AI context\", \"scan my project and set it up\", \"bootstrap the project\". It also actualizes the config of a project already set up — say \"update the config\", \"add missing settings\", \"actualize configuration\", \"fix my config\". On a set-up project it offers the actions to choose from.","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit\u002FSKILL.md",[104],{"categoryNo":105,"categoryName":106,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[100,38,110,111,112,113,19,32,114,29,28,27,115,26,116,117,118,25,119,120],"time","actions","fix","documents","run","config","git","context","initialize","scan","use",{"skillNo":122,"name":123,"nameZh":6,"description":124,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":131,"publishedAt":39},"01M71BPRTMKW7FRAZZBN44NW5Q","unikit-verify","Verify a completed implementation against the plan in .unikit\u002Fcode\u002Fplans\u002F. Checks that every task was implemented, nothing was forgotten, the code compiles, the recorded test run still matches the code, and {{engine_name}} conventions are followed. Use after \u002Funikit-implement completes, or when the user says \"verify\", \"check the work\", \"did we miss anything\". For code review use \u002Funikit-review instead.","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-verify\u002FSKILL.md",[127,130],{"categoryNo":128,"categoryName":129,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":105,"categoryName":106,"taxonomyType":107,"taxonomyTypeDesc":108},[132,133,134,135,136,137,114,28,27,26,116,138,139,120,140,141,142,143,144,145],"unikit verify","verify","powershell","code review","phase","plan","for","system","implement","check","engine","research","name","quality",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":150,"categories":151,"keywords":152,"publishedAt":39},"01M71BPM35M5ETPA4E7EKQYRWD","unikit-todo","Manage the project's TODO list in .unikit\u002FTODO.md — capture work to remember for later, not to do right now. Use it to add a deferred item, mark a todo complete, or show the list. The point is to park tasks you don't want to act on in the moment but don't want to forget. Trigger on \"add a todo\", \"add this to the todo list\", \"put X on the todo list\", \"remind me to...\", \"don't forget to...\", \"note this for later\", \"we should do this later\", \"mark this todo done\", \"what's on the todo list\", \"what's left to do\". This is only for parking reminders — to actually plan or do the work now, use \u002Funikit-plan, \u002Funikit-implement, or \u002Funikit-execute.","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-todo\u002FSKILL.md",[],[153,154,155,156,38,157,158,159,160,161,162,163,137,164,165,166,28,27,26,167],"unikit todo","todo","remind","show","todo list","only","now","you","done","tasks","work","me","reminders","later","act",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":175,"publishedAt":39},"01M71BPEQDVD7DTGFQBQJQ7JKY","unikit-skills-context","Customize how a built-in unikit skill behaves in this specific project by writing workflow overrides into its skill-context file. These are per-skill workflow rules (e.g. \"\u002Funikit-review should also flag TODO comments\", \"\u002Funikit-implement should run tests after each task\"), not coding conventions. Use when the user wants to change, customize, or override how a particular unikit skill works in this project — \"customize the review skill\", \"make \u002Funikit-fix always add logging here\", \"the implement skill should do X differently\", \"add a skill rule for \u002Funikit-commit\". Use \"validate\" to find stale overrides against updated base skills. For a general coding convention (not tied to one skill) use \u002Funikit-rules; to derive rules from past mistakes use \u002Funikit-evolve.","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-skills-context\u002FSKILL.md",[174],{"categoryNo":105,"categoryName":106,"taxonomyType":107,"taxonomyTypeDesc":108},[176,117,38,112,177,178,179,180,181,182,183,34,154,184,185,114,186,28,27,26],"unikit skills context","coding conventions","writing","when","workflow","commit","review","general coding","change","how","past",{"skillNo":188,"name":189,"nameZh":6,"description":190,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":191,"categories":192,"keywords":200,"publishedAt":39},"01M71BP7K5KEGJV4ASRKPG1DM8","unikit-rules","Add a short, project-specific rule, convention, or override to .unikit\u002FRULES.md — the quick-capture inbox for this project's rules (common rules always load; topic files in .unikit\u002Frules\u002F load when the work matches), automatically loaded by \u002Funikit-implement (later promotable via \u002Funikit-memory migrate-rules). Works only with a rule typed as a prompt — it does NOT read files, folders, URLs, or PDFs. Cross-checks the knowledge base (RULES_INDEX.md) to avoid duplicating core\u002Fstack entries. Use for one-line conventions and corrections: \"add a rule\", \"remember this\", \"convention\", \"always do X\", \"never use Y\", \"from now on do Z\", or when the user corrects agent behavior and wants it remembered; also \"split the rules into topics\" (optimise), \"clean up the rules\" (prune), \"shorten RULES.md\" (compact), by keyword or in plain words. If the user points to a source (file, folder, URL, PDF, article, book) or wants to research\u002Fdocument framework usage, use \u002Funikit-memory; for architecture decisions use ARCHITECTURE.md.","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-rules\u002FSKILL.md",[193,196,199],{"categoryNo":194,"categoryName":195,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000002","文档处理",{"categoryNo":197,"categoryName":198,"taxonomyType":107,"taxonomyTypeDesc":108},"01JBSEEDCAT000000000000021","资料检索与研究",{"categoryNo":105,"categoryName":106,"taxonomyType":107,"taxonomyTypeDesc":108},[201,202,203,204,38,205,206,36,207,208,19,209,34,210,32,166,28,27,26,211],"Rules","unikit rules","quick","PDF","clean","knowledge","URL","migrate","batch","knowledge base","prune",{"skillNo":213,"name":214,"nameZh":6,"description":215,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":216,"categories":217,"keywords":218,"publishedAt":39},"01M71BP02S49HHD4R5X6N12C9Q","unikit-rules-registry","Orchestrate the remote rules registry — the shared registry (often connected as a local folder or git repo) that the project's rules are published to and pulled from. Three modes, picked from the user's wording: create scaffolds a new local rules registry (\"create a local rules registry\", \"init a rules registry\"); update migrates\u002Fpromotes local knowledge-base rules from .unikit\u002Fmemory\u002F into the remote registry with automatic semver bumps (\"migrate local rules to the remote registry\", \"promote my rules to the registry\", \"push local rules\", \"publish local rules\", \"update the rules registry\"); sync pulls registry updates back into memory (\"sync the rules registry\", \"pull registry updates\"). Pass \"--module \u003Cid>\" to scope to one knowledge-base module. This skill ONLY orchestrates the CLI (`unikit-ai rules *`) — it never edits .unikit.json or .unikit\u002Fmemory\u002F sources directly.","https:\u002F\u002Fgithub.com\u002FNintendaDev\u002Funikit-ai\u002Fblob\u002Fmain\u002Fskills\u002Funikit-rules-registry\u002FSKILL.md",[],[219,201,220,221,38,222,206,223,208,224,29,28,27,116,225,226,227,228,229,230],"registry","unikit rules registry","shared","local","remote","create","ai rules","automatic","semver","knowledge-base","as","three"]