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 ⭐ |
| 1 |
TheOne.Logging.ILogger (no guards, no prefixes, no constructor logs) vs Debug.Log |
Quality & Hygiene ⭐ |
| 1 |
readonly/const, nameof, using scope, no inline comments |
Quality & Hygiene ⭐ |
| 🟡 PRIORITY 2: Modern C# Patterns |
|
|
| 2 |
LINQ, extension methods, var usage |
LINQ Patterns |
| 2 |
Expression bodies, null-coalescing, pattern matching |
Modern C# Features |
| 2 |
Records, init, with expressions |
Modern C# Features |
| 🟢 PRIORITY 3: Unity Architecture |
|
|
| 3 |
VContainer dependency injection |
VContainer DI |
| 3 |
SignalBus event system |
SignalBus Events |
| 3 |
Data Controllers pattern (NEVER direct data access) |
Data Controllers |
| 3 |
Service/Bridge/Adapter integration |
Integration Patterns |
| 3 |
TheOne.DI + Publisher/Subscriber alternative |
TheOne Framework |
| 3 |
UniTask async/await patterns |
UniTask Patterns |
| 🔵 PRIORITY 4: Performance & Review |
|
|
| 4 |
Performance, LINQ optimization, allocations |
Performance |
| 4 |
Architecture review (DI, events, controllers) |
Architecture Review |
| 4 |
C# quality review (LINQ, null handling) |
C# Quality |
| 4 |
Unity-specific review (components, lifecycle) |
Unity Specifics |
| 4 |
Performance review (allocations, hot paths) |
Performance Review |
🔴 CRITICAL: Code Quality Rules (CHECK FIRST!)
⚠️ MANDATORY QUALITY STANDARDS
ALWAYS enforce these BEFORE writing any code:
- Enable nullable reference types - No nullable warnings allowed
- Use least accessible access modifier - private by default
- Fix ALL warnings - Zero tolerance for compiler warnings
- Throw exceptions for errors - NEVER log errors, throw exceptions
- TheOne.Logging.ILogger for runtime - No conditional guards (#if), no prefixes ([prefix]), NEVER in constructors; Debug.Log ONLY for editor scripts
- Use readonly for fields - Mark fields that aren't reassigned
- Use const for constants - Constants should be const, not readonly
- Use nameof for strings - Never hardcode property/parameter names
- Using directive in deepest scope - Method-level using when possible
- No inline comments - Use descriptive names; code should be self-explanatory
Example: Enforce Quality First
// ✅ 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/ISubscriber 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
// ✅ 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
// ✅ 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)
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)
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):
🟡 Modern C# Patterns:
🟢 Unity Architecture:
🟢 Unity Specifics:
🔵 Performance:
Common Mistakes to Avoid
❌ DON'T:
- Ignore nullable warnings → Enable #nullable and fix all warnings
- Log errors instead of throwing → Throw exceptions for errors
- Use Debug.Log in runtime code → Use TheOne.Logging.ILogger (Debug.Log is editor only)
- Add conditional guards to logs → ILogger handles #if internally
- Add manual log prefixes → ILogger handles [prefix] automatically
- Log in constructors → Never log in constructors (keep fast/side-effect free)
- Use logger?.Method() → Use logger.Method() (DI guarantees non-null)
- Add verbose logs → Keep only necessary logs
- Skip access modifiers → Always use least accessible (private default)
- Hardcode strings → Use nameof() for property/parameter names
- Leave fields mutable → Use readonly/const where possible
- Use Zenject → Use VContainer
- Use MessagePipe directly → Use SignalBus
- Access data models directly → Use Controllers
- Forget to unsubscribe from signals → Implement IDisposable
- Add inline comments → Use descriptive names instead
✅ DO:
- Enable nullable reference types (#nullable enable)
- Throw exceptions for errors (never log errors)
- Use TheOne.Logging.ILogger for runtime (no guards, no prefixes, no constructor logs)
- Use logger.Method() directly (no null-conditional, DI guarantees non-null)
- Debug.Log for editor only (#if UNITY_EDITOR)
- Use least accessible modifiers (private by default)
- Use descriptive names (no inline comments)
- Use nameof() for string literals
- Use readonly/const for immutable fields
- Use VContainer or TheOne.DI for dependency injection
- Use SignalBus or Publisher/Subscriber for all events
- Use Controllers for all data access
- Always implement IDisposable and unsubscribe
- Add [Preserve] or [Inject] to prevent code stripping
- 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 - LINQ, extension methods, var usage
- Modern C# Features - Expression bodies, null-coalescing, pattern matching, records
- Quality & Hygiene - Nullable types, access modifiers, logging, exceptions
- Performance Optimizations - Unity patterns, LINQ performance
Unity Architecture
- VContainer DI - Complete VContainer dependency injection guide
- SignalBus Events - SignalBus event system patterns
- Data Controllers - Data Controller implementation
- Integration Patterns - Service/Bridge/Adapter for third-party SDKs
- TheOne Framework - TheOne.DI + Publisher/Subscriber alternative
- UniTask Patterns - Async/await with UniTask
Code Review
- Architecture Review - VContainer, SignalBus, Controllers violations
- C# Quality Review - LINQ, expression bodies, null handling
- Unity Specifics Review - Component access, lifecycle, cleanup
- Performance Review - 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.
1---2name: theone-unity-standards3description: 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.4---5
6# TheOne Studio Unity Development Standards
7
8⚠️ **Unity 6 (C# 9):** All patterns and examples are compatible with Unity 6, which uses C# 9. No C# 10+ features are used.
9
10## Skill Purpose
11
12This skill enforces TheOne Studio's comprehensive Unity development standards with **CODE QUALITY FIRST**:
13
14**Priority 1: Code Quality & Hygiene** (MOST IMPORTANT)
15- Nullable reference types, access modifiers, fix all warnings
16- Throw exceptions (never log errors)
17- TheOne.Logging.ILogger (runtime, no guards, no prefixes, no constructor logs) vs Debug.Log (editor only)
18- readonly/const, nameof, using directive scope
19- No inline comments (use descriptive names)
20
21**Priority 2: Modern C# Patterns**
22- LINQ over loops, extension methods, expression bodies
23- Null-coalescing operators, pattern matching
24- Modern C# features (records, init, with)
25
26**Priority 3: Unity Architecture**
27- VContainer + SignalBus OR TheOne.DI + Publisher/Subscriber
28- Data Controllers pattern (NEVER direct data access)
29- Resource management, UniTask async patterns
30
31**Priority 4: Performance & Review**
32- LINQ optimization, allocation prevention
33- Code review guidelines
34
35## When This Skill Triggers
36
37- Writing or refactoring Unity C# code
38- Implementing Unity features with dependency injection
39- Working with events and signals
40- Accessing or modifying game data
41- Reviewing code changes or pull requests
42- Setting up project architecture
43
44## Quick Reference Guide
45
46### What Do You Need Help With?
47
48| Priority | Task | Reference |
49|----------|------|-----------|
50| **🔴 PRIORITY 1: Code Quality (Check FIRST)** | | |
51| 1 | Nullable types, access modifiers, warnings, exceptions | [Quality & Hygiene](references/csharp/quality-hygiene.md) ⭐ |
52| 1 | TheOne.Logging.ILogger (no guards, no prefixes, no constructor logs) vs Debug.Log | [Quality & Hygiene](references/csharp/quality-hygiene.md) ⭐ |
53| 1 | readonly/const, nameof, using scope, no inline comments | [Quality & Hygiene](references/csharp/quality-hygiene.md) ⭐ |
54| **🟡 PRIORITY 2: Modern C# Patterns** | | |
55| 2 | LINQ, extension methods, var usage | [LINQ Patterns](references/csharp/linq-patterns.md) |
56| 2 | Expression bodies, null-coalescing, pattern matching | [Modern C# Features](references/csharp/modern-csharp-features.md) |
57| 2 | Records, init, with expressions | [Modern C# Features](references/csharp/modern-csharp-features.md) |
58| **🟢 PRIORITY 3: Unity Architecture** | |
59| 3 | VContainer dependency injection | [VContainer DI](references/unity/vcontainer-di.md) |
60| 3 | SignalBus event system | [SignalBus Events](references/unity/signalbus-events.md) |
61| 3 | Data Controllers pattern (NEVER direct data access) | [Data Controllers](references/unity/data-controllers.md) |
62| 3 | Service/Bridge/Adapter integration | [Integration Patterns](references/unity/integration-patterns.md) |
63| 3 | TheOne.DI + Publisher/Subscriber alternative | [TheOne Framework](references/unity/theone-framework.md) |
64| 3 | UniTask async/await patterns | [UniTask Patterns](references/unity/unitask-patterns.md) |
65| **🔵 PRIORITY 4: Performance & Review** | | |
66| 4 | Performance, LINQ optimization, allocations | [Performance](references/csharp/performance-optimizations.md) |
67| 4 | Architecture review (DI, events, controllers) | [Architecture Review](references/review/architecture-review.md) |
68| 4 | C# quality review (LINQ, null handling) | [C# Quality](references/review/csharp-quality.md) |
69| 4 | Unity-specific review (components, lifecycle) | [Unity Specifics](references/review/unity-specifics.md) |
70| 4 | Performance review (allocations, hot paths) | [Performance Review](references/review/performance-review.md) |
71
72## 🔴 CRITICAL: Code Quality Rules (CHECK FIRST!)
73
74### ⚠️ MANDATORY QUALITY STANDARDS
75
76**ALWAYS enforce these BEFORE writing any code:**
77
781. **Enable nullable reference types** - No nullable warnings allowed
792. **Use least accessible access modifier** - private by default
803. **Fix ALL warnings** - Zero tolerance for compiler warnings
814. **Throw exceptions for errors** - NEVER log errors, throw exceptions
825. **TheOne.Logging.ILogger for runtime** - No conditional guards (#if), no prefixes ([prefix]), NEVER in constructors; Debug.Log ONLY for editor scripts
836. **Use readonly for fields** - Mark fields that aren't reassigned
847. **Use const for constants** - Constants should be const, not readonly
858. **Use nameof for strings** - Never hardcode property/parameter names
869. **Using directive in deepest scope** - Method-level using when possible
8710. **No inline comments** - Use descriptive names; code should be self-explanatory
88
89**Example: Enforce Quality First**
90
91```csharp
92// ✅ EXCELLENT: All quality rules enforced
93#nullable enable // 1. Nullable enabled
94
95public sealed class PlayerService
96{
97 private readonly TheOne.Logging.ILogger logger;
98 private const int MaxHealth = 100;
99
100 public PlayerService(TheOne.Logging.ILogger logger)
101 {
102 this.logger = logger;
103 }
104
105 public Player GetPlayer(string id)
106 {
107 using System.Text.Json;
108
109 return players.TryGetValue(id, out var player)
110 ? player
111 : throw new KeyNotFoundException($"Player not found: {id}");
112 }
113
114 private void LoadGameData()
115 {
116 this.logger.Info("Game data loaded");
117 }
118}
119
120#if UNITY_EDITOR
121public class EditorTool
122{
123 public void Process()
124 {
125 Debug.Log("Processing..."); // 5. Debug.Log OK in editor
126 }
127}
128#endif
129```
130
131## ⚠️ Unity Architecture Rules (AFTER Quality)
132
133### Choose ONE Framework Stack
134
135**Choose ONE stack per project:**
136
137**Option 1: VContainer + SignalBus**
138- ✅ VContainer for dependency injection
139- ✅ SignalBus for events
140- ✅ [Preserve] attribute on constructors
141
142**Option 2: TheOne.DI + Publisher/Subscriber**
143- ✅ TheOne.DI wrapper
144- ✅ IPublisher<T>/ISubscriber<T> for events
145- ✅ [Inject] attribute on constructors
146
147**Universal Rules (Both Stacks):**
148- ✅ Use Data Controllers (NEVER direct data access)
149- ✅ Use UniTask for async operations
150- ✅ Unload assets in Dispose
151- ✅ TheOne.Logging.ILogger for runtime (no guards, no prefixes, no constructor logs), Debug.Log for editor only
152
153## Brief Examples
154
155### 🔴 Code Quality First
156
157```csharp
158// ✅ EXCELLENT: Quality rules enforced
159#nullable enable
160
161public sealed class PlayerController
162{
163 private readonly TheOne.Logging.ILogger logger;
164 private const int MaxRetries = 3;
165
166 public PlayerController(TheOne.Logging.ILogger logger)
167 {
168 this.logger = logger;
169 }
170
171 public Player LoadPlayer(string id)
172 {
173 if (!File.Exists(id))
174 throw new FileNotFoundException($"Player file not found: {id}");
175
176 this.logger.Info($"Loading player {id}");
177 return DeserializePlayer(id);
178 }
179}
180
181#if UNITY_EDITOR
182public class EditorHelper
183{
184 public void Log() => Debug.Log("Editor only"); // Debug.Log OK in editor
185}
186#endif
187```
188
189### 🟡 Modern C# Patterns
190
191```csharp
192// ✅ GOOD: LINQ instead of loops
193var activeEnemies = allEnemies.Where(e => e.IsActive).ToList();
194
195// ✅ GOOD: Expression bodies
196public int Health => this.currentHealth;
197
198// ✅ GOOD: Null-coalescing
199var name = playerName ?? "Unknown";
200
201// ✅ GOOD: Pattern matching
202if (obj is Player player) player.TakeDamage(10);
203```
204
205### Unity Architecture (VContainer)
206
207```csharp
208using UnityEngine.Scripting;
209using VContainer.Unity;
210
211public sealed class GameService : IInitializable, IDisposable
212{
213 private readonly SignalBus signalBus;
214 private readonly LevelDataController levelController;
215
216 [Preserve]
217 public GameService(SignalBus signalBus, LevelDataController levelController)
218 {
219 this.signalBus = signalBus;
220 this.levelController = levelController;
221 }
222
223 void IInitializable.Initialize()
224 {
225 this.signalBus.Subscribe<WonSignal>(this.OnWon);
226 }
227
228 void IDisposable.Dispose()
229 {
230 this.signalBus.TryUnsubscribe<WonSignal>(this.OnWon);
231 }
232}
233```
234
235### Unity Architecture (TheOne.DI)
236
237```csharp
238public sealed class GameService : IAsyncEarlyLoadable, IDisposable
239{
240 private readonly IPublisher<WonSignal> publisher;
241 private IDisposable? subscription;
242
243 [Inject]
244 public GameService(
245 IPublisher<WonSignal> publisher,
246 ISubscriber<WonSignal> subscriber)
247 {
248 this.publisher = publisher;
249 this.subscription = subscriber.Subscribe(this.OnWon);
250 }
251
252 public void Dispose()
253 {
254 this.subscription?.Dispose();
255 }
256}
257```
258
259## Code Review Checklist
260
261### Quick Validation (before committing)
262
263**🔴 Code Quality (CHECK FIRST):**
264- [ ] Nullable reference types enabled (#nullable enable)
265- [ ] All access modifiers correct (private by default)
266- [ ] Zero compiler warnings
267- [ ] Exceptions thrown for errors (no error logging)
268- [ ] TheOne.Logging (runtime) vs Debug.Log (editor only)
269- [ ] readonly used for non-reassigned fields
270- [ ] const used for constants
271- [ ] nameof used instead of string literals
272- [ ] Using directives in deepest scope
273- [ ] No inline comments (self-explanatory code)
274
275**🟡 Modern C# Patterns:**
276- [ ] LINQ used instead of manual loops
277- [ ] Expression bodies for simple members
278- [ ] Null-coalescing operators used
279- [ ] Pattern matching for type checks
280- [ ] Modern C# features used where appropriate
281
282**🟢 Unity Architecture:**
283- [ ] VContainer/TheOne.DI used correctly
284- [ ] SignalBus/Publisher-Subscriber used correctly
285- [ ] Data accessed through Controllers only
286- [ ] All signals unsubscribed in Dispose
287- [ ] [Preserve] or [Inject] attribute on constructors
288
289**🟢 Unity Specifics:**
290- [ ] Assets loaded are unloaded in Dispose
291- [ ] No Find/GetComponent in Update/runtime loops
292- [ ] TryGetComponent used instead of GetComponent + null check
293- [ ] Lifecycle methods in correct order
294
295**🔵 Performance:**
296- [ ] No allocations in Update/FixedUpdate
297- [ ] LINQ avoided in hot paths
298- [ ] .ToArray() used instead of .ToList() when not modified
299
300## Common Mistakes to Avoid
301
302### ❌ DON'T:
3031. **Ignore nullable warnings** → Enable #nullable and fix all warnings
3042. **Log errors instead of throwing** → Throw exceptions for errors
3053. **Use Debug.Log in runtime code** → Use TheOne.Logging.ILogger (Debug.Log is editor only)
3064. **Add conditional guards to logs** → ILogger handles #if internally
3075. **Add manual log prefixes** → ILogger handles [prefix] automatically
3086. **Log in constructors** → Never log in constructors (keep fast/side-effect free)
3097. **Use logger?.Method()** → Use logger.Method() (DI guarantees non-null)
3108. **Add verbose logs** → Keep only necessary logs
3119. **Skip access modifiers** → Always use least accessible (private default)
31210. **Hardcode strings** → Use nameof() for property/parameter names
31311. **Leave fields mutable** → Use readonly/const where possible
31412. **Use Zenject** → Use VContainer
31513. **Use MessagePipe directly** → Use SignalBus
31614. **Access data models directly** → Use Controllers
31715. **Forget to unsubscribe from signals** → Implement IDisposable
31816. **Add inline comments** → Use descriptive names instead
319
320### ✅ DO:
3211. **Enable nullable reference types** (#nullable enable)
3222. **Throw exceptions for errors** (never log errors)
3233. **Use TheOne.Logging.ILogger for runtime** (no guards, no prefixes, no constructor logs)
3244. **Use logger.Method() directly** (no null-conditional, DI guarantees non-null)
3255. **Debug.Log for editor only** (#if UNITY_EDITOR)
3266. **Use least accessible modifiers** (private by default)
3277. **Use descriptive names** (no inline comments)
3288. **Use nameof()** for string literals
3299. **Use readonly/const** for immutable fields
33010. **Use VContainer or TheOne.DI** for dependency injection
33111. **Use SignalBus or Publisher/Subscriber** for all events
33212. **Use Controllers** for all data access
33313. **Always implement IDisposable** and unsubscribe
33414. **Add [Preserve] or [Inject]** to prevent code stripping
33515. **Use LINQ** for collection operations
336
337## Review Severity Levels
338
339### 🔴 Critical (Must Fix)
340- **Nullable warnings not fixed** - Enable #nullable and fix all warnings
341- **Logging errors instead of throwing** - Use throw, not log for errors
342- **Debug.Log in runtime code** - Must use TheOne.Logging.ILogger (Debug.Log = editor only)
343- **Conditional guards on logs** - ILogger handles #if internally, remove guards
344- **Manual log prefixes** - ILogger handles [prefix] automatically, remove prefixes
345- **Logging in constructors** - Never log in constructors (keep fast/side-effect free)
346- **Null-conditional on logger** - Use logger.Method() not logger?.Method()
347- **Missing access modifiers** - All members must have explicit modifiers
348- **Compiler warnings ignored** - Zero tolerance for warnings
349- **Inline comments** - Use descriptive names instead
350- Using Zenject instead of VContainer
351- Using MessagePipe instead of SignalBus
352- Direct data access (not using Controllers)
353- Memory leaks (not unsubscribing)
354- Missing IDisposable implementation
355
356### 🟡 Important (Should Fix)
357- **Missing readonly/const** - Fields should be readonly/const when possible
358- **Hardcoded strings** - Use nameof() for property/parameter names
359- **Using directives not in deepest scope** - Method-level using when possible
360- **Verbose unnecessary logs** - Keep only necessary logs
361- Verbose code instead of LINQ
362- Missing [Preserve] or [Inject] attribute
363- Performance issues in hot paths
364- Missing unit tests for business logic
365- No XML documentation on public APIs
366
367### 🟢 Nice to Have (Suggestion)
368- Could use expression body
369- Could use null-conditional
370- Could use pattern matching
371- Could improve naming
372- Could simplify with modern C# features
373
374## Detailed References
375
376### C# Coding Standards
377- [LINQ Patterns](references/csharp/linq-patterns.md) - LINQ, extension methods, var usage
378- [Modern C# Features](references/csharp/modern-csharp-features.md) - Expression bodies, null-coalescing, pattern matching, records
379- [Quality & Hygiene](references/csharp/quality-hygiene.md) - Nullable types, access modifiers, logging, exceptions
380- [Performance Optimizations](references/csharp/performance-optimizations.md) - Unity patterns, LINQ performance
381
382### Unity Architecture
383- [VContainer DI](references/unity/vcontainer-di.md) - Complete VContainer dependency injection guide
384- [SignalBus Events](references/unity/signalbus-events.md) - SignalBus event system patterns
385- [Data Controllers](references/unity/data-controllers.md) - Data Controller implementation
386- [Integration Patterns](references/unity/integration-patterns.md) - Service/Bridge/Adapter for third-party SDKs
387- [TheOne Framework](references/unity/theone-framework.md) - TheOne.DI + Publisher/Subscriber alternative
388- [UniTask Patterns](references/unity/unitask-patterns.md) - Async/await with UniTask
389
390### Code Review
391- [Architecture Review](references/review/architecture-review.md) - VContainer, SignalBus, Controllers violations
392- [C# Quality Review](references/review/csharp-quality.md) - LINQ, expression bodies, null handling
393- [Unity Specifics Review](references/review/unity-specifics.md) - Component access, lifecycle, cleanup
394- [Performance Review](references/review/performance-review.md) - Allocations, LINQ in hot paths
395
396## Summary
397
398This skill provides comprehensive Unity development standards for TheOne Studio:
399- **C# Excellence**: Modern, concise, professional C# code
400- **Unity Architecture**: VContainer+SignalBus OR TheOne.DI+Publisher patterns
401- **Code Quality**: Enforced quality, hygiene, and performance rules
402- **Code Review**: Complete checklist for pull request reviews
403
404Use the Quick Reference Guide above to navigate to the specific pattern you need.