> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Game Saves 충돌

> 로컬 및 클라우드 저장 데이터가 갈라질 때 PlayFab Game Saves 충돌을 해결하고, 동기화 전략을 사용하여 크로스 디바이스 플레이어의 진행 상황을 보호합니다.

# 게임 저장 충돌 및 원자적 단위

## 개요

저장 충돌은 여러 디바이스에서 동일한 게임 데이터를 수정할 때 발생합니다. 시스템은 유지할 버전을 결정해야 합니다. 저장 데이터 구조를 설계하려면 시스템이 충돌을 감지하고 해결하는 방법을 이해해야 합니다.

## 충돌이 발생하는 시기

충돌은 동기화 작업(`PFGameSaveFilesAddUserWithUiAsync`) 중에 다음 조건이 모두 참인 경우에만 발생합니다.

1. **로컬 변경 사항 존재**: 마지막 동기화 이후 로컬에서 파일을 수정했습니다.
2. **클라우드 변경 사항 존재**: 마지막 동기화 이후 다른 디바이스에서 최신 데이터를 업로드했습니다.
3. **동일한 원자적 단위**: 두 변경 사항 모두 같은 루트 수준 폴더에 있습니다.

### 충돌 감지 매트릭스

| 로컬 디바이스 변경 사항 | 클라우드에 동일한 원자적 단위 내 변경 사항 있음 | 결과      |
| ------------- | --------------------------- | ------- |
| 수정된 파일        | 예                           | **충돌**  |
| 삭제된 파일        | 예                           | **충돌**  |
| 변경 없음         | 예                           | 다운로드 진행 |
| 수정된 파일        | 아니요                         | 업로드 진행  |
| 삭제된 파일        | 아니요                         | 삭제 진행   |

## 원자적 단위란 무엇인가요?

일부 파일 동기화 시스템은 충돌을 파일 단위로 처리합니다. 동일한 파일을 업로드하고 다운로드해야 하는 경우 충돌이 있습니다. Game Saves에서는 각 루트 수준 하위 폴더가 *원자적 단위*로 처리됩니다.

<Note>
  **각 루트 수준 하위 폴더는 하나의 원자적 단위입니다.**
</Note>

루트 수준 하위 폴더 내의 파일이나 하위 폴더를 다운로드해야 하고 같은 루트 하위 폴더의 파일이나 폴더를 업로드해야 하는 경우 전체 원자적 단위가 충돌 상태에 있습니다.

이 접근 방식을 통해 다음이 가능합니다.

* **데이터 무결성 유지**: 상호 종속적인 파일이 일관되게 함께 유지됩니다.
* **격리 제공**: 별도의 폴더에 있는 독립적인 데이터는 충돌 없이 동기화됩니다.
* **충돌 최소화**: 서로 다른 디바이스의 서로 다른 원자적 단위에 대한 변경 사항이 자동으로 병합됩니다.

### 예시 저장 구조

```
SaveRoot/
├── save.dat              ← Atomic unit: root
├── player.dat            ← Atomic unit: root
├── Save1/
│   ├── stats.json        ← Atomic unit: Save1
│   └── inventory.json    ← Atomic unit: Save1
├── Save2/
│   ├── stats.json        ← Atomic unit: Save2
│   └── inventory.json    ← Atomic unit: Save2
└── WorldState/
    ├── map.dat           ← Atomic unit: WorldState
    └── npcs/
        └── positions.dat ← Atomic unit: WorldState
```

### 충돌 시나리오

| 디바이스 A 변경 사항         | 디바이스 B 변경 사항                    | 충돌?   | 이유                     |
| -------------------- | ------------------------------- | ----- | ---------------------- |
| `Save1/stats.json`   | `Save1/inventory.json`          | **예** | 동일한 원자적 단위: Save1      |
| `Save1/stats.json`   | `Save2/stats.json`              | 아니요   | 다른 단위: Save1 vs Save2  |
| `WorldState/map.dat` | `WorldState/npcs/positions.dat` | **예** | 동일한 원자적 단위: WorldState |
| `save.dat`           | `Save1/stats.json`              | 아니요   | 다른 단위: root vs Save1   |
| `player.dat`         | `save.dat`                      | **예** | 동일한 원자적 단위: root       |

## 루트 수준 파일: 특수 사례

**저장 루트의 모든 파일은 하나의 원자적 단위를 공유합니다.**

시스템은 하위 폴더가 아닌 저장 루트에 직접 배치한 모든 파일을 단일 원자적 단위로 그룹화합니다. 로컬에서 하나의 루트 수준 파일을 수정하고 다른 디바이스에서 다른 루트 수준 파일을 수정하면 이 차이가 충돌을 트리거합니다.

| 디바이스 A(로컬)         | 디바이스 B(클라우드)          | 동일한 원자적 단위? | 결과            |
| ------------------ | --------------------- | ----------- | ------------- |
| `rootfile1.txt` 수정 | `rootfile2.txt` 수정    | ✅ 예         | **충돌**        |
| `rootfile1.txt` 수정 | `save1/config.ini` 수정 | ❌ 아니요       | 충돌 없음, 모두 동기화 |
| `save.dat` 삭제      | `progress.dat` 수정     | ✅ 예         | **충돌**        |

## 사용자 선택 옵션

충돌이 발생하면 플레이어는 다음 중에서 선택합니다.

* **로컬 데이터 사용(로컬 유지)**: 디바이스의 현재 저장 데이터를 유지합니다.
* **클라우드 데이터 사용(클라우드 유지)**: 클라우드 저장 데이터를 다운로드하여 사용합니다.

### 중요: 해결은 모두 아니면 무(all-or-nothing)

<Note>
  ⚠️ **중요**: 원자적 단위는 충돌이 감지되는 *시기*를 결정하지만, 사용자의 충돌 해결 선택은 원자적 단위별이 아닌 **전체 저장 데이터**에 적용됩니다.
</Note>

### 예시: 혼합 충돌 시나리오

```
SaveRoot/
├── SlotA/ ← Local: modified, Cloud: modified  → CONFLICT
├── SlotB/ ← Local: modified, Cloud: unchanged → Local-only change
├── SlotC/ ← Local: unchanged, Cloud: modified → Cloud-only change
└── SlotD/ ← Local: modified, Cloud: unchanged → Local-only change
```

**사용자에게 충돌 프롬프트가 표시됨**(SlotA로 인해).

| 사용자 선택      | SlotA       | SlotB              | SlotC               | SlotD              |
| ----------- | ----------- | ------------------ | ------------------- | ------------------ |
| **로컬 유지**   | ✅ 로컬 유지     | ✅ 로컬 업로드           | ❌ 클라우드 변경 사항 **손실** | ✅ 로컬 업로드           |
| **클라우드 유지** | ✅ 클라우드 다운로드 | ❌ 로컬 변경 사항 **덮어씀** | ✅ 클라우드 다운로드         | ❌ 로컬 변경 사항 **덮어씀** |

### 이것이 중요한 이유

1. **로컬 유지는 클라우드 전용 변경 사항을 손실시킴**: SlotA의 충돌 때문에 "로컬 유지"를 선택하면 다른 디바이스에서 만든 SlotC에 대한 클라우드 업데이트를 받지 못합니다.

2. **클라우드 유지는 로컬 전용 변경 사항을 손실시킴**: "클라우드 유지"를 선택하면 클라우드 상태가 SlotB 및 SlotD에 대한 로컬 변경 사항을 덮어씁니다.

3. **롤백 가능**: 두 선택 모두 나중에 롤백할 수 있도록 폐기된 분기를 보존합니다.

### 설계 요약

| 측면        | 세분성                 |
| --------- | ------------------- |
| 충돌 **감지** | 원자적 단위별(루트 하위 폴더)   |
| 충돌 **해결** | 전체 저장 데이터(모두 아니면 무) |

이 모두 아니면 무 방식은 플레이어 경험을 단순화합니다. 원자적 단위별 해결은 기술적으로 데이터 일관성을 유지하지만(원자적 단위가 일관성 경계를 정의하므로), 사용자 경험 문제를 만듭니다.

* 플레이어는 원자적 단위 및 폴더 경계의 개념을 이해해야 합니다.
* 혼합된 결과(일부 폴더는 로컬에서, 다른 폴더는 클라우드에서)는 최종 상태에 대해 플레이어를 혼란스럽게 할 수 있습니다.
* 각 충돌하는 원자적 단위에 대해 별도로 프롬프트하면 충돌 해결이 부담스러워집니다.

**로컬 유지** 대 **클라우드 유지**라는 단일 선택을 제시함으로써 플레이어는 기본 저장 구조를 이해할 필요 없이 하나의 명확한 결정을 내립니다.

## 충돌이 발생하지 않는 경우

### 양쪽에서 삭제

두 디바이스 모두에서 동일한 파일(또는 동일한 원자적 단위의 파일)을 삭제하면 **충돌이 발생하지 않습니다**. 시스템은 두 디바이스가 파일을 삭제해야 한다는 데 동의한다는 것을 인식합니다.

### 서로 다른 원자적 단위의 변경 사항

디바이스 A가 `SlotA/`의 파일을 수정하고 디바이스 B가 `SlotB/`의 파일을 수정하면 충돌이 발생하지 않습니다. 동기화는 두 변경 사항을 자동으로 병합합니다.

## 모범 사례

### 1. 폴더 구조를 신중하게 설계

독립적인 저장 단위에 하위 폴더를 사용합니다.

```
SaveRoot/
├── Slot1/           ← Each slot is independent
│   └── save.dat
├── Slot2/
│   └── save.dat
```

각 슬롯이 루트 수준 하위 폴더인 슬롯 기반 게임 저장 시스템은 원자적 단위를 효과적으로 사용하는 방법의 간단한 예입니다.

기타 예:

* **공유 참조 데이터**: 잠금 해제된 콘텐츠 또는 업적과 같이 저장 슬롯이 사용할 수 있는 데이터를 자체 하위 폴더에 저장하여 개별 저장 슬롯과 독립적으로 동기화되도록 합니다.
* **큰 자산 컬렉션**: 게임이 다운로드된 콘텐츠 팩이나 사용자 제작 레벨과 같이 독립적으로 업데이트되는 큰 파일 집합을 저장하는 경우 여러 루트 하위 폴더로 분할하여 하나의 컬렉션에 대한 업데이트가 다른 컬렉션에 대한 업데이트와 충돌하지 않도록 하는 것을 고려하세요.

### 2. 자주 수정되는 데이터에 대해 루트 수준 파일 사용 방지

모든 루트 수준 파일은 하나의 원자적 단위를 공유합니다. 독립적으로 동기화하려는 자주 수정되는 파일은 루트에 배치하지 마세요.

**대신:**

```
SaveRoot/
├── autosave.dat     ← All root files = 1 atomic unit
└── save1.dat
└── save2.dat
```

**다음을 고려하세요:**

```
SaveRoot/
├── AutoSave/
│   └── autosave.dat     ← Independent unit
└── Save1/
    └── gamesave.dat ← Independent unit
```

### 3. 관련된 데이터를 함께 그룹화

일관되게 함께 유지해야 하는 파일에는 동일한 폴더를 사용합니다.

```
SaveRoot/
├── Save1/
│   ├── stats.json       ← These files are interdependent
│   ├── inventory.json   ← and should conflict together
│   └── quests.json
```

### 4. 충돌 최소화

자주 업로드하여 충돌 가능성을 줄이세요. 더 자주 동기화할수록 두 디바이스에 서로 다른 변경 사항이 있을 가능성이 낮아집니다.

### 5. 충돌 비율 모니터링

[PlayStream 이벤트](/services/playfab/player-progression/game-saves/playstream-events)를 사용하여 충돌이 얼마나 자주 발생하고 플레이어가 어떻게 해결하는지 추적합니다. 충돌 비율이 증가하거나 "로컬 유지"와 "원격 유지" 간의 강한 편향은 조사할 가치가 있는 UX 또는 저장 주기 문제를 나타낼 수 있습니다.


## Related topics

- [Game Saves 롤백](/ko/services/playfab/player-progression/game-saves/rollback.md)
- [Game Saves 빠른 시작](/ko/services/playfab/player-progression/game-saves/quickstart.md)
- [Game Saves UI 콜백](/ko/services/playfab/player-progression/game-saves/ui-callbacks.md)
- [PlayFab Game Saves용 계정 연결 전략](/ko/services/playfab/player-progression/game-saves/linking.md)
- [게임 저장](/ko/build/core-features/common/game-save/index.md)
