Files
Colosseum/AGENTS.md
dal4segno 2d77bcea91 chore: 커밋 메시지 규칙에 chore 접두사 추가
- AGENTS.md에 feat, fix와 함께 chore 접두사를 공식 커밋 타입으로 명시
- 씬/프리팹 정리, 에셋 재구성, 기타 유지보수성 작업에 chore를 사용하는 기준을 추가
- 큰 변경의 경우 한국어 bullet 본문을 함께 작성하는 커밋 메시지 규칙을 유지하도록 정리
2026-03-24 16:54:37 +09:00

341 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Colosseum - Unity Game Project
## Project Overview
Multiplayer arena game built with **Unity 6000.3.10f1** and **Unity Netcode for GameObjects**.
- **Language**: C# 9.0
- **Target Framework**: .NET Standard 2.1
- **Root Namespace**: `Colosseum`
- **Assembly Definition**: `Colosseum.Game` (Assets/Scripts/Colosseum.Game.asmdef)
## Game Design Documentation
Design docs are maintained in Obsidian Vault: `\\Truenas\smb\Obsidian Vault\Colosseum`
- Always use the shared Obsidian Vault at `\\Truenas\smb\Obsidian Vault\Colosseum` for project documentation updates.
- Do not write Colosseum design notes to `C:\Users\dal4s\OneDrive\문서\Obsidian Vault\Colosseum`; that path is not the active vault for this project.
### Game Concept
- **Genre**: Online multiplayer co-op action RPG (3rd person)
- **Theme**: Gladiator survival boss raid in Colosseum
- **Roles**: Multi-role system - players can hybridize (e.g., Tank 0.5 + DPS 0.5) instead of fixed Tank/DPS/Healer
### Stats System
| Stat | Abbr | Description | Derived Formula |
|------|------|-------------|-----------------|
| Strength | STR | Weapon damage | Physical Damage = STR × 2 |
| Dexterity | DEX | Ranged aim/damage, melee speed | Ranged Damage = DEX × 2 |
| Intelligence | INT | Magic damage | Magic Damage = INT × 2 |
| Vitality | VIT | Max health | Max HP = VIT × 10 |
| Wisdom | WIS | Healing power | Heal Power = WIS × 1.5 |
| Spirit | SPI | Max mana | Max MP = SPI × 5 |
### Damage Calculation
```
Final Damage = baseDamage + (statDamage × statScaling)
```
| DamageType | Base Stat | Description |
|------------|-----------|-------------|
| Physical | STR | Melee weapon damage |
| Magical | INT | Spell damage |
| Ranged | DEX | Bow/ranged damage |
| True | None | Fixed damage, no stat scaling |
### Stat Modifier System
Modifiers are applied in order:
1. **Flat**: Add fixed value
2. **PercentAdd**: Sum percentages, then multiply
3. **PercentMult**: Multiply individually
```
Final = (Base + FlatSum) × (1 + PercentAddSum) × PercentMult1 × PercentMult2...
```
### Skill System
- **Active Skills**: 6 slots (L-click, R-click, 1, 2, 3, 4)
- **Passive Skills**: Tree-based progression from center
- **Effects**: Triggered via animation events (`OnEffect(index)`)
- **Animation**: Start clip + optional end clip
## Build/Run Commands
This is a Unity project. Use Unity Editor for building and testing.
```bash
# Open in Unity Editor (requires Unity Hub)
# Build via: File > Build Settings > Build
# Run tests in Unity Editor
# Window > General > Test Runner > EditMode / PlayMode
```
### Build from Command Line (Windows)
```bash
# Build Windows standalone (adjust paths as needed)
"C:\Program Files\Unity\Hub\Editor\6000.3.10f1\Editor\Unity.exe" -batchmode -projectPath . -buildWindows64Player ./Builds/Windows/Colosseum.exe -quit
```
## Project Structure
```
Assets/
Scripts/
Abnormalities/ # Buff/debuff system
Editor/ # Unity editor extensions
Network/ # Network management
Player/ # Player controllers
Skills/ # Skill system
Effects/ # Skill effects (damage, heal, etc.)
Stats/ # Character statistics
UI/ # User interface
```
## Code Style Guidelines
### Namespaces
Follow `Colosseum.{Subnamespace}` pattern:
```csharp
namespace Colosseum.Player { }
namespace Colosseum.Skills { }
namespace Colosseum.Skills.Effects { }
namespace Colosseum.Stats { }
namespace Colosseum.Network { }
namespace Colosseum.Abnormalities { }
```
### Using Statements Order
Organize imports in this order, separated by blank lines:
1. System namespaces
2. UnityEngine namespaces
3. Unity.Netcode / Unity packages
4. Colosseum namespaces
```csharp
using System;
using System.Collections.Generic;
using UnityEngine;
using Unity.Netcode;
using Colosseum.Stats;
using Colosseum.Player;
```
### Naming Conventions
| Element | Convention | Example |
|---------|------------|---------|
| Classes | PascalCase | `PlayerNetworkController` |
| Interfaces | IPascalCase | `IDamageable` |
| Methods | PascalCase | `TakeDamageRpc()` |
| Public Properties | PascalCase | `MaxHealth`, `IsStunned` |
| Private Fields | camelCase | `currentHealth`, `characterStats` |
| Constants | PascalCase or SCREAMING_SNAKE | `SKILL_STATE_NAME`, `MaxValue` |
| Enum values | PascalCase | `DamageType.Physical` |
### Serialization & Inspector
Use `[SerializeField]` with `[Header]` and `[Tooltip]` for organization:
```csharp
[Header("References")]
[Tooltip("CharacterStats component (auto-searched if null)")]
[SerializeField] private CharacterStats characterStats;
[Header("Settings")]
[Min(0f)] [SerializeField] private float baseDamage = 10f;
[SerializeField] private DamageType damageType = DamageType.Physical;
```
### Documentation
Use XML documentation comments in **Korean**:
```csharp
/// <summary>
/// 플레이어 네트워크 상태 관리 (HP, MP 등)
/// </summary>
public class PlayerNetworkController : NetworkBehaviour
{
/// <summary>
/// 대미지 적용 (서버에서만 실행)
/// </summary>
[Rpc(SendTo.Server)]
public void TakeDamageRpc(float damage)
{
// ...
}
}
```
### Network Code Patterns
Use Unity Netcode patterns:
```csharp
// Network variables for synchronized state
private NetworkVariable<float> currentHealth = new NetworkVariable<float>(100f);
// Server RPCs for client-to-server calls
[Rpc(SendTo.Server)]
public void TakeDamageRpc(float damage)
{
currentHealth.Value = Mathf.Max(0f, currentHealth.Value - damage);
}
// Check authority before modifying
if (IsServer)
{
currentHealth.Value = MaxHealth;
}
```
### Expression Body Members
Use for simple properties and methods:
```csharp
public float MaxHealth => vitality.FinalValue * 10f;
public bool IsStunned => stunCount > 0;
public bool CanAct => !IsStunned;
```
### Switch Expressions
Prefer switch expressions for concise mapping:
```csharp
public CharacterStat GetStat(StatType statType)
{
return statType switch
{
StatType.Strength => strength,
StatType.Dexterity => dexterity,
StatType.Intelligence => intelligence,
_ => null,
};
}
```
### ScriptableObjects for Data
Use ScriptableObject for configuration data:
```csharp
[CreateAssetMenu(fileName = "NewSkill", menuName = "Colosseum/Skill")]
public class SkillData : ScriptableObject
{
[SerializeField] private string skillName;
[SerializeField] private List<SkillEffect> effects;
public string SkillName => skillName;
public IReadOnlyList<SkillEffect> Effects => effects;
}
```
### Error Handling
- Use `Debug.LogWarning()` for recoverable issues
- Use `Debug.LogError()` for critical failures
- Null-check parameters in public methods
```csharp
public void ApplyAbnormality(AbnormalityData data, GameObject source)
{
if (data == null)
{
Debug.LogWarning("[Abnormality] ApplyAbnormality called with null data");
return;
}
// ...
}
```
### Events
Use C# events with `Action<T>` or custom delegates:
```csharp
public event Action<ActiveAbnormality> OnAbnormalityAdded;
public event Action<ActiveAbnormality> OnAbnormalityRemoved;
public event Action OnAbnormalitiesChanged;
// Invoke with null-conditional
OnAbnormalityAdded?.Invoke(newAbnormality);
```
## Key Dependencies
| Package | Purpose |
|---------|---------|
| Unity.Netcode.Runtime | Multiplayer networking |
| Unity.InputSystem | New input system |
| Unity.TextMeshPro | Text rendering |
| Unity.Networking.Transport | Low-level networking |
## Common Patterns
### MonoBehaviour Components
```csharp
public class ExampleComponent : MonoBehaviour
{
[Header("References")]
[SerializeField] private Animator animator;
public Animator Animator => animator;
private void Awake()
{
if (animator == null)
animator = GetComponentInChildren<Animator>();
}
}
```
### NetworkBehaviour Components
```csharp
public class NetworkedComponent : NetworkBehaviour
{
private NetworkVariable<int> value = new NetworkVariable<int>();
public override void OnNetworkSpawn()
{
// Initialize networked state
}
public override void OnNetworkDespawn()
{
// Cleanup
}
}
```
## Notes
- For Unity work, prefer Unity MCP for active scene inspection, runtime verification, prefab checks, and console review when it is available in the session.
- Never edit code, scenes, prefabs, components, or Unity asset settings while the Unity Editor is in play mode. Stop play mode first, then edit.
- After Unity-related edits, refresh or compile as needed and check the Unity console before proceeding.
- For networked play tests, prefer a temporary non-conflicting test port when needed and restore the default port after validation.
- The user has a strong project preference that play mode must be stopped before edits because network ports can remain occupied otherwise.
- Commit messages should follow the recent project history style: use a type prefix such as `feat:`, `fix:`, or `chore:` and write the subject in Korean so the gameplay/UI/system change is clear from the log alone.
- When the change is substantial, include a blank line after the subject and add Korean bullet points that summarize the work by feature/purpose, similar to commit `0889bb0` (`feat: 드로그 집행 개시 패턴 및 낙인 디버프 추가`).
- Prefer the format `type: 한글 요약` for the subject, then `- 변경 사항` bullet lines for the body. Use `feat:` for feature work, `fix:` for bug fixes, and `chore:` for non-feature maintenance such as scene/prefab cleanup, asset reorganization, or other miscellaneous upkeep. The body should mention key implementation scope, affected systems/assets, and validation or rollback notes when relevant.
- All code comments and documentation should be in Korean
- Use `[Min()]` attribute for numeric minimums in Inspector
- Use `[TextArea]` for multi-line string fields
- Private fields should use `camelCase` (no `m_` or `_` prefix)
- Prefer `IReadOnlyList<T>` for exposing collections