Skip to main content
Consistent conventions mean any team member can open any file and understand it immediately — without hunting for what m_val means or why this class has a public field named score. These rules apply to every C# file in the project across all layers: Domain, Application, Infrastructure, Presentation, Editor, and Tests. They are enforced by .editorconfig, Roslyn analyzers, and CI. Deviation requires explicit tech-lead approval.
These are not style suggestions — they are production requirements. CI treats analyzer violations as build errors. A PR that introduces a naming violation, a #region, or a public field on an entity will not merge.
The diagram below shows which convention categories apply to which architectural layers. Conventions marked in all layers are universal; those marked only in Presentation apply exclusively to Unity MonoBehaviour code.

Naming Conventions

The table below is the single authoritative reference. When in doubt, check here before naming anything.

Additional Naming Rules

  • No Hungarian notation. Do not prefix member names with type hints (m_, strName, bIsActive).
  • var usage: Use var when the declared type is obvious from the right-hand side (var validator = new SetValidator()). Use an explicit type when it adds clarity (ISetValidator validator = ...).
  • Well-known abbreviations only. AI, MMR, UI, HUD, ID are fine. Invent no new abbreviations.
  • Descriptive, not clever. CalculateScore() rather than Calc(). Names should communicate intent without requiring a comment.

Formatting Rules

All formatting is enforced by the project .editorconfig. The key settings are reproduced here for reference.
Manual rules that .editorconfig cannot fully enforce:
  • Brace style — Allman. Opening brace always on its own line. No Egyptian/K&R braces.
  • Blank lines. One blank line between methods. One blank line between logical groups inside a method. Never two consecutive blank lines.
  • Line length. Soft limit: 140 characters. Hard limit: 180 characters. Split long chains, parameter lists, or LINQ queries at logical points.
  • using statements. Organised inside the namespace declaration: System.* first, then external packages (R3, Nakama, VContainer), then project namespaces (SET.*). Remove all unused using statements — the IDE will flag them.

The #region Ban

#region directives are banned everywhere in this codebase. If you feel the urge to add a region, that is a signal the class is too large. Extract a new class instead.

Class and Interface Design


Method Rules

Writing small, focused methods is the single most effective thing you can do to keep the codebase navigable.

Error Handling


Unity-Specific Rules

These rules apply to the Presentation layer — any code that references UnityEngine.
If you find yourself writing using UnityEngine; in a file inside SET.Domain or SET.Application, stop. You are about to break the most important architectural boundary in the project.
MonoBehaviours are thin views. A MonoBehaviour in this project:
  • Binds UI elements (Text, Button, Image) to ViewModel observable properties
  • Routes touch/pointer events to an injected input handler
  • Manages the lifetime of its CompositeDisposable in OnDestroy()
  • Contains no game logic, state machines, scoring, or AI code
Inspector references. Use [SerializeField] private for all Unity-object references wired in the Inspector. Never use a public field to link components. Forbidden Unity APIs in non-Presentation code: ScriptableObjects. Acceptable for static configuration (AI difficulty config, audio mixer references). Treat them as read-only at runtime — never write to a ScriptableObject field after initialisation.

Reactive Programming (R3)


Common Mistakes That Fail Review

The following mistakes appear frequently enough to call out explicitly. All of them will block a PR:
  1. Public field on an entity. public int Score; on Player — replace with a property and an AddScore(int delta) method.
  2. More than 3 parameters without a parameter object. Introduce a MatchConfig record rather than passing 5 arguments.
  3. #region anywhere. Remove it and split the class if it feels cluttered.
  4. catch (Exception) inside Domain or Application code. Catch specific exceptions at the Infrastructure boundary only.
  5. Forgetting to dispose a CompositeDisposable. Memory leaks and test pollution will follow.
  6. Polling in Update(). Use R3 reactive streams. Update() in a View MonoBehaviour is for visual interpolation only.

Approved Patterns & Anti-Patterns

Which design patterns are adopted and which are explicitly banned with required replacements.

Testing Standards

Unit test naming, AAA structure, coverage targets, and CI integration.

PR Checklist

The complete merge-gate checklist that enforces these conventions at review time.

Roadmap Overview

High-level project timeline and phase dependencies.