skillby The1Studio
theone-unity-standards
Enforces TheOne Studio Unity development standards including C# coding patterns, Unity architecture (VContainer/SignalBus and TheOne.DI/Publisher), and code review guidelines. Triggers when writing, reviewing, or refactoring Unity C# code, implementing features, setting up dependency injection, working with events, or reviewing code changes.
Installs: 0
Used in: 1 repos
Updated: 2d ago
$
npx ai-builder add skill The1Studio/theone-unity-standardsInstalls to .claude/skills/theone-unity-standards/
# TheOne Studio Unity Development Standards
ā ļø **Unity 6 (C# 9):** All patterns and examples are compatible with Unity 6, which uses C# 9. No C# 10+ features are used.
## Skill Purpose
This skill enforces TheOne Studio's comprehensive Unity development standards with **CODE QUALITY FIRST**:
**Priority 1: Code Quality & Hygiene** (MOST IMPORTANT)
- Nullable reference types, access modifiers, fix all warnings
- Throw exceptions (never log errors)
- TheOne.Logging.ILogger (runtime, no guards, no prefixes, no constructor logs) vs Debug.Log (editor only)
- readonly/const, nameof, using directive scope
- No inline comments (use descriptive names)
**Priority 2: Modern C# Patterns**
- LINQ over loops, extension methods, expression bodies
- Null-coalescing operators, pattern matching
- Modern C# features (records, init, with)
**Priority 3: Unity Architecture**
- VContainer + SignalBus OR TheOne.DI + Publisher/Subscriber
- Data Controllers pattern (NEVER direct data access)
- Resource management, UniTask async patterns
**Priority 4: Performance & Review**
- LINQ optimization, allocation prevention
- Code review guidelines
## When This Skill Triggers
- Writing or refactoring Unity C# code
- Implementing Unity features with dependency injection
- Working with events and signals
- Accessing or modifying game data
- Reviewing code changes or pull requests
- Setting up project architecture
## Quick Reference Guide
### What Do You Need Help With?
| Priority | Task | Reference |
|----------|------|-----------|
| **š“ PRIORITY 1: Code Quality (Check FIRST)** | | |
| 1 | Nullable types, access modifiers, warnings, exceptions | [Quality & Hygiene](references/csharp/quality-hygiene.md) ā |
| 1 | TheOne.Logging.ILogger (no guards, no prefixes, no constructor logs) vs Debug.Log | [Quality & Hygiene](references/csharp/quality-hygiene.md) ā |
| 1 | readonly/const, nameof, using scope, no inline comments | [Quality & Hygiene](references/csharp/quality-hygiene.md) ā |
| **š” PRIORITY 2: Modern C# Patterns** | | |
| 2 | LINQ, extension methods, var usage | [LINQ Patterns](references/csharp/linq-patterns.md) |
| 2 | Expression bodies, null-coalescing, pattern matching | [Modern C# Features](references/csharp/modern-csharp-features.md) |
| 2 | Records, init, with expressions | [Modern C# Features](references/csharp/modern-csharp-features.md) |
| **š¢ PRIORITY 3: Unity Architecture** | |
| 3 | VContainer dependency injection | [VContainer DI](references/unity/vcontainer-di.md) |
| 3 | SignalBus event system | [SignalBus Events](references/unity/signalbus-events.md) |
| 3 | Data Controllers pattern (NEVER direct data access) | [Data Controllers](references/unity/data-controllers.md) |
| 3 | Service/Bridge/Adapter integration | [Integration Patterns](references/unity/integration-patterns.md) |
| 3 | TheOne.DI + Publisher/Subscriber alternative | [TheOne Framework](references/unity/theone-framework.md) |
| 3 | UniTask async/await patterns | [UniTask Patterns](references/unity/unitask-patterns.md) |
| **šµ PRIORITY 4: Performance & Review** | | |
| 4 | Performance, LINQ optimization, allocations | [Performance](references/csharp/performance-optimizations.md) |
| 4 | Architecture review (DI, events, controllers) | [Architecture Review](references/review/architecture-review.md) |
| 4 | C# quality review (LINQ, null handling) | [C# Quality](references/review/csharp-quality.md) |
| 4 | Unity-specific review (components, lifecycle) | [Unity Specifics](references/review/unity-specifics.md) |
| 4 | Performance review (allocations, hot paths) | [Performance Review](references/review/performance-review.md) |
## š“ CRITICAL: Code Quality Rules (CHECK FIRST!)
### ā ļø MANDATORY QUALITY STANDARDS
**ALWAYS enforce these BEFORE writing any code:**
1. **Enable nullable reference types** - No nullable warnings allowed
2. **Use least accessible access modifier** - private by default
3. **Fix ALL warnings** - Zero tolerance for compiler warnings
4. **Throw exceptions for errors** - NEVER log errors, throw exceptions
5. **TheOne.Logging.ILogger for runtime** - No conditional guards (#if), no prefixes ([prefix]), NEVER in constructors; Debug.Log ONLY for editor scripts
6. **Use readonly for fields** - Mark fields that aren't reassigned
7. **Use const for constants** - Constants should be const, not readonly
8. **Use nameof for strings** - Never hardcode property/parameter names
9. **Using directive in deepest scope** - Method-level using when possible
10. **No inline comments** - Use descriptive names; code should be self-explanatory
**Example: Enforce Quality First**
```csharp
// ā
EXCELLENT: All quality rules enforced
#nullable enable // 1. Nullable enabled
public sealed class PlayerService
{
private readonly TheOne.Logging.ILogger logger;
private const int MaxHealth = 100;
public PlayerService(TheOne.Logging.ILogger logger)
{
this.logger = logger;
}
public Player GetPlayer(string id)
{
using System.Text.Json;
return players.TryGetValue(id, out var player)
? player
: throw new KeyNotFoundException($"Player not found: {id}");
}
private void LoadGameData()
{
this.logger.Info("Game data loaded");
}
}
#if UNITY_EDITOR
public class EditorTool
{
public void Process()
{
Debug.Log("Processing..."); // 5. Debug.Log OK in editor
}
}
#endif
```
## ā ļø Unity Architecture Rules (AFTER Quality)
### Choose ONE Framework Stack
**Choose ONE stack per project:**
**Option 1: VContainer + SignalBus**
- ā
VContainer for dependency injection
- ā
SignalBus for events
- ā
[Preserve] attribute on constructors
**Option 2: TheOne.DI + Publisher/Subscriber**
- ā
TheOne.DI wrapper
- ā
IPublisher<T>/ISubscriber<T> for events
- ā
[Inject] attribute on constructors
**Universal Rules (Both Stacks):**
- ā
Use Data Controllers (NEVER direct data access)
- ā
Use UniTask for async operations
- ā
Unload assets in Dispose
- ā
TheOne.Logging.ILogger for runtime (no guards, no prefixes, no constructor logs), Debug.Log for editor only
## Brief Examples
### š“ Code Quality First
```csharp
// ā
EXCELLENT: Quality rules enforced
#nullable enable
public sealed class PlayerController
{
private readonly TheOne.Logging.ILogger logger;
private const int MaxRetries = 3;
public PlayerController(TheOne.Logging.ILogger logger)
{
this.logger = logger;
}
public Player LoadPlayer(string id)
{
if (!File.Exists(id))
throw new FileNotFoundException($"Player file not found: {id}");
this.logger.Info($"Loading player {id}");
return DeserializePlayer(id);
}
}
#if UNITY_EDITOR
public class EditorHelper
{
public void Log() => Debug.Log("Editor only"); // Debug.Log OK in editor
}
#endif
```
### š” Modern C# Patterns
```csharp
// ā
GOOD: LINQ instead of loops
var activeEnemies = allEnemies.Where(e => e.IsActive).ToList();
// ā
GOOD: Expression bodies
public int Health => this.currentHealth;
// ā
GOOD: Null-coalescing
var name = playerName ?? "Unknown";
// ā
GOOD: Pattern matching
if (obj is Player player) player.TakeDamage(10);
```
### Unity Architecture (VContainer)
```csharp
using UnityEngine.Scripting;
using VContainer.Unity;
public sealed class GameService : IInitializable, IDisposable
{
private readonly SignalBus signalBus;
private readonly LevelDataController levelController;
[Preserve]
public GameService(SignalBus signalBus, LevelDataController levelController)
{
this.signalBus = signalBus;
this.levelController = levelController;
}
void IInitializable.Initialize()
{
this.signalBus.Subscribe<WonSignal>(this.OnWon);
}
void IDisposable.Dispose()
{
this.signalBus.TryUnsubscribe<WonSignal>(this.OnWon);
}
}
```
### Unity Architecture (TheOne.DI)
```csharp
public sealed class GameService : IAsyncEarlyLoadable, IDisposable
{
private readonly IPublisher<WonSignal> publisher;
private IDisposable? subscription;
[Inject]
public GameService(
IPublisher<WonSignal> publisher,
ISubscriber<WonSignal> subscriber)
{
this.publisher = publisher;
this.subscription = subscriber.Subscribe(this.OnWon);
}
public void Dispose()
{
this.subscription?.Dispose();
}
}
```
## Code Review Checklist
### Quick Validation (before committing)
**š“ Code Quality (CHECK FIRST):**
- [ ] Nullable reference types enabled (#nullable enable)
- [ ] All access modifiers correct (private by default)
- [ ] Zero compiler warnings
- [ ] Exceptions thrown for errors (no error logging)
- [ ] TheOne.Logging (runtime) vs Debug.Log (editor only)
- [ ] readonly used for non-reassigned fields
- [ ] const used for constants
- [ ] nameof used instead of string literals
- [ ] Using directives in deepest scope
- [ ] No inline comments (self-explanatory code)
**š” Modern C# Patterns:**
- [ ] LINQ used instead of manual loops
- [ ] Expression bodies for simple members
- [ ] Null-coalescing operators used
- [ ] Pattern matching for type checks
- [ ] Modern C# features used where appropriate
**š¢ Unity Architecture:**
- [ ] VContainer/TheOne.DI used correctly
- [ ] SignalBus/Publisher-Subscriber used correctly
- [ ] Data accessed through Controllers only
- [ ] All signals unsubscribed in Dispose
- [ ] [Preserve] or [Inject] attribute on constructors
**š¢ Unity Specifics:**
- [ ] Assets loaded are unloaded in Dispose
- [ ] No Find/GetComponent in Update/runtime loops
- [ ] TryGetComponent used instead of GetComponent + null check
- [ ] Lifecycle methods in correct order
**šµ Performance:**
- [ ] No allocations in Update/FixedUpdate
- [ ] LINQ avoided in hot paths
- [ ] .ToArray() used instead of .ToList() when not modified
## Common Mistakes to Avoid
### ā DON'T:
1. **Ignore nullable warnings** ā Enable #nullable and fix all warnings
2. **Log errors instead of throwing** ā Throw exceptions for errors
3. **Use Debug.Log in runtime code** ā Use TheOne.Logging.ILogger (Debug.Log is editor only)
4. **Add conditional guards to logs** ā ILogger handles #if internally
5. **Add manual log prefixes** ā ILogger handles [prefix] automatically
6. **Log in constructors** ā Never log in constructors (keep fast/side-effect free)
7. **Use logger?.Method()** ā Use logger.Method() (DI guarantees non-null)
8. **Add verbose logs** ā Keep only necessary logs
9. **Skip access modifiers** ā Always use least accessible (private default)
10. **Hardcode strings** ā Use nameof() for property/parameter names
11. **Leave fields mutable** ā Use readonly/const where possible
12. **Use Zenject** ā Use VContainer
13. **Use MessagePipe directly** ā Use SignalBus
14. **Access data models directly** ā Use Controllers
15. **Forget to unsubscribe from signals** ā Implement IDisposable
16. **Add inline comments** ā Use descriptive names instead
### ā
DO:
1. **Enable nullable reference types** (#nullable enable)
2. **Throw exceptions for errors** (never log errors)
3. **Use TheOne.Logging.ILogger for runtime** (no guards, no prefixes, no constructor logs)
4. **Use logger.Method() directly** (no null-conditional, DI guarantees non-null)
5. **Debug.Log for editor only** (#if UNITY_EDITOR)
6. **Use least accessible modifiers** (private by default)
7. **Use descriptive names** (no inline comments)
8. **Use nameof()** for string literals
9. **Use readonly/const** for immutable fields
10. **Use VContainer or TheOne.DI** for dependency injection
11. **Use SignalBus or Publisher/Subscriber** for all events
12. **Use Controllers** for all data access
13. **Always implement IDisposable** and unsubscribe
14. **Add [Preserve] or [Inject]** to prevent code stripping
15. **Use LINQ** for collection operations
## Review Severity Levels
### š“ Critical (Must Fix)
- **Nullable warnings not fixed** - Enable #nullable and fix all warnings
- **Logging errors instead of throwing** - Use throw, not log for errors
- **Debug.Log in runtime code** - Must use TheOne.Logging.ILogger (Debug.Log = editor only)
- **Conditional guards on logs** - ILogger handles #if internally, remove guards
- **Manual log prefixes** - ILogger handles [prefix] automatically, remove prefixes
- **Logging in constructors** - Never log in constructors (keep fast/side-effect free)
- **Null-conditional on logger** - Use logger.Method() not logger?.Method()
- **Missing access modifiers** - All members must have explicit modifiers
- **Compiler warnings ignored** - Zero tolerance for warnings
- **Inline comments** - Use descriptive names instead
- Using Zenject instead of VContainer
- Using MessagePipe instead of SignalBus
- Direct data access (not using Controllers)
- Memory leaks (not unsubscribing)
- Missing IDisposable implementation
### š” Important (Should Fix)
- **Missing readonly/const** - Fields should be readonly/const when possible
- **Hardcoded strings** - Use nameof() for property/parameter names
- **Using directives not in deepest scope** - Method-level using when possible
- **Verbose unnecessary logs** - Keep only necessary logs
- Verbose code instead of LINQ
- Missing [Preserve] or [Inject] attribute
- Performance issues in hot paths
- Missing unit tests for business logic
- No XML documentation on public APIs
### š¢ Nice to Have (Suggestion)
- Could use expression body
- Could use null-conditional
- Could use pattern matching
- Could improve naming
- Could simplify with modern C# features
## Detailed References
### C# Coding Standards
- [LINQ Patterns](references/csharp/linq-patterns.md) - LINQ, extension methods, var usage
- [Modern C# Features](references/csharp/modern-csharp-features.md) - Expression bodies, null-coalescing, pattern matching, records
- [Quality & Hygiene](references/csharp/quality-hygiene.md) - Nullable types, access modifiers, logging, exceptions
- [Performance Optimizations](references/csharp/performance-optimizations.md) - Unity patterns, LINQ performance
### Unity Architecture
- [VContainer DI](references/unity/vcontainer-di.md) - Complete VContainer dependency injection guide
- [SignalBus Events](references/unity/signalbus-events.md) - SignalBus event system patterns
- [Data Controllers](references/unity/data-controllers.md) - Data Controller implementation
- [Integration Patterns](references/unity/integration-patterns.md) - Service/Bridge/Adapter for third-party SDKs
- [TheOne Framework](references/unity/theone-framework.md) - TheOne.DI + Publisher/Subscriber alternative
- [UniTask Patterns](references/unity/unitask-patterns.md) - Async/await with UniTask
### Code Review
- [Architecture Review](references/review/architecture-review.md) - VContainer, SignalBus, Controllers violations
- [C# Quality Review](references/review/csharp-quality.md) - LINQ, expression bodies, null handling
- [Unity Specifics Review](references/review/unity-specifics.md) - Component access, lifecycle, cleanup
- [Performance Review](references/review/performance-review.md) - Allocations, LINQ in hot paths
## Summary
This skill provides comprehensive Unity development standards for TheOne Studio:
- **C# Excellence**: Modern, concise, professional C# code
- **Unity Architecture**: VContainer+SignalBus OR TheOne.DI+Publisher patterns
- **Code Quality**: Enforced quality, hygiene, and performance rules
- **Code Review**: Complete checklist for pull request reviews
Use the Quick Reference Guide above to navigate to the specific pattern you need.Quick Install
$
npx ai-builder add skill The1Studio/theone-unity-standardsDetails
- Type
- skill
- Author
- The1Studio
- Slug
- The1Studio/theone-unity-standards
- Created
- 5d ago