Cheat Sheet
Pin this. Glance before every PR. For details, follow the links.
Naming
Classes/Structs/Enums PascalCase PlayerController
Interfaces I + PascalCase IStateMachine
Public methods PascalCase Execute()
Private fields _camelCase _health
Private static fields s_camelCase s_instance
Constants UPPER_SNAKE MAX_AMMO
Local variables camelCase currentState
Parameters camelCase buildContext
Language Rules (Error-Level)
var -> ALWAYS
this. -> NEVER
int vs Int32 -> ALWAYS use keyword
Pattern matching -> ALWAYS over is/as casts
Throw expressions -> ALWAYS over if-then-throw
Bodies
Methods/Constructors -> Block body { return x; }
Properties/Indexers -> Expression => _value;
Formatting
Braces -> New line (Allman)
Indent -> 4 spaces
Line endings -> CRLF
Trailing whitespace -> Trimmed
Final newline -> Required
File Order
1. Using directives (System.* first)
2. Namespace
3. Constants / static readonly
4. Static fields
5. Serialized fields
6. Private fields
7. Properties
8. Events / Delegates
9. Unity lifecycle (Awake -> OnDestroy)
10. Public methods
11. Private methods
12. Nested types
Module Pattern (full docs)
Configuration -> readonly struct (plain C#) / struct (MonoBehaviour)
Reference -> readonly struct (plain C#) / struct (MonoBehaviour)
State -> class, private set properties
Components -> class, private set properties
SetConfiguration -> in keyword (zero-copy pass by ref)
MonoBehaviour access -> ref readonly return for Config/Ref
Inspector fields -> [SerializeField] private
Communication -> event Action / event Action<T>
Update() -> None in template — event-driven by default
Lifecycle (C#) -> Constructor -> Init() -> Dispose()
Lifecycle (MB) -> Awake() -> Init(), OnDestroy() -> Dispose()
Unity Lifecycle Order
Awake -> OnEnable -> Start -> FixedUpdate -> Update -> LateUpdate -> OnDisable -> OnDestroy
Event-Driven Rules (full docs)
State changes -> Fire event, don't poll a bool
Input -> Input System callbacks, not GetKey in Update
UI updates -> Bind to data change events
Component comms -> C# events / delegates / event channels
Waiting -> Coroutine WaitUntil or async, not frame-check
Banned (anti-patterns)
FindObjectOfType -> Service locator
SendMessage -> Direct call / event
Empty Update() -> Delete it
new in Update() -> Pre-allocate
GetComponent in loop -> Cache in Awake
God classes -> Single responsibility
Switch on type -> Polymorphism
Role booleans -> Separate types
Polling in Update -> Events
this. -> Never
Project-Specific (conventions)
External deps -> None. Pure Unity built-in only
Editor scripts -> Never (use built-in attributes)
Debug / Input -> Fully qualify (UnityEngine.Debug)
Architecture -> SOLID, no exceptions
Communication -> Event-driven, never polling
Scene searches -> Never. Use service locator
Performance
Hot path strings -> StringBuilder or cached
Temp buffers -> stackalloc / ArrayPool / pre-allocated
Large struct params -> Pass with 'in' keyword
Immutable structs -> Mark 'readonly struct'
Measure first -> Unity Profiler before optimizing