Azioni
Un'azione è un pezzo di HTML, CSS e JavaScript che compare nell'overlay. Ognuna gira per conto suo, senza rete e senza accesso alle password: ciò che le serve da fuori, lo chiede a Vovó.
Per iniziare
"Nuova azione" ne crea una vuota o una da un esempio: avvisi e chat, cosa sta suonando, conto alla rovescia, obiettivo, estrazione, contatore di morti e altri. L'esempio diventa una tua copia, da cambiare liberamente.
In tre gradini
Solo HTML: un <template> che compare quando succede l'evento, con i campi dell'evento tra graffe.
<template data-on="follow" data-seconds="5">
<div class="avviso">{user} ha iniziato a seguire!</div>
</template>
Un po' di JavaScript: vovo.on("raid", (e) => { ... }) e vovo.show("nome", e). E l'API intera per il resto.
Attivatori
Un'azione riceve solo gli eventi nella sua lista di attivatori, nell'editor. Un pulsante del pad è l'attivatore button.
Condizioni
L'icona dei cursori accanto a un attivatore apre le sue condizioni: l'attivatore scatta solo quando valgono tutte. Un raid di 50 o più, un messaggio che inizia con !partecipo, il premio giusto.
Timer e scorciatoia
L'attivatore Timer scatta ogni tanto: la sua condizione every dice quanti secondi tra uno e l'altro (senza, ogni minuto). L'attivatore Scorciatoia scatta con una combinazione di tasti, la sua condizione keys, anche con il gioco in primo piano.
Controlli
Nella scheda Controlli dell'editor, l'azione dichiara cosa il pad può cambiare mentre gira: attivo o disattivo, una scelta fra opzioni, un contatore (con un obiettivo, se vuoi) o un testo. Ognuno è conservato in vovo.state, sotto la chiave che mostra la finestra, e ogni cambio arriva come evento control, senza bisogno di attivatore. Gli esempi Avvisi e chat, Obiettivo follower e Contatore di morti mostrano come.
vovo.on("control", () =>
{
document.getElementById("chat").hidden = !vovo.state.chat;
});
Personalizza
Un'azione può lasciare che chi la usa la cambi senza aprire il suo codice: il suo colore, la misura del testo, il carattere, un lato dello schermo, un'immagine o un suono tuoi. La tavolozza accanto al nome del suo pannello, o nella sua riga dell'elenco delle azioni, apre Personalizza: una riga per ogni impostazione, con ciò che contiene, il suo predefinito quando è diverso, e la via per tornarci. Un cambio si vede subito nelle scene che mostrano l'azione, senza riavviarla, e ognuno è una versione che il registro annulla. Si sceglie solo su questo computer: un telefono o un'altra Vovó non lo vedono mai. Il pacchetto dell'azione porta i predefiniti, mai le tue scelte; uno che prende il posto dell'azione tiene le scelte per cui ha ancora spazio.
Chi scrive l'azione le dichiara nella scheda Personalizza dell'editor, o sotto settings nel suo action.json: ognuna con un tipo (un colore, un numero da un minimo a un massimo, attivo o disattivo, una scelta, un testo, un'immagine, un suono o un video, un carattere), un nome, una chiave e un predefinito. L'azione le legge in vovo.settings, e sente l'evento settings quando una cambia; il suo CSS le legge come var(--vovo-chiave) (un numero con la sua unità, come 32px), e un attivo o disattivo o una scelta come attributo della pagina, per i selettori:
.chat
{
color: var(--vovo-color);
font-size: var(--vovo-size);
font-family: var(--vovo-font), sans-serif;
}
html[data-vovo-side="Right"] .chat
{
right: 40px;
}
Un'impostazione può essere anche una videocamera: chi usa l'azione sceglie una delle videocamere del proprio computer in Personalizza, e l'azione la mostra dove la colloca (vovo.camera.place, con il permesso camera.show). Un'azione arriva senza videocamera e non sa mai quale è stata scelta, né ne vede le immagini: vovo.settings dice solo se ne è stata scelta una, come true o false. L'esempio "Videocamera" è una videocamera in una cornice.
Pannelli
Ciò che un pulsante non può contenere (i nomi di un'estrazione, gli obiettivi con i loro numeri, una pressione che dovrebbe chiedere due volte) va nel pannello dell'azione: panel nel suo manifesto, mostrato in Pannelli, nella barra laterale (la sua icona sul bordo destro della finestra, presente finché qualche azione ha un pannello). Un pannello è un elenco di pezzi che Vovó disegna: heading e note, un control per la sua chiave, un button (con confirm, chiede prima "Sicuro?"), un form con fino a quattro campi, e una list letta da vovo.state (la sua key, e un path al suo interno), ogni riga con fino a tre pulsanti.
Un'azione con molto da offrire lo divide in due modi. { "kind": "panel", "label": "Estrazione", "icon": "gift" } inizia un altro pannello: una voce sua in Pannelli, con il suo nome e la sua icona (una delle icone di Vovó per nome, o un'emoji; senza, l'icona del primo pulsante del pad dell'azione). I pezzi che seguono, fino al successivo, sono suoi, e quelli prima del primo compaiono in cima a ognuno. Dentro un pannello, tab inizia una sezione (fino a dodici): i pezzi che seguono, fino alla scheda successiva, si vedono mentre è scelta, e quelli prima della prima scheda si vedono in tutte. Così un'estrazione è un pannello con una sezione per l'estrazione, un'altra per chi partecipa e un'altra per chi ha vinto, invece di una pagina lunga. Un'azione che non dichiara nessun { "kind": "panel" } ne ha uno, con il suo nome.
L'intestazione di Pannelli nomina quello davanti; premendola li elenca tutti, ognuno dicendo se una scena aperta lo mostra e di chi è, con una ricerca quando sono più di otto. Le sezioni compaiono come schede sotto l'intestazione: quelle che ci stanno, e il resto sotto "Altro". Un titolo apre un gruppo: i pezzi che seguono condividono una scheda, i pulsanti consecutivi condividono una riga, un elenco è una scheda sua con il conteggio, e una nota sta tra le schede. Un modulo di un campo si scrive nel pannello stesso, con Invio per mandarlo, e così un controllo di testo; un modulo di più campi apre una finestrella. Un contatore con obiettivo (max) mostra a che punto è.
Un elenco può avere migliaia di righe. Uno con più di otto ha una ricerca sua, che resta in vista mentre l'elenco scorre. Quando è l'ultimo pezzo della sua sezione si vede intero; con pezzi dopo, mostra le prime otto righe e la via verso tutte, quindi metti un elenco lungo in fondo, o in una sezione sua.
Ciò che si fa lì arriva come evento panel, senza bisogno di attivatore: il suo name, i values di un modulo, e l'item e l'index di una riga. I nomi sono dell'azione, qualunque sia il pannello che li mostra. Un'azione sente il suo pannello solo mentre una scena aperta la mostra, in OBS o nella finestra di anteprima: senza nessuna, il pannello lo dice, i suoi pulsanti aspettano sbiaditi e "Apri anteprima" apre quella della scena; i suoi controlli ed elenchi si vedono comunque, perché Vovó li conserva. Lo usa solo chi gestisce la diretta, qui o su un dispositivo a cui hai permesso i pannelli, e nulla arriva all'azione durante il panico.
Scrivere in chat
Con il permesso chat.send, vovo.chat.send("...") scrive nella chat della diretta come te. Vovó tiene il ritmo (20 righe in 30 secondi) e scrive una volta sola ciò che chiedono due pagine che mostrano l'azione; due pressioni di un pulsante sono due righe. L'esempio Promemoria in chat mostra come. Con { as: "persona" }, la riga passa invece dall'account Twitch proprio della persona (Integrazioni, sotto Twitch): ciò che la persona dice e che non è una sua risposta, come una riga che qualcuno scrive perché la dica. Finché quell'account non è connesso, non viene scritto nulla, e nulla a nome tuo al suo posto.
Vovó distingue la chiamata di una pagina da quella di un'altra in base all'evento che l'azione stava gestendo quando ha chiamato. Una chiamata fatta dopo, dopo un await o in un timer, dice a quale evento risponde con { event: e }, dove e è ciò che ha ricevuto la tua funzione: vovo.chat.send("Benvenuti!", { event: e }). Lo stesso vale per vovo.emit, vovo.pad.play, vovo.webhook.send, vovo.draw, vovo.media.play e le chiamate a OBS. Senza, due pagine scriverebbero la riga due volte, e il link di un moderatore aspetterebbe nella campanella.
Il microfono, lo schermo e come ti muovi
Un'azione può seguire quanto è forte il tuo microfono (audio.level), il colore dello schermo (screen.color) e come ti muovi in un gioco (input.move): quanto ha girato la telecamera, dove cammini e se salti, dal mouse, W, A, S e D o le frecce, e un controller, così una scena ondeggia con la telecamera. Gli esempi "Bagliore dello schermo" e "Ondeggio della camera" mostrano come. Vovó legge ciascuno solo mentre un overlay aperto mostra un'azione che lo aspetta, e la barra di stato mostra la sua icona al centro finché lo fa, con i nomi delle azioni nel suggerimento. Della tastiera legge solo i tasti di movimento, come una direzione, mai quale tasto, e non mentre la finestra di Vovó è in primo piano, dove ciò che scrivi farebbe ondeggiare la scena; il mouse e il controller la muovono comunque, a meno che "Metti in pausa il movimento con Vovó in primo piano" non sia attivo (Impostazioni, Generale). Il suono non lascia mai il computer, solo quanto è forte.
Clip e video
Con il permesso media.play, vovo.media.play(link) mostra una clip di Twitch, un video di Twitch o un video di YouTube nel suo player ufficiale, dove l'ha messo vovo.media.place(elemento), con il suo audio. Un'azione che solo l'operatore avvia lo riproduce subito; qualunque altra, che qualcuno in chat può aver avviato, aspetta nella campanella finché tu (o un dispositivo autorizzato ad approvare) non lo lasci passare. Il player non sa quando finisce una clip: indica { seconds: 60 }, o chiama vovo.media.stop(). L'esempio Clip su una TV accetta !clip e un link dai moderatori.
I tuoi moderatori sono le persone a cui affidi la chat: in Integrazioni, sotto Twitch, "I link dei moderatori partono subito" lascia che un link incollato da uno di loro (o da te) vada in onda senza aspettare, quando l'azione lo mostra per il suo messaggio. Disattivato finché non lo attivi; il link di chiunque altro aspetta ancora.
Chiamate vocali
Con il permesso call, un'azione può metterti al telefono con un modello di IA, in onda: parli al microfono, risponde ad alta voce, e la diretta sente entrambi. vovo.call.start({ instructions, voice }) apre la chiamata con la tua chiave OpenAI (Integrazioni, IA); instructions è chi è il modello e come parla. La chiamata si apre in silenzio, così l'azione può prima far squillare un telefono; vovo.call.answer() apre il microfono e fa parlare per primo il modello, vovo.call.tell() gli dice qualcosa durante la chiamata, e vovo.call.end() riattacca. call.started, call.answered, call.text (ciò che si dice, per iscritto) e call.ended dicono cosa succede.
Ciò che dice il modello si sente mentre lo dice, senza che nessuno lo legga prima, quindi una chiamata parte solo da qualcosa che hai fatto a mano: un pulsante del pad, una scorciatoia, un controllo o il pannello dell'azione. Chat, premi e webhook non ne avviano nessuna. OpenAI la fa pagare al secondo dall'apertura, quindi ogni chiamata ha un tetto (cinque minuti al massimo). Mentre ce n'è una, un telefono rosso compare nella barra di stato: premilo, o il panico, per riattaccare subito. Usa le cuffie, o il modello si sente dalle tue casse.
Webhook
Con il permesso webhook, vovo.webhook.send("nome", { ... }) chiede a Vovó di inviare il JSON a un webhook configurato in Impostazioni, Webhook: quello di un canale Discord, un'automazione, uno strumento della tua rete. L'indirizzo resta nella cassaforte di questo computer, fuori dai backup e dai pacchetti, e l'azione conosce solo il nome. L'esempio Annuncia su Discord mostra come.
Webhook in entrata
Nel senso opposto, un servizio su internet avvisa Vovó: in Impostazioni, Webhook, crea un webhook in entrata, copia il suo indirizzo e incollalo nel servizio (una pagina di donazioni, un negozio, uno script). Ogni chiamata arriva alle azioni come evento webhook, con hook (il nome) e data (ciò che è stato inviato). Usa l'attivatore webhook con la condizione che hook sia il nome. Ogni webhook ha un indirizzo suo: dallo solo al servizio che lo chiama. Il relay tiene una chiamata sigillata per questo computer un giorno al massimo, quindi una fatta con Vovó chiusa arriva quando si apre. Ciò che arriva è testo di qualcun altro: le azioni lo mostrano solo come testo.
Da un programma di questo computer
Un programma di questo computer può dire a un'azione ciò che sa: uno script che legge il log di un gioco, uno strumento che tiene il punteggio di un torneo, una macro. L'azione ascolta un evento con un nome suo, tra gli attivatori del suo action.json (come in una cartella seguita da vovo dev):
"triggers": ["score"]
e lo sente come qualsiasi altro:
vovo.on("score", (e) =>
{
document.getElementById("home").textContent = e.home;
document.getElementById("away").textContent = e.away;
});
Il programma glielo dice con vovo emit, il nome e i campi:
vovo emit score home=2 away=1
Un numero, true e false arrivano così come sono, tutto il resto come testo. Liste e oggetti vanno interi come JSON, ed è così che lo chiama un programma:
import json, subprocess
subprocess.run(["vovo", "emit", "score", "--fields", json.dumps({"home": 2, "away": 1})])
Dice quali azioni l'hanno sentito, e fallisce (codice di uscita 1, con il motivo) quando nessuna lo sentirebbe: nessuna azione ha quel nome tra i suoi attivatori, le loro condizioni non valgono, o nessuna pagina aperta le mostra. Va dove andrebbe il vovo.emit di un'azione, mai durante il panico, 30 in 10 secondi al massimo, e il registro dice che l'ha avviato la riga di comando. Un'azione solo per l'operatore non lo sente. Ciò che manda un programma è testo di quel programma: l'azione lo mostra solo come testo. Per fingere che sia successo un evento dell'API, come un follow, usa vovo simulate.
Anteprima e Simula
L'editor mostra l'azione dal vivo mentre scrivi, e i pulsanti Simula fanno scattare gli attivatori senza aspettare l'evento vero e muovono i controlli come farebbe il pulsante del pad. Nulla dell'anteprima arriva alla diretta. L'icona nell'angolo del codice o dell'anteprima le dà tutta la finestra; la stessa icona, o Esc, la rimette accanto all'altra.
Screen reader
Gli screen reader non riescono a leggere l'editor del codice. Il pulsante Testo semplice, sopra il codice, mette al suo posto una casella di testo che l'Assistente vocale, NVDA e JAWS leggono intera, per riga, parola e carattere. Parte attivo quando Windows dice che c'è uno screen reader in funzione; Tab passa oltre, quindi indenta con gli spazi.
File
Nella scheda File dell'editor, aggiungi immagini, suoni, video e caratteri. L'azione li usa per nome: <img src="logo.png">. Per far passare uno dei suoi suoni o video attraverso Web Audio (un compressore, un indicatore di livello), chiedilo con crossOrigin = "anonymous" prima di dargli il nome: un'azione gira separata da tutto, e per lei anche i suoi file vengono da fuori, cosa che Web Audio altrimenti sente come silenzio.
Permessi
Ciò che l'azione può chiedere a Vovó sta sotto Comportamento: scrivere in chat, chiamare un webhook, mostrare lo schermo condiviso, mostrare una videocamera, mostrare fonti e attivare filtri in OBS. Disattivato, l'azione non può.
OBS da un'azione
Con il permesso obs.toggle, vovo.obs.source("Scena", "Fonte", true) mostra una fonte in una scena di OBS (false la nasconde; senza, la alterna), e vovo.obs.filter("Fonte", "Filtro", true) fa lo stesso con un filtro. I nomi sono quelli di OBS, a prescindere da maiuscole e accenti; uno che OBS non ha viene detto nella Console, con quello che si intendeva. È tutto ciò che un'azione raggiunge in OBS: non può fermare lo stream né leggerne la chiave.
Solo per l'operatore
Sotto Comportamento, "Solo per chi gestisce la diretta" fa sì che l'azione la avviino solo il pad, le scorciatoie, i timer e i suoi controlli: mai gli spettatori, la chat, i premi, i webhook o l'evento di un'altra azione. Usalo per ciò che nessuno che guarda dovrebbe poter fare, come svuotare la chat o cambiare scena.
Versioni
Ogni salvataggio conserva una versione. "Cronologia" ne riporta indietro una qualsiasi.
Pacchetti
L'icona di esportazione, nell'elenco delle azioni, scrive l'azione in un .zip con il suo codice e i suoi file, da dare a qualcuno. Sotto Comportamento, il suo autore, il suo sito e una riga su cosa fa vanno con lei, così chi la importa sa cos'è e da dove viene. "Importa azione" mostra cosa porta il pacchetto e cosa chiede prima di tenerlo, e apre l'azione nell'editor: leggila prima di usarla. Un pacchetto con il nome di un'azione che hai è molto probabilmente quell'azione in una versione più nuova, quindi propone di prenderne il posto: l'azione tiene le sue scene, i suoi pulsanti e il suo stato, e la versione che aveva resta nella sua cronologia. In un terminale, vovo export e vovo import fanno lo stesso, e vovo import --replace prende il posto dell'azione con il suo nome. Un pacchetto fatto per altri può indicare un id sotto Comportamento, il nome di chi l'ha fatto e quello dell'azione con un punto in mezzo (example.raffle). La sua versione successiva trova allora l'azione che aggiorna anche dopo che l'hai rinominata, e due azioni con lo stesso nome, di autori diversi, non prendono mai il posto l'una dell'altra; anche vovo import --replace si basa su di esso. In ogni caso, l'importazione dice quale versione prende il posto di quale, e lo segnala quando il file è la stessa versione o una più vecchia, e ciò che hai scelto in Personalizza resta ovunque la nuova versione abbia ancora quell'impostazione. Un pacchetto può dire con quale licenza viene consegnato: il nome di una licenza o una riga tua sotto Comportamento, e il testo completo della licenza, scelto lì da un file o tenuto come LICENSE accanto ad action.json in una cartella. Chi importa l'azione vede la riga, e legge il testo dalla finestra di importazione prima che entri. Vovó dice ciò che hai scritto e non vincola nessuno: non controlla chiavi, account né acquisti, e la vendita di un'azione avviene fuori da Vovó. L'icona di copia, accanto, duplica l'azione e apre la copia nell'editor, per partire da una che funziona verso una variante: il suo codice, i file e gli attivatori la seguono; il suo stato, le scene e i pulsanti no, e un attivatore di scorciatoia arriva senza la sua combinazione, così un tasto non le avvia entrambe.
Nel tuo editor
Un'azione si può scrivere nell'editor che preferisci, o con una build tua: tieni le sue parti in una cartella come le tiene un pacchetto (action.json, index.html, style.css, script.js e files/) e, in un terminale, esegui vovo dev con la cartella. Vovó apre il suo editor sull'azione con quel nome, creandola dalla cartella quando il profilo non ce l'ha, e mostra subito nell'anteprima ogni cambio salvato nella cartella; Simula funziona come sempre. Come un cambio scritto qui, arriva alla diretta solo quando Salvi. vovo dev stop, o Smetti di seguire in cima all'editor, lascia la cartella.
vovo new <cartella> crea quella cartella per te, vuota o da uno degli esempi (vovo new --list li elenca, e --from goal ne prende uno), e vovo check <cartella> dice in una volta tutto ciò che non va in una cartella o in un pacchetto, senza creare né aprire nulla: ogni problema con il suo file, e ciò che Vovó accetterebbe ignorandolo, come una chiave che non usa. Entrambi rispondono anche con Vovó chiusa. vovo export <azione> <cartella> scrive come una cartella così un'azione che hai già.
vovo dev scrive anche vovo.d.ts nella cartella, l'API come ce l'ha questa Vovó, e un jsconfig.json quando non ce n'è uno, così un editor come VS Code completa vovo., i nomi degli eventi in vovo.on(" e i campi di ogni evento. Nessuno dei due fa parte dell'azione, e un pacchetto non li porta mai; sotto controllo di versione, tienili o ignorali come preferisci. Perché un campo sbagliato venga sottolineato, aggiungi "checkJs": true alle compilerOptions del jsconfig.
Lì scrive anche action.schema.json, che non fa parte dell'azione neppure lui: con "$schema": "./action.schema.json" all'inizio di action.json, l'editor completa le sue chiavi, propone eventi e permessi per nome e sottolinea ciò che Vovó rifiuterebbe.
L'anteprima si apre anche nel tuo browser, all'indirizzo che stampa vovo dev o dalla freccia nell'angolo dell'anteprima: la stessa bozza, eseguita dallo stesso vovo che in onda, ricaricata a ogni cambio, raggiunta da Simula, e con gli strumenti per sviluppatori del browser (la sua console, i punti di interruzione, gli elementi).
Per mostrarla in diretta
L'azione deve stare in una scena, e la scena in OBS.