Quiz
Run a spoken quiz, game show or test on your page with a character as host
Experimental, Team plan
The request and response shape may change.
A character hosts a run of a question set. Ordering, hints, judging and scoring happen on the server; the page shows the scene and forwards what the player says. Sets are authored in Question Sets; how a run works is in Web API Quiz.
The host must be in characters. Restrict playable sets with questionSets (default: all your team's sets).
Element
<neocortex-quiz endpoint="/api/neocortex" character-id="host-id" question-set-id="set-id" voice></neocortex-quiz>Options, typed and spoken answers, hint, pass, progress and leaderboard are built in. state is idle, playing or finished; nx-turn and nx-finished let you follow along.
QuizAgent
import { QuizAgent } from "@neocortex-link/web/client";
const quiz = new QuizAgent({ endpoint: "/api/neocortex", characterId: "host-id", questionSetId: "set-id", voice: true });
quiz.on("hostLine", ({ line }) => subtitles.show(line.text));
quiz.on("questionChanged", (question) => ui.showQuestion(question));
quiz.on("leaderboardChanged", (standings) => ui.showScores(standings));
quiz.on("finished", () => ui.showResults(quiz.leaderboard));
startButton.onclick = () => {
quiz.primeAudio();
quiz.begin();
};| Player did | Call |
|---|---|
| Clicked an option | choose(optionId) |
| Spoke | say(transcript) |
| Typed | say(text, { typed: true }) |
| Skipped or timed out | pass() |
Hints, repeats and stopping are just words: say("Can I have a hint?"). lastIntent says how the host read it.
Voice answers
Open the mic after the host finishes, when it expects something:
const mic = new AudioReceiver();
mic.on("recorded", async (wav) => {
const { response } = await quiz.client.transcribe({ characterId: "host-id", audio: wav });
if (response.trim()) quiz.say(response.trim());
else mic.start();
});
quiz.on("hostFinished", (turn) => {
if (turn.expecting !== "nothing") mic.start();
});Don't send an empty transcript as pass(). A pass means the player chose to skip.
Scene timing
questionChanged fires after the host has read the question. To show the scene as the question line starts, and preload the next one:
let next = null;
quiz.on("turn", (turn) => (next = turn.question ?? null));
quiz.on("hostLine", ({ line }) => line.role === "question" && next?.keyword && scene.show(next.keyword));
quiz.on("upcoming", ({ keyword }) => keyword && scene.preload(keyword));Several players
quiz.begin([{ id: "alex", displayName: "Alex" }, { id: "maya", displayName: "Maya" }]);
quiz.chooseAs("alex", optionId);
quiz.sayAs("maya", transcript);
quiz.passAs("maya"); // their timer ran outThe host waits until everyone has answered; pending and answered track who. Timers are yours. Up to 10 players.
State and errors
On the agent: question, progress, expecting, leaderboard, lastResult, attempt, attemptsLeft, hintGiven, isFinished.
creditsExhaustedfires beforeerrorwhen the team is out of credits.- An answer after the run ended replays the closing turn and fires
finished. - Input before
begin()or after the end firesinputDropped. resync()restores standings andexpectingafter a dropped connection. Runs are not kept across reloads.