Gameplay and system architecture advisor for Unity. Use when users want module boundaries, scene design, SOLID structure, decoupling, or refactoring direction before writing code. Triggers: architecture, system design, how to structure, how to organize, module boundary, decouple, refactor, SOLID, 架构设计, 怎么组织代码, 模块划分, 代码结构, 解耦, 重构方向, 系统设计.
Scanned 5/27/2026
Install via CLI
openskills install Besty0728/Unity-Skills---
name: unity-architecture
description: "Gameplay and system architecture advisor for Unity. Use when users want module boundaries, scene design, SOLID structure, decoupling, or refactoring direction before writing code. Triggers: architecture, system design, how to structure, how to organize, module boundary, decouple, refactor, SOLID, 架构设计, 怎么组织代码, 模块划分, 代码结构, 解耦, 重构方向, 系统设计."
---
# Unity Architecture Advisor
Use this before generating lots of gameplay scripts or when the user asks for a cleaner architecture.
## Workflow
1. Identify scope: prototype, small game, or long-lived project.
2. Define the core loop and the minimum runtime systems needed.
3. Recommend the smallest architecture that fits the scope.
4. Separate:
- scene/bootstrap layer
- gameplay/domain logic
- data/config assets
- view/presentation layer
5. Call out what should stay simple now vs what is worth abstracting.
## Output Format
When using this skill, structure the advice as:
- Project tier: prototype / small-game / long-lived
- Recommended modules: 3-7 modules with one-line responsibilities
- Scene/bootstrap plan: where composition and initialization happen
- Data ownership: what belongs in scene objects, ScriptableObjects, or pure C# classes
- Communication rules: direct refs, interfaces, events, or commands
- Performance risks: only the hot paths that matter
- Do now / skip now: avoid over-engineering
## Default Guidance
- Prefer thin `MonoBehaviour` scripts as composition bridges.
- Put reusable gameplay rules in plain C# classes when possible.
- Use `ScriptableObject` for authored config and shared static data, not as a default dump for runtime state.
- Keep dependencies explicit. Avoid hidden global state unless the project size clearly justifies a small service layer.
- Favor simple module boundaries over framework-heavy architecture.
## Explicit Execution Order and Entry Guards
Most "random" gameplay bugs trace back to two silent assumptions: that scripts run in a predictable order, and that `Update` runs only when its data is ready. Neither is true unless you make them so.
### Make startup order explicit
Do not rely on Script Execution Order panels or accidental `Awake` ordering. Prefer these patterns in order of preference:
- **One Bootstrap script** as the single entry point. It owns the initialization sequence and calls `sub.Init()` on the managers it creates. Only this one script has `[DefaultExecutionOrder(-10000)]`.
- **Pull, don't push**: a subscriber that needs data calls `source.GetValue()` on demand or subscribes to an event. A publisher that pushes into others during its own `Awake` creates hidden order dependencies.
- **Reserve `[DefaultExecutionOrder(n)]`** for load-bearing singletons only (Bootstrap, InputRouter, SceneController). If more than 3-4 scripts need it, the architecture is wrong, not the ordering.
The analogous ECS pattern — `[UpdateBefore(typeof(BarSystem))]` / `[UpdateAfter]` — works because the framework validates contradictions at sort time. In MonoBehaviour code the compiler won't catch them; be conservative. *Source: `EntitiesSamples/Docs/systems.md:32` — "if the ordering attributes of a group's children create a contradiction, an exception is thrown".*
### Make update preconditions explicit
Every `Update` / `LateUpdate` / `FixedUpdate` should open with guard clauses that early-return when the system is not ready. Prefer the cheapest check first:
```csharp
void Update() {
if (!_isInitialized) return; // construction-time
if (_dataSource == null) return; // dependency-level
if (_paused) return; // gameplay-state
// real work here
}
```
A missing guard is the difference between "doesn't run yet" (safe) and "runs with stale/null data and silently corrupts state" (debug nightmare). The ECS equivalent is `state.RequireForUpdate<Config>()` in `OnCreate`, which turns the precondition into a system-level invariant. *Source: `Dots101/Entities101/Assets/HelloCube/3. Prefabs/SpawnSystem.cs:17-19` — the system does not update unless a `Spawner` entity exists.*
## Guardrails
> **Mode**: Documentation only — no REST skills to gate; load freely under any operating mode (Approval / Auto / Bypass).
- Do not start from a giant reusable framework unless the project truly needs it.
- Do not add layers just to satisfy textbook SOLID wording.
- Prefer a small architecture that can grow, not an impressive one that slows iteration.
## Load Related Advisory Modules When Needed
- Pattern choice: see [`../patterns/SKILL.md`](../patterns/SKILL.md)
- Async / Update / UniTask decisions: see [`../async/SKILL.md`](../async/SKILL.md)
- Inspector-facing field design: see [`../inspector/SKILL.md`](../inspector/SKILL.md)
- Script quality review: see [`../scriptdesign/SKILL.md`](../scriptdesign/SKILL.md)
No comments yet. Be the first to comment!