{"id":148,"date":"2026-05-31T18:18:25","date_gmt":"2026-05-31T18:18:25","guid":{"rendered":"https:\/\/camp.wiserighteous.org\/?page_id=148"},"modified":"2026-05-31T18:29:07","modified_gmt":"2026-05-31T18:29:07","slug":"identify-unrighteous-behavior-patterns-game-mode","status":"publish","type":"page","link":"https:\/\/camp.wiserighteous.org\/index.php\/identify-unrighteous-behavior-patterns-game-mode\/","title":{"rendered":"Good Heart Heroes"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\">\n    <title>Righteous Rangers \u2013 Mission: Good Choices<\/title>\n    <style>\n        * {\n            box-sizing: border-box;\n            user-select: none; \/* prevent accidental text selection on buttons *\/\n        }\n        body {\n            font-family: 'Comic Neue', 'Comic Neue', 'Segoe UI', 'Comic Sans MS', 'Chalkboard SE', cursive, sans-serif;\n            background: linear-gradient(145deg, #c8e8ff 0%, #9ad4f5 100%);\n            min-height: 100vh;\n            margin: 0;\n            padding: 20px;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n        }\n        .game-container {\n            max-width: 900px;\n            width: 100%;\n            background: #fff9ef;\n            border-radius: 64px;\n            box-shadow: 0 20px 35px rgba(0,0,0,0.2);\n            overflow: hidden;\n            transition: all 0.2s;\n        }\n        .header {\n            background: #ffb347;\n            padding: 15px 25px;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            border-bottom: 5px solid #ff8c1a;\n        }\n        .title {\n            font-size: 1.6rem;\n            font-weight: bold;\n            color: white;\n            text-shadow: 2px 2px 0 #b4621a;\n        }\n        .badge-area {\n            background: #fff0c0;\n            padding: 6px 15px;\n            border-radius: 40px;\n            font-size: 0.9rem;\n            font-weight: bold;\n            color: #b45f06;\n        }\n        .main-card {\n            padding: 25px 30px;\n        }\n        .story-box {\n            background: #feffdd;\n            border-radius: 48px;\n            padding: 20px;\n            border: 3px solid #ffcd94;\n            margin-bottom: 25px;\n            font-size: 1.2rem;\n            line-height: 1.4;\n            text-align: center;\n        }\n        .character {\n            font-size: 3rem;\n            margin-bottom: 8px;\n        }\n        .choices {\n            display: flex;\n            flex-wrap: wrap;\n            gap: 15px;\n            justify-content: center;\n            margin: 20px 0;\n        }\n        .choice-btn {\n            background: #f2d8b0;\n            border: none;\n            border-radius: 60px;\n            padding: 12px 25px;\n            font-family: inherit;\n            font-weight: bold;\n            font-size: 1rem;\n            cursor: pointer;\n            transition: 0.1s;\n            box-shadow: 0 4px 0 #b48b5a;\n        }\n        .choice-btn:active {\n            transform: translateY(2px);\n            box-shadow: 0 2px 0 #b48b5a;\n        }\n        .tool-grid {\n            display: flex;\n            flex-wrap: wrap;\n            gap: 15px;\n            justify-content: center;\n            margin: 20px 0;\n        }\n        .tool-card {\n            background: #ffe0b5;\n            width: 140px;\n            border-radius: 40px;\n            padding: 12px 5px;\n            text-align: center;\n            cursor: pointer;\n            transition: 0.1s;\n            border: 2px solid #ffb347;\n        }\n        .tool-card.selected {\n            background: #ffb347;\n            color: white;\n            border-color: white;\n            transform: scale(1.02);\n        }\n        .next-btn {\n            background: #4caf50;\n            color: white;\n            font-size: 1.2rem;\n            padding: 12px 30px;\n            border: none;\n            border-radius: 60px;\n            cursor: pointer;\n            font-weight: bold;\n            margin-top: 20px;\n            width: 100%;\n        }\n        .reset-btn {\n            background: #f44336;\n            margin-top: 10px;\n        }\n        .feedback {\n            background: #e0f2fe;\n            border-radius: 32px;\n            padding: 12px;\n            margin: 20px 0;\n            text-align: center;\n            font-weight: bold;\n        }\n        .garden {\n            background: #e3f2cf;\n            border-radius: 40px;\n            padding: 15px;\n            margin-top: 20px;\n            display: flex;\n            gap: 12px;\n            flex-wrap: wrap;\n            align-items: center;\n            justify-content: center;\n        }\n        .flower {\n            font-size: 2rem;\n            filter: drop-shadow(2px 2px 2px rgba(0,0,0,0.2));\n        }\n        button {\n            font-family: inherit;\n        }\n        .hidden {\n            display: none;\n        }\n        @media (max-width: 550px) {\n            .game-container { border-radius: 32px; }\n            .main-card { padding: 20px; }\n            .choice-btn { font-size: 0.8rem; padding: 8px 16px; }\n            .tool-card { width: 110px; font-size: 0.8rem; }\n        }\n    <\/style>\n<\/head>\n<body>\n<div class=\"game-container\" id=\"gameApp\">\n    <div class=\"header\">\n        <div class=\"title\">\u2b50 Righteous Rangers<\/div>\n        <div class=\"badge-area\" id=\"badgeDisplay\">\ud83c\udf31 Garden: 0 flowers<\/div>\n    <\/div>\n    <div class=\"main-card\" id=\"mainContent\">\n        <!-- dynamic content -->\n    <\/div>\n<\/div>\n\n<script>\n    \/\/ Game state\n    let gameState = {\n        currentEpisode: 1,\n        currentStep: \"examine\", \/\/ examine, equip, engage, finished\n        completedEpisodes: [],   \/\/ store IDs of episodes fully completed\n        earnedBadges: [],        \/\/ pattern names\n        \/\/ episode specific data\n        selectedPattern: null,\n        selectedTool: null\n    };\n\n    \/\/ Episode database (first episode)\n    const episodes = {\n        1: {\n            title: \"The Broken Sculpture\",\n            story: \"\ud83d\udc3b\u200d\u2744\ufe0f Mia the bear made a beautiful clay butterfly. \ud83d\udc30 Tom the rabbit was playing and accidentally knocked it over \u2013 CRASH! The sculpture broke into pieces.\",\n            characters: \"Mia (bear) and Tom (rabbit)\",\n            examine: {\n                question: \"What unrighteous pattern did Mia show? She yelled: 'You always break everything! I hate you!'\",\n                options: [\n                    { text: \"\ud83d\ude21 Blaming\", value: \"blaming\", correct: true },\n                    { text: \"\ud83d\ude36 Avoiding\", value: \"avoiding\", correct: false },\n                    { text: \"\u26a1 Reacting quickly (yelling)\", value: \"reacting\", correct: true }  \/\/ both blaming and reacting are acceptable but we'll accept either? For simplicity we accept Blaming as primary.\n                ],\n                correctValues: [\"blaming\", \"reacting\"] \/\/ both can be considered correct, but UI will allow any choice, we'll give feedback.\n            },\n            equip: {\n                description: \"Now choose a Righteous Tool to help Mia fix the situation.\",\n                tools: [\n                    { name: \"\ud83e\uddd8 Pause Button\", desc: \"Take 3 deep breaths before speaking\", effect: \"Mia calms down.\" },\n                    { name: \"\ud83d\udee1\ufe0f Honesty Shield\", desc: \"Say how you feel without blaming\", effect: \"Mia says: 'I'm sad my sculpture broke, but I know you didn't mean it.'\" },\n                    { name: \"\ud83e\udd1d Helper's Hand\", desc: \"Offer to fix it together\", effect: \"Mia asks Tom to help rebuild the butterfly.\" }\n                ]\n            },\n            engage: {\n                miniGameDescription: \"Help Mia finish the sentence. Drag the feeling slider and click the right words.\",\n                \/\/ we'll create a simple button selection instead of drag for simplicity\n                sentenceStart: \"I feel ______, but I can ______.\",\n                options: [\n                    { feeling: \"angry\", action: \"yell\", correct: false },\n                    { feeling: \"sad\", action: \"tell you how I feel and forgive\", correct: true },\n                    { feeling: \"confused\", action: \"run away\", correct: false }\n                ],\n                correctFeeling: \"sad\",\n                correctAction: \"tell you how I feel and forgive\"\n            },\n            reward: {\n                pattern: \"Blaming Buster\",\n                flower: \"\ud83c\udf3b\",\n                badge: \"Blaming Buster\"\n            }\n        }\n    };\n\n    \/\/ Load saved data from localStorage\n    function loadGame() {\n        const saved = localStorage.getItem(\"righteousRangers\");\n        if (saved) {\n            try {\n                const data = JSON.parse(saved);\n                gameState.completedEpisodes = data.completedEpisodes || [];\n                gameState.earnedBadges = data.earnedBadges || [];\n                updateBadgeDisplay();\n            } catch(e) {}\n        }\n        \/\/ always start from episode 1 examine mode (but if completed, we could show garden; but we'll default to episode 1 examine)\n        gameState.currentEpisode = 1;\n        gameState.currentStep = \"examine\";\n        gameState.selectedPattern = null;\n        gameState.selectedTool = null;\n        render();\n    }\n\n    function saveGame() {\n        const toSave = {\n            completedEpisodes: gameState.completedEpisodes,\n            earnedBadges: gameState.earnedBadges\n        };\n        localStorage.setItem(\"righteousRangers\", JSON.stringify(toSave));\n        updateBadgeDisplay();\n    }\n\n    function updateBadgeDisplay() {\n        const badgeDiv = document.getElementById(\"badgeDisplay\");\n        if (badgeDiv) {\n            badgeDiv.innerHTML = `\ud83c\udf3c Garden: ${gameState.earnedBadges.length} flower${gameState.earnedBadges.length !== 1 ? 's' : ''}`;\n        }\n    }\n\n    \/\/ Mark episode as completed and give badge\/flower\n    function completeEpisode() {\n        const ep = episodes[gameState.currentEpisode];\n        if (!gameState.completedEpisodes.includes(gameState.currentEpisode)) {\n            gameState.completedEpisodes.push(gameState.currentEpisode);\n            if (ep.reward.badge && !gameState.earnedBadges.includes(ep.reward.badge)) {\n                gameState.earnedBadges.push(ep.reward.badge);\n            }\n            saveGame();\n            renderGarden(); \/\/ update garden on main content if needed\n        }\n        gameState.currentStep = \"finished\";\n        render();\n    }\n\n    \/\/ Render garden in the main view after completion or on demand\n    function renderGarden() {\n        const gardenDiv = document.createElement(\"div\");\n        gardenDiv.className = \"garden\";\n        gardenDiv.innerHTML = `<strong>\ud83c\udf37 Your Garden of Growth \ud83c\udf37<\/strong><br>`;\n        if (gameState.earnedBadges.length === 0) {\n            gardenDiv.innerHTML += `<div>No flowers yet. Finish a mission to grow a flower!<\/div>`;\n        } else {\n            gameState.earnedBadges.forEach(badge => {\n                gardenDiv.innerHTML += `<div class=\"flower\">\ud83c\udf3b ${badge}<\/div>`;\n            });\n        }\n        return gardenDiv;\n    }\n\n    \/\/ Main rendering\n    function render() {\n        const container = document.getElementById(\"mainContent\");\n        if (!container) return;\n        const ep = episodes[gameState.currentEpisode];\n        if (!ep) {\n            container.innerHTML = `<h3>\ud83c\udf89 You've completed all missions! \ud83c\udf89<\/h3>${renderGarden().outerHTML}<button class=\"next-btn reset-btn\" id=\"resetGameBtn\">Start Over<\/button>`;\n            document.getElementById(\"resetGameBtn\")?.addEventListener(\"click\", () => {\n                localStorage.removeItem(\"righteousRangers\");\n                location.reload();\n            });\n            return;\n        }\n\n        if (gameState.currentStep === \"examine\") {\n            container.innerHTML = `\n                <div class=\"story-box\">\n                    <div class=\"character\">\ud83d\udc3b\u200d\u2744\ufe0f + \ud83d\udc30<\/div>\n                    <p><strong>\ud83d\udcd6 ${ep.title}<\/strong><br>${ep.story}<\/p>\n                    <p>${ep.examine.question}<\/p>\n                <\/div>\n                <div class=\"choices\" id=\"examineChoices\">\n                    ${ep.examine.options.map(opt => `<button class=\"choice-btn\" data-value=\"${opt.value}\">${opt.text}<\/button>`).join('')}\n                <\/div>\n                <button class=\"next-btn\" id=\"examineNextBtn\" disabled>\u27a1\ufe0f Next: Choose Tool<\/button>\n                <div class=\"feedback\" id=\"examineFeedback\"><\/div>\n            `;\n            const buttons = document.querySelectorAll(\"#examineChoices .choice-btn\");\n            let selectedValue = null;\n            buttons.forEach(btn => {\n                btn.addEventListener(\"click\", () => {\n                    buttons.forEach(b => b.style.background = \"#f2d8b0\");\n                    btn.style.background = \"#ffb347\";\n                    selectedValue = btn.getAttribute(\"data-value\");\n                    const correctValues = ep.examine.correctValues || [\"blaming\"];\n                    const isCorrect = correctValues.includes(selectedValue);\n                    const feedbackDiv = document.getElementById(\"examineFeedback\");\n                    if (isCorrect) {\n                        feedbackDiv.innerHTML = \"\u2705 Great spotting! That's an unrighteous pattern. Now let's equip a tool to make it right.\";\n                        document.getElementById(\"examineNextBtn\").disabled = false;\n                        gameState.selectedPattern = selectedValue;\n                    } else {\n                        feedbackDiv.innerHTML = \"\u274c Hmm, that's not the main unrighteous behaviour. Try again!\";\n                        document.getElementById(\"examineNextBtn\").disabled = true;\n                    }\n                });\n            });\n            document.getElementById(\"examineNextBtn\").addEventListener(\"click\", () => {\n                if (gameState.selectedPattern) {\n                    gameState.currentStep = \"equip\";\n                    render();\n                }\n            });\n        } \n        else if (gameState.currentStep === \"equip\") {\n            container.innerHTML = `\n                <div class=\"story-box\">\n                    <p>\ud83d\udee0\ufe0f ${ep.equip.description}<\/p>\n                <\/div>\n                <div class=\"tool-grid\" id=\"toolGrid\">\n                    ${ep.equip.tools.map(tool => `<div class=\"tool-card\" data-tool=\"${tool.name}\"><strong>${tool.name}<\/strong><br><small>${tool.desc}<\/small><\/div>`).join('')}\n                <\/div>\n                <button class=\"next-btn\" id=\"equipNextBtn\" disabled>\u2728 Use Tool & Move to Practice<\/button>\n                <div class=\"feedback\" id=\"equipFeedback\"><\/div>\n            `;\n            const toolCards = document.querySelectorAll(\".tool-card\");\n            let selectedTool = null;\n            toolCards.forEach(card => {\n                card.addEventListener(\"click\", () => {\n                    toolCards.forEach(c => c.classList.remove(\"selected\"));\n                    card.classList.add(\"selected\");\n                    selectedTool = card.getAttribute(\"data-tool\");\n                    gameState.selectedTool = selectedTool;\n                    document.getElementById(\"equipFeedback\").innerHTML = `\u2705 You chose ${selectedTool}. Great! Now see how it helps.`;\n                    document.getElementById(\"equipNextBtn\").disabled = false;\n                });\n            });\n            document.getElementById(\"equipNextBtn\").addEventListener(\"click\", () => {\n                if (gameState.selectedTool) {\n                    gameState.currentStep = \"engage\";\n                    render();\n                }\n            });\n        }\n        else if (gameState.currentStep === \"engage\") {\n            const engageData = ep.engage;\n            container.innerHTML = `\n                <div class=\"story-box\">\n                    <p>\ud83c\udfae ${engageData.miniGameDescription}<\/p>\n                    <p>Complete the sentence: <strong>\"I feel ______, but I can ______.\"<\/strong><\/p>\n                <\/div>\n                <div class=\"choices\" id=\"engageOptions\">\n                    ${engageData.options.map(opt => `<button class=\"choice-btn\" data-feeling=\"${opt.feeling}\" data-action=\"${opt.action}\">\"I feel ${opt.feeling}, but I can ${opt.action}.\"<\/button>`).join('')}\n                <\/div>\n                <button class=\"next-btn\" id=\"engageCompleteBtn\" disabled>\ud83c\udf31 Complete Mission<\/button>\n                <div class=\"feedback\" id=\"engageFeedback\"><\/div>\n            `;\n            const engageBtns = document.querySelectorAll(\"#engageOptions .choice-btn\");\n            let correctChosen = false;\n            engageBtns.forEach(btn => {\n                btn.addEventListener(\"click\", () => {\n                    const feeling = btn.getAttribute(\"data-feeling\");\n                    const action = btn.getAttribute(\"data-action\");\n                    const isCorrect = (feeling === engageData.correctFeeling && action === engageData.correctAction);\n                    if (isCorrect) {\n                        document.getElementById(\"engageFeedback\").innerHTML = \"\ud83c\udf89 Perfect! That's a righteous response. You saved the friendship!\";\n                        document.getElementById(\"engageCompleteBtn\").disabled = false;\n                        correctChosen = true;\n                    } else {\n                        document.getElementById(\"engageFeedback\").innerHTML = \"\u274c Not quite. Try a kinder way \u2013 Mia is sad, not just angry. What would help both feel better?\";\n                        document.getElementById(\"engageCompleteBtn\").disabled = true;\n                    }\n                });\n            });\n            document.getElementById(\"engageCompleteBtn\").addEventListener(\"click\", () => {\n                if (correctChosen || true) { \/\/ actually need to track if correct chosen, but we'll enforce via variable\n                    if (!document.getElementById(\"engageCompleteBtn\").disabled) {\n                        completeEpisode();\n                    } else {\n                        alert(\"First choose the correct sentence!\");\n                    }\n                } else {\n                    alert(\"First choose the correct sentence!\");\n                }\n            });\n        }\n        else if (gameState.currentStep === \"finished\") {\n            container.innerHTML = `\n                <div class=\"story-box\">\n                    <p>\ud83c\udf89\u2728 Mission Accomplished! \u2728\ud83c\udf89<\/p>\n                    <p>You helped Mia and Tom become friends again. You earned the <strong>${ep.reward.badge}<\/strong> badge!<\/p>\n                <\/div>\n                <div class=\"garden\" id=\"gardenView\"><\/div>\n                <button class=\"next-btn\" id=\"playAgainBtn\">\u2b50 Play Again (New Episode Coming Soon!) \u2b50<\/button>\n                <button class=\"next-btn reset-btn\" id=\"resetAllBtn\">\ud83d\uddd1\ufe0f Reset All Progress<\/button>\n            `;\n            const gardenDiv = renderGarden();\n            document.getElementById(\"gardenView\")?.replaceWith(gardenDiv);\n            document.getElementById(\"playAgainBtn\")?.addEventListener(\"click\", () => {\n                \/\/ reset episode but keep badges? Actually we just restart the same episode but not re-award badge. \n                \/\/ For prototype, we will reset the step but keep completed episodes to avoid double badge.\n                if (!gameState.completedEpisodes.includes(1)) {\n                    \/\/ if not completed, call complete again? but it's already completed.\n                }\n                gameState.currentStep = \"examine\";\n                gameState.selectedPattern = null;\n                gameState.selectedTool = null;\n                render();\n            });\n            document.getElementById(\"resetAllBtn\")?.addEventListener(\"click\", () => {\n                if (confirm(\"Delete all your flowers and start over?\")) {\n                    localStorage.removeItem(\"righteousRangers\");\n                    location.reload();\n                }\n            });\n        }\n    }\n\n    \/\/ Initialize\n    loadGame();\n<\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Righteous Rangers \u2013 Mission: Good Choices \u2b50 Righteous Rangers \ud83c\udf31 Garden: 0 flowers<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-148","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/camp.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/pages\/148","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/camp.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/camp.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/camp.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/camp.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/comments?post=148"}],"version-history":[{"count":3,"href":"https:\/\/camp.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/pages\/148\/revisions"}],"predecessor-version":[{"id":153,"href":"https:\/\/camp.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/pages\/148\/revisions\/153"}],"wp:attachment":[{"href":"https:\/\/camp.wiserighteous.org\/index.php\/wp-json\/wp\/v2\/media?parent=148"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}