# Contributing Guide Thanks for helping build **AR Room Scanner & Furnishing (iOS‑first, Unity 6.0 LTS)**. This doc explains how to set up your environment, propose changes, and keep the project healthy and fast. ## Table of Contents - [Project Setup](#project-setup) - [Branching Model](#branching-model) - [Commit Messages](#commit-messages) - [Pull Request Checklist](#pull-request-checklist) - [Coding Standards (C#)](#coding-standards-c) - [Unity Guidelines](#unity-guidelines) - [Scenes & Prefabs Rules](#scenes--prefabs-rules) - [Feature Flags](#feature-flags) - [API Config & Secrets](#api-config--secrets) - [Testing](#testing) - [Performance Budget](#performance-budget) - [Git LFS & Large Files](#git-lfs--large-files) - [Releases](#releases) - [Code Review](#code-review) - [Smart Merge](#smart-merge) --- ## Project Setup - **Unity**: 6.0 LTS (URP template). - **Platform**: iOS (Metal only). Switch platform before importing heavy assets. - **Packages**: AR Foundation 6.x, ARKit XR Plugin 6.x, (optional) XR Interaction Toolkit 3.x. - **Folder layout** is under `Assets/_Project/...` with `.asmdef` per root module. - Keep `Settings/` (URP and project assets) and `Packages/` committed. - Enable **Visible Meta Files** and **Force Text Serialization**. ## Branching Model - `main`: protected; always releasable. - Use short‑lived branches: `feature/`, `fix/`, `chore/`. - Rebase or squash merge to keep history clean. - Tag releases with SemVer (e.g., `v0.1.0`). ## Commit Messages We use **Conventional Commits**: ``` feat: add room mesh exporter (OBJ) fix: avoid collider spike when updating sharedMesh docs: update iOS build steps refactor: split placement into service + controller perf: decimate combined mesh when >3M tris test: add domain unit tests build: bump ARKit XR Plugin to 6.2.x ci: cache Library on CI revert: revert placement snapping change ``` Scope is optional (e.g., `feat(placement): ...`). ## Pull Request Checklist - [ ] Builds in Unity Editor and exports to **Xcode**. - [ ] Tested on **real iOS device** (LiDAR when feature needs it). - [ ] Scene follows **hierarchy rules** (see below). - [ ] **No per‑frame allocations** in hot paths; profiled once on device. - [ ] `.asmdef` references minimal and correct; no upward dependencies. - [ ] Updated **README/CHANGELOG** if user‑facing behavior changed. - [ ] Added/updated **tests** (Domain: unit; ARRuntime/App: playmode/manual checklist). - [ ] **No secrets** or hardcoded URLs; use `ApiConfig` ScriptableObject. - [ ] Large binaries are tracked by **LFS**; unnecessary assets removed. ## Coding Standards (C#) - Namespaces by module: `App.*`, `ARRuntime.*`, `Domain.*`, `Infra.*`. - Prefer `readonly` fields, `record` for immutable DTOs, `TryGetComponent` over `FindObjectOfType`. - Avoid `new` allocations in `Update`; reuse buffers/lists (`.Clear()`). - Use `async/await` for API; timeouts & cancellation tokens where sensible. - No logic in `MonoBehaviour` constructors; use `Awake/OnEnable/Start`. - Guard nulls; avoid exceptions for control flow. ## Unity Guidelines - One **Main Camera** under **XR Origin**. - `ARMeshManager` **must be a child of XR Origin**. - Keep **AR managers** grouped under a child GO (e.g., `AR Managers`). - Update **MeshCollider.sharedMesh** only when the combined mesh changes. - Place assets under `Assets/_Project/Art/...`; avoid dumping in root. - Use **prefabs** for placeable furniture; include colliders at authoring time. ## Scenes & Prefabs Rules - Scene names live in `Assets/_Project/App/Scenes/`. - Do not reference Sample assets. Delete `SampleScene` once the project boots. - Minimal global singletons. Prefer scene‑local controllers in `App/Controllers`. - Prefabs: no missing scripts; default layer unless a dedicated layer is needed. ## Feature Flags - Compile‑time defines: - `LIGHTSHIP_ENABLED` → compiles `Detectors.Lightship/` only when set. - `ROOMPLAN_ENABLED` → future native bridge for RoomPlan. - Runtime toggles: ScriptableObject `ProjectFeatures` (in `Infra/Settings/`). ## API Config & Secrets - `Infra/Settings/ApiConfig` contains the base URL and timeouts per env. - **Do not commit secrets** or production keys. - For iOS, additional entitlements (e.g., iCloud) should be added in Xcode per‑target, not committed if secret‑bearing. ## Testing - **Domain**: unit tests (EditMode). - **ARRuntime/App**: PlayMode tests + manual device checklist. - Provide a short test plan for PRs affecting scanning/placement. ## Performance Budget - IL2CPP, ARM64, **Metal only**. - URP: SRP Batcher ON, MSAA 2x, mobile shadows. - Mesh combine every **1–2 s**; consider decimation > 3M tris. - Avoid large textures where not needed; prefer 2K for preview. ## Git LFS & Large Files - Track large assets: `*.glb, *.gltf, *.obj, *.fbx, *.psd, *.exr, *.hdr, *.tga, *.tif`. - Keep big room exports outside `Assets/` in a top‑level `Scans/` folder (LFS‑tracked) to reduce Unity import cost. - Use **LFS locking** for shared binary assets when editing (`git lfs lock` / `unlock`). ## Releases - Bump version using **SemVer** and update **CHANGELOG.md** (Keep a Changelog format). - Tag the commit (`vX.Y.Z`) and create a GitHub Release with notes and device compatibility. - Attach build artifacts as needed; Xcode projects are generated from Unity. ## Code Review - At least **1 approval** (or 2 for risky changes). - Reviewers check: compile/run on device, profiler snapshot, GC allocs, scene hierarchy, asmdef deps, docs updated. ## Smart Merge Enable Unity SmartMerge globally: ``` git config --global merge.unityyamlmerge.name "Unity SmartMerge (YAML)" git config --global merge.unityyamlmerge.driver "/Tools/UnityYAMLMerge merge -p %O %A %B %P" ``` Ensure **Visible Meta Files** and **Force Text** are set in Unity.