Como a máquina de estados funciona
O Game Saves usa uma máquina de estados interna para coordenar os retornos de chamada de interface com o ciclo de vida da operação assíncrona. Quando um retorno de chamada de interface é acionado, a operação assíncrona é pausada. O retorno de chamada deXAsyncBlock não é acionado até que o retorno de chamada seja resolvido. A máquina de estados não avança até que o jogo chame a API de resposta correspondente ou a operação assíncrona seja cancelada.
Isso significa que:
- Cada tipo de retorno de chamada tem uma API de resposta correspondente. Chame a API de resposta para informar ao sistema o que fazer em seguida.
- As APIs de resposta podem ser chamadas dentro ou fora da função de retorno de chamada.
- Se uma ação de resposta for
Retry, a operação será repetida e poderá acionar o mesmo retorno de chamada novamente. - O retorno de chamada de
XAsyncBlocksó é acionado quando a operação atinge um estado final: êxito, cancelamento ou fallback offline.
PFGameSaveFilesUiSyncFailedCallbacké acionado com o erro.- O retorno de chamada de
XAsyncBlockainda não é acionado. A máquina de estados aguarda uma resposta. - Se o usuário selecionar
Retrye a nova tentativa também falhar, o retorno de chamada de falha de sincronização será acionado novamente. - Se o usuário selecionar
Cancel, o retorno de chamada deXAsyncBlockserá acionado comE_PF_GAMESAVE_USER_CANCELLED. - Se uma nova tentativa tiver êxito, o retorno de chamada de
XAsyncBlockserá acionado comS_OK.
Quando os retornos de chamada são acionados
Os retornos de chamada de interface só são acionados durante duas operações assíncronas:Registrando retornos de chamada
Registre todos os retornos de chamada antes de chamarPFGameSaveFilesAddUserWithUiAsync ou PFGameSaveFilesUploadWithUiAsync:
Referência de retornos de chamada
Progresso
Informa o progresso do upload ou download. UsePFGameSaveFilesUiProgressGetProgress dentro do retorno de chamada para obter o PFGameSaveFilesSyncState atual, os bytes concluídos e o total de bytes.
Retorno de chamada: PFGameSaveFilesUiProgressCallback
API de resposta: PFGameSaveFilesSetUiProgressResponse
O retorno de chamada de progresso não exige uma resposta para continuar. A operação continua avançando por conta própria. Chame a API de resposta somente se o usuário quiser cancelar.
Estados de sincronização
A enumeraçãoPFGameSaveFilesSyncState indica em qual fase a operação está:
Falha de sincronização
É acionado quando uma operação de sincronização falha, por exemplo, devido a problemas de rede ou limites de taxa. Retorno de chamada:PFGameSaveFilesUiSyncFailedCallback
Parâmetros: recebe PFGameSaveFilesSyncState (a fase que falhou) e HRESULT (o código de erro).
API de resposta: PFGameSaveFilesSetUiSyncFailedResponse
Para obter mais detalhes sobre o comportamento do modo offline, consulte Modo offline do Game Saves.
Contenção de dispositivo ativo
É acionado durantePFGameSaveFilesAddUserWithUiAsync quando outro dispositivo já é o dispositivo ativo para este usuário. O retorno de chamada recebe structs PFGameSaveDescriptor para os dados de salvamento local e remoto, que incluem nomes de dispositivos, carimbos de data/hora e tamanhos de salvamento que você pode exibir para ajudar o usuário a decidir.
Retorno de chamada: PFGameSaveFilesUiActiveDeviceContentionCallback
API de resposta: PFGameSaveFilesSetUiActiveDeviceContentionResponse
Para obter mais detalhes sobre o comportamento do dispositivo ativo, consulte Alterações de dispositivo ativo do Game Saves.
Conflito
É acionado durantePFGameSaveFilesAddUserWithUiAsync quando os dados de salvamento local e na nuvem divergiram. O retorno de chamada recebe structs PFGameSaveDescriptor para os dados de salvamento local e remoto.
Retorno de chamada: PFGameSaveFilesUiConflictCallback
API de resposta: PFGameSaveFilesSetUiConflictResponse
A resolução de conflitos se aplica ao salvamento inteiro, não a arquivos ou pastas individuais. Para obter detalhes sobre como os conflitos são detectados no nível da unidade atômica e resolvidos globalmente, consulte Conflitos do Game Saves.
Armazenamento insuficiente
É acionado durantePFGameSaveFilesAddUserWithUiAsync quando o dispositivo local não tem espaço em disco suficiente para baixar os dados de salvamento da nuvem. O retorno de chamada recebe requiredBytes, que indica quanto espaço é necessário.
Retorno de chamada: PFGameSaveFilesUiOutOfStorageCallback
API de resposta: PFGameSaveFilesSetUiOutOfStorageResponse
No processo versus fora do processo (interface do sistema)
O local em que o Game Saves é executado depende da plataforma, e isso afeta como os eventos de interface são tratados:- Fora do processo (XBOX e Windows): no XBOX e no Windows, o Game Saves sempre é executado fora do processo. A plataforma (Connected Storage / GRTS) executa a sincronização e fornece caixas de diálogo internas da interface do sistema para falhas de sincronização, conflitos, contenção de dispositivo ativo e armazenamento insuficiente. O jogador interage diretamente com essas caixas de diálogo, e a plataforma converte o resultado nos mesmos códigos de conclusão assíncrona que seu jogo recebe no processo. Você ainda pode registrar retornos de chamada para substituir a interface interna.
- No processo (outras plataformas, como o Steam Deck): onde o serviço da plataforma não está disponível, seu jogo hospeda o mecanismo de sincronização do Game Saves e trata os eventos de interface por meio dos retornos de chamada descritos acima. Seu jogo controla totalmente a máquina de estados com as APIs de resposta.
O cancelamento é sempre um resultado possível
Independentemente do caminho, todo fluxo de interface pode terminar com o usuário desistindo sem uma sincronização bem-sucedida, portanto seu jogo deve sempre tratar um cancelamento final:
A única ação de “desistir” que ainda permite que o jogador continue é Use Offline no aviso de falha de sincronização (um resultado de êxito). Todos os outros cancelamentos são finais e não deixam uma pasta de salvamento. Trate-os como não permitir jogar. Consulte Modo offline do Game Saves.
Na interface interna do sistema (fora do processo), essas opções aparecem com a terminologia da plataforma. Por exemplo, a caixa de diálogo de falha de sincronização oferece “Try again” / “Play offline”, e a caixa de diálogo de contenção oferece “Stop sync & continue” / “Quit game”. “Play offline” corresponde ao modo offline (
S_OK, não conectado); “Quit game” corresponde a E_PF_GAMESAVE_USER_CANCELLED.
Cancelar um aviso de conflito é final em ambos os caminhos. Ele é concluído com E_PF_GAMESAVE_USER_CANCELLED e não passa para um aviso de falha de sincronização.
Para uma interface multiplataforma personalizada (por exemplo, igual à sua implementação para o Steam Deck), registre retornos de chamada em todos os lugares e valide os fluxos fora do processo no hardware de destino. Independentemente do caminho, condicione o jogo ao resultado da conclusão: S_OK + conectado → jogar online; S_OK + não conectado → jogar offline (avise o jogador); cancelamento/falha sem pasta → bloquear o jogo.
Requisitos de plataforma
Para obter detalhes de implementação para o Steam Deck, consulte o Guia de implementação para o Steam Deck.
