Como uma ação roda
O que a Vovó faz com uma ação a partir do momento em que uma cena a mostra: o que ela garante, e com o que uma ação não pode contar. Para quem escreve ações para entregar ou vender; como escrever uma está em Ações.
Uma página só dela
Cada ação é um documento próprio, num quadro que a página da cena dá a ela: o HTML dela, com o style.css e o script.js escritos dentro, o script por último, então ele roda quando o HTML já está lá. Uma ação quebrada não derruba as outras. Uma cena mostra as ações umas sobre as outras, na ordem dela, a primeira embaixo.
O quadro não recebe clique nem tecla: um overlay é para ser visto, nunca apertado. O que quem opera a live faz, faz no pad, no painel da ação ou em Personalizar, e chega à ação como um evento.
Uma ação só ouve um evento enquanto uma página aberta a mostra, e só no perfil ativo. Sem nenhuma página aberta, nada conta os follows.
Sem rede, nada guardado no navegador
Uma ação alcança os próprios arquivos e o que a Vovó serve a ela, e mais nada. Imagens, sons, vídeos e fontes vêm dos arquivos da ação, pelo nome, ou de um endereço que um evento trouxe (um emote, uma capa, um arquivo escolhido em Personalizar), nunca da internet. O código e os estilos dela são só o script.js e o style.css: nenhum script ou folha de estilo de um arquivo ou de fora, nada de eval, nada de worker. fetch, XMLHttpRequest e WebSocket são recusados, até para os arquivos da própria ação, então os dados de que ela precisa vão no script. O armazenamento do navegador (localStorage, cookies, IndexedDB) não existe ali: o que uma ação guarda, guarda em vovo.state.
O que ela precisa de fora, pede à Vovó, dentro das permissões que declara: uma linha no chat, um webhook pelo nome, um som do pad, um clipe no player oficial.
Toda página aberta roda a ação
A mesma ação roda onde quer que a cena dela esteja aberta: no OBS, na janela de prévia da cena, numa aba do navegador, em duas fontes ao mesmo tempo. Cada cópia recebe os mesmos eventos e desenha o mesmo. Por isso uma página só desenha e toca, e o que precisa acontecer uma vez é pedido à Vovó, que o faz uma vez para as páginas que pedem tratando o mesmo evento: uma linha no chat, um sorteio, uma fala, um webhook, um som do pad, uma fonte no OBS, um evento próprio da ação.
A Vovó distingue a chamada de uma página da de outra pelo evento que está sendo tratado. Uma chamada feita depois que o ouvinte terminou (depois de um await, quando uma animação acaba, num timer) diz a qual evento responde com { event: e }, o objeto que o ouvinte recebeu; sem isso, a Vovó não consegue distinguir uma segunda página de uma segunda vez.
vovo.on("raid", async (e) =>
{
const gift = await vovo.draw(["a hug", "a song", "a dance"]);
vovo.show("raid", { user: e.user, gift: gift.value });
vovo.chat.send(e.user + " gets " + gift.value + "!", { event: e });
});
O que uma página começa sozinha não tem evento por trás: um setInterval da ação roda em todas as páginas, e o que ela faz ao carregar também. A Vovó então só pode se guiar pelo que é pedido (a mesma linha no chat, a mesma fala, o mesmo webhook ou evento próprio em 5 segundos é um só), então o que conta, ou precisa acontecer uma vez, fica no gatilho timer, que é do app e um só para todas as páginas.
Estado, nunca replay
O vovo.state é guardado pela Vovó, não pela página. Uma página que carrega (o OBS abrindo, uma fonte atualizada, o pânico acabando, a Vovó aberta de novo) tem ele inteiro antes de o script rodar, e uma chave definida numa página chega às outras na hora, sem aviso, já que elas trataram o mesmo evento. Eventos nunca são tocados de novo: uma página que não estava lá quando veio uma raid não fica sabendo dela depois. Por isso uma ação guarda no estado tudo o que precisa mostrar de novo (a contagem de uma meta, os nomes de um sorteio, quando uma contagem regressiva acaba) e desenha a partir dele ao carregar.
function draw()
{
document.getElementById("count").textContent = vovo.state.count || 0;
}
vovo.on("follow", () =>
{
vovo.state.count = (vovo.state.count || 0) + 1;
draw();
});
draw();
- Defina a chave de novo quando o que ela guarda muda:
vovo.state.names = names.concat([user]). Uma lista ou um objeto alterado no lugar (push) não é salvo. - Mude o estado no próprio ouvinte, antes de qualquer
await: toda página então parte do mesmo estado e chega ao mesmo. Depois de umawaitoutra página pode já ter escrito, então escreva o que não depende do que está lá (o nome de um vencedor, um horário), nunca um a mais do que ele tem. - Uma chave guarda no máximo 64 KB, em JSON, e o nome dela 64 caracteres.
O que é atual, e o que é leitura contínua
Quatro eventos são um valor tanto quanto um momento: obs.scene, media.track, twitch.viewers e screen.shared. Uma ação que carrega recebe na hora o mais recente de cada um que ela ouve, como se tivesse acabado de acontecer, então mostra a música que toca sem esperar a próxima. Ele vem de novo a cada carregamento, em toda página, sem evento por trás: desenhe a partir dele, e não responda a ele com o que deve acontecer uma vez.
audio.level, screen.color, input.move e speech.text são leituras, até 60 por segundo: entregues e esquecidas, lidas só enquanto uma página aberta mostra uma ação que as ouve. Mantenha os ouvintes delas leves, e deixe o CSS fazer o movimento.
Carregar, recarregar e o pânico
Uma página pode carregar a qualquer momento, e mais de uma vez: o OBS inicia uma fonte quando a cena dela aparece, pode desligá-la enquanto está escondida e atualizá-la quando volta a aparecer, e a Vovó carrega uma ação de novo quando o código ou os arquivos dela mudam. O pânico limpa todas as cenas de uma vez e carrega as ações de novo, o que para o que elas estavam fazendo; quando acaba, elas carregam mais uma vez e partem do estado. Nada chega a uma ação durante o pânico, e nada do que veio nesse meio-tempo é tocado depois; o valor de um controle fica guardado, porque é estado.
Então uma ação volta certa só com o estado, a qualquer momento, sem contar com nada que a página anterior deixou pela metade.
O palco
Uma ação desenha num palco em pixels de CSS cujo lado curto é 1080: 1920 × 1080 para uma live em 16:9, em qualquer resolução (uma fonte em 4K desenha nítido no dobro do tamanho), 1080 × 1920 para uma vertical, outro formato para uma tela de outro formato. O documento dela tem o tamanho do palco e é transparente, então 100vw por 100vh é a imagem inteira, e o que ela não desenha mostra o jogo. Uma ação feita para as lives de outras pessoas não presume o formato: posicione as coisas a partir das bordas e em porcentagens, e use @media (orientation: portrait) para uma live vertical.
O navegador do OBS
O OBS mostra as cenas num navegador próprio, mais antigo que o do editor e da janela de prévia da Vovó (Chromium 127 no OBS 32), que pode rodar sem a ajuda da placa de vídeo. Confira um recurso novo de CSS ou JavaScript contra essa versão antes de contar com ele, e veja a ação no próprio OBS antes de entregá-la. O som toca ali na hora, sem clique, e vai para a live: nada que seja só para quem faz a live cabe numa ação.
Uma página não tem console no OBS. Os erros que a ação não trata, e o que a Vovó tem a dizer sobre as chamadas dela, chegam ao console da Vovó com o nome da ação e a linha; o console.log não. Para isso, abra o endereço da prévia num navegador (o vovo dev o mostra) e use as ferramentas de desenvolvedor dele.
Ritmos e limites
- Chat: uma linha de 500 caracteres; 20 linhas em 30 segundos para todas as ações, uma por segundo para cada uma.
- Webhooks: 16 KB de JSON; 30 por minuto, um por segundo para cada ação.
- Clipes e vídeos: 3 esperando aprovação para cada ação.
- Câmeras: 4 aparecendo ao mesmo tempo, e 4 configurações de câmera para cada ação.
- Uma chamada de voz: no máximo 300 segundos.
- Um botão mostrado em andamento: no máximo 15 minutos.
- Estado: 64 KB por chave.
- Um pacote: 200 arquivos, 32 MB cada um e 128 MB no total;
index.html,style.cssescript.jscom 2 MB cada.
Uma chamada além do ritmo fica de fora, nunca em fila: a promise dela rejeita, dizendo por quê.
Antes de entregar
- Recarregue a cena no meio de tudo o que ela faz: ela volta certa, a partir do estado.
- Abra a cena duas vezes, no OBS e na janela de prévia, e dispare cada gatilho: uma linha no chat, um som, uma contagem.
- Ligue e desligue o pânico enquanto ela mostra alguma coisa.
- Teste num perfil vertical, e no próprio OBS.
- Peça só as permissões que ela usa, e diga o que ela é em Comportamento: o autor, o site e uma linha.
- Dê a ela um id, e uma versão maior a cada vez que a entregar, para a atualização encontrar a ação que substitui e dizer qual versão traz.
- Diga sob qual licença você a entrega, com o texto inteiro quando os termos forem seus.