Use when building reusable Unity game systems, creating UPM packages, or designing ScriptableObject-based modular architecture for gameplay systems like inventory, combat, dialogue, quests, or save/load. Also use when connecting multiple independent Unity packages that need to communicate without direct dependencies.
Instalação
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Use when building reusable Unity game systems, creating UPM packages, or designing ScriptableObject-based modular architecture for gameplay systems like inventory, combat, dialogue, quests, or save/load. Also use when connecting multiple independent Unity packages that need to communicate without direct dependencies.
Unity Reusable Systems
Build every gameplay system as a self-contained UPM package. Data lives in
ScriptableObjects, behavior lives in small single-responsibility MonoBehaviours,
and systems talk through SO Event Channels — never direct references.
Target: Unity 6+ / C# 11.
The Rules
ALWAYS
NEVER
One system = one UPM package
Create a "shared contracts" package with interfaces
Data in ScriptableObjects, behavior in MonoBehaviours
Put data and behavior in the same class
MonoBehaviour [SerializeField] only for SO refs, component refs, scene refs, UnityEvents
[SerializeField] primitives (float, int, bool, string, LayerMask, enum, AnimationCurve) directly on MonoBehaviours — these belong in an SO Config asset
SO Event Channels for cross-system communication
Use singletons, service locators, or static managers
One assembly definition per folder (Runtime, Editor, Tests)
Ship without assembly definitions
Version Defines for optional cross-package awareness
Use #if defines without versionDefines in asmdef
Define Constraints for conditional integration assemblies
Create hard dependencies between gameplay packages
Small MonoBehaviours with [RequireComponent]
God classes that handle input + logic + rendering
ScriptableVariable for shared runtime state
Public static fields or global state holders
RuntimeSet for tracking active instances
FindObjectsOfType or singleton registries
Awaitable with destroyCancellationToken for async
Coroutines for new async work
[SerializeReference] for polymorphic serialized data
Deep inheritance hierarchies
Composition: many small components on one GameObject
One MonoBehaviour doing everything
Interfaces only at package boundaries when SO Events can't solve it
Interfaces inside a single package
Tests using ScriptableObject.CreateInstance in Edit Mode
Skipping tests because "it's just a SO"
Editor menu item that generates a fully-wired sample scene
Shipping a package without a one-click working demo scene
Generate docs/packages/<package-name>.md with full integration surface
Create a package without documenting its public events, variables, and interfaces
Read all docs/packages/*.md before designing a new package
Design a new package without checking what existing packages expose
Cross-package, always installed together? → SO Event Channel
Cross-package, optionally installed? → Version Defines + SO Event Channel or bridge package
Integration Discovery
Before designing a new package, read every file in docs/packages/*.md. These documents describe the integration surface of each existing package — their event channels, ScriptableVariables, RuntimeSets, and interfaces.
Discovery steps:
Read all docs/packages/*.md files. If the folder doesn't exist, this is the first package — skip to step 4.
List every event channel, ScriptableVariable, RuntimeSet, and interface from existing packages that is relevant to the new package.
Produce an Integration Plan as part of the new package design:
Listen to — existing events the new package should subscribe to (via Version Defines)
Publish — new events the new package should raise for others to consume
Read/Write — existing ScriptableVariables the new package should use
Expose — new ScriptableVariables the new package should create for shared state
Implement — existing interfaces the new package should implement
Bridge needed? — whether a Bridge Package is required for complex cross-package logic
Suggested changes to existing packages — checklist of Version Defines, listeners, or asmdef updates other packages could add to become aware of the new package
After building the package, generate docs/packages/<package-name>.md (see Package Integration Doc below).
MonoBehaviour Field Rule
A MonoBehaviour's [SerializeField] fields must only be references — never raw config values.
Allowed on a MonoBehaviour:
SO references: config SOs, event channels, ScriptableVariables, RuntimeSets
Component / GameObject references (scene wiring)
UnityEvents (designer-hookable callbacks)
Belongs in an SO Config asset instead:
Primitives and value types: float, int, bool, string, enum
Shared runtime state as an asset. Any component can read/write. Resets on play mode exit.
publicabstractclassScriptableVariable<T> : ScriptableObject
{
[SerializeField] private T initialValue;
[System.NonSerialized] private T runtimeValue;
public T Value
{
get => runtimeValue;
set => runtimeValue = value;
}
privatevoidOnEnable() => runtimeValue = initialValue;
}
// Concrete types for the serializer:
[CreateAssetMenu(menuName = "Variables/Float")]
publicclassFloatVariable : ScriptableVariable<float> { }
SO Event Channel
Fire-and-forget broadcast. Publishers and subscribers share an asset reference — never each other.
Create one concrete SO per payload type (void, float, int, Vector3, DamageInfo, etc.). Generic SO base classes are not directly serializable — always create concrete leaf types.
GameEventListener
Bridges SO Event Channels to the scene via UnityEvent. Designers wire responses in the Inspector.
Every package must include Editor/SampleSceneGenerator.cs with menu item Tools/{Company}/{System}/Create Sample Scene. The generator must:
Create a new scene
Instantiate all SO assets (config, event channels, variables, runtime sets) into a data folder
Create GameObjects with all components attached
Wire every [SerializeField] — SO references, event channels, variables
Press Play → system works without manual setup
Package Integration Doc
Every package must have a project-level integration doc at docs/packages/<package-name>.md. Generate this as the final step of package creation. If the docs/packages/ directory doesn't exist, create it.
Required sections:
# <package-name> — Integration Surface## Event Channels
| Event | Payload Type | Raised When | Suggested Listeners |
|-------|-------------|-------------|---------------------|
| `OnX` | `void` / concrete type | Description of trigger | Systems that should react |
## ScriptableVariables
| Variable | Type | Purpose |
|----------|------|---------|
| `VarName` | `FloatVariable` / concrete type | What this variable represents |
## RuntimeSets
| Set | Item Type | Purpose |
|-----|-----------|---------|
| `SetName` | `ComponentType` | What instances this set tracks |
## Interfaces (Package Boundary)
| Interface | Purpose | When to Implement |
|-----------|---------|-------------------|
| `IName` | What contract it defines | When another package should implement it |
## Assembly & Version Define-**Assembly:**`{Company}.{System}`-**Package ID:**`com.{company}.{system}`-**Version Define symbol:**`{COMPANY}_{SYSTEM}`## Integration Examples-**SystemA** → listen to `OnX`, do Y
-**SystemB** → read `VarName`, display Z
Omit any section that has no entries (e.g., if the package exposes no interfaces, omit "Interfaces"). Never omit Event Channels or Assembly & Version Define — every package has at least one event and an assembly.
Edit Mode unless you need MonoBehaviour lifecycle or physics. Edit Mode tests are faster and more reliable.
New Package Checklist
Before shipping any package, verify:
Read all docs/packages/*.md and produce an Integration Plan before designing
package.json with correct name, version, unity (6000.0+), displayName
Runtime/ with {Company}.{Package}.asmdef — zero external references
Editor/ with Editor-only asmdef (if any editor code exists)
Tests/Editor/ with test asmdef using overrideReferences and testAssemblies
Samples~/ with at least one importable sample
Editor menu item under Tools/{Company}/{System}/Create Sample Scene that generates a fully-wired demo scene — all SO assets instantiated, all components on GameObjects, all event channels and variables assigned, playable on first run
CHANGELOG.md following SemVer
All SOs have [CreateAssetMenu] with organized menu paths
All MonoBehaviours use [RequireComponent] where applicable
No [SerializeField] primitives on MonoBehaviours — all config in SO assets
SO Event Channels for every output event (no direct subscriber lists)
ScriptableVariables for any shared runtime state
RuntimeSets for any "all active X" queries
Version Defines in asmdef for any optional package awareness
No FindObjectsOfType, no singletons, no static mutable state
Generate docs/packages/<package-name>.md with all events, variables, RuntimeSets, interfaces, and integration examples
Reference Files
For deeper details — extended code, edge cases, and advanced patterns: