Project Conventions
Project-specific rules that go beyond standard C# / Unity conventions. No external dependencies -- pure Unity built-in APIs only.
For the module architecture, see Module Pattern. For event-driven details, see Unity Patterns. For what NOT to do, see Anti-Patterns.
Fully Qualify Debug and Input
Avoid namespace collisions with System.Diagnostics.Debug and custom Input classes.
// GOOD
UnityEngine.Debug.Log("message");
UnityEngine.Input.GetAxis("Horizontal");
// BAD — ambiguous when System.Diagnostics is imported
Debug.Log("message");
No Custom Editor Scripts
Keep Inspector logic in the data itself using Unity's built-in attributes. Never create custom Editor, PropertyDrawer, or EditorWindow classes for data display.
| Do | Don't |
|---|---|
[Header], [Tooltip], [Space] |
CustomEditor class |
[Range], [Min], [TextArea] |
PropertyDrawer |
[HideInInspector], [SerializeField] |
EditorGUILayout code |
[ContextMenu] for debug actions |
EditorWindow for simple tools |
Service Locator over Scene Searches
Never use FindObjectOfType, FindObjectsByType, GameObject.Find, or FindWithTag.
ServiceLocator.Register<IWeaponService>(this);
var weapons = ServiceLocator.Get<IWeaponService>();
if (ServiceLocator.TryGet<IWeaponService>(out var svc))
{
svc.Fire();
}
SOLID Principles
| Principle | Rule | Violation |
|---|---|---|
| S -- Single Responsibility | One reason to change per class | God class doing input + physics + UI |
| O -- Open/Closed | Extend via interfaces, not if/switch |
Adding a new type requires editing existing code |
| L -- Liskov Substitution | Subtypes must be substitutable | Overriding methods that throw NotSupportedException |
| I -- Interface Segregation | Small, focused interfaces | IEntity with 20 methods |
| D -- Dependency Inversion | Depend on abstractions | new ConcreteService() inside a MonoBehaviour |
Event-Driven Communication
| Need | Use |
|---|---|
| Code-to-code notifications | C# event Action<T> |
| Inspector-wirable callbacks | UnityEvent |
| Cross-system decoupled events | ScriptableObject event channels |
| Service access | Service locator |
| Never | Polling in Update(), SendMessage, BroadcastMessage |
See Unity Patterns for full event-driven architecture docs.
No External Dependencies
This project uses only Unity built-in APIs. No third-party packages.
| Banned | Why |
|---|---|
| Third-party Inspector plugins | Use Unity's built-in attributes |
| External DI frameworks | Use the service locator pattern |
| Third-party serialization | Use Unity's [Serializable] + JsonUtility |
| External async libraries | Use Unity's Awaitable or coroutines |