Loading the Kaya editor…
// A Quiet Harbor: a visual novel with a face. visual-novel.html draws the
// stage; this program owns the story. Press Space in Preview (or tap
// Continue) to advance, then choose before the tide turns. Each advance is
// answered by the next line, each choice by its ending.
//
// faces.json declares the face: it reads vn.scene, vn.line, vn.choices and
// vn.end, and sends vn.advance and vn.choice {index, text}. No model is called.
mount(component: "visual-novel", layout: "full")
"⚓ A Quiet Harbor. Press Space in the Preview to advance, and choose when asked."
// Dawn.
emitEvent(eventType: "vn.scene", data: {location: "A quiet harbor at dawn", tone: "dawn"})
emitEvent(eventType: "vn.line", data: {speaker: "Mira", text: "You came. I wasn't sure you would.", emotion: "surprised"})
awaitEvent(eventType: "vn.advance")
// The light shifts to the sea as she warns you of the tide.
emitEvent(eventType: "vn.scene", data: {location: "The dock, mid-morning", tone: "sea"})
emitEvent(eventType: "vn.line", data: {speaker: "Mira", text: "The tide turns at noon. After that, the boat is gone, and so is the answer you came for.", emotion: "thinking"})
awaitEvent(eventType: "vn.advance")
// The question, and the choice.
emitEvent(eventType: "vn.line", data: {speaker: "Mira", text: "So. What will it be?", emotion: "default"})
emitEvent(eventType: "vn.choices", data: {prompt: "Choose", options: ["Take the boat with her", "Stay and ask the question now", "Say nothing, and watch the water"]})
// Any session client can post vn.choice straight to the event door, past the
// face's schema, so anything but the first two options is a silence.
let pick = awaitEvent(eventType: "vn.choice")
let idx = pick.content[0].data?.index ?? -1
emitEvent(eventType: "vn.choices", data: {prompt: "", options: []})
if idx == 0 {
emitEvent(eventType: "vn.scene", data: {location: "Open water", tone: "sea"})
emitEvent(eventType: "vn.line", data: {speaker: "Mira", text: "Then cast off. Whatever we find, we find together.", emotion: "happy"})
} else if idx == 1 {
emitEvent(eventType: "vn.line", data: {speaker: "Mira", text: "Brave. Ask it, then, before the tide decides for us both.", emotion: "surprised"})
} else {
emitEvent(eventType: "vn.scene", data: {location: "The empty dock", tone: "dusk"})
emitEvent(eventType: "vn.line", data: {speaker: "Mira", text: "I see. Some answers are silences. Goodbye, then.", emotion: "sad"})
}
emitEvent(eventType: "vn.end", data: {title: "The end"})
"The end."