Xstoryplayer |top| Guide

nodeCounterSpan.textContent = nodeTitle;

// -------- Story Player State ---------- class StoryPlayer constructor(storyGraph, startId, fallbackNode) this.graph = storyGraph; this.startId = startId; this.fallback = fallbackNode; this.history = []; // stack of visited node IDs (strings) this.currentNodeId = startId; this.statsListeners = []; xstoryplayer

// apply a choice by target id makeChoice(targetId) if (!targetId) return false; // check if target exists in graph or fallback let targetNode = this.graph[targetId]; if (!targetNode) // if invalid, maybe use fallback as new node, but also preserve history targetNode = this.fallback; targetId = targetNode.id; // push current node into history before transition this.history.push(this.currentNodeId); this.currentNodeId = targetId; this._notify(); return true; nodeCounterSpan

window.addEventListener("keydown", handleKeyboard); nodeCounterSpan.textContent = nodeTitle

// get current node object getCurrentNode() let node = this.graph[this.currentNodeId]; if (!node) console.warn("missing node, fallback"); node = this.fallback; if (node && node.id !== this.currentNodeId) this.currentNodeId = node.id; if (!this.history.includes(this.currentNodeId)) this.history.push(this.currentNodeId); return node;

/* animations */ @keyframes fadeSlide 0% opacity: 0; transform: translateY(8px); 100% opacity: 1; transform: translateY(0);

// generate choices if (currentNode.choices && currentNode.choices.length > 0) choicesContainer.innerHTML = ""; currentNode.choices.forEach((choice, idx) => const btn = document.createElement("button"); btn.className = "choice-btn"; btn.textContent = choice.text; // store target id btn.dataset.target = choice.targetId; btn.addEventListener("click", (e) => e.stopPropagation(); const target = btn.dataset.target; if (target) player.makeChoice(target); ); choicesContainer.appendChild(btn); ); else // ending screen: special restart hint and maybe extra flair choicesContainer.innerHTML = ` <button class="choice-btn" id="restartFromEnding">✨ Start a new legend ✨</button> `; const restartEndBtn = document.getElementById("restartFromEnding"); if (restartEndBtn) restartEndBtn.addEventListener("click", () => player.reset(); );