> ## 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.

# Modo offline do Game Saves

> Use o modo offline do PlayFab Game Saves para permitir que os jogadores continuem progredindo sem conectividade e sincronizem os salvamentos na nuvem quando a rede voltar.

O Game Saves foi projetado para funcionar online e offline, permitindo que os jogadores continuem jogando mesmo quando a conectividade de rede não está disponível. O sistema opera em dois modos distintos, com base na disponibilidade da rede e nas escolhas do usuário.

## Modos de conexão

### Modo conectado à nuvem

Quando a rede está disponível e `PFGameSaveFilesAddUserWithUiAsync()` é concluído com êxito, o sistema opera no modo conectado à nuvem. Nesse modo:

* Todas as APIs funcionam normalmente, com sincronização completa com a nuvem
* Os uploads de dados de salvamento funcionam conforme o esperado
* As informações de cota de armazenamento estão disponíveis
* O monitoramento do dispositivo ativo funciona corretamente

### Modo offline (não conectado à nuvem)

Quando a rede não está disponível ou o usuário escolhe jogar offline, o sistema entra no modo offline com funcionalidade limitada. Você pode verificar o status atual da conexão usando `PFGameSaveFilesIsConnectedToCloud()` para determinar em qual modo o sistema está operando.

## Tratamento de falhas de rede durante a sincronização inicial

Quando `PFGameSaveFilesAddUserWithUiAsync()` é chamado sem conectividade de rede, ele aciona um `PFGameSaveFilesUiSyncFailedCallback`. O retorno de chamada de `XAsyncBlock` não é acionado enquanto o sistema aguarda a resposta do usuário. A operação assíncrona fica pausada até que o usuário selecione uma ação final.

```cpp theme={null}
// Handle sync failure callback
void MyPFGameSaveFilesUiSyncFailedCallback(PFLocalUserHandle localUserHandle, PFGameSaveFilesSyncState syncState, HRESULT error, void* context)
{
    // Tell the user something like this:
    std::cout << "We couldn't sync your data with the cloud just now" << std::endl;
    std::cout << "Try syncing again or use this game offline" << std::endl;
    std::cout << "[Try Again]" << std::endl;
    std::cout << "[Use Offline]" << std::endl;

    // if user chooses [Try Again], call PFGameSaveFilesSetUiSyncFailedResponse(localUserHandle, PFGameSaveFilesUiSyncFailedUserAction::Retry);
    // if user chooses [Use Offline], call PFGameSaveFilesSetUiSyncFailedResponse(localUserHandle, PFGameSaveFilesUiSyncFailedUserAction::UseOffline);

    // These API calls can happen inside or outside of this callback
}
```

**Opções de resposta do usuário:**

* **Try Again (`Retry`)**: tenta novamente a chamada de rede. Se a nova tentativa também falhar, este retorno de chamada é acionado novamente e o usuário precisa responder outra vez. O retorno de chamada de `XAsyncBlock` permanece adiado durante cada ciclo de repetição.
* **Use Offline (`UseOffline`)**: o retorno de chamada de `XAsyncBlock` é acionado com `S_OK`, mas o sistema entra no modo offline (detectável com `PFGameSaveFilesIsConnectedToCloud()`).
* **Cancel**: o retorno de chamada de `XAsyncBlock` é acionado com `E_PF_GAMESAVE_USER_CANCELLED`.

## Comportamento das APIs no modo offline

No modo offline, as APIs se comportam de maneira diferente:

### APIs que funcionam normalmente

* `PFGameSaveFilesGetFolder()` - Retorna o caminho da pasta de salvamento local

### APIs com funcionalidade limitada

* `PFGameSaveFilesUploadWithUiAsync()` - Retorna `S_OK` imediatamente, mas a conclusão assíncrona retorna `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD`
* `PFGameSaveFilesGetRemainingQuota()` - Retorna `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD`
* `PFGameSaveFilesSetActiveDeviceChangedCallback()` - Pode ser definido, mas nunca será acionado

### Voltando ao modo online

* Chame `PFGameSaveFilesAddUserWithUiAsync()` novamente para tentar se reconectar
* Não é necessário reinicializar totalmente o sistema Game Saves
* A interface de falha será exibida novamente se a rede ainda não estiver disponível
* Use `PFGameSaveFilesIsConnectedToCloud()` para verificar o status da conexão após as tentativas de repetição

## Quando o Game Saves entra no modo offline ou retorna um erro

Uma dúvida comum de integração é: *quando a sincronização inicial (`PFGameSaveFilesAddUserWithUiAsync`) coloca o jogador no modo offline e quando ela falha com um código de erro?* Há três resultados finais (conectado, offline ou cancelado), e um cancelamento pode vir do jogador ou do jogo:

| Resultado | Como é alcançado | Resultado assíncrono | `IsConnectedToCloud()` | Pasta de salvamento disponível? | Tratamento recomendado |
| - | - | - | - | - | - |
| **Conectado** | A sincronização foi concluída com êxito | `S_OK` | `true` | Sim | Permitir jogar; os salvamentos são sincronizados com a nuvem. |
| **Offline** | O usuário selecionou **Use Offline** no aviso de falha de sincronização (ou outro dispositivo se tornou o dispositivo ativo) | `S_OK` | `false` | Sim | Permitir jogar com salvamentos locais; informar ao jogador que os salvamentos não serão sincronizados. |
| **Cancelado pelo jogador** | O usuário selecionou **Cancel** em qualquer aviso | `E_PF_GAMESAVE_USER_CANCELLED` (`0x800704C7`) | n/a | **Não** | **Bloquear o jogo** ou voltar a um menu seguro; não há pasta para salvar ou carregar. |
| **Cancelado pelo jogo** | O jogo chamou `XAsyncCancel` no `XAsyncBlock` | `E_ABORT` (`0x80004004`) | n/a | **Não** | O mesmo que um cancelamento pelo jogador; não há pasta para salvar ou carregar. |

Pontos principais:

* **O modo offline é um resultado de êxito, não um erro.** Ele só é ativado por uma escolha explícita de **Use Offline**, e a operação assíncrona é concluída com `S_OK`. Detecte-o com `PFGameSaveFilesIsConnectedToCloud()`.
* **Falhas transitórias/técnicas são exibidas por meio da interface de falha de sincronização**, e não retornadas diretamente de `PFGameSaveFilesAddUserWithUiAsync`. Em seguida, o usuário (ou sua resposta automática) escolhe `Retry`, `UseOffline` ou `Cancel`, o que resulta em um dos três resultados acima.
* **O cancelamento é final e não produz uma pasta de salvamento.** Trate "cancelado" (ou qualquer falha que não deixe uma pasta) como *não permitir jogar*.
* **O cancelamento pelo jogador e pelo jogo retornam códigos diferentes.** Somente o jogador escolhendo **Cancel** em um aviso produz `E_PF_GAMESAVE_USER_CANCELLED`. Se o seu jogo cancelar a operação por conta própria com `XAsyncCancel`, ela será concluída com `E_ABORT`. Verifique ambos se quiser tratá-los da mesma forma.

<Note>
  Cancelar um aviso de **conflito** também é final. Ele é concluído com `E_PF_GAMESAVE_USER_CANCELLED` e não passa automaticamente para um aviso "Use Offline" de falha de sincronização. Se você quiser uma experiência de "rejeitar o conflito, mas continuar jogando offline", projete-a explicitamente (por exemplo, execute novamente `PFGameSaveFilesAddUserWithUiAsync` e selecione Use Offline na falha resultante). Consulte [Conflitos do Game Saves](/pt-BR/services/playfab/player-progression/game-saves/conflicts).
</Note>

## Códigos de erro do Game Saves

Os HRESULTs a seguir são definidos pelo SDK do Game Saves. Os códigos no intervalo `0x8923xxxx` são específicos do Game Saves; `0x800704C7` é `HRESULT_FROM_WIN32(ERROR_CANCELLED)`.

| Código | Valor | Quando é retornado |
| - | - | - |
| `E_PF_GAMESAVE_USER_CANCELLED` | `0x800704C7` | O usuário selecionou **Cancel** em qualquer aviso da interface. Final; sem pasta de salvamento. (Se o jogo cancelar o `XAsyncBlock` com `XAsyncCancel`, a operação será concluída com o `E_ABORT` padrão (`0x80004004`).) |
| `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD` | `0x89237004` | Retornado por `PFGameSaveFilesUploadWithUiAsync()` e `PFGameSaveFilesGetRemainingQuota()` enquanto a sessão está no modo offline. |
| `E_PF_GAMESAVE_NETWORK_FAILURE` | `0x89237005` | Retornado por `PFGameSaveFilesUploadWithUiAsync()` após uma falha de rede transitória enquanto ainda conectado à nuvem. É seguro tentar novamente mais tarde. |
| `E_PF_GAMESAVE_DEVICE_NO_LONGER_ACTIVE` | `0x89237007` | Retornado por `PFGameSaveFilesUploadWithUiAsync()` quando este dispositivo não é mais o dispositivo ativo (outro dispositivo assumiu). |
| `E_PF_GAMESAVE_DISK_FULL` | `0x89237008` | Espaço em disco local insuficiente para baixar os dados de salvamento. Solicite que o usuário libere espaço e tente novamente. |
| `E_PF_GAMESAVE_OPERATION_IN_PROGRESS` | `0x89237009` | Uma operação conflitante já está em execução para este usuário: `PFGameSaveFilesUploadWithUiAsync()` foi chamado enquanto outro upload ou uma redefinição da nuvem estava em andamento, `PFGameSaveFilesAddUserWithUiAsync()` foi chamado enquanto uma redefinição da nuvem estava em andamento ou `PFGameSaveFilesResetCloudAsync()` foi chamado enquanto outra redefinição, um upload ou um download estava em andamento. Nada foi iniciado ou modificado; aguarde a conclusão da operação em andamento e tente novamente. Disponível a partir do GDK de outubro de 2026 (2610). |
| `E_PF_GAMESAVE_LOCAL_FILE_UNAVAILABLE` | `0x8923700A` | Retornado por `PFGameSaveFilesUploadWithUiAsync()` quando um arquivo de salvamento local não pode ser lido durante o upload; por exemplo, o título ainda o mantém aberto para gravação. Nada foi confirmado na nuvem. Transitório: tente novamente quando o título parar de gravar esse arquivo. Disponível no GDK de outubro de 2025 (2510) QFE5, no GDK de abril de 2026 (2604) QFE6 e no GDK de outubro de 2026 (2610). |
| `E_PF_GAMESAVE_DOWNLOAD_IN_PROGRESS` | `0x89237006` | `PFGameSaveFilesUploadWithUiAsync()` foi chamado antes que `PFGameSaveFilesAddUserWithUiAsync()` concluísse a sincronização inicial. |
| `E_PF_GAMESAVE_USER_NOT_ADDED` | `0x89237003` | Uma API foi chamada antes que `PFGameSaveFilesAddUserWithUiAsync()` fosse concluído para esse usuário. |
| `E_PF_GAMESAVE_USER_ALREADY_ADDED` | `0x89237002` | `PFGameSaveFilesAddUserWithUiAsync()` foi chamado novamente para um usuário já adicionado. |
| `E_PF_GAMESAVE_ALREADY_INITIALIZED` | `0x89237001` | `PFGameSaveFilesInitialize()` foi chamado duas vezes sem uma chamada intermediária a `PFGameSaveFilesUninitializeAsync()`. |
| `E_PF_GAMESAVE_NOT_INITIALIZED` | `0x89237000` | Uma API foi chamada antes de `PFGameSaveFilesInitialize()`. |

Para saber como esses resultados são produzidos pela interface interna do sistema (fora do processo) em comparação com seus próprios retornos de chamada, consulte [Retornos de chamada de interface do Game Saves](/pt-BR/services/playfab/player-progression/game-saves/ui-callbacks#in-process-vs-out-of-process-system-ui).

## Cenários adicionais de status de conexão

A API `PFGameSaveFilesIsConnectedToCloud()` é particularmente útil porque a desconexão pode acontecer de várias maneiras:

* **Rede indisponível durante a sincronização**: o usuário escolhe explicitamente jogar offline
* **Dispositivo ativo alterado**: outro dispositivo assume como dispositivo ativo, colocando automaticamente este dispositivo no modo offline

Use esta API antes de tentar operações na nuvem para fornecer o feedback adequado ao usuário.

## Práticas recomendadas para suporte offline

1. **Sempre implemente retornos de chamada de falha de sincronização** para lidar com problemas de rede de forma adequada
2. **Verifique o status da conexão regularmente** usando `PFGameSaveFilesIsConnectedToCloud()` antes de tentar operações na nuvem
3. **Informe os jogadores** quando estiver operando no modo offline, para que eles entendam que os salvamentos não serão sincronizados
4. **Forneça opções de repetição** quando a conectividade de rede for restaurada
5. **Os salvamentos locais sempre funcionam** - os jogadores podem continuar jogando independentemente do status da rede
6. **Monitore a desconexão** - lembre-se de que os dispositivos podem ser desconectados quando outro dispositivo se torna ativo

## Comportamento de upload no modo conectado

Mesmo no modo conectado, os uploads podem falhar devido a problemas de rede ou limites de taxa. Quando isso acontece, o retorno de chamada de `XAsyncBlock` não é acionado imediatamente. A operação assíncrona é pausada enquanto o sistema aguarda a resposta do usuário por meio da [máquina de estados dos retornos de chamada de interface](/pt-BR/services/playfab/player-progression/game-saves/ui-callbacks#how-the-state-machine-works):

1. O `PFGameSaveFilesUiSyncFailedCallback` é acionado com os detalhes do erro.
2. O retorno de chamada de `XAsyncBlock` ainda não é acionado. A operação fica pausada enquanto o sistema aguarda uma resposta.
3. Se o usuário selecionar `Retry`, o upload será repetido. Se falhar novamente, o retorno de chamada será acionado outra vez e o usuário precisará responder novamente.
4. Se o usuário selecionar `Cancel`, o retorno de chamada de `XAsyncBlock` será acionado com `E_PF_GAMESAVE_USER_CANCELLED`.
5. Se uma nova tentativa tiver êxito, o retorno de chamada de `XAsyncBlock` será acionado com `S_OK`.

O jogo pode chamar `PFGameSaveFilesUploadWithUiAsync()` novamente mais tarde, quando a rede for restaurada.

<Note>
  **No processo, não ofereça `Use Offline` no aviso de falha de sincronização enquanto um upload estiver em execução.** O upload aciona o mesmo `PFGameSaveFilesUiSyncFailedCallback` que a sincronização inicial, portanto o SDK não restringe as opções. No entanto, se o seu jogo responder com `UseOffline` a uma falha de upload, o upload falhará com `E_ABORT` (e os builds de depuração disparam uma asserção). Ofereça apenas `Retry` e `Cancel` nesse caso.
</Note>

## Quando um upload deixa a sessão offline

Normalmente, um upload não altera o modo de conexão, mas ele pode terminar com a sessão offline nos casos a seguir. Em cada um deles, o upload é concluído com `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD`, e `PFGameSaveFilesIsConnectedToCloud()` retorna `false` depois.

* **A sessão já estava offline.** O upload não é executado e é concluído com `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD`, mesmo que a rede tenha sido restaurada.
* **A nuvem tem um salvamento mais recente.** Se o serviço informar que um salvamento mais recente foi confirmado a partir de outro dispositivo quando o upload for finalizado, o Game Saves coloca a sessão offline, aciona o retorno de chamada de alteração do dispositivo ativo e conclui o upload com `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD`.
* **O jogador escolhe `Use Offline` no aviso de novo bloqueio.** Se um upload anterior confirmou seus dados, mas falhou depois, o próximo upload primeiro precisa readquirir o bloqueio de salvamento. Um aviso de falha de sincronização durante essa etapa pode ser respondido com `UseOffline`, o que deixa a sessão offline e conclui o upload com `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD`.

Para se reconectar, chame `PFGameSaveFilesAddUserWithUiAsync()` novamente.

## Cancelando um upload

Um upload pode ser cancelado da mesma forma que a sincronização inicial: o usuário pode usar `Cancel` na interface de **progresso** enquanto o upload está em andamento ou usar `Cancel` no aviso de **falha de sincronização** se o upload encontrar um erro. Em ambos os casos, `PFGameSaveFilesUploadWithUiAsync()` é concluído com `E_PF_GAMESAVE_USER_CANCELLED` (`0x800704C7`) e o salvamento não é enviado. Seus resultados finais são **êxito**, **cancelado** ou **falha** (em que `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD` significa que a sessão agora está offline; consulte [Quando um upload deixa a sessão offline](#when-an-upload-takes-the-session-offline)). Trate `E_PF_GAMESAVE_USER_CANCELLED` separadamente de outras falhas para que você possa distinguir "o jogador desistiu" de "o upload apresentou erro". Se o seu jogo cancelar o upload por conta própria com `XAsyncCancel`, ele será concluído com `E_ABORT` em vez de `E_PF_GAMESAVE_USER_CANCELLED`.


## Related topics

- [Início rápido do Game Saves](/pt-BR/services/playfab/player-progression/game-saves/quickstart.md)
- [Perguntas frequentes sobre tratamento de erros do Game Saves](/pt-BR/services/playfab/player-progression/game-saves/error-handling-faq.md)
- [Retornos de chamada de interface do Game Saves](/pt-BR/services/playfab/player-progression/game-saves/ui-callbacks.md)
- [Noções básicas sobre o fluxo de sincronização do Game Saves](/pt-BR/build/core-features/common/game-save/game-saves-syncing.md)
- [Caixas de diálogo do sistema do Game Saves](/pt-BR/build/core-features/common/game-save/game-saves-dialogues.md)
