61 lines
2.3 KiB
Markdown
61 lines
2.3 KiB
Markdown
# ADR-001: Three-Layer Architecture & Code Isolation
|
||
|
||
**Status**: Accepted
|
||
**Date**: 2026-04-27
|
||
**Engine**: Unity 2022.3.62f3c1
|
||
**GDD Requirements Addressed**: All L0/L1/L2 system boundaries from systems-index.md
|
||
|
||
---
|
||
|
||
## Context
|
||
|
||
夜裔的架构要求在 L0(纯 C# 核心逻辑)、L1(Unity 适配层)、L2(Unity 表现层)之间建立严格的代码隔离。L0 必须零 UnityEngine 依赖以支持独立测试和未来复用。外部开发者需要清晰的物理边界来理解什么代码属于哪一层。
|
||
|
||
## Decision
|
||
|
||
### Directory Structure
|
||
|
||
```
|
||
Assets/Scripts/
|
||
Core/ # L0 — Zero UnityEngine dependency
|
||
Core.asmdef
|
||
Combat/ # BloodEnergyEconomy, CombatLogic, FormSwitchSM, AttackStyle
|
||
Enemy/ # EnemyAILogic, BossAILogic, WaveManagerLogic
|
||
Player/ # DeathRespawnRules
|
||
Progression/ # SkillTreeRules
|
||
Persistence/ # SaveLoadLogic
|
||
Meta/ # ScoreCalculator
|
||
Geometry/ # Vector3, Shape, MathUtil (pure C#)
|
||
Adapters/ # L1 — Thin MonoBehaviour wrappers
|
||
Adapters.asmdef
|
||
InputAdapter.cs, CameraController.cs, LevelLoader.cs,
|
||
AudioPlayer.cs, VFXSpawner.cs
|
||
Presentation/ # L2 — UI Rendering
|
||
Presentation.asmdef
|
||
HUDManager.cs, HUDState.cs, MenuSystem.cs
|
||
```
|
||
|
||
### asmdef Reference Chain
|
||
|
||
| Assembly | References | Prohibited |
|
||
|----------|-----------|------------|
|
||
| Core | (none) | All UnityEngine packages |
|
||
| Adapters | Core | Presentation |
|
||
| Presentation | Core, Adapters | — |
|
||
| Core.Tests | Core | Unity (NUnit standalone) |
|
||
| Adapter.Tests | Core, Adapters | — |
|
||
|
||
### Enforcement Rules
|
||
|
||
1. `using UnityEngine;` in any L0 file → violation
|
||
2. `MonoBehaviour` inheritance in L0 → violation
|
||
3. L1 classes may NOT contain game rule logic — forwarding and subscription only
|
||
4. asmdef reference chain is strictly one-way: Core ← Adapters ← Presentation
|
||
|
||
## Consequences
|
||
|
||
- L0 compiles and tests via `dotnet test` + NUnit without Unity, enabling fast feedback
|
||
- External developers cannot accidentally put game logic in MonoBehaviour — asmdef enforces it
|
||
- If the project migrates engines or adds server-side, L0 is directly reusable
|
||
- Tradeoff: small systems (e.g., ScoreCalculator) pay the adapter abstraction cost
|