Role Playing Story Adventure body { font-family: Arial, sans-serif; background-color: #fffbeb; margin: 0; padding: 20px; } .container { max-width: 800px; margin: 0 auto; background-color: #fffbeb; border-radius: 8px; padding: 20px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); } h1 { text-align: center; color: #92400e; margin-bottom: 20px; } .scene-container { background-color: white; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } .character-header { display: flex; align-items: center; margin-bottom: 15px; } .character-icon { font-size: 2rem; margin-right: 10px; } .character-name { font-size: 1.2rem; font-weight: bold; color: #92400e; } .scene-text { margin-bottom: 20px; font-size: 1.1rem; line-height: 1.5; } .choices-container { margin-top: 20px; } .choice-heading { font-weight: bold; margin-bottom: 10px; color: #92400e; } .choice-btn { display: block; width: 100%; text-align: left; padding: 12px; margin-bottom: 8px; background-color: #fef3c7; border: 1px solid #fde68a; border-radius: 4px; cursor: pointer; font-size: 1rem; transition: background-color 0.2s; } .choice-btn:hover { background-color: #fde68a; } .ending-message { padding: 15px; background-color: #fef3c7; border: 1px solid #fde68a; border-radius: 4px; } .builder-section { background-color: white; padding: 20px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } .builder-title { font-weight: bold; font-size: 1.2rem; margin-bottom: 15px; color: #92400e; } .form-group { margin-bottom: 15px; } .form-label { display: block; font-size: 0.9rem; font-weight: 500; margin-bottom: 5px; color: #4b5563; } .form-input { width: 100%; padding: 8px; border: 1px solid #d1d5db; border-radius: 4px; font-size: 1rem; } .form-textarea { width: 100%; padding: 8px; border: 1px solid #d1d5db; border-radius: 4px; font-size: 1rem; min-height: 80px; } .btn { padding: 10px 15px; border: none; border-radius: 4px; cursor: pointer; font-size: 1rem; } .btn-primary { background-color: #d97706; color: white; } .btn-primary:hover { background-color: #b45309; } .btn-secondary { background-color: #6b7280; color: white; } .btn-danger { background-color: #92400e; color: white; } .edit-btn { font-size: 0.8rem; background-color: #e5e7eb; padding: 4px 8px; border: none; border-radius: 4px; cursor: pointer; margin-bottom: 15px; } .controls { display: flex; justify-content: space-between; } .teacher-notes { margin-top: 20px; padding: 15px; background-color: #d1fae5; border-radius: 8px; } .teacher-title { font-weight: bold; color: #065f46; } .teacher-list { margin-left: 20px; margin-top: 10px; } .teacher-list li { margin-bottom: 5px; } .teacher-suggestion { margin-top: 10px; font-style: italic; font-size: 0.9rem; }

Role Playing Story Adventure

Story Builder
New Choice Text:
New Scene ID:
Character Role:
Scene Text:
Add This Path
Go Back Start Over
Teacher Notes: W.3.3 Alignment
  • Students establish characters and settings through role-based scenarios
  • Narrative sequence is developed through branching choices
  • Dialogue and descriptions create vivid experiences
  • Multiple ending possibilities demonstrate story closure techniques
  • Character motivation exploration through decision-making

Suggestion: Have students first map out their story on paper, identifying key decision points and character development opportunities.

// Initial story data structure const storyData = { start: { text: “You are in a busy marketplace. As the town’s new guard, it’s your job to keep the peace. Suddenly, you notice a child crying near a fruit stand.”, character: “Town Guard”, choices: [ { text: “Approach the child and ask what’s wrong”, nextNode: “approach_child” }, { text: “Watch from a distance to see if parents appear”, nextNode: “watch_distance” } ] }, approach_child: { text: “\”I can’t find my mom,\” the child sobs. \”We were looking at apples and then she was gone!\” The marketplace is crowded and noisy.”, character: “Town Guard”, choices: [ { text: “Take the child’s hand and search together”, nextNode: “search_together” }, { text: “Ask the fruit vendor if they saw where the mother went”, nextNode: “ask_vendor” } ] }, watch_distance: { text: “While watching, you see the fruit vendor trying to shoo the child away. The child seems even more upset now.”, character: “Town Guard”, choices: [ { text: “Intervene and speak to the vendor”, nextNode: “speak_vendor” }, { text: “Now approach the child directly”, nextNode: “approach_child” } ] }, search_together: { text: “You and the child weave through the market. \”What does your mother look like?\” you ask. \”She’s wearing a blue dress,\” the child answers.”, character: “Town Guard”, choices: [ { text: “Head toward the town square”, nextNode: “town_square” }, { text: “Check by the baker’s stall”, nextNode: “bakery” } ] }, ask_vendor: { text: “\”The woman in the blue dress? She went toward the fountain,\” the vendor says. \”Poor thing was frantically looking for someone.\””, character: “Town Guard”, choices: [ { text: “Take the child to the fountain”, nextNode: “fountain” }, { text: “Ask the vendor to watch the child while you check”, nextNode: “vendor_watches” } ] }, speak_vendor: { text: “\”This child is lost,\” you explain to the vendor. \”Have you seen their mother?\” The vendor points toward the town fountain. \”A woman was looking for a child.\””, character: “Town Guard”, choices: [ { text: “Take the child to the fountain”, nextNode: “fountain” }, { text: “Thank the vendor and ask more questions”, nextNode: “more_questions” } ] }, town_square: { text: “In the town square, you spot a woman in a blue dress frantically searching. \”Mom!\” the child yells, running toward her. The woman turns with relief flooding her face.”, character: “Town Guard”, choices: [ { text: “Approach the reunited pair”, nextNode: “reunion” }, { text: “Watch from a distance to ensure all is well”, nextNode: “watch_reunion” } ] }, bakery: { text: “At the bakery, there’s no sign of a woman in a blue dress. The child looks increasingly worried.”, character: “Town Guard”, choices: [ { text: “Try the town square next”, nextNode: “town_square” }, { text: “Ask the baker if they’ve seen the mother”, nextNode: “ask_baker” } ] }, fountain: { text: “At the fountain sits a woman in a blue dress, wiping tears away. She jumps up when she sees the child. \”Oh thank goodness!\” she cries, embracing the child.”, character: “Town Guard”, choices: [ { text: “Introduce yourself as the town guard”, nextNode: “introduce” }, { text: “Give them a moment before speaking”, nextNode: “give_moment” } ] }, vendor_watches: { text: “When you return from the fountain with news of the mother, the vendor and child are gone. You panic until you see them already walking toward the fountain.”, character: “Town Guard”, choices: [ { text: “Follow them to the fountain”, nextNode: “fountain” }, { text: “Take a shortcut to reach the fountain first”, nextNode: “shortcut” } ] }, more_questions: { text: “\”When did you last see them together?\” you ask. \”Just moments ago,\” the vendor replies. \”The mother was buying apples and turned around to pay me. When she looked back, the child was gone.\””, character: “Town Guard”, choices: [ { text: “Head to the fountain immediately”, nextNode: “fountain” }, { text: “Ask the child about wandering off”, nextNode: “ask_child” } ] }, reunion: { text: “\”Thank you so much for helping my child,\” the mother says gratefully. \”It’s my first week as town guard,\” you explain. \”Just doing my duty to help.\””, character: “Town Guard”, choices: [ { text: “Offer safety advice about the market”, nextNode: “safety_advice” }, { text: “Wish them well and continue your patrol”, nextNode: “continue_patrol” } ] }, watch_reunion: { text: “From a distance, you see the joyful reunion. The mother kneels to embrace her child, then looks around as if searching for someone – perhaps whoever helped her child.”, character: “Town Guard”, choices: [ { text: “Approach and introduce yourself”, nextNode: “introduce” }, { text: “Give a friendly wave and continue your patrol”, nextNode: “wave_continue” } ] }, ask_baker: { text: “\”A woman in blue was here not five minutes ago,\” the baker says. \”She was looking for her child and headed toward the fountain.\””, character: “Town Guard”, choices: [ { text: “Thank the baker and head to the fountain”, nextNode: “fountain” }, { text: “Ask for more details about the woman”, nextNode: “more_details” } ] }, introduce: { text: “\”I’m glad I could help,\” you say, introducing yourself as the new town guard. \”Please let me know if you need anything else.\” The mother thanks you profusely for your kindness.”, character: “Town Guard”, choices: [] // Ending }, give_moment: { text: “After giving them a moment, you approach. \”Is everything alright now?\” The mother nods gratefully. \”Thank you for helping my child. We’ll be more careful in the market.\””, character: “Town Guard”, choices: [] // Ending }, shortcut: { text: “Taking a shortcut, you arrive at the fountain just as the vendor and child approach from the other direction. The mother spots her child and rushes over, overwhelmed with relief.”, character: “Town Guard”, choices: [ { text: “Thank the vendor for their help”, nextNode: “thank_vendor” }, { text: “Check if the family needs anything else”, nextNode: “check_needs” } ] }, ask_child: { text: “\”Did you wander away from your mother?\” you ask gently. The child nods. \”I saw a puppy…\” Understanding dawns on you as you lead the child to the fountain.”, character: “Town Guard”, choices: [ { text: “Talk about staying close to parents”, nextNode: “stay_close_talk” }, { text: “Head to the fountain without further delay”, nextNode: “fountain” } ] }, safety_advice: { text: “\”The market gets very busy,\” you explain. \”Perhaps holding hands or having a meeting spot if separated might help.\” The mother nods appreciatively at your advice.”, character: “Town Guard”, choices: [] // Ending }, continue_patrol: { text: “With a warm smile, you continue your patrol, feeling good about helping reunite the family. It’s been a successful first week as the town guard.”, character: “Town Guard”, choices: [] // Ending }, wave_continue: { text: “You give a friendly wave and continue your patrol. Later, you see the mother and child at the baker’s, and they wave back with grateful smiles.”, character: “Town Guard”, choices: [] // Ending }, more_details: { text: “\”She seemed quite worried,\” the baker adds. \”Said the child was wearing a red cap.\” You look down at the child’s red cap and know you’re on the right track.”, character: “Town Guard”, choices: [ { text: “Head to the fountain immediately”, nextNode: “fountain” } ] }, thank_vendor: { text: “\”Thank you for your help,\” you tell the vendor. They smile. \”It takes a village, doesn’t it?\” The mother approaches to thank you both.”, character: “Town Guard”, choices: [] // Ending }, check_needs: { text: “\”Is there anything else you need?\” you ask the family. \”No, thank you,\” the mother says. \”You’ve done more than enough. We’re just happy to be together again.\””, character: “Town Guard”, choices: [] // Ending }, stay_close_talk: { text: “\”It’s important to stay close to your parents in busy places,\” you explain gently. The child nods seriously. When you reach the fountain, the mother embraces her child with relief.”, character: “Town Guard”, choices: [ { text: “Explain what happened to the mother”, nextNode: “explain_mother” } ] }, explain_mother: { text: “You explain how the child was distracted by a puppy. The mother smiles understandingly. \”Thank you for your help and the valuable lesson,\” she says to you.”, character: “Town Guard”, choices: [] // Ending } }; // Character icons mapping const characterIcons = { “Town Guard”: “🛡️”, “Merchant”: “💰”, “Child”: “👧”, “Baker”: “🍞”, “Farmer”: “🌾”, “Default”: “👤” }; // State management let currentNode = “start”; let history = []; let story = JSON.parse(JSON.stringify(storyData)); // Deep copy let editMode = false; let editingNode = null; // DOM references const sceneContainer = document.getElementById(‘scene-container’); const backBtn = document.getElementById(‘back-btn’); const restartBtn = document.getElementById(‘restart-btn’); const addChoiceBtn = document.getElementById(‘add-choice-btn’); const newChoiceText = document.getElementById(‘new-choice-text’); const newNodeKey = document.getElementById(‘new-node-key’); const newNodeText = document.getElementById(‘new-node-text’); const newNodeCharacter = document.getElementById(‘new-node-character’); // Initialize the story renderCurrentNode(); // Event listeners backBtn.addEventListener(‘click’, goBack); restartBtn.addEventListener(‘click’, restart); addChoiceBtn.addEventListener(‘click’, addChoice); // Navigation function function navigateTo(nodeKey) { history.push(currentNode); currentNode = nodeKey; renderCurrentNode(); } // Go back function function goBack() { if (history.length > 0) { currentNode = history.pop(); renderCurrentNode(); } } // Restart function function restart() { currentNode = “start”; history = []; renderCurrentNode(); } // Add new choice and destination function addChoice() { const choiceText = newChoiceText.value.trim(); const nodeKey = newNodeKey.value.trim(); const nodeText = newNodeText.value.trim(); const nodeCharacter = newNodeCharacter.value.trim() || story[currentNode].character; if (nodeKey && nodeText) { // Create the new node if it doesn’t exist if (!story[nodeKey]) { story[nodeKey] = { text: nodeText, character: nodeCharacter, choices: [] }; } // Add the choice to the current node if (choiceText) { story[currentNode].choices.push({ text: choiceText, nextNode: nodeKey }); } // Clear form fields newChoiceText.value = ”; newNodeKey.value = ”; newNodeText.value = ”; newNodeCharacter.value = ”; // Update the display renderCurrentNode(); } else { alert(‘Please fill in all required fields (Scene ID and Scene Text)’); } } // Enter edit mode function startEditing() { editMode = true; editingNode = currentNode; renderCurrentNode(); } // Save edits function saveEdits() { const textArea = document.getElementById(‘edit-text’); const characterInput = document.getElementById(‘edit-character’); if (editingNode && textArea && characterInput) { story[editingNode].text = textArea.value; story[editingNode].character = characterInput.value; editMode = false; editingNode = null; renderCurrentNode(); } } // Render the current node function renderCurrentNode() { const node = story[currentNode]; if (!node) { sceneContainer.innerHTML = ‘

Error: Node not found!

‘; return; } let html = ”; // Character header html += `
${characterIcons[node.character] || characterIcons[‘Default’]} ${node.character || ‘Character’}
`; // Scene text or edit form if (editMode && editingNode === currentNode) { html += `
Character:
Scene Text: ${node.text}
Save Changes
`; } else { html += `

${node.text}

Edit Scene `; } // Choices if (node.choices && node.choices.length > 0) { html += ‘
‘; html += ‘
What will you do?
‘; node.choices.forEach((choice, index) => { html += ` ${choice.text} `; }); html += ‘
‘; } else { html += `

The End of This Path

Create new choices or start over

`; } sceneContainer.innerHTML = html; }