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

# Modo sin conexión de Game Saves

> Use el modo sin conexión de PlayFab Game Saves para permitir que los jugadores continúen su progreso sin conectividad y sincronizar los guardados en la nube cuando vuelva la red.

Game Saves está diseñado para funcionar tanto en línea como sin conexión, lo que permite a los jugadores seguir jugando incluso cuando la conectividad de red no está disponible. El sistema funciona en dos modos distintos según la disponibilidad de la red y las elecciones del usuario.

## Modos de conexión

### Modo conectado a la nube

Cuando la red está disponible y `PFGameSaveFilesAddUserWithUiAsync()` se completa correctamente, el sistema funciona en modo conectado a la nube. En este modo:

* Todas las API funcionan normalmente con sincronización completa en la nube
* Las cargas de datos de guardado funcionan según lo esperado
* La información de cuota de almacenamiento está disponible
* La supervisión del dispositivo activo funciona correctamente

### Modo sin conexión (no conectado a la nube)

Cuando la red no está disponible o el usuario elige jugar sin conexión, el sistema entra en modo sin conexión con funcionalidad limitada. Puede comprobar el estado de conexión actual mediante `PFGameSaveFilesIsConnectedToCloud()` para determinar en qué modo está funcionando el sistema.

## Control de errores de red durante la sincronización inicial

Cuando se llama a `PFGameSaveFilesAddUserWithUiAsync()` sin conectividad de red, se desencadena una `PFGameSaveFilesUiSyncFailedCallback`. La devolución de llamada de `XAsyncBlock` no se activa mientras el sistema espera la respuesta del usuario. La operación asincrónica se pausa hasta que el usuario selecciona una acción terminal.

```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
}
```

**Opciones de respuesta del usuario:**

* **Reintentar (`Retry`)**: Reintenta la llamada de red. Si el reintento también falla, esta devolución de llamada se activa de nuevo y el usuario debe responder otra vez. La devolución de llamada de `XAsyncBlock` permanece diferida durante cada bucle de reintento.
* **Usar sin conexión (`UseOffline`)**: La devolución de llamada de `XAsyncBlock` se activa con `S_OK`, pero el sistema entra en modo sin conexión (detectable con `PFGameSaveFilesIsConnectedToCloud()`).
* **Cancelar**: La devolución de llamada de `XAsyncBlock` se activa con `E_PF_GAMESAVE_USER_CANCELLED`.

## Comportamiento de las API en modo sin conexión

En el modo sin conexión, las API se comportan de manera diferente:

### API que funcionan normalmente

* `PFGameSaveFilesGetFolder()`: devuelve la ruta de la carpeta de guardado local

### API con funcionalidad limitada

* `PFGameSaveFilesUploadWithUiAsync()`: devuelve `S_OK` inmediatamente, pero la finalización asincrónica devuelve `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD`
* `PFGameSaveFilesGetRemainingQuota()`: devuelve `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD`
* `PFGameSaveFilesSetActiveDeviceChangedCallback()`: se puede establecer, pero nunca se desencadenará

### Volver al modo en línea

* Llame de nuevo a `PFGameSaveFilesAddUserWithUiAsync()` para intentar la reconexión
* No es necesario reinicializar completamente el sistema de Game Saves
* Volverá a mostrar la interfaz de usuario de error si la red sigue sin estar disponible
* Use `PFGameSaveFilesIsConnectedToCloud()` para comprobar el estado de la conexión después de los intentos de reintento

## Cuándo Game Saves entra en modo sin conexión o devuelve un error

Una pregunta de integración habitual es: *¿cuándo la sincronización inicial (`PFGameSaveFilesAddUserWithUiAsync`) deja al jugador en modo sin conexión y cuándo falla con un código de error?* Hay tres resultados finales (conectado, sin conexión o cancelado), y una cancelación puede proceder del jugador o del juego:

| Resultado | Cómo se alcanza | Resultado asincrónico | `IsConnectedToCloud()` | ¿Carpeta de guardado disponible? | Control recomendado |
| - | - | - | - | - | - |
| **Conectado** | La sincronización se completó correctamente | `S_OK` | `true` | Sí | Permitir jugar; los guardados se sincronizan con la nube. |
| **Sin conexión** | El usuario seleccionó **Use Offline** en el mensaje de error de sincronización (u otro dispositivo pasó a ser el dispositivo activo) | `S_OK` | `false` | Sí | Permitir jugar con guardados locales; indicar al jugador que los guardados no se sincronizarán. |
| **Cancelado por el jugador** | El usuario seleccionó **Cancel** en cualquier mensaje | `E_PF_GAMESAVE_USER_CANCELLED` (`0x800704C7`) | n/a | **No** | **Bloquear el juego** o volver a un menú seguro: no hay ninguna carpeta para guardar ni cargar. |
| **Cancelado por el juego** | El juego llamó a `XAsyncCancel` en el `XAsyncBlock` | `E_ABORT` (`0x80004004`) | n/a | **No** | Igual que una cancelación del jugador: no hay ninguna carpeta para guardar ni cargar. |

Puntos clave:

* **El modo sin conexión es un resultado correcto, no un error.** Solo se entra en él mediante una elección explícita de **Use Offline**, y la operación asincrónica se completa con `S_OK`. Detéctelo con `PFGameSaveFilesIsConnectedToCloud()`.
* **Los errores transitorios o técnicos se muestran a través de la interfaz de usuario de error de sincronización**, no se devuelven directamente desde `PFGameSaveFilesAddUserWithUiAsync`. A continuación, el usuario (o su respuesta automática) elige `Retry`, `UseOffline` o `Cancel`, lo que se resuelve en uno de los tres resultados anteriores.
* **La cancelación es definitiva y no produce ninguna carpeta de guardado.** Trate "cancelado" (o cualquier error que no deje ninguna carpeta) como *no permitir jugar*.
* **La cancelación del jugador y la del juego devuelven códigos diferentes.** Solo la elección de **Cancel** por parte del jugador en un mensaje produce `E_PF_GAMESAVE_USER_CANCELLED`. Si su juego cancela la operación por sí mismo con `XAsyncCancel`, se completa con `E_ABORT`. Compruebe ambos si desea tratarlos de la misma manera.

> [!NOTE]
>
> Cancelar un mensaje de **conflicto** también es definitivo. Se completa con `E_PF_GAMESAVE_USER_CANCELLED` y no pasa automáticamente a un mensaje de error de sincronización con "Use Offline". Si desea una experiencia de "rechazar el conflicto pero seguir jugando sin conexión", diséñela explícitamente (por ejemplo, vuelva a ejecutar `PFGameSaveFilesAddUserWithUiAsync` y seleccione Use Offline en el error resultante). Consulte [Conflictos de Game Saves](https://docs.xbox.com/es/services/playfab/player-progression/game-saves/conflicts.md).

## Códigos de error de Game Saves

El SDK de Game Saves define los siguientes HRESULT. Los códigos del intervalo `0x8923xxxx` son específicos de Game Saves; `0x800704C7` es `HRESULT_FROM_WIN32(ERROR_CANCELLED)`.

| Código | Valor | Cuándo se devuelve |
| - | - | - |
| `E_PF_GAMESAVE_USER_CANCELLED` | `0x800704C7` | El usuario seleccionó **Cancel** en cualquier mensaje de la interfaz de usuario. Definitivo; no hay carpeta de guardado. (Si el juego cancela el `XAsyncBlock` con `XAsyncCancel`, la operación se completa en su lugar con el código estándar `E_ABORT` (`0x80004004`)). |
| `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD` | `0x89237004` | Lo devuelven `PFGameSaveFilesUploadWithUiAsync()` y `PFGameSaveFilesGetRemainingQuota()` mientras la sesión está en modo sin conexión. |
| `E_PF_GAMESAVE_NETWORK_FAILURE` | `0x89237005` | Lo devuelve `PFGameSaveFilesUploadWithUiAsync()` después de un error de red transitorio mientras sigue conectado a la nube. Se puede reintentar más tarde con seguridad. |
| `E_PF_GAMESAVE_DEVICE_NO_LONGER_ACTIVE` | `0x89237007` | Lo devuelve `PFGameSaveFilesUploadWithUiAsync()` cuando este dispositivo ya no es el dispositivo activo (otro dispositivo tomó el control). |
| `E_PF_GAMESAVE_DISK_FULL` | `0x89237008` | No hay suficiente espacio en el disco local para descargar los datos de guardado. Pida al usuario que libere espacio y vuelva a intentarlo. |
| `E_PF_GAMESAVE_OPERATION_IN_PROGRESS` | `0x89237009` | Ya se está ejecutando una operación en conflicto para este usuario: se llamó a `PFGameSaveFilesUploadWithUiAsync()` mientras había otra carga o un restablecimiento de la nube en curso, se llamó a `PFGameSaveFilesAddUserWithUiAsync()` mientras había un restablecimiento de la nube en curso, o se llamó a `PFGameSaveFilesResetCloudAsync()` mientras había otro restablecimiento, una carga o una descarga en curso. No se inició ni modificó nada; espere a que se complete la operación en curso y vuelva a intentarlo. Disponible a partir del GDK de octubre de 2026 (2610). |
| `E_PF_GAMESAVE_LOCAL_FILE_UNAVAILABLE` | `0x8923700A` | Lo devuelve `PFGameSaveFilesUploadWithUiAsync()` cuando no se puede leer un archivo de guardado local durante la carga; por ejemplo, el título todavía lo tiene abierto para escritura. No se confirmó nada en la nube. Transitorio: vuelva a intentarlo cuando el título deje de escribir ese archivo. Disponible en el GDK de octubre de 2025 (2510) QFE5, el GDK de abril de 2026 (2604) QFE6 y el GDK de octubre de 2026 (2610). |
| `E_PF_GAMESAVE_DOWNLOAD_IN_PROGRESS` | `0x89237006` | Se llamó a `PFGameSaveFilesUploadWithUiAsync()` antes de que `PFGameSaveFilesAddUserWithUiAsync()` terminara la sincronización inicial. |
| `E_PF_GAMESAVE_USER_NOT_ADDED` | `0x89237003` | Se llamó a una API antes de que `PFGameSaveFilesAddUserWithUiAsync()` se completara para ese usuario. |
| `E_PF_GAMESAVE_USER_ALREADY_ADDED` | `0x89237002` | Se volvió a llamar a `PFGameSaveFilesAddUserWithUiAsync()` para un usuario ya agregado. |
| `E_PF_GAMESAVE_ALREADY_INITIALIZED` | `0x89237001` | Se llamó dos veces a `PFGameSaveFilesInitialize()` sin una llamada intermedia a `PFGameSaveFilesUninitializeAsync()`. |
| `E_PF_GAMESAVE_NOT_INITIALIZED` | `0x89237000` | Se llamó a una API antes de `PFGameSaveFilesInitialize()`. |

Para saber cómo se producen estos resultados con la interfaz de usuario del sistema integrada (fuera de proceso) frente a sus propias devoluciones de llamada, consulte [Devoluciones de llamada de la interfaz de usuario de Game Saves](https://docs.xbox.com/es/services/playfab/player-progression/game-saves/ui-callbacks.md#in-process-vs-out-of-process-system-ui).

## Escenarios adicionales de estado de conexión

La API `PFGameSaveFilesIsConnectedToCloud()` es particularmente útil porque la desconexión puede producirse de varias maneras:

* **Red no disponible durante la sincronización**: El usuario elige explícitamente jugar sin conexión
* **Cambio de dispositivo activo**: Otro dispositivo toma el control como dispositivo activo, lo que pone automáticamente este dispositivo en modo sin conexión

Use esta API antes de intentar operaciones en la nube para proporcionar comentarios adecuados al usuario.

## Procedimientos recomendados para la compatibilidad sin conexión

1. **Implemente siempre las devoluciones de llamada de error de sincronización** para controlar correctamente los problemas de red
2. **Compruebe el estado de la conexión con regularidad** mediante `PFGameSaveFilesIsConnectedToCloud()` antes de intentar operaciones en la nube
3. **Informe a los jugadores** cuando funcionen en modo sin conexión para que entiendan que los guardados no se sincronizarán
4. **Proporcione opciones de reintento** cuando se restaure la conectividad de red
5. **Los guardados locales siempre funcionan**: los jugadores pueden seguir jugando independientemente del estado de la red
6. **Supervise las desconexiones**: recuerde que los dispositivos pueden desconectarse cuando otro dispositivo se convierte en el activo

## Comportamiento de la carga en modo conectado

Incluso en modo conectado, las cargas pueden fallar debido a problemas de red o límites de frecuencia. Cuando esto sucede, la devolución de llamada de `XAsyncBlock` no se activa inmediatamente. La operación asincrónica se pausa mientras el sistema espera la respuesta del usuario a través de la [máquina de estados de devoluciones de llamada de la interfaz de usuario](https://docs.xbox.com/es/services/playfab/player-progression/game-saves/ui-callbacks.md#how-the-state-machine-works):

1. La `PFGameSaveFilesUiSyncFailedCallback` se activa con los detalles del error.
2. La devolución de llamada de `XAsyncBlock` aún no se activa. La operación se pausa mientras el sistema espera una respuesta.
3. Si el usuario selecciona `Retry`, la carga se reintenta. Si vuelve a fallar, la devolución de llamada se activa de nuevo y el usuario debe responder otra vez.
4. Si el usuario selecciona `Cancel`, la devolución de llamada de `XAsyncBlock` se activa con `E_PF_GAMESAVE_USER_CANCELLED`.
5. Si un reintento se realiza correctamente, la devolución de llamada de `XAsyncBlock` se activa con `S_OK`.

El juego puede llamar de nuevo a `PFGameSaveFilesUploadWithUiAsync()` más adelante cuando se restaure la red.

> [!NOTE]
>
> **En proceso, no ofrezca `Use Offline` en el mensaje de error de sincronización mientras se ejecuta una carga.** La carga activa la misma `PFGameSaveFilesUiSyncFailedCallback` que la sincronización inicial, por lo que el SDK no restringe las opciones. Sin embargo, si su juego responde con `UseOffline` a un error de carga, la carga falla con `E_ABORT` (y las compilaciones de depuración generan una aserción). Ofrezca allí solo `Retry` y `Cancel`.

## Cuándo una carga deja la sesión sin conexión

Normalmente, una carga no cambia el modo de conexión, pero puede terminar con la sesión sin conexión en los siguientes casos. En cada uno de ellos, la carga se completa con `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD` y `PFGameSaveFilesIsConnectedToCloud()` devuelve `false` a continuación.

* **La sesión ya estaba sin conexión.** La carga no se ejecuta y se completa con `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD`, aunque se haya restaurado la red.
* **La nube tiene un guardado más reciente.** Si el servicio informa de que se confirmó un guardado más reciente desde otro dispositivo cuando finaliza la carga, Game Saves pone la sesión sin conexión, activa la devolución de llamada de cambio de dispositivo activo y completa la carga con `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD`.
* **El jugador elige `Use Offline` en el mensaje de rebloqueo.** Si una carga anterior confirmó sus datos pero falló después, la siguiente carga primero tiene que volver a adquirir el bloqueo de guardado. Un mensaje de error de sincronización durante ese paso se puede responder con `UseOffline`, lo que deja la sesión sin conexión y completa la carga con `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD`.

Para volver a conectarse, llame de nuevo a `PFGameSaveFilesAddUserWithUiAsync()`.

## Cancelación de una carga

Una carga se puede cancelar de la misma manera que la sincronización inicial: el usuario puede seleccionar `Cancel` en la interfaz de usuario de **progreso** mientras la carga está en curso, o seleccionar `Cancel` en el mensaje de **error de sincronización** si la carga encontró un error. En cualquier caso, `PFGameSaveFilesUploadWithUiAsync()` se completa con `E_PF_GAMESAVE_USER_CANCELLED` (`0x800704C7`) y el guardado no se carga. Sus resultados finales son **correcto**, **cancelado** o **error** (donde `E_PF_GAMESAVE_DISCONNECTED_FROM_CLOUD` significa que la sesión ahora está sin conexión; consulte [Cuándo una carga deja la sesión sin conexión](#when-an-upload-takes-the-session-offline)). Controle `E_PF_GAMESAVE_USER_CANCELLED` de forma distinta a los demás errores para poder diferenciar "el jugador salió" de "la carga produjo un error". Si su juego cancela la carga por sí mismo con `XAsyncCancel`, se completa con `E_ABORT` en lugar de `E_PF_GAMESAVE_USER_CANCELLED`.


## Related topics

- [Inicio rápido de Game Saves](https://docs.xbox.com/es/services/playfab/player-progression/game-saves/quickstart.md)
- [Preguntas frecuentes sobre el control de errores de Game Saves](https://docs.xbox.com/es/services/playfab/player-progression/game-saves/error-handling-faq.md)
- [Devoluciones de llamada de la interfaz de usuario de Game Saves](https://docs.xbox.com/es/services/playfab/player-progression/game-saves/ui-callbacks.md)
- [Tutoriales y ejemplos de Game Saves](https://docs.xbox.com/es/build/core-features/common/game-save/game-saves-walkthroughs-and-samples.md)
- [Descripción del flujo de sincronización de Game Saves](https://docs.xbox.com/es/build/core-features/common/game-save/game-saves-syncing.md)
