O frame
O que um jogo pode e não pode fazer dentro do player do uloggd, como ele começa e termina, e os parâmetros com que é aberto.
O jogo roda num iframe, numa página do uloggd feita só para aquele jogo. A política da página deixa o frame conter a sua origem e nenhuma outra, e o frame fica coberto até o SDK concluir o handshake.
O sandbox
<iframe
src="https://orbit.example.com/?frame_id=...&instance_id=...&platform=desktop&locale=pt-BR&mode=live&protocol=1"
sandbox="allow-scripts allow-same-origin allow-forms"
allow="autoplay; gamepad; ..."
referrerpolicy="strict-origin"
></iframe>| Token | Quando |
|---|---|
allow-scripts | Sempre. |
allow-same-origin | Sempre. O jogo mantém a própria origem, o que dá a ele armazenamento e dá ao uloggd uma origem para conferir. É seguro porque essa origem nunca é a do uloggd. |
allow-forms | Sempre, para que eventos submit disparem. |
allow-pointer-lock | Só quando o lançamento declara a capacidade pointer-lock. |
Nunca concedidos: popups, navegação da página de cima, diálogos modais, downloads, a Storage Access API, trava de orientação e apresentação. Na prática:
window.open, links comtarget="_blank"etop.locationfalham. Na v1 um jogo não consegue abrir link nenhum; a página da loja traz os links da sua política de privacidade, dos termos e do suporte.alert,confirmepromptnão fazem nada. Desenhe os seus próprios diálogos.
Permissões
O atributo allow delega autoplay e gamepad. Todo o resto é negado, pelo
atributo e pela Permissions-Policy da página do player: câmera, microfone,
geolocalização, pagamentos, USB, serial, HID, Bluetooth, captura de tela,
WebAuthn e as outras APIs de credenciais, fontes locais, gerenciamento de
janelas, detecção de ociosidade, picture-in-picture, as APIs do privacy
sandbox e acesso à rede local. O Firefox ignora o cabeçalho
Permissions-Policy.
O acesso à rede local é negado em todas as páginas do uloggd menos uma: a
página da sua
URL de desenvolvimento, e só
quando essa URL está na sua própria máquina. Ali, a política da página e o
allow do frame deixam o frame alcançar aquela origem local, e mais nada da
sua rede. O navegador ainda pode perguntar a você antes.
A tela cheia é da página do uloggd, e o jogo a pede pelo SDK (abaixo).
A primeira requisição à sua URL de entrada leva Referer: https://uloggd.com/,
nunca o caminho da página.
Armazenamento e cookies
- O armazenamento é particionado pelo site de cima. localStorage, IndexedDB, a Cache API e os service workers dentro do uloggd são separados dos do mesmo jogo aberto no seu próprio site, e um jogador que limpa os dados do site do uloggd limpa esses também. Guarde no seu servidor o que importa.
- Os cookies não são particionados de forma confiável. O Safari bloqueia
cookies de terceiros e o Firefox os separa por site, mas o Chrome ainda
envia os seus cookies não particionados, e os de todo terceiro que o jogo
incorpora. Não construa sessões em cookies: depois que o seu servidor
verificar um token de identidade, dê ao jogo um token seu e mande-o num
cabeçalho
Authorization. Se precisar de um cookie, marque-oSameSite=None; Secure; Partitioned. - Um service worker que você registra mora na partição do uloggd e continua servindo o que guardou aos jogadores que voltam, seja o que for que o seu servidor serve hoje, e as verificações do uloggd não o enxergam. Se usar um, amarre o cache dele ao build.
Um documento, do começo ao fim
- Qualquer navegação do frame tira o jogo da tela: um segundo evento
load, um canal de mensagens fechado ou uma navegação que a política da página bloqueou. O jogador fica sabendo que o jogo reiniciou, com um botão para jogar de novo. Jogos de várias páginas elocation.reload()não são suportados. - A política da página só admite exatamente a sua origem, então o navegador bloqueia um redirecionamento ou um link para qualquer outra.
- Frames que você coloca dentro do jogo herdam o sandbox, mas seguem a sua própria Content-Security-Policy, não a do uloggd. Declare no lançamento todo terceiro que você incorpora.
- Nunca chame
history.back(): de um frame com sandbox, isso pode mover a aba inteira do jogador.
Começar, continuar vivo, fechar
- Handshake.
createArcadeSDKmanda um handshake ao uloggd, que responde com um canal de mensagens privado. O frame fica coberto até lá; depois de 30 segundos, o jogador fica sabendo que o jogo não carregou. Crie o SDK como a primeira coisa que a página faz, antes de baixar arquivos grandes, para o jogador ver a sua própria tela de carregamento. - Sinal de vida. O uloggd manda um ping ao jogo a cada segundo, e o SDK responde. Depois de 2 segundos sem resposta, o frame é coberto de novo e o jogador fica sabendo que o jogo não está respondendo; a próxima resposta descobre o frame. Deixe a thread principal livre: divida trabalhos longos ou leve-os para um worker.
- Aba escondida. Depois de 5 minutos escondida (15 com a capacidade
background-audio), o uloggd mandaCLOSINGe tira o frame. - Fechar. Quando o jogador aperta Fechar, o jogo recebe
CLOSINGe até 1 segundo para salvar antes de o frame sair. Salve ao longo do jogo em vez de contar com esse segundo. - Suspensão. Se o uloggd suspende o jogo, novas aberturas são recusadas na hora, e os frames em execução são fechados com o código 4010 em até 60 segundos.
Tela cheia e trava do cursor
- O frame não consegue entrar em tela cheia sozinho. Chame
arcade.commands.requestFullscreen()a partir de um clique ou de uma tecla: o uloggd põe o próprio contêiner em tela cheia, com a barra dele ainda visível, ou ocupa a tela inteira num iPhone. Sem um gesto recente, a chamada falha comrequires_gesture. - Declare a capacidade
pointer-lockpara usarrequestPointerLock(). O uloggd não enxerga uma trava que o seu jogo segura, então, num lançamento com ela, o diálogo de consentimento nunca abre sozinho: quandoauthorizepede, a barra do jogador mostra o pedido com um botão Responder e avisa que Esc libera o cursor, e o diálogo abre a partir desse clique. Sem a capacidade,authorizeabre o diálogo direto.
Parâmetros de abertura
O uloggd acrescenta a própria query à sua URL de entrada:
?frame_id=Q1r9...&instance_id=0b7e...&platform=desktop&locale=pt-BR&mode=live&protocol=1| Parâmetro | Valor |
|---|---|
frame_id | 22 caracteres base64url, que o SDK usa no handshake. |
instance_id | Um uuid desta partida. |
platform | desktop ou mobile. |
locale | pt-BR, en ou es. |
mode | live, ou test quando você abre um lançamento seu no modo de teste ou a sua URL de desenvolvimento. Quem revisa joga em live. |
protocol | 1. |
Nada nela identifica o jogador, então os seus logs e análises podem guardá-la.
O SDK a lê por você, e os mesmos valores chegam em context quando ready()
resolve.
Limites que você precisa conhecer
- A revisão atesta um momento, não um build. Verificações diárias, novas revisões, denúncias de jogadores e a suspensão são como o uloggd continua acompanhando um jogo depois da aprovação.
- Os endereços IP dos jogadores chegam aos seus servidores e a todo terceiro que o jogo carrega.
- Onde o navegador não dá a frames de outro site um processo próprio (Safari, Firefox para Android e Chrome para Android), um jogo que trava a thread principal congela também a página do uloggd em volta dele, até ceder.
- Nenhum cabeçalho impede uma escrita na área de transferência depois de um gesto. Pedir que o jogador cole ou execute alguma coisa é contra as regras (veja Política de revisão).